最近初学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)

最新文章

  1. 基于MVC4+EasyUI的Web开发框架经验总结(17)--布局和对话框自动适应大小的处理
  2. Concurrency in csharp (Asynchronous, Parallel, and Multithreaded Programming)
  3. http错误码大全?
  4. 【人在江湖飘,哪有不带刀】神器Jumony
  5. Codeforces Round #283 Div.2 D Tennis Game --二分
  6. ccpc_南阳 C The Battle of chibi dp + 树状数组
  7. FZU 2214 Knapsack problem 01背包变形
  8. 懒加载异常:org.hibernate.LazyInitializationException: could not initialize proxy - no Session
  9. OpenCV示例学习笔记(1)-contours2.cpp-通过findContours 函数实现轮廓提取
  10. 转 如何不耍流氓的做运维之——SHELL脚本
  11. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2版本正式发布
  12. vuejs2+webpack2+vuxui2多页面架手脚,支持二级目录
  13. 时间戳转日期 mysql以及sql server 用法
  14. SQL Server 2005详细安装过程及配置
  15. vmware 中安装Ghost XP 版本心得
  16. 15个Spring的核心注释示例
  17. LeetCode 10 Regular Expression Matching(字符串匹配)
  18. 根据wsdl,apache cxf的wsdl2java工具生成客户端、服务端代码
  19. 猎豹浏览器(chrome内核)屏蔽视频广告
  20. linux下lz4解压缩遇到的那些事儿

热门文章

  1. ArcGIS紧凑型切片读取与应用3-紧凑型批量转分散型(附源码)
  2. Java设计模式学习记录-单例模式
  3. FFmpeg简易播放器的实现-音视频播放
  4. nodejs的__dirname,__filename,process.cwd()区别
  5. .3-浅析express源码之applicaiton模块(2)-app.render
  6. mybatis-plus排除非表中字段
  7. Mybatis的类型处理器
  8. 解决 iframe 后退不是主页面后退(浏览器 history)问题
  9. 基于std::mutex std::lock_guard std::condition_variable 和std::async实现的简单同步队列
  10. Python paramiko ssh 在同一个session里run多个命令