先来回忆一下我做游戏的步骤。 第一步:先做页面,放背景图片、定位“地鼠”位置,设置按钮,总体布局做好。 第二步:实现“地鼠”能随机出来,打“地鼠”,“地鼠”隐藏,并记录得分。 第三步:实现一定时间未点击时“地鼠”隐藏。 第四步:设置进度条,控制游戏的时间。 第五步:js实现按钮的控制作用。 第六步:就进一步完善,总结了。 这个步骤可能并不是正确做游戏的一个步骤,因为这样它的应用性就不太好,后面改的时候改动也比较大,而且我在做的时候其实并没有一个清晰的思路,完全是做一步,想一步的,这也导致我后面改的地方多而杂。下次做东西前就要先想好你的布局,你的效果,你的按钮的功能,然后先做什么再做什么,步骤越详细越好,最好把他列出来,不要以为这样浪费时间,看着别人都在写了,你还不知道在干什么,其实你这样列出来以后,整个脉络清晰了,做的也快了。这可能就是所谓的建模吧,算法、Java其实都是一个道理的,要慢慢试着做东西前把详细的步骤列出来了! |
一、页面总体布局
这部分找好背景图片和“地鼠”后问题就不大了,无非就是定位的问题。然后就开始设置布局和结构。
这部分我比较疑惑地地方是“地鼠”的位置是不是直接在html文件中就设置好的,因为看了一些别人的代码,发现并没有在html中放那么多的“地鼠”,但是,我没有深入研究,做的比较简单,就在html中把所有的“地鼠”列出来了。然后还需要注意的是,背景图片和“地鼠”用的都是background:url();来实现的。附上代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>疯狂打</title>
<link rel="stylesheet" type="text/css" href="mycss/fright.css">
</head>
<body>
<div class="big">
<div class="game_area">
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div class="mole"></div>
<div id="paly">
<button id="come">来,发泄吧!</button>
</div>
<div class="flowing">时间:
<span id="progress"></span>
</div>
<div id="counts">当前得分
<p id="nowScore">0分</p>
</div>
<!-- 背景地图 -->
<div class="map"></div>
<!-- 刷新按钮 -->
<div class="restart">
<button id="Refresh">重新开始吧</button>
</div>
</div>
<!-- 开始按钮 -->
<button id="Start">开始游戏</button>
<!-- 暂停按钮 -->
<button id="Pause">暂停游戏</button>
<!--结束游戏-->
<button id="End">结束游戏</button>
</div>
<script type="text/javascript" src="myjs/fright.js"></script>
</body>
</html>
*{
margin: 0;
padding: 0;
}
.big{
width: 1349px;
margin: 70px auto;
position: relative;
}
.game_area{
width: 1000px;
height: 520px;
/*cursor: url(../imgs/1.ico),auto;*/
margin: 20px auto;
position: relative;
font-size: 20px;
}
#paly,.restart{
position: absolute;
z-index: 5;
width: 1349px;
height: 520px;
left: -178px;
top: 0;
background: url(../imgs/11.jpg) no-repeat;
background-size: 350px;
background-position: 520px 110px;
}
.restart{
display: none;
background: url(../imgs/1.jpg) no-repeat;
background-size: 350px;
background-position: 520px;
}
#come,#Refresh{
position: absolute;
background-color: #f6a561;
border-radius: 5px;
border: 1px solid #989e9c;
font-size: 20px;
color: #694040;
font-weight: bold;
padding: 3px;
top: 170px;
left: 540px
}
#Refresh{
color: #998282;
top: 80px;
left: 610px;
padding: 3px 35px;
background-color: #292624;
font-family: kaiti;
}
.map{
background: url(../imgs/00.jpg) no-repeat;
height: 520px;
background-size: 100%;
}
.mole{
position: absolute;
width: 108px;
display: none;
height: 101px;
background-image: url(../imgs/h5.png);
}
.mole:nth-child(1){
top: 65px;
left: 266px;
}
.mole:nth-child(2){
top: 65px;
left: 460px;
}
.mole:nth-child(3){
top: 65px;
left: 659px;
}
.mole:nth-child(4){
top: 141px;
left: 150px;
}
.mole:nth-child(5){
top: 141px;
left: 365px;
}
.mole:nth-child(6){
top: 141px;
left: 585px;
}
.mole:nth-child(7){
top: 141px;
left: 800px;
}
.mole:nth-child(8){
top: 222px;
left: 210px;
}
.mole:nth-child(9){
top: 222px;
left: 470px;
}
.mole:nth-child(10){
top: 222px;
left: 725px;
}
.mole:nth-child(11){
top: 308px;
left: 53px;
}
.mole:nth-child(12){
top: 308px;
left: 337px;
}
.mole:nth-child(13){
top: 308px;
left: 620px;
}
.mole:nth-child(14){
top: 308px;
left: 880px;
}
.mole:nth-child(15){
top: 406px;
left: 106px;
}
.mole:nth-child(16){
top: 406px;
left: 458px;
}
.mole:nth-child(17){
top: 406px;
left: 805px;
}
#Score{
top: 33px;
left: 45px;
font-size: 20px;
font-weight: bold;
font-family: 楷体;
color: #213b0f;
text-align: center;
transform: rotateZ(4deg)
}
#counts{
top: 35px;
right: 40px;
font-size: 19px;
font-weight: bold;
color: #27220a;
font-family: 楷体;
text-align: center;
transform: rotateZ(-3deg);
}
.flowing{
position: absolute;
top: 10px;
left: 380px;
width: 400px;
}
#progress{
width: 250px;
height: 25px;
position: relative;
top: 5px;
display: inline-block;
background-color: #ec3232e6;
border-radius: 25px;
z-index: 1;
}
#progress:before{
content: '';
width: 250px;
height: 25px;
position: absolute;
border: 1px solid #666060;
top: -1px;
left: -1px;
border-radius: 25px;
}
#Score,#counts,#Pause,#Start,#End{
position: absolute;
}
#Pause,#Start,#End{
background: #cb9966;
border: 1px solid #6f310f;
padding: 1px 15px;
border-radius: 5px;
font-size: 18px;
color: #fff;
left: 30px;
}
#Start{
top: 190px;
}
#Pause{
top: 240px;
}
#End{
top: 290px;
}
二、“地鼠”随机出现
这一部分的思路是什么呢?首先要随机出现一个“地鼠”,然后当你点击的时候隐藏,隐藏之后再随机出现一个“地鼠”,这样就构成了一个循环一样的结构,可以自动出现、隐藏。那么就是一个点击函数(click_),一个隐藏函数(down_),一个出现函数(up),点击函数里又down_(),down_()里有up(),然后up()函数里面又可以随机出现一个“地鼠”,再点击,OK,这样就基本实现了。但是啊,第一个地鼠要怎么出来呢?是不是要先点击按钮,调用up()函数,然后再调用click_()函数,然后才开始循环呢?
function start() {
up();
click_();
}
首先要知道随机函数吧-->Math.random(); 返回0~1之间的一个数字,这样又不能获取一个整数是吧,parseInt()来了,parseInt()是解析一个字符串返回一个整数的,由此,就可以定义一个变量(rand)让其等于parseInt(Math.random()*n)(n表示“地鼠”的个数)。随机数解决了,那来看怎么让“地鼠”出现和隐藏吧。
出现隐藏前还是要有一个点击函数的,点击是实现出现隐藏的一个中枢系统。
点击就是点击出来的那一个“地鼠”呀,直接用mole[rand].οnclick=function(){down_()} ? 这样是不可以的,因为此rand非彼rand呀,要利用一个循环来实现点击隐藏效果的。还有呀,怎么让第一个“地鼠”出来呢?
var mole = document.querySelectorAll('.mole');
function click_(){
for(var i = 0; i < mole.length; i++) {
mole[i].onclick = function() {
down_();
}
}
}
来看down_()函数:
function down_(){
mole[rand].style.display="none";
up();
}
up()函数:
function up() {
random_();
mole[rand].style.display = 'block';
}
OK,点击出现隐藏做完了。
三、时间控制隐藏
点击出现隐藏做好,似乎这个游戏也差不多完成了,但是,有没有感觉哪里不对,对,他不能自己下去。那么如何控制时间让他自己下去呢,这个时候就要用到setInterval()方法或者setTimeout()方法(这两种方法都可以进行计时控制落下)了,因为是在出现后未点击才会隐藏,所以此方法应该是用在up()函数里面的。但此方法也是一个计时器,若不清除,就会就会一直执行,在这里清除这两种计时方法可以用clearInterval()或者clearTimeout()。而且,我发现他们是可以混着用的。
另外一个加分的也很容易,你每次敲打后才会加分,那么你就获取那个加分的值,一次加几分就可以了呀。然后输出利用innerHTML。OK了。
四、时间进度条
时间进度条,怎么控制长度的变化?这是一个大问题,这个问题解决的基本就好做了,长度均速缩短,当长度为0时,游戏结束。
offsetWidth,又认识一个新的属性,offsetWidth可以获取物体宽度的数值,并且实际获取的是盒模型(width+border + padding)的宽度。利用offsetWidth获取进度条长度,然后每次减一定长度,再进行改变宽度的值,就可以让时间条变化了。但有一点,你在哪里调用这个函数呢?在哪个时间让他减短呢?这是一个问题,我是把它放在了down_()函数里面了,因为每次你点击的时间和隐藏的时间是差不多的,但这样其实是有问题的,嗯,我暂时也没找到比较好的办法。就先这样吧,留一个瑕疵。
最后结束的时候跳出另一个界面,这样就OK了吗?然而并没有,若是就简单的控制一下长度,结束的时候跳出另一个页面,但是“地鼠”还是在跳动的呀,你如何关闭他的跳动呢?
要对时间条加一个setInterval()事件,并且,当时间条长度变为0时,要清除所有的时间控制事件,这样,“地鼠”才不会再进行乱跳。
这个就是清除所有的定时操作函数:
function clearTimer() {
var timer = setInterval(function() {}, 1);
for(var i = 0; i < timer; i++) {
clearInterval(i);
}
}
时间条的函数:
var progress_t=progress.offsetWidth;
function progressTimer(){
setInterval(function(){
progress_t--;
progress.style.width=progress_t+'px';
if(progress_t<=0){
restart.style.display='block';
clearTimer();
}
},50);
}
五、按钮控制事件
按钮控制应该说也是比较简单的吧,一个暂停按钮,当你点击的时候,直接跳出一个alert(),游戏就暂停了。
然后是重新开始按钮,其实呢就是再来一个开始的按钮就可以了。
结束按钮呢就是你要清除之前的操作吧,这就要用到之前定义的清楚计时函数了,然后就是一些样式恢复的设置。
//暂停游戏
var Pause_btn = document.getElementById("Pause");
Pause_btn.onclick=pause;
function pause(){
alert("Pause");
}
//重新开始
var Refresh_btn = document.getElementById("Refresh");
Refresh_btn.onclick=refresh;
function refresh(){
restart.style.display='none';
for(var i=0;i<mole.length;i++){
mole[i].style.display='none';
}
progress_t=250;
score=0;
nowScore_btn.innerHTML=score+'分';
up();
click_();
progressTimer();
}
//结束游戏
var end=document.getElementById('End');
end.onclick=over;
function over(){
for (var i = mole.length - 1; i >= 0; i--) {
mole[i].style.display='none';
}
nowScore_btn.innerHTML='0分';
progress_t=250;
progress.style.width=progress_t+'px';
clearTimer();
}
六、完善游戏
以上步骤基本就完成了这个游戏,但是还存在一些问题,比如开始按钮你点击两次的时候就会出现两个“地鼠”呀,这个就要想一下是不是每次点击开始按钮的时候所有“地鼠”都要隐藏呀。还有一些其它的功能,这些都可以自己添加实现的。我呢,就先不实现了吧,偷个懒,以后有兴趣了再来完善。
七、总结
这次js小游戏再次认识了querySelector(),querySelectorAll()属性,parseInt()属性,随机数,计时器与清除计时器,调用函数加括号与不加括号的区别,游戏之间的逻辑关系,嗯,基本就这些了。
附上完整代码
链接:https://pan.baidu.com/s/1eP2c1HFqQ0Iip84svOWiHA
提取码:sa6p