纯JavaScript 实现flappy bird小游戏实例代码


Posted in Javascript onSeptember 27, 2016

前言:

《flappy bird》是一款由来自越南的独立游戏开发者Dong Nguyen所开发的作品,游戏于2013年5月24日上线,并在2014年2月突然暴红。2014年2月,《Flappy Bird》被开发者本人从苹果及谷歌应用商店撤下。2014年8月份正式回归APP STORE,正式加入Flappy迷们期待已久的多人对战模式。游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍。
正文:

接下来就是一步一步来实现它

步骤1:页面布局,这儿就不多说了,页面内容如下:

纯JavaScript 实现flappy bird小游戏实例代码

步骤2:如何让小鸟下落以及让小鸟跳起来

鸟下降:

给小鸟一个speed,初始值为0,通过计时器让speed每隔30ms加1,当speed超出最大值speedMax,即speed>8时,让速度保持最大值。

//获取鸟div
var bird = document.getElementById("flybird");
//鸟下降
function down() {
speed += 1;
bird.id = 'flybird_down';
up_bgm.pause();//关闭小鸟上升音乐;
//当鸟下落速度达到最大值speedMax时,保持不变
if(speed >= speedMax) {
speed = speedMax;
}
bird.style.top = bird.offsetTop + speed + 'px';
floorText(); //落地检测
}

鸟上升:

上升,即小鸟的top值减小的过程。让speed减小即可。同时,在鸟上升时,关闭小鸟下降的计时器,以及上次起跳时的上升的计时器,并重新启动上升计时器。在这儿,有个isGameOver,为游戏开关,默认为ture,即当该值为false时,游戏未开始,小鸟无法起跳。

//小鸟上升
function up() {
speed -= 0.8;
bird.id = 'flybird_up'//该id下的样式为小鸟下降的背景图片,并增加动画不断替换小鸟的背景图像,让小鸟翅膀动起来~
up_bgm.play()
if(speed <= 0) {
speed = 0;
clearInterval(upTimer);
DownTimer = setInterval(down, 30);
}
bird.style.top = bird.offsetTop - speed + 'px';
}
//鸟跳动的方法;
function birdJump() {
speed = speedMax;
if(isGameOver) {
//每次向上跳时,先将向上、向下计时器清楚,防止叠加
clearInterval(upTimer);
clearInterval(DownTimer); //清除向下的定时器;
upTimer = setInterval(up, 30);
}
}
//判断小鸟落地或者小鸟跳出上边界,此时游戏结束
function floorText() {
var t1 = bird.offsetTop;
if(t1 > 396) {
//游戏结束;
gameover();
}
if(t1 < 0) {
gameover();
}
}

步骤3:通过以上步骤,小鸟可以起跳啦。接下来就是管道的创建。玩过flappybird游戏的都知道,里面的管道的高度是随机的,但上下两个管道之间的距离是固定的。用Math.random()来产生随机数。

//随机函数,用来随机产生钢管的高度
function rand(min, max) {
return parseInt(Math.random() * (max - min) + min);
}
//创建管道。在点击开始按钮后,通过计时器来创建
function create_pipe() {
var conduit_group = document.querySelector(".conduit_group");
var conduitItem = document.createElement("div");
//给创建的管道一个样式
conduitItem.className = 'conduitItem';
//将创建的管道放入外层div
conduit_group.appendChild(conduitItem);
var topHeight = rand(60, 223);//管道里面 上管道的高度值
var bottomHeight = 373 - 100 - topHeight;//管道里面 下管道的高度值
//创建上下管道
conduitItem.innerHTML = '<div class="top_conduit"><div style="height:' + topHeight + 'px"></div></div><div class="bottom_conduit"><div style="height:' + bottomHeight + 'px"></div></div>'
//获取最外层div的宽度,即为管道可以移动的最大值
var maxWidth = canvas.offsetWidth;
//让管道刚开始在canvas外面,一开始看不到
conduitItem.style.left = maxWidth + 'px';
//加分开关,每通过一个管道分数才能加1
conduitItem.AddToscore = true;
//管道移动方法,通过计时器不断使其的left值递减来实现管道移动。
conduitItem.movetimer = setInterval(function() {
maxWidth -= 3;//每30ms向左移动3个像素
conduitItem.style.left = maxWidth + 'px'
//在管道跑出去之后,清除使该管道移动的计时器,并将其移除。
if(maxWidth <= -70) {
clearInterval(conduitItem.movetimer);
conduit_group.removeChild(conduitItem);
}
//当管道的offsetLeft小于30时,即小鸟成功通过管道之后,分数加1
if(conduitItem.offsetLeft <= 30 && conduitItem.AddToscore == true) {
score++;
conduitItem.AddToscore = false;
scoreFn(score);
}
}, 30)
}

