文档章节

原生javascript开发仿微信打飞机小游戏

zaaack
 zaaack
发布于 2014/02/04 12:21
字数 1309
阅读 9614
收藏 237

今天闲来无事,于是就打算教一个初学javascript的女童鞋写点东西,因此为了兼顾趣味性与简易程度,果断想到了微信的打飞机小游戏。。

本来想用html5做的,但是毕竟人家才初学,连jquery都还不会,所以最终还是决定用原生的javascript。虽说相对于园内的高手们而言代码算不上优雅,效率算不上高,不过对于初学者来练手还是足以。。

 

   三个文件,main.js(主函数),entity.js(实体类与工厂类),util.js(工具类),基本原理就是把位置信息保存在对象里面,然后在setInterval里面统一对所有对象进行更新显示。程序所用到的飞机与子弹图片都是从微信上截屏得来的。

 

先上图:

 

再上代码:

index.html:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>打飞机</title>
<script type="text/javascript" src="js/util.js"></script>
<script type="text/javascript" src="js/entity.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript">
window.onload=function(){
 Main.init();
 Util.g("startBtn").onclick=function(){
  Main.start();
  this.style.display="none";
 }
}
</script>
</head>
<body>
<div id="parent" style="
        margin: 0 auto; 
        width:350px; height:480px; 
        background-color:#c3c9c9; 
        position: relative;
        overflow:hidden;">
 <div style="
     position:absolute;
        left:5px;
        top:5px;">积分:<span id="score">0</span></div>
    <button 
     style=" 
      position:absolute; 
         left:150px;
            top:240px;
            display:block;" 
        id="startBtn">
    点击开始
    </button>
</div>
</body>
</html>

main.js:

 // JavaScript Document
var Main={
 init:function(){
  Util.init();
 },
 _totalEnemies:8,
 start:function(){
  //初始化敌机
  enemyPlaneFactory.creatEnemyPlane(this._totalEnemies);
  
  //初始化自己
  selfPlane.init();
  
  //初始化子弹
  bulletFactory.creatBullet(100);
  //开始渲染画面
  this._render();
  //开始射击子弹
  this._startShoot();
  
  //初始化键盘事件响应
  this._initEvent();
 },
 
 //渲染定时器
 _render_t:null,
 _render:function(){
  this._render_t=setInterval(function(){
   //渲染敌机
   var enemys=enemyPlaneFactory.enemys;
   for(var i in enemys){
    var enemy=enemys[i];
    enemy.move(0,enemy.speed);
    
    //判断自己是否被敌机击中
    if(enemy.x+enemy.e.width>selfPlane.x+10
     &&enemy.x<selfPlane.x+selfPlane.e.width-10
     &&enemy.y+enemy.e.height>selfPlane.y+selfPlane.e.height/2
     &&enemy.y<selfPlane.y+selfPlane.e.height-40){
      enemy.isDied=true;
      clearInterval(Main._render_t);
      clearInterval(Main._startShoot_t);
      var b=window.confirm("对不起,您已经挂了,是否重玩?")
      if(b){
       window.location.reload();
      }
    }
    
    //判断敌机是否已经消失或者已死
    if(enemy.y>Util.windowHeight||enemy.isDied){
     enemy.restore();
    }
   }
   
   //渲染子弹
   var bullets=bulletFactory.bullets;
   for(var i in bullets){
    var bullet=bullets[i];
    bullet.move(0,-bullet.speed);
    
    for(var i in enemys){
     var enemy=enemys[i];
     //判断子弹是否击中敌机,如果击中则隐藏子弹,杀死敌机,增加积分..
     if(bullet.y>10
      &&bullet.x>enemy.x
      &&bullet.x<enemy.x+enemy.e.width
      &&bullet.y<enemy.y+enemy.e.height){
       enemy.isDied=true;
       bullet.moveTo(0,-bullet.e.height);
       selfPlane.score+=50;
       Util.scoreSpan.innerHTML=selfPlane.score+"";
     }
    }
   }
   
   
  },1000/15);
 },
 //射击定时器
 _startShoot_t:null,
 _startShoot:function(){
  var i=0;
  var bullets=bulletFactory.bullets;
  var bulletsCount=bullets.length;
  this._startShoot_t=setInterval(function(){
   if(i>=bulletsCount){
    i=0;
   }
   var bullet=bullets[i];
   bullet.moveTo(selfPlane.x+selfPlane.e.width/2-bullet.e.width/2,selfPlane.y-bullet.e.height-3);
   i++;
  },300);
 },
 keyMove:10,
 _initEvent:function(){
  window.onkeydown=function(e){
   /*
   37:左
   38:上
   39:右
   40:下
   */
   var keynum;
   var left=37,up=38,right=39,down=40;
   if(window.event){// IE
     keynum = window.event.keyCode;
   }else if(e.which) {// Netscape/Firefox/Opera
     keynum = e.which
   }
   
   switch(keynum){
    case left:
    selfPlane.move(-Main.keyMove,0);
    break;
    case up:
    selfPlane.move(0,-Main.keyMove);
    break;
    case right:
    selfPlane.move(Main.keyMove,0);
    break;
    case down:
    selfPlane.move(0,Main.keyMove);
    break;
    
    default:
    break;
   }
   
   //console.log(keynum);
  }
  
 }
 
 
}

