- 项目只有四个文件:index.html、Game.js、Snake.js、Food.js
- 贪吃蛇游戏较为简单,有什么疑问欢迎在评论区探讨
- index.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
background: rgb(0, 255, 221);
color: #fff;
text-align: center;
}
table{
border-collapse: collapse;
background:rgb(0, 255, 221);
border:1px solid #fff;
margin:50px auto;
}
td{
width: 24px;
height: 24px;
color: blue;
text-align: center;
background: #333;
border:1px solid #fff;
border-radius: 50%;
}
</style>
</head>
<body>
<h3 id = "f">帧编号:0</h3>
<h3 id = "score">分数:0</h3>
<div id="app"></div>
<script src="js/Game.js"></script>
<script src="js/Snake.js"></script>
<script src="js/Food.js"></script>
<script>
var game = new Game();
</script>
</body>
</html>
- Game.js 文件
function Game(){
//行数
this.row = 20;
//列数
this.col = 20;
//分数
this.score = 0;
//初始化节点
this.init();
//实例化蛇类
this.snake = new Snake();
//初始化食物
this.food = new Food(this);
//执行定时器任务
this.start();
//键盘的事件监听
this.bindEvent();
//
}
Game.prototype.init = function(){
this.dom = document.createElement("table");
var tr,td;
// 遍历行与列上树
for(var i = 0;i < this.row;i ++){
//遍历行,创建节点上树
tr = document.createElement("tr");
//追加节点上树
this.dom.appendChild(tr);
for(var j = 0;j < this.col;j ++){
//遍历列,创建节点上树
td = document.createElement("td");
//追加节点上树
tr.appendChild(td);
}
}
//表格上树
document.getElementById("app").appendChild(this.dom);
};
Game.prototype.clear = function(){
//遍历表格,擦除画布
for(var i = 0;i < this.row;i ++){
for(var j = 0;j < this.col;j ++){
this.dom.getElementsByTagName("tr")[i].getElementsByTagName("td")[j].style.backgroundColor = "rgb(0, 255, 221)";
//删除食物
this.dom.getElementsByTagName("tr")[i].getElementsByTagName("td")[j].innerHTML = "";
}
}
};
//设置颜色的方法
Game.prototype.setColor = function(row,col,color){
//让表格的第几行第几列设置什么颜色
this.dom.getElementsByTagName("tr")[row].getElementsByTagName("td")[col].style.backgroundColor = color;
};
//渲染食物
Game.prototype.setHTML = function(row,col,html){
this.dom.getElementsByTagName("tr")[row].getElementsByTagName("td")[col].innerHTML = html;
};
//设置键盘的事件监听
Game.prototype.bindEvent = function(){
var self = this;
//键盘事件
document.onkeydown = function(event){
switch(event.keyCode){
//按下左键
case 37:
//先进行判断,如果当前的方向向右移动,此时我们不能按左键
if(game.snake.direction == "R"){
return;
}
// self.snake.direction = "L";
self.snake.changeDirection("L");
break;
//按下上键
case 38:
//先进行判断,如果当前的方向向下移动,此时我们不能按上键
if(game.snake.direction == "D"){
return;
}
// self.snake.direction = "U";
self.snake.changeDirection("U");
break;
//按下右键
case 39:
if(game.snake.direction == "L"){
return;
}
// self.snake.direction = "R";
self.snake.changeDirection("R");
break;
//按下下键
case 40:
if(game.snake.direction == "U"){
return;
}
// self.snake.direction = "D";
self.snake.changeDirection("D");
break;
}
};
};
Game.prototype.start = function(){
//帧编号
this.f = 0;
this.timer = setInterval(function(){
//定时器里面的核心就是游戏的渲染本质,清屏-更新-渲染
game.f++;
document.getElementById("f").innerHTML = "帧编号:" + game.f;
//渲染分数
document.getElementById("score").innerHTML = "分数:" + game.score;
//清除屏幕
game.clear();
//蛇的更新
//蛇的更新速度,当蛇变长的时候,速度要加快
var during = game.snake.body.length < 30 ? 30 - game.snake.body.length : 1;
game.f % during == 0 && game.snake.update();
//蛇的渲染
game.snake.render();
//食物渲染
game.food.render();
},20);
};
- Snake.js 文件
function Snake(){
//蛇的初始化身体
this.body = [
{"row":3,"col":6},
{"row":3,"col":5},
{"row":3,"col":4},
{"row":3,"col":3},
{"row":3,"col":2}
];
//信号量,蛇的运动方向
this.direction = "R";
//即将改变的方向,目的就是防止出现原地调头的情况
this.willDirection = "R";
}
//蛇的运动
Snake.prototype.update = function(){
//让当前的 direction 接收一下 willDirection
this.direction = this.willDirection;
//蛇的不同方向的运动
switch(this.direction){
case "R":
this.body.unshift({"row":this.body[0].row,"col":this.body[0].col + 1});
break;
case "D":
this.body.unshift({"row":this.body[0].row + 1,"col":this.body[0].col});
break;
case "L":
this.body.unshift({"row":this.body[0].row,"col":this.body[0].col - 1});
break;
case "U":
this.body.unshift({"row":this.body[0].row - 1,"col":this.body[0].col});
break;
}
//死亡的判定,超出了表格边缘的部分
if(this.body[0].col > game.col - 1 || this.body[0].row > game.row - 1 || this.body[0].col < 0 || this.body[0].row < 0){
//删除是因为当前的头增是不合法的
this.body.shift();
alert("游戏结束,您当前的得分为:" + game.score + "分");
clearInterval(game.timer);
}
//死亡的判定,自己撞到了自己
for(var i = 1;i < this.body.length; i ++){
if(this.body[0].col == this.body[i].col && this.body[0].row == this.body[i].row){
this.body.shift();
alert("游戏结束,您当前的得分为:" + game.score + "分");
clearInterval(game.timer);
}
}
//蛇吃食物变长
if(this.body[0].row == game.food.row && this.body[0].col == game.food.col){
//删除原来的食物,还可以在 Game 中的 clear 方法中操作
// game.setHTML(game.food.row,game.food.col,"");
//创建新的食物
game.food = new Food(game);
//让帧编号归0,因为蛇会窜一下
game.f = 0;
//加分数
game.score ++;
}else{
this.body.pop();
}
};
//蛇的方向改变,防止的是一次渲染之前会出现调头的情况
Snake.prototype.changeDirection = function(d){
this.willDirection = d;
};
Snake.prototype.render = function(){
//蛇头的渲染
game.setColor(this.body[0].row,this.body[0].col,'pink');
//蛇身的渲染
for(var i = 1;i < this.body.length;i ++){
game.setColor(this.body[i].row,this.body[i].col,'cyan');
}
};
- Food.js 文件
function Food(gameSnake){
var self = this;
//食物的位置
//先产生食物,在判断是否在蛇身上
do{
this.row = parseInt(Math.random() * gameSnake.row);
this.col = parseInt(Math.random() * gameSnake.col);
}while((function(){
for(var i = 0 ;i < gameSnake.snake.body.length;i ++){
if(gameSnake.snake.body[i].row == self.row && gameSnake.snake.body[i].col == self.col){
return true;
}
}
return false;
})());
}
Food.prototype.render = function(){
game.setHTML(this.row,this.col,"★");
}