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>
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 }
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;width: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.width:_this.left+_this.movepx;
125 _this.update();
126
127 },this.moveSpeed);
128 }
129
130 },
131 //刷新变大次数显示,外部调用接口
132 flashBigCount : function(){}
133 }
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;width: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.width:_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;width: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 }
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;width: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 }
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