步骤4:通过以上步骤,移动的管道创建好了,小鸟也可以跳了。接下来就是进行碰撞检测,判断小鸟是否碰到管道。

//鸟和管道碰撞检测,obj1为小鸟,obj2为上下管道的父集
//直接获取上下管道,offsetLeft为0,因此要获取其父集;
function crashTest(obj1, obj2) {
//小鸟的相关量
var l1 = bird.offsetLeft;
console.log(l1)
var r1 = l1 + bird.offsetWidth;
var t1 = bird.offsetTop;
var b1 = t1 + bird.offsetHeight
//管道的相关量
var l2 = obj2.offsetLeft;
var r2 = l2 + obj2.offsetWidth;
var t2 = obj1.offsetTop;
var b2 = t2 + obj1.offsetHeight;
//判断条件
if(r1 > l2 && l1 < r2 && b1 > t2 && t1 < b2) {
gameover();
}
}
function judge() {
//获取创造的在当前页面显示的所有管道,为一个数组
var conduitItem = document.querySelector('.conduit_group').querySelectorAll('.conduitItem');
//遍历显示的管道,为crashTest方法传递参数来进行判断。
for(var i = 0; i < conduitItem.length; i++) {
var top_conduit = conduitItem[i].querySelector('.top_conduit');
var bottom_conduit = conduitItem[i].querySelector('.bottom_conduit');
crashTest(top_conduit, conduitItem[i]);
crashTest(bottom_conduit, conduitItem[i]);
}
}

步骤5:游戏结束方法。当碰到管道,碰到上边界,落地,游戏结束,显示本局分数,并显示历史最高记录。

//游戏结束
function gameover() {
//游戏结束背景音乐打开
gameover_bgm.play();
isGameOver = false;
//结束音乐
bgm.pause();
clearTimer();
//小鸟换回原来的样式
bird.id = 'flybird'
bird.className = 'birddown'
bird.style.top = '392px';
//存储最高纪录
var historyscore = localStorage.getItem('maxScore');
//当历史记录不存在或者历史记录小于当前记录时,创建masScore.
if(historyscore == null || historyscore < score) {
localStorage.setItem('maxScore', score);
//刷新记录
historyscore = score;
}
//历史最高纪录
historyScore.innerHTML = historyscore;
//当前分数
thisScore.innerHTML = score;
//显示游戏结束画面
document.querySelector('.gameover').style.display = 'block';
}

步骤7:游戏开始方法。

//游戏初始化
function init() {
//为start_btn,即页面刚开始显示的start创建点击事件,即开始按钮
start_btn.onclick = function() {
//点击之后,开始界面隐藏
gameStartDiv.style.display = 'none';
//小鸟显示出来
bird.style.display = 'block';
//使小鸟在中间显示
bird.style.top = '200px';
bgm.play();
//通过点击,来调用birdJump方法,来使小鸟上升
//开始创造管道
conduitTimer = setInterval(create_pipe, 2000)
document.addEventListener('click', birdJump, false)
crashTestTimer = setInterval(judge, 1000 / 60);
}
}
init();

步骤7:游戏重新开始方法

//重新开始
var game_restart = document.querySelector(".game_restart")
game_restart.onclick = restart;
var conduit_group = document.querySelector(".conduit_group")
//回到刚开始的界面
function restart() {
bird.className = 'bird'
clearTimer();
scoreDiv.innerHTML = null;
isGameOver = true;
speed = 0;
score=0;
speedMax = 8;
document.querySelector('.gameover').style.display = 'none';
gameStartDiv.style.display = 'block';
bird.style.display = 'none';
conduit_group.innerHTML = '';
}

这儿用到的clearTimer方法为清除所有记时器,代码如下:

function clearTimer() {
var timer = setInterval(function() {}, 30);
for(i = 0; i < timer; i++) {
clearInterval(i);
}
}

