使用JavaScript實現簡單的小游戲-貪吃蛇


最近初學JavaScript,在這里分享貪吃蛇小游戲的實現過程, 希望能看到的前輩們能指出這個程序的不足之處。
##大致思路
- 首先要解決的問題 - 隨着蛇頭的前進,尾巴也要前進。 - 用鍵盤控制蛇的運動方向。 - 初始化食物的時候不能初始化到蛇的身體上。 - 蛇吃食物的時候身體會變長。 - 蛇頭碰到“牆”,或者自己的身體游戲結束 - 不影響游戲的實現但是有關於游戲體驗的設計 - 界面的美觀。 - 分數的設置。 - 等級的設置(隨着分數的增加,蛇前進的速度的增加)。 - 暫停與繼續的快捷鍵。

##符號$說明
function $(id){       //在文件base.js中
	return document.getElementById(id);
}


##代碼
<!DOCTYPE html>
<html>
	<head>
		<title>Snake</title>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
		<style type="text/css" >
		body{background-color: #eee; font-family: 手札體-簡;}
			#page{width: 960px; height: 560px; margin: 30px auto; background-color: #fdf5e6;box-shadow: 3px 3px 3px rgba(0,0,0,0.2),10px 10px 20px rgba(0,0,0,0.2); border-radius: 5px;}
			#page div{float: left;}
			#left{width: 710px; height: 560px; }
			table{margin: 20px 100px;background-color: #9cc;}
			td{background-color: #cff;}

			#right{width: 205px; height: 560px;}
			#right div{float: none;}
			#score{width: 200px; height: 190px;;background-color: #ffffe0; border-radius: 10px;box-shadow: 3px 3px 3px rgba(0,0,0,0.2),5px 5px 10px rgba(0,0,0,0.2);margin-top: 20px;}
			#rank{width: 200px; height: 190px; margin-top: 10px;background-color: #ffffe0;border-radius: 10px;box-shadow: 3px 3px 3px rgba(0,0,0,0.2),5px 5px 10px rgba(0,0,0,0.2);}
			
			#right .tag{height:30px; width: 200px ;font-size: 40px;color: #9cf;font-weight: bolder; }
			#score_num{height: 130px; width: 200px; text-align: center;color: #9cf; font-size: 100px;}
			#rank_num{height: 130px; width: 200px; text-align: center;color: #9cf; font-size: 100px;}
			#notice{width: 200px;color: #9cf; margin-top: 5px;box-shadow: 3px 3px 3px rgba(0,0,0,0.2),5px 5px 10px rgba(0,0,0,0.2);background-color: #ffffe0; border-radius: 5px;margin-top: 90px;}
		</style>
		<script type="text/javascript" src="base.js"></script>
		<script type="text/javascript">
			//全局變量
			var max_scope = 30;//貪吃蛇的移動范圍
			var unit = 13;//每一個單元格的大小
			var speed = 300;//貪吃蛇移動速度
			var direction = 'left';//貪吃蛇移動方向
			var snake_body = null;
			var interval = null;//計時器
			var food = null;
			var score = 0;//分數(每吃一次,分數加一)
			var rank = 1;//隨着分數的增加,等級逐漸增加,速度逐漸增加
			

			//初始化游戲,使用表格做貪吃蛇移動的范圍
			function initGame(){
				snake_body = new Array();

				for(i = 0 ; i < max_scope; i++)
				{
					var row = document.createElement("tr");
					for( j = 0 ; j < max_scope; j++)
					{
						var cell = document.createElement("td");
						cell.id = i + "-" + j;
						cell.width = unit;
						cell.height = unit;
						row.appendChild(cell);
					}
					$("tbody").appendChild(row);
				}
				initSnake();
				snakeInterval();
				initFood();
			}


			//貪吃蛇身體初始化(隨機生成)
			function initSnake(){
				var x = parseInt(Math.random()*(max_scope-2));
				var y = parseInt(Math.random()*(max_scope-2));
				var now_position = x + "-" + y;
				snake_body.push(now_position);

				setCellState(now_position);


			}

			// 貪吃蛇身體染色
			function setCellState(id){
				$(id).style.background = "#000";
			}

			// 食物染色
			function setFootState(id){
				$(id).style.background = "#b10000";
			}

			// 貪吃蛇尾巴離開位置染色
			function setCellStateBack(id){
				$(id).style.background = "";
			}

			// 獲取貪吃蛇坐標
			function getSnakePos(i){
				switch(i){
					case 'x':
					return snake_body[0].split('-')[0];
					case 'y':
					return snake_body[0].split('-')[1];
				}

			}

			// 計時器
			function snakeInterval(){
				
				interval = window.setInterval('snakeMove()',speed);

			}

			// 初始化計時器
			function resetSnakeInterval(){
				window.clearInterval(interval);
				interval = window.setInterval('snakeMove()',speed);
			}

			// 設置蛇的移動與移動過程中發生的事件
			function snakeMove(){

				foodx = food.split('-')[0];
				foody = food.split('-')[1];

				switch(direction){

					case 'left':
					_x = getSnakePos('x');
					_y = parseInt(getSnakePos('y')) -1;
					break;
					case 'right':
					_x = getSnakePos('x');
					_y = parseInt(getSnakePos('y')) +1;
					break;

					case 'up':
					_x = parseInt(getSnakePos('x')) -1;
					_y = getSnakePos('y');
					break;
					case 'down':
					_x = parseInt(getSnakePos('x')) +1;
					_y = getSnakePos('y');
					break;
					default:
					_x = getSnakePos('x');
					_y = parseInt(getSnakePos('y')) -1;
					break;
				}

				//撞到牆游戲結束
				if (_x < 0 || _x >= max_scope|| _y < 0 || _y >= max_scope){
					alert("Game Over! Stupid!");
					window.clearInterval(interval);
				}

				//撞到自己游戲結束
				else if (eatItself(_x, _y))
				{
					alert("Game Over! Stupid!");
					window.clearInterval(interval);
				}
				
				//蛇吃到食物與吃到食物以后加一分,並設置相應的等級
				else if (foodx == _x && foody == _y)
				{
					snake_body.unshift(foodx + '-' + foody);
					setCellState(snake_body[0]);
					initFood();
					score+=1;
					$('score_num').innerText = score;
					if (score == 3) {
						speed = 250; 
						resetSnakeInterval();
						rank = 2;
					}
					if (score == 6) {
						speed = 200; 
						resetSnakeInterval();
						rank = 3;
					}
					if (score == 10) {
						speed = 150; 
						resetSnakeInterval();
						rank = 4;
					}
					if (score == 20) {
						speed = 100;
						resetSnakeInterval();
						 rank = 5;
					}
					if (score == 30) {
						speed = 70; 
						resetSnakeInterval();
						rank = 6;
					}
					//將等級寫到層中
					$('rank_num').innerText = rank;
				}

				//普通的移動
				else {
					snake_body.unshift(_x + '-' + _y);
					setCellState(snake_body[0]);
					setCellStateBack(snake_body.pop());
				}
			}

			// 判斷貪吃蛇頭碰到身體的函數
			function eatItself( x,y){
				var nowpos = x + '-' + y;
				for (i = 1 ; i < snake_body.length; i++){
					if (nowpos == snake_body[i])
					return true; 

				}
			}

			// 設置蛇的移動方向以及鍵盤控制暫停與繼續
			function setDirction(){
				  // alert(event.keyCode);
				  if (event.keyCode == 81) window.clearInterval(interval);
				  if (event.keyCode == 82) interval = window.setInterval('snakeMove()',speed);

				switch (event.keyCode){
					case 37:
					if (direction != "right")
					direction = "left";
					break;
					case 38:
					if (direction != "down")
					direction = "up";
					break;
					case 39:
					if (direction != "left")
					direction = "right";
					break;
					case 40:
					if (direction != "up")
					direction = "down";
					break;
				}

			}


			// 初始化食物
			function initFood(){
				var temp = new Array();
				for (i = 0 ; i < max_scope ; i++){
					for (j = 0 ; j < max_scope; j++){
						temp.push(i + '-' + j);
					}
				}

				var addFoodString = temp.join(',')+',';

				for(k = 0 ; k <snake_body.length; k++){
					addFoodString = addFoodString.replace(snake_body[k]+',',"")
				}

				var food_array = addFoodString.split(',');

				food = food_array[parseInt(Math.random()*(food_array.length - 1))]
				setFootState(food);
				// $('display').innerText = addFoodString;

			}

			// function pause(){
			// 	if (event.keyCode == 81) 
			// 		window.clearInterval(interval);
			// }

		</script>
	</head>
	<body onload="initGame()" onkeydown="setDirction()" >
		<div id = "page">
			<div id = "left">
				<table>
					<tbody id = "tbody">
					</tbody>
				</table>
			</div>
			
			<div id = "right">
				<div id = "score">
					<div class = "tag">Score</div>
					<div id = "score_num">0</div>
				</div>
				<div id = "rank">
					<div class = "tag">Rank</div>
					<div id = "rank_num">1</div>
				</div>
				<div id = "notice">NOTICE:按'Q'暫停,'E'繼續</div>
			</div>
		</div>
		<!-- <div id = "display"> </div> -->
	</body>
</html>


以下是效果圖: ![](http://images2017.cnblogs.com/blog/885599/201708/885599-20170828144621249-460981364.png)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM