js实现flappybird解析

    xiaoxiao2023-10-12  143

    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,但是小鸟图会有一边框 需要慢慢测试处理细节(同下

    碰到柱子:即柱子到达小鸟位置时 需要判断小鸟位置与这个柱子有没有碰触 同样是简单数学问题

    游戏大概是这样子

    因为游戏是一个月半前写的其实还有很多很多优化的地方 比如 所有柱子共用一个定时器向前移动 小鸟碰触柱子时判断简化等等…而且也不是面向对象的写法 写得很乱 不过还是可以跑得起来的~

    最新回复(0)