entity.js:

 //自身的对象
var selfPlane={
 x:0,
 y:0,
 score:0,
 e:null,
 init:function(){
  this.x=(Util.windowWidth-Util.selfPlaneElement.width)/2;//相对于父窗体的x偏移(css:left)
  this.y=Util.windowHeight-Util.selfPlaneElement.height;//相对于父窗体的y偏移(css:top)
  this.e=Util.selfPlaneElement;//对应的dom元素
  Util.selfPlaneElement.style.left=this.x+"px";
  Util.selfPlaneElement.style.top=this.y+"px";
  Util.parentElement.appendChild(this.e);
 },
 move:function(moveX,moveY){
  var x=this.x+moveX;
  var y=this.y+moveY;
  
  if(x<0-this.e.width/2||x>Util.windowWidth-this.e.width/2){
   return ;
  }
  if(y<0-this.e.height/2||y>Util.windowHeight-this.e.height/2){
   return ;
  }
  this.x=x;
  this.y=y;
  
  this.e.style.left=this.x+"px";
  this.e.style.top=this.y+"px";
 },
 moveTo:function(x,y){
  
  if(x<0-this.e.width/2||x>Util.windowWidth-this.e.width/2){
   return ;
  }
  if(y<0-this.e.height/2||y>Util.windowHeight-this.e.height/2){
   return ;
  }
  this.x=x;
  this.y=y;
  
  this.e.style.left=this.x+"px";
  this.e.style.top=this.y+"px";
 }
}

//敌机的类
var enemyPlane=function(x,y,speed){
 this.x=x;
 this.y=y;
 this.e=Util.enemyPlaneElement.cloneNode(true);
 this.e.style.left=x;
 this.e.style.top=y;
 this.e.style.display="none";
 Util.parentElement.appendChild(this.e);
 this.e.style.display="block";
 this.speed=speed;
 this.isDied=false;
}
//prototype:原型
enemyPlane.prototype.move=function(moveX,moveY){
 this.x+=moveX;
 this.y+=moveY;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}
//敌人复活
enemyPlane.prototype.restore=function(){
 this.x=Math.random()*(Util.windowWidth-Util.enemyPlaneElement.width);
 this.y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
 this.speed=2+Math.random()*4;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
 this.isDied=false;
}
//敌机工厂
var enemyPlaneFactory={
 enemys:[],
 creatEnemyPlane:function(n){
  for(var i=0;i<n;i++){
   //0~1 乘以窗口宽度,得到的就是从0~窗口宽度的一个随机x值
   var x=Math.random()*(Util.windowWidth-Util.enemyPlaneElement.width);
   var y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
   var speed=2+Math.random()*4;
   var ep=new enemyPlane(x,y,speed);
   this.enemys.push(ep);
  }
 }
}
//子弹
var bullet=function(x,y,speed){
 this.x=x;
 this.y=y;
 this.speed=speed;
 this.e=Util.bulletElement.cloneNode(true);
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
 Util.parentElement.appendChild(this.e);
 this.isUsed=false;
}
bullet.prototype.move=function(moveX,moveY){
 this.x+=moveX;
 this.y+=moveY;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}
bullet.prototype.moveTo=function(X,Y){
 this.x=X;
 this.y=Y;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}

//子弹恢复
bullet.prototype.restore=function(){
 this.x=Main.self
 this.y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
 this.speed=2+Math.random()*4;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}
//子弹工厂
var bulletFactory={
 bullets:[],
 creatBullet:function(n){
  for(var i=0;i<n;i++){
   var b=new bullet(0,-Util.bulletElement.height,20);
   this.bullets.push(b);
  }
 }
}

util.js:

 // JavaScript Document
var Util={
 windowWidth:350,
 windowHeight:480,
 selfPlaneElement:null,
 enemyPlaneElement:null,
 bulletElement:null,
 parentElement:null,
 scoreSpan:null,
 g:function(id){
  return document.getElementById(id);
 },
 
 init:function(){
  this.parentElement=this.g("parent");
  //http://sandbox.runjs.cn/uploads/rs/222/crfsjcjp/boss.gif
  this.selfPlaneElement=this._loadImg("images/self.gif");
  
  this.enemyPlaneElement=this._loadImg("images/boss.gif");
  
  this.bulletElement=this._loadImg("images/bullet.jpg");
  
  this.scoreSpan=this.g("score");
 },
 
 _loadImg:function(src){
  var e=document.createElement("img");
  e.style.position="absolute";
  e.src=src;
  return e;
 }
}

 在线预览:预览

