今天这篇博客是关于一个叫做疯狂管道鸟的纯JS小游戏。
首先来看一下它的各个界面:
首页:
下方管道不断向左滚动,上方字母和小鸟上下浮动,点击start开始游戏。
开始游戏:
开始游戏后,界面上下方会同时出现不同长度的管道,点击鼠标左键使小鸟上升,小鸟需要从管道中间飞过 。当小鸟碰到管道或者飞出界面时游戏结束,此时会出现如图所示是样子,有一个“呸!老子瞧不起你!”的图片,还有一个当前积分,以及历史最佳分数,当前积分显示这局游戏的分数,历史最佳显示历史最高分。同时页面最上方正中间也会记录当前分数。点击OK重新开始游戏。
下面开始:
首先是开始界面,大概是这个样子:
插入背景图片,使其铺满整个页面(343*480px),然后从上到下依次是字母和小鸟,开始,管道。接下来写JS让它们动起来。
怎么让小鸟飞起来,首先先确定小鸟是哪个网页标签来修饰的,然后通过JS来找到这个修饰小鸟的网页标签;通过JS程序去改变小鸟背景图片的样式;让logo和小鸟能够一起上下动起来,这里设置了一个范围,就是当小鸟和logo离顶部的距离小于等于80或大于等于120的时候,就像相反的方向移动。
滚动条滚动效果,滚动条不断向左移动,每次向左移动1px,移动到343px的时候重新执行。
首先定义一个变量,获取滚动条;改变滚动条的样式,向左移动移动;当滚动条向左移动的距离小于-343px,也就是大于页面的宽度时,向左移动的距离变为0,即循环滚动。
// 滚动条滚动效果
var banner = $("#banner"); // 找到希望让Javascript去改变这个标签
banner.style.left = banner.offsetLeft - 1 + "px";
if(banner.offsetLeft <= -343) {
banner.style.left = "0px";
}
游戏开始按钮是事件触发,首先得到开始按钮的网页标签,使用onclick按钮点击事件。点击开始游戏之后隐藏logo和小鸟,清除管道滚动动效。
定义游戏开始的函数,记分div显示出来,创建小鸟的过程使用DOM操作;执行管道移动,调用waterPipe函数,随机生成0~180之间的整数,两组管道进行移动,2400毫秒进行一次管道创建;管道向右移动,如果管道移动到了最左侧,则清除管道(用remove方法);
定义小鸟飞起来,模仿自由落体(即不断在Y轴方向加一个距离值);小鸟在飞行的过程中不断煽动翅膀,通过不断切换背景图实现;在30毫秒内连续执行;keycode代表键盘当中的某一个键,32代表空格键;点击空格键小鸟向上移动一段距离;
// 定义小鸟飞起来的代码
var speedY = 0.1;
var imgindex = 0;
function AbridMove(Brid) {
function fly() {
speedY = speedY + 0.5;
Brid.style.top = Brid.offsetTop + speedY + "px"; // 模仿自由落体
// 煽动翅膀
Brid.style.background = "url("+ Arr[imgindex++] +") " + "no-repeat";
if(imgindex == 2) {
imgindex = 0;
}
// 碰撞到游戏界面边缘
if(Brid.offsetTop + Brid.offsetHeight >= 422 || Brid.offsetTop < 0) {
gameover(); // 执行游戏结束的函数
}
}
time2 = setInterval(fly, 30);
// 点击键盘空格键,让小鸟向上飞
document.onkeydown = function(ev) {
var e = ev || event; // 整合浏览器的兼容性
if(e.keyCode == 32) {
speedY = -8;
}
}
鼠标点击事件:
document.onclick = function() {
speedY = -8;
}
创建管道:
// 创建管道代码
function waterPipe(conduit, height1, height2, top, bottom, img1, img2) {
conduit.setAttribute("class", "conduit"); // 先添加管道的样式
conduit.style.top = top;
conduit.style.bottom = bottom;
// 制作管道的上半部分(身体)
var smalltop = document.createElement("div");
smalltop.style.height = height1; // 上半部分高度
smalltop.style.backgroundImage = "url("+ img1 +")"; // 上半部分的图片
// 制作管道的下半部分(头)
var smalldown = document.createElement("div");
smalldown.style.height = height2;
smalldown.style.backgroundImage = "url("+ img2 +")";
conduit.appendChild(smalltop);
conduit.appendChild(smalldown);
$("#BG").appendChild(conduit); // 将整个制作好的管道添加到界面里面
this.move = function() {
time3 = setInterval(function() {
conduit.style.left = conduit.offsetLeft - 1 + "px"; // 管道往右移动
if(conduit.offsetLeft + conduit.offsetWidth <= 0) { // 管道如果已经到达最左侧,则移除管道
conduit.remove(); // remove是JS中方法
}
管道移动:随机生成0~180之间的随机整数
// 执行管道移动,调用waterPipe函数
function createWater() {
var a = parseInt(Math.random() * 180); // 随机生成0~180之间随机整数
var bigTop = document.createElement("div");
var bigBottom = document.createElement("div");
var waterTop = new waterPipe(bigTop, a+"px", "60px", "0px", "none", "img/up_mod.png", "img/up_pipe.png"); // JSOO的语法,面向对象的语法
var waterBottom = new waterPipe(bigBottom, "60px", (180-a)+"px", "none", "57px", "img/down_pipe.png", "img/down_mod.png");
waterTop.move(); // 第一组管道进行移动
waterBottom.move(); // 第二组管道移动
}
time4 = setInterval(createWater, 2400); // 2400毫秒进行一次管道创建
}
判断碰撞:当小鸟出界或者碰到管道则游戏结束。左右碰撞,上下碰撞。
if($(".Brid").offsetTop + $(".Brid").offsetHeight >= conduit.offsetTop && $(".Brid").offsetTop <= conduit.offsetTop + conduit.offsetHeight && $(".Brid").offsetLeft + $(".Brid").offsetWidth >= conduit.offsetLeft && $(".Brid").offsetLeft <= conduit.offsetLeft + conduit.offsetWidth) {gameover(); // 执行游戏结束}
记分:为什么是70?鸟的高度是70px,等于70也就是说鸟刚好通过管道,得1分。
if(conduit.offsetLeft + conduit.offsetWidth == 70)
{number++;}
记分函数向下取整。
function jiFen() {
$("#bigScore").innerHTML = "";
var scoreStr = Math.floor(number / 2).toString(); // 向下取整数的操作
for (var i = 0; i < scoreStr.length; i++) {
$("#bigScore").innerHTML += "<img src='img/"+ scoreStr[i] +".jpg'>";
}
}
游戏结束函数:游戏结束,清除所有动画,即停止游戏中所有的定时器。本地存储分数,如果当前分数小于历史最高分,则历史最高分不变,否则将历史最高分变为当前分数。
function gameover() {
// 第一个步骤:显示最终的得分
$(".number").innerHTML = Math.floor(number / 2); // 显示游戏最终得分
// H5的存储的技术
if(window.localStorage.getItem("history") > Math.floor(number / 2)) {
$(".HistoryNumber").innerHTML = window.localStorage.getItem("history");
} else {
window.localStorage.setItem("history", Math.floor(number / 2)); // 重新设置历史最高分
$("HistoryNumber").innerHTML = Math.floor(number / 2);
}
$("#gameover").style.display = "block"; // 显示积分牌
// 清除所有的定时器
for (var i = 0; i < 1000; i++) {
clearInterval(i);
}
}
重新开始游戏:
$(".ok").onclick = function() {
number = 0; // 游戏结束的时候分数要清零
$("#gameover").style.display = "none"; // 隐藏了记分牌
$("#start").style.display = "none"; // 开始游戏的过程
$("#BG").innerHTML = ""; // 清除上一次游戏的所有界面元素
startganme(); // 开始游戏
}