纯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 相关文章推荐
JS应用之禁止抓屏、复制、打印
Feb 21 Javascript
JavaScript控制table某列不显示的方法
Mar 16 Javascript
JavaScript的History API使搜索引擎抓取AJAX内容
Dec 07 Javascript
jquery UI Datepicker时间控件的使用及问题解决
Apr 28 Javascript
vue.js学习之递归组件
Dec 13 Javascript
bootstrap实现图片自动轮播
Dec 21 Javascript
微信小程序之MaterialDesign--input组件详解
Feb 15 Javascript
微信小程序 判断手机号的实现代码
Apr 19 Javascript
浅谈vuex actions和mutation的异曲同工
Dec 13 Javascript
全面分析JavaScript 继承
May 30 Javascript
ES6 proxy和reflect的使用方法与应用实例分析
Feb 15 Javascript
js实现点击上传图片并设为模糊背景
Aug 02 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
typecho插件编写教程(一):Hello World
2015/05/28 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
yii2中关于加密解密的那些事儿
2018/06/12 PHP
PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】
2018/06/13 PHP
php strftime函数的详细用法
2018/06/21 PHP
laravel 框架配置404等异常页面
2019/01/07 PHP
javascript判断非数字的简单例子
2013/07/18 Javascript
固定网页背景图同时保持图片比例的思路代码
2013/08/15 Javascript
jquery实现checkbox 全选/全不选的通用写法
2014/02/22 Javascript
js如何调用qq互联api实现第三方登录
2014/03/28 Javascript
nodejs中实现路由功能
2014/12/29 NodeJs
React.js入门实例教程之创建hello world 的5种方式
2016/05/11 Javascript
jquery中取消和绑定hover事件的实现代码
2016/06/02 Javascript
js中遍历对象的属性和值的方法
2016/07/27 Javascript
layui table 参数设置方法
2018/08/14 Javascript
用npm-run实现自动化任务的方法示例
2019/01/14 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
2019/05/01 Javascript
koa+mongoose实现简单增删改查接口的示例代码
2019/05/13 Javascript
Vue3 源码导读(推荐)
2019/10/14 Javascript
ant design实现圈选功能
2019/12/17 Javascript
15分钟上手vue3.0(小结)
2020/05/20 Javascript
vue element 关闭当前tab 跳转到上一路由操作
2020/07/22 Javascript
python中使用enumerate函数遍历元素实例
2014/06/16 Python
Python中列表的一些基本操作知识汇总
2015/05/20 Python
浅谈Python浅拷贝、深拷贝及引用机制
2016/12/15 Python
opencv3/C++实现视频读取、视频写入
2019/12/11 Python
python中的split()函数和os.path.split()函数使用详解
2019/12/21 Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
2020/02/07 Python
css3背景图片透明叠加属性cross-fade简介及用法实例
2013/01/08 HTML / CSS
HTML5 video标签(播放器)学习笔记(二):播放控制
2015/04/24 HTML / CSS
英国最大的邮寄种子和植物公司:Thompson & Morgan
2017/09/21 全球购物
小学竞选班干部演讲稿
2014/08/20 职场文书
2015年采购部工作总结
2015/04/23 职场文书
四年级语文教学反思
2016/03/03 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书
创业计划书之奶茶店开店方案范本!
2019/08/06 职场文书