前端小游戏

前端小游戏——简易贪吃蛇

  • 概要: 使用前端基础技术实现简易版贪吃蛇,涉及到的技术点有:html、css、javascript、jQuery

  • 要实现的功能: ①生成蛇移动的界面,这里使用二维数组(矩阵);②画出蛇;③蛇可以自动移动,并根据键盘的上下左右改变方向;④随机生成食物(食物不在蛇的身上产生);⑤吃食物,当蛇吃到食物时,蛇身变长,并且重新生成一个食物;⑥吃到食物后速度变快;⑦蛇死亡,分为两种情况,一个是吃到自己,另一个是撞墙;⑧结束游戏并重置画面(蛇的位置)。

  • web界面: 前端小游戏_第1张图片

  • html部分:

<div id="mainpanel" class="mainpanel"></div>
<div id="end" class="end">游戏结束!</div>
<p>
<input id="starBtn" type="button" value="开始" />
<input id="endBtn" type="button" value="结束" />
得分:<span id="point">0</span>
</p>
  • css部分:
            .mainpanel{
     
				border: 1px solid black;
				height: 400px;
				width: 800px;
				margin: 0px auto;
				font-size: 1px;
			}
			.innerbg{
     
				height: 18px;
				width: 18px;
				margin: 1px;
				background-color: lightgray;
				float: left;
			}
			.snake{
     
				background-color: goldenrod;
			}
			.food{
     
				background-color: lightgreen;
			}
			
			.end{
     
				width: 200px;
				height: 100px;
				border: 5px solid darkgray;
				background-color: #D3D3D3;
				border-radius: 10px;
				position: absolute;
				top: 30%;
				left: 50%;
				margin-left: -100px;
				display: none;
				text-align: center;
				line-height: 100px;
			}
			
			p{
     
				text-align: center;
			}

- JS部分:
定义全局变量


        //蛇横纵坐标
   		var snakeX = [4,5,6,7];
   		var snakeY = [4,4,4,4];
   		
   		//初始蛇头的位置
   		var snakeXHead = 7;
   		var snakeYHead = 4;
   		
        /*
        蛇头的初始朝向
   		37左
   		38上
   		39右
   		40下
   		 */
   	    var direction = 39;
   		 
   		//食物的横纵坐标
   		var foodX;
   		var foodY;
   		
   		var moveTime = 100; //蛇移动的初始速度
   		var score = 0; //分数
   		var startGame; //计时函数返回的对象名
   		
   		var state = true; //判断是否生成食物
   		var turn = true; //判断是否继续接受键盘的输入

基础数组:

       var basearr = new Array(40);
   		for(var i = 0;i<40;i++){
     
   			basearr[i] = new Array(20);
   		}

画蛇:

function drawSnake(){
     
   		for(var i = 0;i<snakeX.length;i++){
     
   			if(snakeX[i]<=39&&snakeX[i]>=0&&snakeY[i]<=19&&snakeY[i]>=0){
      //判断是否超出画面
   			basearr[snakeX[i]][snakeY[i]].addClass("snake");
   	    	}
    	}
   }

清除蛇:

function clearSnake(){
     
				for(var i = 0;i<snakeX.length;i++){
     
					basearr[snakeX[i]][snakeY[i]].removeClass("snake");
				}
			}

蛇移动:
①每次画蛇前,先清除原有的数组;
②根据键盘的输入判断蛇头的方向后移动;
③每次移动后用shift()函数清楚数组中的第一个元素;
④其他功能函数。eat()–>吃食物;death()–>死亡;drawSnake()–>画蛇

function snakeMove(){
     
				clearSnake();
				turn = true;
				
				switch(direction){
     
					case 39:snakeX.push(++snakeXHead);snakeY.push(snakeYHead);break;					
					case 37:snakeX.push(--snakeXHead);snakeY.push(snakeYHead);break;
					case 38:snakeX.push(snakeXHead);snakeY.push(--snakeYHead);break;
					case 40:snakeX.push(snakeXHead);snakeY.push(++snakeYHead);break;
				}
				
				snakeX.shift();
				snakeY.shift();
				
				eat();
				death();
				drawSnake();
			}

食物出现:
①用random函数随机生成食物的X、Y坐标;
②遍历循环蛇身数组,判断当随机生成的食物在蛇身上时不生成食物,并继续循环直到不在为止。

function foodShow(){
     
				
				do{
     
					foodX = Math.floor(Math.random()*39+0);
					foodY = Math.floor(Math.random()*19+0);
					state = false;
					for(var i = 0;i<snakeX.length;i++){
     
						if(snakeX[i]==foodX&&snakeY[i]==foodY){
     
							console.log("在蛇身上出现!不生成!")
							state = true;
						}
					}
				}while(state)
				
				basearr[foodX][foodY].addClass("food");
				console.log("食物坐标:"+foodX,foodY);
			}

