JavaScript游戏之飞机接子弹

啥都不说,先预览一下。这次没UI,哈哈。。。都是用css凑出来的。。。

游戏说明:方向键左右控制移动,左Ctrl为变大5秒,吃到白色加100分,红色扣100分,蓝色增加一次变大

  以下是源码以及解析:

html代码
 1 <style>
 2     #panel{height:400px;width:300px;background:Black;position:absolute;left:100px;top:100px;overflow:hidden;}
 3     #panel div{position:absolute;left:0;color:White;font-size:12px;}
 4     #panel .time{top:0;}
 5     #panel .canBigCount{top:12px;}
 6     #panel .score{top:24px;}
 7 </style>
 8 
 9 <div style="color:Red;">游戏说明:方向键左右控制移动,空格为变大5秒,吃到白色加100分,红色扣100分,蓝色增加一次变大</div>
10 <div><input type="button" value="开始" onclick="GameStart()" /></div>
11 
12 <div id="panel" tabindex="0">
13     <div class="time">时间:<span id="time">60</span></div>
14     <div class="canBigCount">可变大次数:<span id="canBigCount">1</span></div>
15     <div class="score">分数:<span id="score">0</span></div>
16 </div>


两个工具函数
 1 //根据ID获取对应的dom元素
 2 function $(obj){
 3     return typeof obj == 'string'?document.getElementById(obj):obj;
 4 }
 5 //获取某dom元素name对应的css值
 6 function getCss(obj,name){
 7     obj = $(obj);
 8     if(obj.currentStyle) {
 9         return obj.currentStyle[name];
10     }
11     else {
12         return document.defaultView.getComputedStyle(obj,null)[name];
13     }
14 }
飞机类
  1 var Fly = function(){
  2     //飞机对应的dom元素
  3     this.dom = null;
  4     //飞机信息
  5     this.left = 0;
  6     this.top = 0;
  7     this.width = 0;
  8     this.height = 0;
  9     //可变大次数
 10     this.canBigCount = 1;
 11     //目前变大状态
 12     this.isBig = false;
 13     //移动状态
 14     this.isMove = false;
 15     //移动ID
 16     this.moveId = null;
 17 
 18     this.create();
 19 }
 20 Fly.prototype = {
 21     //移动位移
 22     movepx : 10,
 23     //移动速度
 24     moveSpeed : 30,
 25     //创建飞机dom
 26     create : function(){
 27 
 28         this.dom = document.createElement('div');
 29         this.dom.style.cssText = 'position:absolute;40px;height:15px;background:Yellow;';
 30         
 31         this.width = parseInt(this.dom.style.width,10);
 32         this.height = parseInt(this.dom.style.height,10);
 33     },
 34     //初始化飞机位置
 35     initPosition : function(gameWidth,gameHeight){
 36         
 37         this.left = (gameWidth-this.width)/2;
 38         this.top = gameHeight-this.height;
 39         this.dom.style.left = this.left + 'px';
 40         this.dom.style.top = this.top + 'px';
 41     },
 42     //更新位置
 43     update : function(){
 44         this.dom.style.left = this.left+'px';
 45         this.dom.style.top = this.top +'px';
 46     },
 47     //变大
 48     changeBig : function(){
 49         this.dom.style.width = (this.width*2+ 'px';
 50         this.width = this.width*2;
 51         this.isBig = true;
 52     },
 53     //还原
 54     changeNormal : function(){
 55         this.dom.style.width = (this.width/2) + 'px';
 56         this.width = this.width/2;
 57         this.isBig = false;
 58     },
 59     //键盘按下事件,e为event,gameWidth为游戏背景宽度
 60     keydown : function(e,gameWidth){
 61         switch(e.keyCode){
 62             //空格
 63             case 32:{
 64                 //判断剩余变大次数与变大状态
 65                 if(this.canBigCount > 0 && !this.isBig){
 66                     
 67                     var _this = this;
 68                     //变大
 69                     this.changeBig();
 70                     //设置还原事件
 71                     setTimeout(function(){
 72                         _this.changeNormal();
 73                     },5000);
 74                     
 75                     this.canBigCount -= 1;
 76                     //刷新变大次数显示
 77                     this.flashBigCount();
 78                 }
 79                 break;
 80             };
 81             //方向左
 82             case 37:{
 83                 if(!this.isMove){
 84                     this.isMove = true;
 85                     this.move('left');
 86                 }
 87                 break;
 88             };
 89             //方向右
 90             case 39:{
 91                 if(!this.isMove){
 92                     this.isMove = true;
 93                     this.move('right',gameWidth);
 94                 }
 95                 break;
 96             };
 97         }
 98     },
 99     //键盘释放事件
100     keyup : function(e){
101         
102         if(e.keyCode == 37 || e.keyCode == 39){
103             this.isMove = false;
104             clearInterval(this.moveId);
105         }
106         
107     },
108     //飞机移动
109     move : function(dir,gameWidth){
110         
111         _this = this;
112         
113         if(dir == 'left'){
114             this.moveId = setInterval(function(){
115                 
116                 _this.left = _this.left-_this.movepx <=0?0:_this.left-_this.movepx;
117                 _this.update();
118                 
119             },this.moveSpeed);
120         }
121         else{
122             this.moveId = setInterval(function(){
123                 
124                 _this.left = _this.left+_this.movepx >=gameWidth-_this.width?gameWidth-_this._this.left+_this.movepx;
125                 _this.update();
126                 
127             },this.moveSpeed);
128         }
129         
130     },
131     //刷新变大次数显示,外部调用接口
132     flashBigCount : function(){}
133 }
子弹类
 1 var Bullet = function(type){
 2     //子弹dom元素
 3     this.dom = null;
 4     //子弹信息
 5     this.left = 0;
 6     this.top = 0;
 7     this.width = 0;
 8     this.height = 0;
 9     this.type = type;
10     
11     this.create();
12 }
13 Bullet.prototype = {
14     //子弹类型与颜色映射表
15     bullettype:{
16         "good":"White",
17         "bad":"Red",
18         "big":"Blue"
19     },
20     //每次移动位移
21     movepx : 10,
22     //子弹速度
23     movespeed : 50,
24     //创建子弹dom
25     create : function(){
26 
27         this.dom = document.createElement('div');
28         this.dom.style.cssText = 'position:absolute;5px;height:5px;overflow:hidden;background:' + this.bullettype[this.type]+';';
29         
30         this.width = parseInt(this.dom.style.width,10);
31         this.height = parseInt(this.dom.style.height,10);
32     },
33     //初始化子弹位置
34     initPosition : function(gameWidth){
35         
36         this.left = parseInt(Math.random()*gameWidth+1,10);
37         this.dom.style.left = this.left + 'px';
38     },
39     //子弹动画,height为游戏背景高度
40     animation : function(height){
41         
42         var _this = this;
43         //向下移动函数
44         var downmove = function(){
45             //更新位置
46             _this.top = _this.top +  _this.movepx;
47             _this.update();
48             //判断子弹位置以及是否击中飞机
49             if(_this.top < height && !_this.isBeatFly()){
50                 
51                 setTimeout(downmove,_this.movespeed);
52             }
53             else {
54                 //动画结束触发事件
55                 _this.onEnd();
56             }
57         }
58         downmove();
59     },
60     //更新位置
61     update : function(){
62         this.dom.style.left = this.left+'px';
63         this.dom.style.top = this.top +'px';
64     },
65     //判断子弹击中飞机否
66     checkBeatFly :function(fly){
67         if (this.left >= fly.left && this.left + this.width <= fly.left + fly.width) {
68             if (this.top + this.height >= fly.top && this.top + this.height <= fly.top + fly.height) {
69                 return true;
70             }
71         }
72         return false;
73     },
74     //动画结束触发事件,外部覆盖
75     onEnd : function(){},
76     //子弹是否击中飞机以及击中后处理事件,外部覆盖
77     isBeatFly : function(){}
78 }


游戏控制类
  1 var Game = {
  2     //游戏背景dom元素
  3     gamePanel:null,
  4     //游戏背景宽度
  5     gameWidth : 0,
  6     //游戏背景高度
  7     gameHeight : 0,
  8     //子弹生成频率
  9     bulletHz : 200,
 10     //飞机
 11     fly : null,
 12     //分数
 13     score:0,
 14     //时间
 15     time : 61,
 16     //是否开始
 17     start : false,
 18     //初始化
 19     init : function(){
 20         
 21         this.initGamePanel();
 22         
 23         this.initFly();
 24         
 25         this.initBullet();
 26         
 27         this.startTime();
 28         
 29         this.start = true;
 30     },
 31     //初始化游戏背景数据
 32     initGamePanel : function(){
 33         this.gamePanel = $('panel');
 34         this.gameWidth = parseInt(getCss(this.gamePanel,'width'),10);
 35         this.gameHeight = parseInt(getCss(this.gamePanel,'height'),10);
 36         
 37         this.gamePanel.focus();
 38     },
 39     //初始化飞机
 40     initFly : function(){
 41         this.fly = new Fly();
 42         
 43         this.fly.initPosition(this.gameWidth,this.gameHeight);
 44         this.fly.flashBigCount = function(){
 45             $('canBigCount').innerHTML = this.canBigCount;
 46         }
 47         
 48         this.gamePanel.appendChild(this.fly.dom);
 49         //为body绑定键盘按下事件
 50         document.body.onkeydown = function(e){Game.flymove(e);};
 51         //为body绑定键盘释放事件
 52         document.body.onkeyup = function(e){Game.stopmove(e);};
 53     },
 54     //初始化子弹
 55     initBullet : function(){
 56         
 57         var _this = this;
 58         //生成子弹函数
 59         var process = function(){
 60             //随机数,决定生成加分或扣分子弹
 61             var random = parseInt(Math.random()*10+1,10);
 62             //随机数,决定生成增加变大子弹
 63             var addbig = parseInt(Math.random()*50+1,10);
 64             //新建一个子弹对象
 65             var bullet = new Bullet(random%3==0?'bad':addbig==28?'big':'good');
 66             
 67             bullet.initPosition(_this.gameWidth);
 68             //覆盖子弹动画结束事件
 69             bullet.onEnd = function(){
 70                 _this.gamePanel.removeChild(this.dom);
 71                 this.dom = null;
 72             }
 73             //覆盖子弹是否击中飞机以及击中后处理事件
 74             bullet.isBeatFly = function(){
 75             
 76                 if (this.checkBeatFly(_this.fly)){
 77                     _this.changeScore(this.type);
 78                     return true;
 79                 }
 80                 return false;
 81             }
 82             
 83             _this.gamePanel.appendChild(bullet.dom);
 84             
 85             bullet.animation(_this.gameHeight);
 86 
 87             if(_this.time > 0)setTimeout(process,_this.bulletHz);
 88         }
 89         process();
 90     },
 91     //飞机移动
 92     flymove : function(e){
 93         e = e || window.event;
 94 
 95         this.fly.keydown(e,this.gameWidth);
 96     },
 97     //飞机停止
 98     stopmove : function(e){
 99         e = e || window.event;
100         
101         this.fly.keyup(e);
102     },
103     //改变分数
104     changeScore : function(type){
105         if (type == 'big') {
106             this.fly.canBigCount += 1;
107             this.fly.flashBigCount();
108         }
109         else {
110             this.score += type == "bad" ? -100 : 100;
111             $('score').innerHTML = this.score;
112         }
113     },
114     //计时
115     startTime : function(){
116         if(this.time >0){
117             var _this = this;
118             this.time -= 1;
119             $('time').innerHTML = this.time;
120             setTimeout(function(){_this.startTime();},1000);
121         }
122         else {
123             this.start = false;
124         }
125     },
126     //重置
127     reset : function(){
128         this.gameWidth = 0;
129         this.gameHeight = 0;
130         this.fly && $('panel').removeChild(this.fly.dom);
131         this.fly = null;
132         this.movepx = 30;
133         this.score = 0;
134         $('score').innerHTML = this.score;
135         this.time = 61;
136         $('time').innerHTML = this.time-1;
137         $('canBigCount').innerHTML = 1;
138     }
139 }
140 
141 function GameStart(){
142     
143     if (Game.start == false) {
144         
145         Game.reset();
146         Game.init();
147     }
148 }

完整源码下载>> 

源码跟演示有点出入。。。方便演示,所以修改了部分。。

顺带说一句,上一个游戏,打地鼠,会出现卡死,是因为出现死循环。。。稍微修改一下速度跟频率的参数就能解决。。。 

时间:60
可变大次数:1
分数:0
原文地址:https://www.cnblogs.com/floyd/p/1850164.html