javascript实现flappybird 解析
很早之前写了这个小鸟的代码 不是很难 一起看看吧~
html和css代码
引入图片和游戏框居中
<!DOCTYPE html
>
<html
>
<head
>
<meta charset
="utf-8" />
<title
></title
>
<style
>
* {
margin
: 0;
padding
: 0;
}
</style
>
</head
>
<body
>
<div id
="background" style
="overflow: hidden;width: 800px;height: 600px;background: url(img/sky.png) repeat-x;position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);">
<div id
="bird" style
="background: url(img/birds.png);width: 52px;height:45px;position: absolute;top: 40%;left:33%;">
</div
>
</div
>
</body
>
<script src
="js/new_file.js" type
="text/javascript" charset
="utf-8"></script
>
</html
>
js代码
onload = function() {
background
= document
.querySelector('#background');
background
.x
= 0;
bird
= document
.querySelector('#bird');
bird
.fly
= 0;
var speed
= 1;
var play
= true;
bird
.y
= bird
.offsetTop
;
document
.onclick = function() {
speed
= -4;
}
var mark
= new Array();
var timerId
= new Array();
var k
= 0;
var j
= 0;
mark
[k
] = createPipe(k
);
setInterval(function() {
if (play
)
createPipe(++k
);
}, 3000);
function createPipe(m
) {
var pipe
= new Object();
var long
= Math
.random() * 300;
pipe
.top
= document
.createElement('div');
pipe
.bottom
= document
.createElement('div');
pipe
.x
= 0;
pipe
.top
.style
.background
= 'url(img/pipe2.png) no-repeat';
pipe
.top
.style
.width
= '52px';
pipe
.top
.style
.height
= '420px';
pipe
.top
.style
.position
= 'absolute';
pipe
.top
.style
.top
= -320 + long
+ 'px';
pipe
.top
.style
.right
= 0 + 'px';
pipe
.bottom
.style
.background
= 'url(img/pipe1.png) no-repeat'
pipe
.bottom
.style
.width
= '52px';
pipe
.bottom
.style
.height
= '420px';
pipe
.bottom
.style
.position
= 'absolute';
pipe
.bottom
.style
.top
= 220 + long
+ 'px';
pipe
.bottom
.style
.right
= 0 + 'px';
background
.appendChild(pipe
.top
);
background
.appendChild(pipe
.bottom
);
timerId
[m
] = setInterval(function() {
if (play
) {
pipe
.x
+= 2;
pipe
.top
.style
.right
= pipe
.x
+ 'px';
pipe
.bottom
.style
.right
= pipe
.x
+ 'px';
if (pipe
.top
.offsetLeft
<= (bird
.offsetLeft
+ bird
.offsetWidth
- 15) && pipe
.top
.offsetLeft
>= (bird
.offsetLeft
-
pipe
.top
.offsetWidth
+ 15)) {
if (bird
.offsetTop
<= 85 + long
|| bird
.offsetTop
+ bird
.offsetWidth
>= pipe
.bottom
.offsetTop
+ 15)
{
play
= false;
j
= m
;
}
}
if (pipe
.bottom
.offsetLeft
+ pipe
.bottom
.offsetWidth
<= 0) {
clearInterval(timerId
[m
]);
pipe
.top
.parentNode
.removeChild(pipe
.bottom
);
pipe
.top
.parentNode
.removeChild(pipe
.top
);
delete pipe
.bottom
;
delete pipe
.top
;
delete pipe
;
}
}
}, 30);
return pipe
;
}
var time
= setInterval(function() {
if (play
) {
background
.x
-= 2;
background
.style
.backgroundPositionX
= background
.x
+ 'px';
bird
.fly
++;
bird
.style
.backgroundPositionX
= (bird
.fly
% 3) * bird
.offsetWidth
+ 'px';
} else {
alert('通过' + j
+ '个柱子!');
clearInterval(time
);
}
}, 10);
setInterval(function() {
if (play
) {
bird
.y
+= speed
;
speed
+= 0.12;
bird
.style
.top
= bird
.y
+ 'px';
if (bird
.y
>= background
.offsetHeight
- bird
.offsetHeight
+ 15)
play
= false;
}
}, 10)
}
背景 小鸟 柱子 三个主体对象
背景
背景的移动,背景无限向左移动 模拟了向前的的感觉 实际上小鸟是不动的
注意:元素背景图片要设置为repeat-x这样子x方向就是无限的 可以无限向右移动达到动画效果(下面小鸟的飞翔也同理)
小鸟
使用精灵图 无限向左(右,可以模拟小鸟煽动翅膀的效果)
bird.style.backgroundPositionX = (bird.fly % 3) * bird.offsetWidth + 'px'; //小鸟翅膀扇动 实际上是一个精灵图不断变换位置
小鸟会往下掉 而且掉的速度会不断增大(加速度)
bird.y += speed;
speed += 0.12; //加速度设置 速度如同一个等加数列
当点击时 改变speed为负数 小鸟就跳起来了
speed = -4; //小鸟每次点击后跳起的高度(不完全是跳起的高度 是跳起时的速度 速度会减小 类似'重力加速度')
柱子
写一个工厂函数 隔几秒就创建柱子对象
一个竖直上 我用top和bottom 分上下
柱子有最高和最低点 距离固定为100px 具体实现是这样子
var long = Math.random() * 300; //柱子随机高度
pipe.top.style.top = -320 + long + 'px';
pipe.bottom.style.top = 220 + long + 'px';//需要配合游戏界面高度计算
这个是一个具体而简单的加减数学问题 大家可以分析一下
每个竖直关卡都会有一个定时器使他向左移动
游戏逻辑
over逻辑
设定一个标志play 为false 即游戏结束
两种情况游戏结束:掉地上和碰到柱子了
掉到地上:即offsettop 为 游戏界面高度,play=false,但是小鸟图会有一边框 需要慢慢测试处理细节(同下
碰到柱子:即柱子到达小鸟位置时 需要判断小鸟位置与这个柱子有没有碰触 同样是简单数学问题
游戏大概是这样子
因为游戏是一个月半前写的其实还有很多很多优化的地方 比如 所有柱子共用一个定时器向前移动 小鸟碰触柱子时判断简化等等…而且也不是面向对象的写法 写得很乱 不过还是可以跑得起来的~