js小游戏之打地鼠

先来回忆一下我做游戏的步骤。

第一步:先做页面,放背景图片、定位“地鼠”位置,设置按钮,总体布局做好。

第二步:实现“地鼠”能随机出来,打“地鼠”,“地鼠”隐藏,并记录得分。

第三步:实现一定时间未点击时“地鼠”隐藏。

第四步:设置进度条,控制游戏的时间。

第五步: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

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值