基于JavaScript实现的网页版贪吃蛇

效果截图

实现原理

通过div布局来实现贪吃蛇小游戏,html+JavaScript实现, 通过方向键的上下左右实现蛇的移动

首先,地图为一个二维数组 Map[*][*]

蛇的坐标分为X轴和Y轴 即 行(H) 与 列(L),且分别用 SnakeH 和 SnakeL 两个一维数组来存储

并且都以SnakeH[0] 和 SnakeL[0]作为蛇头进行移动

食物的坐标分为X轴和Y轴,用 foodX 和 foodY 来记录食物坐标

首先通过双层for循环生成存储地图用的二维数组

然后通过循环使用 document.createElement("div"); 在一个div中添加多个子元素

一共添加800个子元素,填充至父div中.

然后通过css设置,地图div的背景颜色为肉色,蛇身的div背景颜色为绿色,食物为红色.

通过改变div颜色来实现物体显示

其中还使用了 window.onkeydown = function( ) 方法来获取键盘输入按键

还使用了 

     定时器  (要执行的代码或方法名,间隔的时间(毫秒));
                var hh = setInterval("move()",200);

使其每0.2秒就调用一次移动方法.

下面是全部代码!

代码分析

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>贪吃蛇</title>
		<style type="text/css">
			h1{
				font-family: 楷体;
				text-align: center;
				color: #9555af;
			}
			#father{
				width: 800px;
				height: 400px;
				border: 1px solid black;
				margin: 0 auto;
			}
			.baby{
				height: 18px;
				width: 18px;
				border: 1px solid black;
				background-color: bisque;	
				float: left;
			}
			.snake{
				height: 18px;
				width: 18px;
				border: 1px solid black;
				background-color: green;	
				float: left;
			}
			.food{
				height: 18px;
				width: 18px;
				border: 1px solid black;
				background-color: red;	
				float: left;
			}
			#buttn{
				width: 70px;
				height: auto;
				border: 1px solid transparent;
				margin: 0 auto;
				margin-top: 50px;
			}
			button {
				/*清除button默认的样式*/
			  padding: 0;
			  border: none;
			  font: inherit;
			  color: inherit;
			  background-color: transparent;
			  cursor: pointer;
			}
			.btn {
			  /* 默认为button 但是在<a>上依然有效 */
			  display: inline-block;
			  text-align: center;
			  text-decoration: none;
			
			  /* 创造上下间距一定的空间 */
			  margin: 2px 0;
			  /* border透明 (当鼠标悬停时上色) */
			  border: solid 1px transparent;
			  border-radius: 4px;
			
			  /* padding大小与字体大小相关 (no width/height) */
			  padding: 0.5em 1em;
			
			  /* 确保字体颜色和背景色有足够区分度! */
			  color: #ffffff;
			  background-color: #9555af;
			}
		</style>
	</head>
	<body>
		<h1>网页版贪吃蛇</h1>
		<div id="father"></div>
		<div id="buttn">
			<button type="button" class="btn" onclick="starGame()">开始</button>
		</div>
		<script type="text/javascript">
			//全局变量
			var Map = new Array(); // 地图数组
			var snakeH = [10,10,10,10,10]; //行
			var snakeL = [27,28,29,30,31];//列
			var foodX = 0;
			var foodY = 0
			var snakeLength = 5; //蛇的长度
			
			function starMap(){//用于产生初始地图与资源									
				for (var i=0; i<20; i++) {
					Map[i] = Array();
					for(var j=0; j<40; j++){
						var div2 = document.createElement("div");
						div2.className = "baby";
						Map[i][j] = document.getElementsByTagName("div")[0].appendChild(div2);	
					}	
				}				
			}
			
			function cleanMap(){//将地图全部变成肉色
				for (var i=0; i<20; i++) {
					for (var j=0; j<40; j++) {
						Map[i][j].className="baby";
					}
				}
			}
			
			function showSnake(){
				//初始蛇身长度为3,包括蛇头
				for (var i=0; i<snakeLength; i++) {
					console.log("蛇的坐标:"+snakeH[i]+","+snakeL[i]+";");
				}
				
				for (var i=0; i<snakeLength; i++) {
					Map[snakeH[i]][snakeL[i]].className="snake";
				}
			}
			
			function creayFood(){
				//随机生成食物坐标
				foodX = parseInt(RandoMath(0,20));
				foodY = parseInt(RandoMath(0,40));
				//如果食物生成到了蛇身,则重新生成食物
				for(var i=0; i<snakeLength; i++){
					if(snakeH[i]==foodX && snakeL[i]==foodY){
						foodX = parseInt(RandoMath(0,20));
						foodY = parseInt(RandoMath(0,40));
					}
				}
				console.log("新的食物的坐标:"+foodX+","+foodY+"; ");
			}
			
			function showFood(){			
				Map[foodX][foodY].className="food";
			}
			
			function eatFood(){
				//每次都记录下蛇身数组
				var fSnakeH = snakeH;
				var fSnakeL = snakeL;
				//如果蛇头的位置等于食物的位置
				if(snakeH[0] == foodX && snakeL[0] == foodY){
					//记录食物的坐标
					var fH = foodX;
					var fL = foodY;
					//将食物坐标放入蛇数组的第一位
					snakeH[0] = fH;
					snakeL[0] = fL;
					for (var i=1; i<snakeLength; i++) {
						snakeH[i] = fSnakeH[i];
						snakeL[i] = fSnakeL[i];
					}
					snakeLength += 1;//蛇身长度加1
					console.log("吃到了食物!");
					//生成一个新食物
					creayFood();
				}else{
					console.log("没有吃到食物!");
				}
			}
			
			function death(){
				if(snakeH[0] < 0 || snakeL[0] < 0){
					console.log("你撞墙了!");
					alert("你撞墙了!  你的分数为"+snakeLength);
					location.reload(); 
				}
				if(snakeH[0] > 20 || snakeL[0] > 40){
					console.log("你撞墙了!");
					alert("你撞墙了!  你的分数为"+snakeLength);
					location.reload(); 
				}
				for (var i=1; i<snakeLength; i++) {
					if(snakeH[0] == snakeH[i] && snakeL[0] == snakeL[i]){
						console.log("你自杀了!");
						alert("你自杀了!  你的分数为"+snakeLength);
						location.reload();
					}
				}
			}

				var zhi = 38;//默认开始方向向上走
				var f = zhi;
				window.onkeydown = function(e){
					var ke = e.keyCode;
					if(ke == 37 && zhi != 39){
						zhi=ke;
						f = zhi;
						console.log(zhi);
					}
					if(ke === 38 && zhi != 40){
						zhi=ke;
						f = zhi;
						console.log(zhi);
					}
					if(ke === 39 && zhi != 37){
						zhi=ke;
						f = zhi;
						console.log(zhi);
					}
					if(ke === 40 && zhi != 38){
						zhi=ke;
						f = zhi;
						console.log(zhi);
					}
					if(ke != 37 && ke != 38 && ke != 39 && ke != 40){
						zhi = f;
					}
				}
			
			function move(){
				var flag1 = 0;
				var flag2 = 0;
				var flag3 = 0;
				var flag4 = 0;
				//方向键  ←为37  ↑ 38  → 39  ↓ 40
				switch(zhi){
					case 37:
						flag1 = snakeL[0];
						flag2 = snakeL[1];
						flag3 = snakeH[0];
						flag4 = snakeH[1];
						snakeL[0] -= 1; //向左移动,蛇头的列发生变化,向左-1
					break;
					case 38:
						flag1 = snakeL[0];
						flag2 = snakeL[1];
						flag3 = snakeH[0];
						flag4 = snakeH[1];
						snakeH[0] -= 1;//向上移动,蛇头的行发生变化,向上-1
					break;
					case 39:
						flag1 = snakeL[0];
						flag2 = snakeL[1];
						flag3 = snakeH[0];
						flag4 = snakeH[1];
						snakeL[0] += 1; 向右移动,蛇头的列发生变化,向右+1
					break;
					case 40:
						flag1 = snakeL[0];
						flag2 = snakeL[1];
						flag3 = snakeH[0];
						flag4 = snakeH[1];
						snakeH[0] += 1; 向下移动,蛇头的列发生变化,向下+1
						
					break;
				}
				//蛇头坐标修改之后,再将除蛇头外的蛇身坐标全部向后交换   
				//   *!!!* 这里的细节原理文章结尾会有解释
				console.log("屁股的坐标:"+snakeH[snakeLength-1]+","+snakeL[snakeLength-1]+"; ");
						for(var i=1; i<snakeLength; i+=2){
							snakeL[i] = flag1;
							flag1 = snakeL[i+1];
							snakeH[i] = flag3;
							flag3 = snakeH[i+1];
							snakeL[i+1] = flag2;
							flag2 = snakeL[i+2];
							snakeH[i+1] = flag4;
							flag4 = snakeH[i+2];
						}
				console.log("移动一次结束!");
				eatFood();//判断是否吃到食物
				death();//判断是否死亡
				//每一次移动之后,都重新将所有div恢复成肉色,重新显示出蛇的最新位置,和食物的最新位置		
				cleanMap();
				showSnake();
				showFood();
			}
			
			function starGame(){//开始游戏
				showSnake();
				creayFood();
				showFood();
				//定时器  (要执行的代码,间隔的时间(毫秒))
				var hh = setInterval("move()",200);
			}
			
			function RandoMath(Min,Max){//生成[Min,Max)之间的随机数
				var num = Min + Math.random()*Max;
				return num;
			}
			starMap();
		</script>
	</body>
</html>

总结

第250行代码解释:   数组中的蛇身坐标值交换

1.先将A[0]的值赋给flag1 , 再将A[1]的值赋给flag2

2.开始for循环,从下标1开始循环

for(var i=1; i<snakeLength; i+=2){   //由于两个flag,所以一次更改了两个数组节点的值,所以下标一次加2
                            snakeL[i] = flag1;     
                            flag1 = snakeL[i+1];  // 在SnakeL[i+1]的值被flag2覆盖前,保存到flag1中去
                            snakeL[i+1] = flag2;
                            flag2 = snakeL[i+2];
            }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值