源码下载地址:打飞机小游戏原生javascript版

© 著作权归作者所有

共有 人打赏支持
zaaack

zaaack

粉丝 34
博文 92
码字总数 43513
作品 8
长沙
程序员
私信 提问
加载中

评论(37)

心不在焉
不错!有时间一定研读一下!!
bingb511
bingb511
很棒,是用json的 转的?
胡神父
胡神父
教女孩子打飞机是在暗示什么吗?初学者上来就给人家谈什么对象。
ppNoon
ppNoon

引用来自“ZaneYoung”的评论

引用来自“aeolusj”的评论

ie8实测不兼容键盘的响应事件,可以修改代码为
_initEvent:function(){
    document.onkeydown=function(event){
      /*
      37:左
      38:上
      39:右
      40:下
      */
      var keynum;
      var left=37,up=38,right=39,down=40;

      if(window.event){// IE
       keynum = window.event.keyCode;
        
      }else if(event.which) {// Netscape/Firefox/Opera
       keynum = event.which;
      }
保证ie浏览器的兼容性

谢谢提醒!

这样或许比较简洁:keynum = window.event.keyCode||event.which;
杜易阳
杜易阳
太卡了 居然发了三遍...
兰若寺
兰若寺
00
杜易阳
杜易阳
教女孩子打飞机 哈哈 技术大牛13
杜易阳
杜易阳
教女孩子打飞机 哈哈 技术大牛13
杜易阳
杜易阳
教女孩子打飞机 哈哈 技术大牛13
牛三儿
牛三儿
女童鞋击中了吗?13
如何入门微信小游戏开发,有哪些学习资料?

开发微信小游戏并非难事 1.首先,微信小游戏的开发方法 可以看到微信游戏的开发方式 答主有一些COCOS的开发经验,于是这里我们主要探讨COCOS制作小游戏的方法 2.需要学习什么 JS(JavaScrip...

qq_40126542
05/05
0
0
【开发记录】微信小游戏开发入门——俄罗斯方块

叨叨   我在前一阵子,打算做一个微信小游戏,当然是单机的,只是为了了解小游戏开发的过程,最终选择了俄罗斯方块这一经典小游戏作为demo,源代码已托管值github,当然,这个游戏demo对用...

愉悦的绅士
08/23
0
0
白鹭引擎推出 5.2.6 稳定版,集中性修复数个 BUG

白鹭引擎(Egret Engine)在 2018年5月25日发布了5.2 版本,历经持续更新优化,于7月31日正式发布5.2.6 稳定版本,本次版本是对 5.2版本的一次集中性缺陷修复。在此,我们要再次特别感谢开发...

白鹭科技
07/31
1K
4
【开发记录】微信小游戏开发——俄罗斯方块

叨叨   我在前一阵子,打算做一个微信小游戏,当然是单机的,只是为了了解小游戏开发的过程,最终选择了俄罗斯方块这一经典小游戏作为demo,源代码已托管值github,当然,这个游戏demo对用...

愉悦的绅士
08/23
0
0
20 款免费的 JavaScript 游戏引擎

使用 HTML5,CSS3 和 Javascript 可以帮助面向对象开发者开发拥有各种特性的游戏,比如:3D 动画效果,Canvas,数学,颜色,声音,WebGL 等等。最明显的优势在于使用 HTML5 开发的游戏能在任...

oschina
2014/02/20
17.5K
13

没有更多内容

加载失败,请刷新页面

加载更多

11月NEO技术社区开发进展汇总

为了帮助大家了解NEO平台上技术社区的开发进展,NEONewsToday将每月发布一份值得关注的更新报告。这些报告将包括对NEO核心项目的贡献以及对社区创建项目的改进。 这个报告不是包括所有项目进...

NEO-FANS
7分钟前
0
0
flutter FlatButton有间隔

这个按钮上下会有空隙,不是铺满的

大灰狼wow
10分钟前
0
0
WiFi攻击的三种方式

WiFi的安全问题已经引起了不少的使用者重视,甚至已经出现草木皆兵的现象。那么黑客到底是如何做到绕过身份验证来获取WiFi使用权的呢?主要有以下三种方式,其中最后一种方式十分简单。 WiFi...

Linux就该这么学
12分钟前
1
0
添加并发

<!-- 认购线程池,支持最大并发送10 最大排队队列为一万--> <task:executor id="investBuyPool" pool-size="1-10" queue-capacity="10000"/> 方法添加注解@Async("investBuyPool")......

一夜
22分钟前
2
0
Gensim?

Gensim是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。它支持包括TF-IDF,LSA,LDA,和word2vec在内的多种主题模型算法,支持流式训...

火力全開
35分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部