纯JavaScript 实现flappy bird小游戏实例代码
作者:celen_ 发布时间:2024-05-11 09:05:57
前言:
《flappy bird》是一款由来自越南的独立游戏开发者Dong Nguyen所开发的作品,游戏于2013年5月24日上线,并在2014年2月突然暴红。2014年2月,《Flappy Bird》被开发者本人从苹果及谷歌应用商店撤下。2014年8月份正式回归APP STORE,正式加入Flappy迷们期待已久的多人对战模式。游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍。
正文:
接下来就是一步一步来实现它
步骤1:页面布局,这儿就不多说了,页面内容如下:
步骤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小游戏实例代码网站的支持!
来源:http://blog.csdn.net/litong94/article/details/52642968


猜你喜欢
- 1.需求:在后台添加一条数据的同时要把添加者记录到表中。2.models.pyclass Setting(models.Model): &
- 我们在制作网页时,有时会遇到这样的情况:根据用户的选择,显示不同的内容。比如,制作一个登录网页,上面有
- 通过学习装饰器可以让我们更好更灵活的使用函数,通过学会使用装饰器还可以让我们的代码更加优雅。在我们的实际工作中,很多场景都会用到装饰器,比如
- 关于Django生成迁移文件,我是在虚拟机上完成的1.创建虚拟环境:在终端上输入创建python3的虚拟环境mkvirtualenv -p
- Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信。1. Queue的使用可以使用multiprocessing模块的
- 在之前的几篇文章中,介绍了业界中比较火爆的图片技术SVG(Scalable Vector Graphics),比如Iconfont(矢量图标
- 我的操作系统为centos6.51 首先选择django要使用什么数据库。django1.10默认数据库为sqlite3,本人想
- 首先,我们要先看看微信远程控制电脑的原理是什么呢? 我们可以利用Python的标准库控制本机电脑,然后要实现远程的话,我们可以把电子邮件作为
- #include <string>#include <iostream>using namespace std; v
- 首先,如果你还没有对yield有个初步分认识,那么你先把yield看做“return”,这个是直观的
- 参数数量及其作用tf.layers.dense用于添加一个全连接层。函数如下:tf.layers.dense( i
- 各种坑用py2exe,不支持,仅支持2.x用cx_frezee,各种问题方法 用pyinstaller。安装时务必用pip3 install
- 1.多选按钮的方法以下为常用的方法:方法描述deselect()清除多选按钮选中选项。flash()在激活状态颜色和正常颜色之间闪烁几次多选
- 发现一个有意思的现象,labelimg打开图片和xml标签时候,看不到标注好的框框,仔细查看了xml文件,没发现什么异常,后面试一下,才发现
- 决定数据类型的第一步是定义所存数数据的分类: 数值型, 字符串型还是临时型等;除了一些特别的并不是那么直观的外, 这通常是很直观的。接下来是
- 前言在使用pandas的时候,有些场景需要对数据内部进行分组处理,如一组全校学生成绩的数据,我们想通过班级进行分组,或者再对班级分组后的性别
- 随着“ * ”建设的逐步深入和 * 信息化的高速发展, * 计算机应用系统被广泛应用在各警种、各部门。与此同时,应用系统体系的核心、系统数据的
- 规律:半角空格的 charCode 为 32, 全角空格为 12288. 其他半角字符 ( 33 – 126 ) 与全角 ( 65281 –
- 前后端分离的开发模式,原本觉得没什么稀奇的玩艺,在最近参与的一个大型项目中,让我有了更深的理解。前后端分离的开发模式:系统分析阶段,系分和前
- 前言我们经常会有这样的需求,比如评论功能,每个评论都有可能会有自己的子评论,如果在界面只展示成一列的话非常不美观,也不能体现出他们的层级关系