文档章节

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

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

今天闲来无事,于是就打算教一个初学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
博文 91
码字总数 43011
作品 7
长沙
程序员
加载中

评论(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
白鹭引擎推出 5.2.6 稳定版,集中性修复数个 BUG

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

白鹭科技
07/31
0
0
javascript统一世界?

[到微信关注我][1]今天facebook将react native框架的源码开源,瞬间火得一塌糊涂,目前github上的star已经快7000了。javascript作为这个框架的开发使用语言又一次出现在人们面前。这几年jav...

卢勇福
2015/03/28
0
0
移动应用和游戏开发两个阶段在线视频培训的未来计划

在51CTO学院开线上视频课程已经3个多月了,也上了不少课。不过发现还有很多课没有开。现在就将未来的开课计划公布一下。计划分为两个阶段。第一阶段主要是Cocos2d-x和Cocos2d-js的游戏开发培...

androidguy
06/29
0
0
目前有成熟的App代码翻译技术吗?

大家好: 本人多年技术老鸟,现有抛出一个思考。针对目前市面上的移动互联网项目(主要指客户端)类型,无非以下几种主要类型: 原生App: iOS/Android H5响应式 H5套壳(PhoneGap/微信小程序/国...

瑾少
04/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Ubuntu18.04 显卡GF-940MX安装NVIDIA-390.77

解决办法: 下面就给大家一个正确的姿势在Ubuntu上安装Nvidia驱动: (a)首先去N卡官网下载自己显卡对应的驱动:www.geforce.cn/drivers (b)下载后好放在英文路径的目录下,怎么简单怎么来...

AI_SKI
今天
0
0
深夜胡思乱想

魔兽世界 最近魔兽世界出了新版本, 周末两天升到了满级,比之前的版本体验好很多,做任务不用抢怪了,不用组队打怪也是共享拾取的。技能简化了很多,哪个亮按哪个。 运维 服务器 产品 之间的...

Firxiao
今天
1
0
MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
今天
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
3
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部