这是一个网页版本的贪吃蛇项目,用了html和js实现,代码有很多注释,方便阅读,是一个不错的练手项目。
1.html代码
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GluttonousSnaketitle>
<link rel = "stylesheet" href="../index.css">
head>
<body>
<div class="content">
<div class="btn statrtBtn"><input type = "image" src="../startGame.png">div>
<div class="btn pausBtn"><input type = "image" src="../start.png">div>
<div id = "snakeWrap">
div>
div>
<script src = "index.js" >script>
body>
html>
2.css样式
.content{
width: 640px;
height: 640px;
margin: 100px auto;
position: relative;
}
.btn{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background-color: rgba(0,0,0,0.3);
z-index: 2;
}
.btn input{
background: none;
border: none;
background-size: 100% 100%;
cursor: pointer;
outline: none;
position: absolute;
left: 50%;
top:50%;
}
.statrtBtn input
{
width: 200px;
height: 200px;
margin-left: -100px;
margin-top: -100px;
}
.pausBtn{
display: none;
}
.pausBtn input{
width: 128px;
height: 128px;
margin-left: -64px;
margin-top: -64px;
}
#snakeWrap{
width: 600px;
height: 600px;
background: #225675;
border: 20px solid #7dd9ff;
position: relative;
}
#snakeWrap div{
width: 20px;
height: 20px;
}
.snakeBody{
background-color: #9ddbb1;
border-radius: 50%;
}
3.js代码
var sw = 20,//一个格子的宽
sh = 20,//格子的高度
tr = 30,//行数
td = 30;
var snake = null;
var food = null;//食物的实例
var game = null;
//构造函数(构造方格)
function Square(x,y,classnmae,src)
{
this.x = x*sw;
this.y = y*sh;
this.class = classnmae;
//创建标签并添加标签
this.viewContent = document.createElement('img');//格子对应的DOM元素
this.viewContent.className = this.class;
this.viewContent.src = src;
this.parent = document.getElementById('snakeWrap');//格子的父级
}
//创建格子DOM(添加)
Square.prototype.create = function ()
{
this.viewContent.style.position = 'absolute';
this.viewContent.style.width = sw + 'px';
this.viewContent.style.height = sh + 'px';
this.viewContent.style.left = this.x + 'px';
this.viewContent.style.top = this.y + 'px';
this.parent.appendChild(this.viewContent);//添加到页面
};
//删除格子DOM元素
Square.prototype.remove = function ()
{
this.parent.removeChild(this.viewContent);
}
//蛇的构造函数
function Snake()
{
this.head = null;//保存蛇头的信息
this.tail = null;
this.pos = [];//保存蛇身方格的位置
//存储蛇走的方向
this.directionNum = {
left:{x:-1,y:0,rotate:180},
right:{x:1,y:0,rotate:0},
up:{x:0,y:-1,rotate:-90},
down:{x:0,y:1,rotate:90}
}
}
//初始化蛇
Snake.prototype.init = function ()
{
//创建蛇头
var snakeHead = new Square(2,0,'snakeHead', "../snake.png");
snakeHead.create();
this.head = snakeHead;//存储蛇头信息
this.pos.push([2,0]);//存储蛇头的坐标
//创建蛇身体第一个
var snakeBody1 = new Square(1,0,'snakeBody',"../body.png");
snakeBody1.create();
this.pos.push([1,0]);
//创建蛇身体第二个
var snakeBody2 = new Square(0,0,'snakeBody',"../body.png");
snakeBody2.create();
this.tail = snakeBody2;//把蛇尾的信息存起来
this.pos.push([0,0]);
//让蛇形成链表关系
snakeHead.last = null;
snakeHead.next = snakeBody1;
snakeBody1.last = snakeHead;
snakeBody1.next = snakeBody2;
snakeBody2.last = snakeBody1;
snakeBody2.next = null;
//给蛇添加一个属性,用来表示蛇走的方向
this.direction = this.directionNum.right;
};
//获取蛇头的下一个位置对应的元素
Snake.prototype.getNextPos = function ()
{
//蛇头要走的下一个点的坐标
var nextPos = [this.head.x/sw+this.direction.x,this.head.y/sh+this.direction.y];
//下一个点是自己,代表撞到了自己,游戏结束
var selfCollied = false;
this.pos.forEach(function (value){
if(value[0] == nextPos[0] && value[1] == nextPos[1])
{
selfCollied = true;
}
});
if(selfCollied)
{
console.log("撞到自己了!");
this.strategies.die.call(this);
return;
}
//下一个点是围墙,游戏结束
if(nextPos[0] < 0 || nextPos[1] < 0 || nextPos[0] > td-1 || nextPos[1] > tr -1 )
{
console.log("撞墙了!");
this.strategies.die.call(this);
return;
}
//条件成立,蛇头撞到食物
if(food && food.pos[0] == nextPos[0] && food.pos[1] == nextPos[1])
{
this.strategies.eat.call(this);
return;
}
//下一个点没有标记,继续走
this.strategies.move.call(this);//this指向实例
}
//使用call方法,能调用父类的实例
Snake.prototype.strategies ={
move:function (format)//参数决定要不要删除最后一个方块
{
//创建新身体(在旧蛇头的位置)
var newBody = new Square(this.head.x/sw,this.head.y/sh,'snakeBody',"../body.png");
//更新链表的关系
newBody.next = this.head.next;
newBody.next.last = newBody;
newBody.last = null;
this.head.remove();//把旧蛇头从位置上删除
newBody.create();
//创建新的蛇头(蛇头下一个移动的点)
var newHead = new Square(this.head.x/sw+this.direction.x,this.head.y/sh+this.direction.y,'snakeHead',"../snake.png");
//更新链表的关系
newHead.next = newBody;
newHead.last = null;
newBody.last = newHead;
//旋转蛇头图像方向
newHead.viewContent.style.transform = 'rotate('+this.direction.rotate+'deg)';
newHead.create();
//蛇身上的每一个坐标都要更新
this.pos.splice(0,0,[this.head.x/sw+this.direction.x,this.head.y/sh+this.direction.y]);
//更新蛇头的位置
this.head = newHead;
if(!format)//删除蛇尾
{
this.tail.remove();
this.tail = this.tail.last;
this.pos.pop();
}
},
eat:function ()
{
this.strategies.move.call(this,true);
createFood();
game.score ++;
},
die:function ()
{
game.over();
},
}
//1.开始创建蛇头
snake = new Snake();
//2.碰撞后处理的事件
function createFood()
{
//食物方格的随机坐标
//1.食物不能出现在墙上
//2.食物不能出现在蛇的身上
var x = null;
var y = null;
var includeSnake = true;//为ture表示生成在蛇身上,那么就要继续生成食物
while (includeSnake)
{
x = Math.round(Math.random()*(td-1));
y = Math.round(Math.random()*(tr-1));
snake.pos.forEach(function (value){
if(x != value[0] && y != value[1])
{
includeSnake = false;
}
});
//生成食物
food = new Square(x,y,'food',"../food.png");
food.pos = [x,y];//存储食物坐标,用与判断是否与蛇头相撞
var foodDom = document.querySelector('.food');
if(foodDom)
{
foodDom.style.left = x*sw+'px';
foodDom.style.top = y*sh+'px';
}
else
{
food.create();
}
}
}
function Game()
{
this.timer = null;
this.score = 0;
}
Game.prototype.init = function ()
{
snake.init();
createFood();
document.onkeydown = function (ev)
{
if(ev.which === 37 && snake.direction != snake.directionNum.right)//用户按下左键时,蛇的移动方向不能是向右
{
snake.direction = snake.directionNum.left;
}
else if(ev.which === 38 && snake.direction != snake.directionNum.down)
{
snake.direction = snake.directionNum.up;
}
else if(ev.which === 39 && snake.direction != snake.directionNum.left)
{
snake.direction = snake.directionNum.right;
}
else if(ev.which === 40 && snake.direction != snake.directionNum.up)
{
snake.direction = snake.directionNum.down;
}
}
this.start();
}
Game.prototype.start = function ()
{
this.timer = setInterval(function (){
snake.getNextPos();
},200);
}
Game.prototype.pause = function ()
{
clearInterval(this.timer);
}
Game.prototype.over = function ()
{
clearInterval(this.timer);
alert("当前得分为:" + this.score);
//游戏回到最初的状态
var snakeWrap = document.getElementById('snakeWrap');
snakeWrap.innerHTML = '';
snake = new Snake();
game = new Game();
var startBtnWrap = document.querySelector('.statrtBtn');
startBtnWrap.style.display = 'block';
}
//开启游戏
game = new Game();
var startBtn = document.querySelector('.statrtBtn input');
startBtn.onclick = function ()
{
startBtn.parentNode.style.display = 'none';
game.init();
};
//暂停游戏
var snakeWrap = document.getElementById('snakeWrap');
var pauseBtn = document.querySelector('.pausBtn input');
snakeWrap.onclick = function ()
{
game.pause();
pauseBtn.parentNode.style.display = 'block';
}
pauseBtn.onclick = function ()
{
game.start();
pauseBtn.parentNode.style.display = 'none';
}
5.整个项目的源码与资源:https://download.csdn.net/download/matt45m/85073431