JavaScript实现Fly Bird小游戏
1.分析页面结构,理清需求和功能
游戏有三个界面,分别是开始界面,游戏界面和游戏结束界面。
1.1 开始界面
- 游戏的大背景
- 上下移动的游戏标题和翅膀摆动的小鸟
- start 按钮,点击进入游戏界面
- 一直移动的地面
1.2 游戏界面
- 显示越过障碍数量的计分器
- 移动的障碍物,分别是上管道和下管道
- 点击游戏界面,小鸟向上飞起,然后在重力作用下下坠,
- 当小鸟和管道碰撞后,结束界面弹出,同时小鸟落到地面
1.3 结束界面
- GAMEOVER 提示面板
- OK 按钮
2. 开发“开始界面”
考虑到草地的移动效果,我们在页面中加入两个草地
2.1 HTML
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>Fly Bird</title><link rel="stylesheet" type="text/css" href="css/index.css"/></head><body><div id="wrapBg"> <!--游戏背景--><div id="headTitle"> <!--开始标题--><img id="headBird" src="img/bird0.png" alt="小鸟" /> <!--标题中的小鸟--></div><button id="startBtn" ></button> <!--开始按钮--><div id="grassLand1"></div> <!--草地1--><div id="grassLand2"></div> <!--草地2--></div></body>
</html>
2.2 CSS
#wrapBg{/*游戏背景*/width: 343px;height: 480px; margin: 0 auto;background-image:url(../img/bg.jpg);position: relative;top: 100px;overflow: hidden;
}
#headTitle{/*开始标题*/width: 236px;height: 77px;background-image: url(../img/head.jpg);position: absolute; left: 53px; top: 100px;
}
#headBird{/*开始标题中的小鸟*/float:right;margin-top: 25px;
}
#startBtn{/*开始按钮*/width: 85px;height: 29px;padding: 0;margin: 0;background-image: url(../img/start.jpg);position: absolute;left: 129px;top: 250px;
}
#grassLand1{/*草地1*/height: 14px;width: 343px;background-image: url(../img/banner.jpg);position: absolute;top: 423px;
}
#grassLand2{/*草地2*/height: 14px;width: 343px;background-image: url(../img/banner.jpg);position: absolute;top: 423px;left: 343px;
}
将wrapBg中的overflow:hidden 注释掉的页面效果
2.3 JS
小鸟煽动翅膀的效果需要用到逐帧动画的原理
逐帧动画是一种常见的动画形式(Frame By Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。
2.3.1 开始标题的摆动
var jsHeadTitle = document.getElementById("headTitle");// 获取标题var jsHeadBird = document.getElementById("headBird"); // 获取标题中小鸟var Y = 3;//标题的摆动幅度var index = 0;var imgArr = ["img/bird0.png","img/bird1.png"] //将小鸟图片路径放入一个数组,利用逐帧动画的原理做出小鸟翅膀摆动的样子var headWaveTimer = setInterval(headWave,200); //设置标题上下摆动的定时器function headWave() {Y *= -1;jsHeadTitle.style.top = jsHeadTitle.offsetTop + Y + "px";jsHeadBird.src = imgArr[index++];if (index == 2) {index = 0;}}
2.3.2 移动的草地
var jsGrassLand1 = document.getElementById("grassLand1"); //获取草地1var jsGrassLand2 = document.getElementById("grassLand2"); //获取草地2var landTimer = setInterval(landRun,30); //让草地动起来的定时器function landRun() {if (jsGrassLand1.offsetLeft <= -343) {jsGrassLand1.style.left = "343px";}if (jsGrassLand2.offsetLeft <= -343) {jsGrassLand2.style.left = "343px";}jsGrassLand1.style.left = jsGrassLand1.offsetLeft - 3 + "px";jsGrassLand2.style.left = jsGrassLand2.offsetLeft - 3 + "px";}
2.3.3 Start按键
var jsStartBtn = document.getElementById("startBtn");jsStartBtn.onclick = function() { //为start按键添加点击事件处理程序jsHeadTitle.style.display = "none"; //隐藏标题clearInterval(headWaveTimer); //关闭让标题摆动的定时器jsStartBtn.style.display = "none"; //隐藏按键//待添加功能//点击开始按键进入游戏界面}
完成后的效果(注释掉了wrapBg中的overflow:hidden )
接下来我们开发“游戏界面”
3. “游戏界面”的开发
游戏界面中有三样元素,分别是“小鸟”,“障碍”,和“计分器”,我们依次来创建相应的对象。
3.1 小鸟
首先,创建小鸟的对象, bird.js 文件。
var bird = {flyTimer:null,//小鸟飞翔定时器wingTimer:null,//小鸟翅膀摆动定时器div:document.createElement("div"),showBird:function(parentObj) {this.div.style.width = "40px";this.div.style.height = "28px";this.div.style.backgroundImage = "url(img/bird0.png)";this.div.style.backgroundRepeat = "no-repeat";this.div.style.position = "absolute";this.div.style.left = "50px";this.div.style.top = "200px";this.div.style.zIndex = "1";parentObj.appendChild(this.div); //将小鸟DIV插入游戏界面中},fallSpeed: 0, //小鸟下落速度flyBird: function(){ //控制小鸟飞翔下落的函数bird.flyTimer = setInterval(fly,40);function fly() {bird.div.style.top = bird.div.offsetTop + bird.fallSpeed++ + "px";if (bird.div.offsetTop < 0) { bird.fallSpeed = 2; //这里用于控制小鸟不要飞出界面}if (bird.div.offsetTop >= 395) {bird.fallSpeed = 0;clearInterval(bird.flyTimer); //一旦飞到地面,清除定时器clearInterval(bird.wingTimer); //清除翅膀摆动定时器}if (bird.fallSpeed > 12) {bird.fallSpeed = 12; //鸟的最大下落速度控制在12}}},wingWave: function() { //控制小鸟煽动翅膀的函数var up = ["url(img/up_bird0.png)", "url(img/up_bird1.png)"];var down = ["url(img/down_bird0.png)", "url(img/down_bird1.png)"];var i = 0, j = 0;bird.wingTimer = setInterval(wing,120);//逐帧动画,小鸟煽动翅膀function wing() {if (bird.fallSpeed > 0) {bird.div.style.backgroundImage = down[i++];if (i==2) {i = 0}}if (bird.fallSpeed < 0) {bird.div.style.backgroundImage = up[j++];if (j==2) {j = 0}}}},
};
下面,实现点击start按钮时,加载小鸟。(在之前的代码基础上添加)
jsStartBtn.onclick = function() { //为start按键添加点击事件处理程序jsHeadTitle.style.display = "none"; //隐藏标题clearInterval(headWaveTimer); //关闭让标题摆动的定时器jsStartBtn.style.display = "none"; //隐藏按键bird.showBird(jsWrapBg); //插入小鸟到界面中bird.flyBird(); //控制小鸟飞翔下落bird.wingWave(); //逐帧动画,小鸟煽动翅膀jsWrapBg.onclick = function(){bird.fallSpeed = -8;};//待添加功能//点击开始按键进入游戏界面
}
添加小鸟后的效果
3.2 障碍(上方水管和下方水管)
障碍分为上方管道和下方管道,如示意图所示结构嵌套,这样就可以通过随机设置DownDiv2的高度和gapHeight的高度,来改变生成障碍的形态
block.js
function Block() {this.upDivWrap = null;this.downDivWrap = null;this.downHeight = baseObj.randomNum(0,150);this.gapHeight = baseObj.randomNum(150,160);this.upHeight = 312 - this.downHeight - this.gapHeight;// 用来生成Div的方法this.createDiv = function(url, height, positionType, left, top) {var newDiv = document.createElement("div");newDiv.style.width = "62px";newDiv.style.height = height;newDiv.style.position = positionType;newDiv.style.left = left;newDiv.style.top = top;newDiv.style.backgroundImage = url; //"url(/img/0.jpg)"return newDiv;};this.createBlock = function() {var upDiv1 = this.createDiv("url(img/up_mod.png)", this.upHeight + "px");var upDiv2 = this.createDiv("url(img/up_pipe.png)", "60px");this.upDivWrap = this.createDiv(null, null, "absolute", "450px");this.upDivWrap.appendChild(upDiv1);this.upDivWrap.appendChild(upDiv2);//生成上方管道var downDiv1 = this.createDiv("url(img/down_pipe.png)", "60px");var downDiv2 = this.createDiv("url(img/down_mod.png)", this.downHeight +"px");this.downDivWrap = this.createDiv(null, null, "absolute", "450px", 363 - this.downHeight + "px");this.downDivWrap.appendChild(downDiv1);this.downDivWrap.appendChild(downDiv2); //生成下方的管道jsWrapBg.appendChild(this.upDivWrap);jsWrapBg.appendChild(this.downDivWrap);};this.moveBlock = function() { //控制管道移动的方法this.upDivWrap.style.left = this.upDivWrap.offsetLeft - 3 + "px";this.downDivWrap.style.left = this.downDivWrap.offsetLeft - 3 + "px";};
}
公共对象文件 baseObj.js ,用来提供随机数,和两个矩形div的碰撞检测
var baseObj = {//随机数randomNum: function(min, max) {return parseInt(Math.random() * (max - min + 1) + min);},//两个矩形元素之间的碰撞检测rectangleCrashExamine: function (obj1, obj2) {var obj1Left = obj1.offsetLeft;var obj1Width = obj1.offsetLeft + obj1.offsetWidth;var obj1Top = obj1.offsetTop;var obj1Height = obj1.offsetTop + obj1.offsetHeight;var obj2Left = obj2.offsetLeft;var obj2Width = obj2.offsetLeft + obj2.offsetWidth;var obj2Top = obj2.offsetTop;var obj2Height = obj2.offsetTop + obj2.offsetHeight;if (!(obj1Left > obj2Width || obj1Width < obj2Left || obj1Top > obj2Height || obj1Height < obj2Top)) {return true;}return false;},
};
下面我的想法是在start按钮点击的时候创建一个block,把这个block存储到数组 blocksArr 中,在 landTimer 定时器的方法 landRun 中检查此数组的长度,如果数组不为空数组,那么就让数组中所有的block移动。
检查最后一个block离开的距离,达到一定距离,就重新new 一个block,添加到数组。
检查第一个block,一旦达到一定位置,就在结构中移除downDivWrap 和 upDivWrap,同时在数组中删除。
var landTimer = setInterval(landRun,30); //让草地动起来的定时器function landRun() {if (jsGrassLand1.offsetLeft <= -343) {jsGrassLand1.style.left = "343px";}if (jsGrassLand2.offsetLeft <= -343) {jsGrassLand2.style.left = "343px";}jsGrassLand1.style.left = jsGrassLand1.offsetLeft - 3 + "px";jsGrassLand2.style.left = jsGrassLand2.offsetLeft - 3 + "px";if (blocksArr.length) {for (var i = 0; i < blocksArr.length; i++) {blocksArr[i].moveBlock();var x =baseObj.rectangleCrashExamine(blocksArr[i].downDivWrap, bird.div);var y = baseObj.rectangleCrashExamine(blocksArr[i].upDivWrap, bird.div);var z = bird.div.offsetTop >= 390;if (x || y || z) {window.clearInterval(landTimer);//清除landTimer定时器bird.fallSpeed = 0; //小鸟下落jsWrapBg.onclick = null; //消除点击事件}}if (blocksArr[blocksArr.length - 1].downDivWrap.offsetLeft < (450 - blockDistance)) {blockDistance = baseObj.randomNum(130,250);var newBlock = new Block();newBlock.createBlock();blocksArr.push(newBlock);}if (blocksArr[0].downDivWrap.offsetLeft < -50) {jsWrapBg.removeChild(blocksArr[0].downDivWrap);jsWrapBg.removeChild(blocksArr[0].upDivWrap);blocksArr.shift(blocksArr[0]);}}}
当前的游戏效果
3.3 计分器
游戏中的计分器相对较好实现
<div id="score"><div id="num1"></div><div id="num2"></div><div id="num3"></div></div>
var jsScore = document.getElementById("score");var jsNum1 = document.getElementById("num1");var jsNum2 = document.getElementById("num2");var jsNum3 = document.getElementById("num3");var score = 0;
今天先这样了,改天再写。哈哈
原文链接:http://www.jianshu.com/p/45d994d04a25
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
JavaScript实现Fly Bird小游戏相关推荐
- java fly bird小游戏_java swing实现的小游戏flybird源码附带视频配置修改教程
大家好,今天给大家演示一下由Java swing实现的一款小游戏flybird,该游戏操作比较简单,点击鼠标确保小鸟不要触碰到柱子即可,该游戏可运行在Java环境下,jdk版本不限,下面我们来看看如何 ...
- cmd小游戏_使用pygame制作Flappy bird小游戏
原文链接: [Python]使用Pygame做一个Flappy bird小游戏(一)mp.weixin.qq.com 最近看到很多大佬用强化学习玩Flappy bird.所以打算也上手玩一玩,但是苦 ...
- 用javascript编写的打字小游戏
最近在学ExtJs,看了蔡世友老师的视频课程,在第十课中留了一个小作业,就是用javascript写一个打字小游戏,于是按照前几课所讲的知识自己编写了一个. 一.需求:网页上在随机位置会出现字母,字母 ...
- 弹力细胞,一个由JavaScript写的网页小游戏
弹力细胞 (BounceCell) 一个由JavaScript写的网页小游戏 作为大一菜鸟,这是我第一次比较正式的写文章 [害臊] 游戏玩法 通过鼠标或触屏控制屏幕底部的滑动弹板将发射的小球反弹出去撞 ...
- 用javascript+jquery编写的小游戏-贪吃蛇(双人对战版)
前言 这是我在多年前初学jquery, 并结合javascript, 编写的一个小游戏.那洋洋洒洒几千行的js代码时刻提醒着我"不忘初心!". 效果演示 代码 引入文件 由于用到了 ...
- c语言像素鸟游戏,mfc编写的像素鸟flappy bird 小游戏
压缩包内容概览: mfc编写的像素鸟flappy bird 小游戏-FP_Beta1 ; 调试 ; FPβ1 ; 关于我们 ; 背景 ; FPβ1.VCXPROJ ; FPβ1动态心电图 ; 管子 ; ...
- Python flappy bird 小游戏
Python flappy bird 小游戏: 源码: from random import * from turtle import *from freegames import vectorbir ...
- 原生JavaScript抒写——贪吃蛇小游戏
原生JavaScript抒写--贪吃蛇小游戏 文章目录 原生JavaScript抒写--贪吃蛇小游戏 前言 一.需求分析 二.效果展示 三.具体逻辑代码分析 1.首先创建一个html文件,然后我们利用 ...
- 使用canvas写一个flappy bird小游戏
简介 canvas 是HTML5 提供的一种新标签,它可以支持 JavaScript 在上面绘画,控制每一个像素,它经常被用来制作小游戏,接下来我将用它来模仿制作一款叫flappy bird的小游戏. ...
- html5翻卡片游戏,用 JavaScript 写一个卡片小游戏
小游戏使用了HTML5,CSS3和JavaScript的基本的技术. 将讨论数据属性.定位.透视.转换.flexbox.事件处理.超时和三元组. 你不需要在编程方面有太多的知识和经验就能看懂,不过还是 ...
最新文章
- 5位最具影响力的程序员
- SAP Spartacus split view控制同屏显示最大视图数的配置
- mysql 5.5 重新编译_源码编译mysql5.5过程记录
- JQuery EasyUI DataGrid 、tree查询
- [UE4] 内容浏览器不显示继承自 None 的类
- mongodb 全文搜索---ttlsa教程系列之mongodb(十)
- python3字典详解_Python3实现的字典遍历操作详解
- bootstrap 和 jqueryui
- python编写递归函数和非递归函数、输出斐波那契数列_C语言编程:用递归和非递归法输出斐波那契数列...
- SPSS数据插补方法
- html小游戏社区,h5小游戏源码(h5养成社区源码)
- 【北亚数据恢复】zfs文件系统的服务器误删除的数据恢复
- C++关键字分析系列
- 你还记得大明湖畔的oop原则吗?
- 简单解决SVN cleanup failed to process the following paths错误
- 关于S参数的一些理解
- js中find和findIndex的使用
- linux---VI
- 如何写一个简单的手写识别算法?
- oracle启用amm,Oracle11g自动内存管理(AMM)相关的初始化参数