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); //先创建第一个对象(因为计时器在0时不执行)
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'; //设定管子固定的间隔是100px 计算不详解
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)) {
//判断当柱子移动到某个区间时 小鸟的高度是否触碰到柱子 计算不详解 15是因为小鸟图左右各有15的距离是空的
if (bird.offsetTop <= 85 + long || bird.offsetTop + bird.offsetWidth >= pipe.bottom.offsetTop + 15) //判断如果触碰到柱子 游戏执行变量会等于false;
{
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; //小鸟触碰到底部 执行变量变为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,但是小鸟图会有一边框 需要慢慢测试处理细节(同下
碰到柱子:即柱子到达小鸟位置时 需要判断小鸟位置与这个柱子有没有碰触 同样是简单数学问题
游戏大概是这样子
因为游戏是一个月半前写的其实还有很多很多优化的地方 比如 所有柱子共用一个定时器向前移动 小鸟碰触柱子时判断简化等等…而且也不是面向对象的写法 写得很乱 不过还是可以跑得起来的~