这样游戏大致已经做好啦。

效果图如下:

纯JavaScript 实现flappy bird小游戏实例代码

下面附上源码下载地址,请在谷歌浏览器上进行试验。

源码下载地址

以上所述是小编给大家介绍的纯JavaScript 实现flappy bird小游戏实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Javascript 错误处理的几种方法
Jun 13 Javascript
ajax不执行success回调而是执行了error回调
Dec 10 Javascript
JS模块与命名空间的介绍
Mar 22 Javascript
js实现点小图看大图效果的思路及示例代码
Oct 28 Javascript
jQuery代码实现表格中点击相应行变色功能
May 09 Javascript
js中获取jsp表单中radio类型的值简单实例
Aug 15 Javascript
简单理解vue中Props属性
Oct 27 Javascript
微信小程序 MD5加密登录密码详解及实例代码
Jan 12 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
Mar 02 Javascript
JS实现全屏预览F11功能的示例代码
Jul 23 Javascript
浅谈开发eslint规则
Oct 01 Javascript
vue实现动态给id赋值,点击事件获取当前点击的元素的id操作
Nov 09 Javascript
jQuery实现表格文本框淡入更改值后淡出效果
Sep 27 #Javascript
angular基于路由控制ui-router实现系统权限控制
Sep 27 #Javascript
IOS中safari下的select下拉菜单文字过长不换行的解决方法
Sep 26 #Javascript
javascript动画之模拟拖拽效果篇
Sep 26 #Javascript
微信小程序(应用号)简单实例应用及实例详解
Sep 26 #Javascript
微信小程序 框架详解及实例应用
Sep 26 #Javascript
jQuery中JSONP的两种实现方式详解
Sep 26 #Javascript
You might like
dedecms后台验证码总提示错误的解决方法
2007/03/21 PHP
IStream与TStream之间的相互转换
2008/08/01 PHP
php从memcache读取数据再批量写入mysql的方法
2014/12/29 PHP
PHP使用NuSOAP调用Web服务的方法
2015/07/18 PHP
CodeIgniter配置之database.php用法实例分析
2016/01/20 PHP
总结PHP中数值计算的注意事项
2016/08/14 PHP
JavaScript自执行闭包的小例子
2013/06/29 Javascript
jquery prop的使用介绍及与attr的区别
2013/12/19 Javascript
逐一介绍Jquery data()、Jquery stop()、jquery delay()函数(详)
2015/11/04 Javascript
js实现的二分查找算法实例
2016/01/21 Javascript
javascript先序遍历DOM树的方法
2016/02/27 Javascript
JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解
2016/05/31 Javascript
js实现彩色条纹滚动条效果
2017/03/15 Javascript
浅谈Vue服务端渲染框架Nuxt的那些事
2018/12/21 Javascript
微信小程序导航栏跟随滑动效果的实现代码
2019/05/14 Javascript
微信小程序如何使用canvas二维码保存至手机相册
2019/07/15 Javascript
layui对工具条进行选择性的显示方法
2019/09/19 Javascript
[06:23]2014DOTA2西雅图国际邀请赛 小组赛7月12日TOPPLAY
2014/07/12 DOTA
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
Python常见文件操作的函数示例代码
2011/11/15 Python
Python中实现常量(Const)功能
2015/01/28 Python
将Python中的数据存储到系统本地的简单方法
2015/04/11 Python
python开发中range()函数用法实例分析
2015/11/12 Python
Django框架实现的简单分页功能示例
2018/12/04 Python
Django ORM filter() 的运用详解
2020/05/14 Python
运行时异常与一般异常有何异同?
2014/01/05 面试题
如何利用cmp命令比较文件
2013/09/23 面试题
nohup的用法
2014/08/10 面试题
电子商务应届生求职信
2013/11/16 职场文书
羽毛球社团活动总结
2014/06/27 职场文书
新教师培训心得体会
2014/09/02 职场文书
2014社会治安综合治理工作总结
2014/12/04 职场文书
公司欠款证明
2015/06/24 职场文书
Golang 对es的操作实例
2022/04/20 Golang
JS前端宏任务微任务及Event Loop使用详解
2022/07/23 Javascript
蓝牙耳机怎么连接电脑win11? Win11蓝牙耳机连接电脑的技巧
2023/01/09 数码科技