原生js实现Flappy Bird小游戏
作者:microcosm1994 发布时间:2024-04-29 13:37:03
标签:js,Flappy,Bird
这是一个特别简单的用原生js实现的一个小鸟游戏,比较简单,适合新手练习。
html结构
<div id="game">
<div id="bird"></div>
</div>
css样式
#game {
width: 800px;
height: 600px;
border: 1px solid #000;
background: url(images/sky.png);
overflow: hidden;
position: relative;
}
#game .pipeD {
background: url(images/pipe1.png) top center;
position: absolute;
}
#game .pipeU {
background: url(images/pipe2.png) bottom center;
position: absolute;
}
#bird {
width: 34px;
height: 25px;
/*border-radius: 10px;*/
/*background-color: red;*/
position: absolute;
top: 100px;
left: 100px;
background: url(images/birds.png) -8px -10px no-repeat;
}
下面就是原生js代码了,这个小案例还运用了自己前期封装的一个小的动画方法
function animate(obj, json, fn) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
var flag = true;
for (var k in json) {
if (k === "opacity") {
var leader = getStyle(obj, k) * 100;
var target = json[k] * 100;
var step = (target - leader) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
leader = leader + step;
obj.style[k] = leader / 100;
} else if (k === "zIndex") {
obj.style.zIndex = json[k];
} else {
var leader = parseInt(getStyle(obj, k)) || 0;
var target = json[k];
var step = (target - leader) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
leader = leader + step;
obj.style[k] = leader + "px";
}
if (leader !== target) {
flag = false;
}
}
if (flag) {
clearInterval(obj.timer);
if (fn) {
fn();
}
}
}, 15);
}
function getStyle(obj, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(obj)[attr];
} else {
return obj.currentStyle[attr];
}
}
下面就是控制游戏的js代码了
var birdElement = document.getElementById("bird");
var game = document.getElementById("game");
var gameover = false;
var g = 1;
var i = 0;
var timer=null;
var bird = {
x: birdElement.offsetLeft,
y: birdElement.offsetTop,
speedX: 5,
speedY: 0,
entity: birdElement
};
var sky = {
x: 0
};
//var timer=setInterval(function(){
// birdElement.style.backgroundPositionX=-52*i+"px";
// i++;
// if(i===3){
// i=0;
// }
//},100);
setInterval(function () {
//游戏没有结束的时候运行代码
if (!gameover) {
//整个游戏背景x轴移动的距离
sky.x = sky.x - bird.speedX;
game.style.backgroundPositionX = sky.x + "px";
//小鸟下落时y轴的坐标
bird.speedY = bird.speedY + g;
//设置一个变量用来接收小鸟下落时y轴的坐标,用来设置小鸟下降时的速度
var step = bird.speedY;
bird.y = bird.y + step;
//用一个变量来设定小鸟下落的最低高度,用来 判断游戏是否结束
var overY = game.offsetHeight - birdElement.offsetHeight;
//小鸟的y轴坐标大于最低高度,所以游戏停止
if (bird.y > overY) {
bird.y = overY;
stop();
}
//小鸟的y轴坐标小于0,说明碰到顶部边框,所以游戏结束
if (bird.y < 0) {
bird.y = 0;
stop();
}
//设置游戏开始时小鸟出现的位置
bird.entity.style.top = bird.y + "px";
}
}, 25);
//添加键盘事件,实现键盘上下键控制小鸟
document.onkeyup = function (e) {
if (e.keyCode === 38) {
bird.speedY = -10;
}
}
function Pipe(positonX) {
//管子的坐标
this.x = positonX;
this.upPipeY = 0;
this.width = 52;
this.upPipeH = parseInt(Math.random() * 175 + 100);
this.downPipeY = this.upPipeH + 200;
this.downPipeH = game.offsetHeight - this.downPipeY;
// 动态添加管子
var divUp = document.createElement("div");
divUp.className = "pipeU";
divUp.style.width = this.width + "px";
divUp.style.height = this.upPipeH + "px";
divUp.style.left = this.x + "px";
divUp.style.top = this.upPipeY + "px";
game.appendChild(divUp);
var divDown = document.createElement("div");
divDown.className = "pipeD";
divDown.style.width = this.width + "px";
divDown.style.height = this.downPipeH + "px";
divDown.style.left = this.x + "px";
divDown.style.top = this.downPipeY + "px";
game.appendChild(divDown);
//因为定时器会混乱this的指向问题,所以提前保存this的指向,这里的this指向调用该方法的实例
var that = this;
// 设置定时器让管子向后移动
this.timer=setInterval(function () {
that.x = that.x - 1;
//简单实现管子无缝滚动
if (that.x < -52) {
that.x = 800;
}
if (!gameover) {
divUp.style.left = that.x + "px";
divDown.style.left = that.x + "px";
}
// 设置变量,进行游戏碰撞检测,并停止游戏
var downCrash = (bird.x + 34 > that.x) && (bird.x < that.x + 52) && (bird.y + 25 > that.downPipeY);
var upCrash = (bird.x + 34 > that.x) && (bird.x < that.x + 52) && (bird.y < that.upPipeH);
if (downCrash || upCrash) {
//gameover = true;
stop();
}
}, 10);
}
//执行上面的函数方法
var arr=[];
for (var i = 0; i < 4; i++) {
arr[i]=new Pipe(i * 200 + 400);
}
//封装一个用来停止游戏的方法,
function stop(){
gameover=true;
clearInterval(timer);
for(var i=0;i<arr.length;i++){
clearInterval(arr[i].timer);
}
}
注释都写在了了代码里,一个简单小游戏就完成了。
来源:https://blog.csdn.net/qq_39081974/article/details/78134885