吃食物动作: 当蛇头的XY坐标与食物的XY坐标一致时,吃到食物(碰撞事件)。
①分数+1;
②蛇速度变快,重置计时函数的时间,而后重新调用计时函数;
③移除当前食物,再次生成食物;
④使用unshift()函数给数组的开头添加一个新的元素并返回新的长度。

function eat(){
     
				
				if(snakeXHead==foodX&&snakeYHead==foodY){
     
					
					score += 1;
					moveTime -= 2;
					clearTimeout(startGame);
					startGame = setInterval(snakeMove,moveTime);
					
					$("#point").html(score);
					console.log("蛇移动速度"+moveTime);
					$(".food").removeClass('food');
					foodShow();
					
					snakeX.unshift(foodX);
					snakeY.unshift(foodY);
				}
			}

死亡:
①当蛇头的XY坐标和自身XY坐标重合时(吃到自己),调用clearInterval()函数停止计时函数,游戏结束;
②当蛇头的XY坐标超过界面长度时(撞墙),调用clearInterval()函数停止计时函数,游戏结束;

function death(){
     
				for(var i =0;i<snakeX.length-1;i++){
     
					if(snakeX[i] == snakeXHead && snakeY[i] == snakeYHead){
     

						clearInterval(startGame);
						$("#end").show();
						
						console.log("吃到自己啦!")
					}
					if(snakeXHead>39 ||snakeXHead<0 || snakeYHead>19 || snakeYHead<0 ){
     
						
						clearInterval(startGame);
						$("#end").show();
						
						console.log("出界啦!")
					}
				}
			}

重置页面:

function initGame(){
     

				$("#mainpanel").html("");//防止叠加界面
				
				//重置坐标面板
				for(var y = 0;y<20;y++){
     
					for(var x = 0;x<40;x++){
     
						var mycontent = $('
'
); basearr[x][y] = mycontent; $("#mainpanel").append(basearr[x][y]); } } snakeX =[4,5,6,7]; snakeY =[4,4,4,4]; drawSnake(); snakeXHead = 7; snakeYHead = 4; direction = 39; turn = true; moveTime = 100; }

- jQuery部分:

创建画面: 40*20

for(var y = 0;y<20;y++){
     
					for(var x = 0;x<40;x++){
     
						var mycontent = $('
'
); basearr[x][y] = mycontent; $("#mainpanel").append(basearr[x][y]); } } drawSnake();//创建初始蛇

通过键盘输入改变蛇移动的方向:
①限定接受键盘输入的范围(37-40);
Math.abs(direction-event.keyCode)!=2 用于判断不能直接掉头移动。例:当蛇头右移动时不能接收←、当蛇头向下移动时不能接收 ↑;
③turn作用:例如当蛇正在向下移动,此时快速按 → ↑,会导致蛇头穿过自己(死亡),为了防止这种情况发生,加入一个布尔变量turn,一次只接收一个按键的输入,当蛇再次移动时将turn的值变更为true;

$(document).keyup(function(event){
     
					
	 if(turn&&event.keyCode<=40&&event.keyCode>=37&&Math.abs(direction-event.keyCode)!=2){
     
	 
				direction = event.keyCode;
				turn = false;
			}
		})

开始按钮绑定监听事件:
①禁用开始按钮,开启结束按钮;
②重置画面
③开始计时函数,生成食物

$("#starBtn").click(function(){
     

		          $(this).prop("disabled",true);
	              $("#endBtn").prop("disabled",false);
					
		          initGame()
				
		          $("#end").hide();
		          startGame = setInterval(snakeMove,moveTime);
		          foodShow();			
               })

结束按钮绑定监听事件:
①结束计时函数
②清空分数
③禁用结束按钮,开启开始按钮;
④移除画面中的食物,展示结束弹窗;

$("#endBtn").click(function(){
     
					
					clearInterval(startGame);
					
					score = 0;
					$("#point").html(score);
					
					$(this).prop("disabled",true);
					$("#starBtn").prop("disabled",false);
					$(".food").removeClass('food');
					$("#end").show();
				})

总结: 一周的前端技术学习后实现的贪吃蛇小游戏。总体思路容易理通,关键点在于处理每个动过时的逻辑需要更细致,否则运行时就会出一些bug。

难点归纳:
①为了实现蛇的动态移动,需要考虑到每次增加元素后要及时删除一个元素,才能实现动态移动。
②如何防止食物不在蛇身上出现?
首先要考虑到出现在蛇身上时的食物XY坐标是与蛇的XY数组坐标相重合的,使用do while循环并遍历蛇身数组进行判断,当重合时将while循环条件实现为true,直到不重合false跳出do while循环生成食物。
③吃食物时如何让蛇变长?
这个动作的实现方法很多,我是直接使用unshift()函数增加元素,也可以进行判断,当吃到食物时不用shift()删除元素就可以。
④怎么让蛇每次吃到食物后速度变快?
在吃到食物时,先要停止当前的计时函数,而后再次调用setInterval()函数,并将时间设为变量,每次吃到食物后做减法。

你可能感兴趣的:(游戏,js,jquery,html,前端)