要求
坑中随机会出现大狼或者小狼,点击大狼加十分,点击小狼扣十分。
分析
这个小游戏里定时器非常多,所以定时器的创建和删除是比较关键的地方
开始游戏按钮相当于函数入口
点击开始游戏之后开始启动倒计时定时器,倒计时定时器不会受其他事件,除非自身宽度到底。
所有的事件都包含在生成狼的定时器中。意思为不管狼被不被打都不会影响狼定时器的工作。
这个小游戏里有很多非负即正的flag量控制的定时器,这也为以后类似情况的解决方法提供参考
一个例子:
在随机坑的时候,要保证连续两次随机出来的坑的位置不能相同,这个时候用了以下的方法去解决:
var prevIndex = -7;
var resultBol = true;//代表是否继续随机的状态
while (resultBol) {
r = random(0, arrPosi.length - 1);
if (prevIndex == r) {
//说明和上次重复
resultBol = true;
} else{
//不重复
resultBol = false;
}
}
……
……
……
prevIndex = r;
刚开始的时候,prevIndex的值是一个不可能存在的数。进入while循环中。当resultBol为真时继续循环,直到resultBol为假为止。循环体中首先就是随机坑的位置。再判断之前的坑的位置和随机的位置一样不一样,如果一样的话继续随机、判断;如果不一样的话就把标志量改为false。
又如
为了防止刷分,也采用了类似方法进行对应
//记录点击的状态,假设true为已经未点击狼
wolf.clickBol = true;
wolf.onclick = function () {
console.log(wolf.type);
//如果状态值为false,表明已点击
if (wolf.clickBol == false) {
return;//当状态量变化的时候直接返回
}
wolf.clickBol = false;
}
上面的程序段是防止刷分的处理程序,先设置狼的点击属性clickBol,当单击一次之后就把这个值取反(比如示例程序中开始的状态为true,点击之后将状态改为false)。
源代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#wrap {
width: 320px;
height: 480px;
background: url("img/game_bg.jpg") 0 0 no-repeat;
position: relative;
}
#score {
position: absolute;
font-weight: bold;
left: 64px;
top: 15px;
color: white;
}
#countDown {
background: url(img/progress.png);
width: 180px;
height: 16px;
position: absolute;
left: 63px;
top: 66px;
}
#wolf img {
position: absolute;
}
#menu {
position: absolute;
left: 0;
top: 200px;
width: 320px;
text-align: center;
font-size: 2em;
}
#start,
#handle,
#gameover {
font-weight: bold;
color: #f60;
text-shadow: 0 0 3px yellow;
}
#gameover {
font-size: 2em;
position: absolute;
width: 320px;
text-align: center;
top: 200px;
left: 0px;
display: none;
}
</style>
</head>
<body>
<div id="wrap">
<!--分数-->
<div id="score">0</div>
<!--显示时间-->
<div id="countDown"></div>
<!--大狼或者小狼部分-->
<div id="wolf">
<!--<img src="img/h5.png" />-->
</div>
<div id="menu">
<h4 id="start">开始</h4>
<h5 id="handle">游戏说明</h5>
</div>
<div id="gameover">游戏结束</div>
</div>
</body>
<script type="text/javascript">
window.onload = function() {
function random (m, n) {
return Math.floor(Math.random() * ((n - m + 1) + m));
}
var score = document.getElementById("score");
var countDown = document.getElementById("countDown");
var wolfs = document.getElementById("wolf");
var menu = document.getElementById("menu");
var start = document.getElementById("start");
var gameover = document.getElementById("gameover");
//狼出现的位置,用数组存储有对应关系的数据
//随机出现共有9个位置
var arrPosi = [{
l: "98px",
t: "115px"
}, {
l: "17px",
t: "160px"
}, {
l: "15px",
t: "220px"
}, {
l: "30px",
t: "293px"
}, {
l: "122px",
t: "273px"
}, {
l: "207px",
t: "295px"
}, {
l: "200px",
t: "211px"
}, {
l: "187px",
t: "141px"
}, {
l: "100px",
t: "185px"
}];
//创建一个狼出现的定时器
var createWolfTimer;
//获取倒计时图片宽度
var countDownWidth = countDown.offsetWidth;
//设置倒计时状态 是否开始倒计时
var countDownBol = false;//假设未开始为false
//处理得分还是失分
function scoreFn (a) {
var scores = parseInt(score.innerHTML);
if (a.type == "x") {
score.innerHTML = scores - 10;
} else {
score.innerHTML = scores + 10;
}
}
//设置倒计时定时器
var countDownTimer = setInterval(function () {
//如果开始游戏,则执行以下程序(启动定时器)
if (countDownBol) {
//倒计时图片宽度每次-1px
countDownWidth -= 2;
if (countDownWidth <= 0) {
gameover.style.display = "block";
clearInterval(countDownTimer);
clearInterval(createWolfTimer);
}
//每执行一次定时器,图片宽度-2,同时重新设置图片宽度
countDown.style.width = countDownWidth + "px";
}
}, 100);
countDownTimer;
var prevIndex = -7;//记录上一次狼位置的下标
start.onclick = function () {
//点击开始游戏时。需要将倒计时定时器状态设置为true,以便启动countDownTimer;
countDownBol = true;
menu.style.display = "none";
createWolfTimer = setInterval(function () {
var wolf = document.createElement("img");//狼所在的图片对象
wolf.type = random(0, 100) > 20 ? "h" : "x";//随机大狼或者是小狼(大狼几率比小狼几率高)
wolf.index = 0;//设置属性值 表示狼出现图片的时候处于第一张状态
wolf.src = "img/" + wolf.type + wolf.index + ".png";
var nowWolfs = wolfs.children;//获取所有狼
var r = random(0, arrPosi.length - 1);//随机坑
/**
* 避免此次随机狼的位置和上次的位置相同
*/
var resultBol = true;//代表是否继续随机的状态
while (resultBol) {
r = random(0, arrPosi.length - 1);
if (prevIndex == r) {
//说明和上次重复
resultBol = true;
} else{
//不重复
resultBol = false;
}
}
/**
* 给狼定位 将r下标对应的位置对象里的left和top值赋给狼位置
*/
wolf.style.left = arrPosi[r].l;
wolf.style.top = arrPosi[r].t;
wolfs.appendChild(wolf);//将狼对象wolf插入节点wolfs中
prevIndex = r;//执行顺序技巧,把这次的狼或者说坑的位置定下来之后再把这次的值赋给prevIndex以便下一次循环的时候做不重复处理
//创建狼钻出来的定时器
wolf.upTimer = setInterval(function () {
wolf.index++;
if (wolf.index > 4) {
//清除狼出现的定时器
clearInterval(wolf.upTimer);
//启动狼消失的定时器
wolf.downFn();
}
wolf.src = "img/" + wolf.type + wolf.index + ".png";
}, 150);
/**
* 这个定时器延迟时间可以和downTimer的延迟时间不一样,因为downTimer是封装在函数中作为判断条件用的,当满足判断条件时upTimer已经被清除。
*/
//狼消失函数
wolf.downFn = function () {
//创建狼消失的定时器
wolf.downTimer = setInterval(function () {
wolf.index--;
if (wolf.index <= 0) {
//清空定时器
clearInterval(wolf.downTimer);
//移除狼所在的节点
wolfs.removeChild(wolf);
}
wolf.src = "img/" + wolf.type + wolf.index + ".png";
}, 150);
}
//记录点击的状态,假设true为已经未点击狼
wolf.clickBol = true;
//为狼添加点击事件
wolf.onclick = function () {
console.log(wolf.type);
//如果状态值为false,表明已点击
if (wolf.clickBol == false) {
return;//当状态量变化的时候直接返回
}
wolf.clickBol = false;
//处理得分还是失分
scoreFn(wolf);
//重置属性index,切换到打击图片
wolf.index = 5;
//清除出现和消失的定时器
clearInterval(wolf.upTimer);
clearInterval(wolf.downTimer);
//点击狼之后,创建一个打击图片播放的定时器
wolf.clickTimer = setInterval(function () {
wolf.index++;
if (wolf.index >= 9) {
clearInterval(wolf.clickTimer);
wolfs.removeChild(wolf);
}
wolf.src = "img/" + wolf.type + wolf.index + ".png";
}, 150);
}
}, 1000);
}
}
</script>
</html>