猜你喜欢
- %r用rper()方法处理对象%s用str()方法处理对象相同结果有些情况下,两者处理的结果是一样的,比如说处理int型对象。例:print
- 本文简单总结了一下Python处理时间和日期方面的模块,主要就是datetime、time、calendar三个模块的使用,希望这篇文章对于
- 线性回归属于监督学习,因此方法和监督学习应该是一样的,先给定一个训练集,根据这个训练集学习出一个线性函数,然后测试这个函数训练的好不好(即此
- 今天在继续学习Python时,打开Pycharm后,发现有一个项目下的项目文件名是红色的,如下图:刚开始我以为是我升级 Pycharm导致的
- 需求:1.用户输入密码正确登录2.用户输入密码错误退出并调用函数继续输入3.用户输入密码符合原先给定的一个值时,允许用户重置密码,并且可以用
- 00 小编的问题小编向我们反馈,从微信里复制出来的图片,会被微信屏蔽,无法显示我们后天采用的是百度编辑器,而且已经做了远程图片本地化,于是检
- 我就废话不多说了,直接上代码吧!import matplotlibmatplotlib.use('Agg')import o
- PowerDesigner简介 工具的用途 :这里我只介绍他在SqlServer数据库的应用,其它的我也不懂。工具的好处 : 个人
- 前言最近一个项目需要iOS和安卓使用一个二维码,让扫描的机器自己识别操作系统实现跳转到相应的下载链接。比如iPhone用微信进行扫描就让他跳
- 目录MYSQL METADATA LOCK(MDL LOCK)学习 理论知识和加锁类型测试 一、初步了解二、基础重要的数据结构(类
- 布尔类型是PHP中 最简单的类型。它的值可以为 TRUE 或 FALSE。如:$foo=false;$foo1=true;echo &quo
- 简单Python词法分析器实现,供大家参考,具体内容如下词法分析器状态转换图:词法分析器总流程图:预处理程序:词法分析器:词法分析器程序详细
- 产品是一款服务于人力资源的SaaS在线服务,面向HR有Web Android/iOS 小程序多个客户端后端采用RESTful风格API来提供
- 有时候我反问我自己,怎么不知道在Python 3中用更简单的方式做“这样”的事,当我寻求答案时,随着时间的推移,我当然发现更简洁、有效并且b
- SqlServer将数据库中的表复制到另一个数据库一、如果两个数据库在同一台服务器上1、复制表结构和数据(A->B):SELECT *
- 在Mysql中很多表都包含可为NULL(空值)的列,即使应用程序并不需要保存NULL也是如此,这是因为可为NULL是列的默认属性。但我们常在
- 新版的path 虽然 取代了 之前的url,但是在写路由的时候不能在路由中直接写正则表达式,不然会找不到页面。解决方法使用re_pathfr
- 初入Python,一开始就被她简介的语法所吸引,代码简洁优雅,之前在C#里面打开文件写入文件等操作相比Python复杂多了,而Python打
- 进程、线程和协程之间的关系和区别也困扰我一阵子了,最近有一些心得,写一下。进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调
- 本文实例讲述了Python排序搜索基本算法之插入排序。分享给大家供大家参考,具体如下:插入排序生活中非常常见,打扑克的时候人的本能就在用插入