一、代码需要完成的需求
1.把游戏页面的画面框分割成一个个方块,设置坐标
2.构造Square函数生成方块对象:
该对象具有的宽高属性、类名;
原型上的方法有:创建相应类名的方块DOM,删除方块DOM
3.通过调用Square构造函数帮忙生成蛇对象:
属性:蛇头的方向、保存整条蛇数组、蛇头、蛇尾;
原型上的方法:初始化函数 调用Square创建蛇头、蛇身、蛇尾等放入数 组,再建立链表关系;蛇的下一步:蛇撞墙、蛇咬到自己、蛇要吃、蛇要移动:采用链表进行移动,参数为是否吃到食物,是就不删除蛇尾,反之删除。
4 创建食物对象:随机产生,不产生在蛇的身上,当蛇撞上食物时,删除原先食物,再调用square创建新食物对象
5.游戏逻辑:
点击“开始游戏”按钮,按钮和遮罩层消失,开启定时器,开始游戏
点击游戏页面暂停游戏,关闭定时器;点击“继续游戏”,再次开启定时器
上下左右键控制蛇头方向
游戏结束时弹出分数,点击确定后回到初始界面
二、游戏画面展示
三、代码展示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>贪吃蛇小游戏</title>
<style type="text/css">
*{
margin:0;
padding: 0;
}
#content{
width: 600px;
height: 600px;
/*background-color: #3c3c3c;*/
margin: 50px auto;
position: relative;
}
#content .startBtn,
#content .pauseBtn{
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.2);
position: absolute;
left: 0;
top: 0;
z-index: 2;
}
#content .startBtn button,
#content .pauseBtn button{
width: 200px;
height: 80px;
background-color:#3c3c3c;
border:none;
border-radius: 40px;
cursor: pointer;
outline: none;
position: absolute;
left: 50%;
top: 50%;
margin-left: -100px;
margin-top: -40px;
color: #fff;
font-size: 32px;
}
#content .pauseBtn,
#content .pauseBtn button{
display: none;
}
#content .innerSnake{
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
position: absolute;
left: 0;
top: 0;
}
#content .innerSnake .food,
#content .innerSnake .snakeBody,
#content .innerSnake .snakeHead{
/*width: 20px;
height:20px;*/
border-radius: 50%;
/*background-color: #000;*/
/*background-color: #2F4F4F*/
}
#content .innerSnake .food{
/*border-radius: 50%;*/
background-color: #F0FFFF;
}
#content .innerSnake .snakeHead{
background-color: #000;
}
#content .innerSnake .snakeBody{
background-color: #fff;
}
</style>
</head>
<body>
<div id="content">
<div class="startBtn"><button>开始游戏</button></div>
<div class="pauseBtn"><button>继续游戏</button></div>
<div class="innerSnake">
<div class="food"></div>
<div class="snakeHead"></div>
<div class="snakeBody"></div>
</div>
</div>
<script type="text/javascript">
// 方块属性,创建DOM方块,删除DOM方块
// 蛇的方向、数组、蛇头、蛇尾,初始化函数调用Square创建蛇头、蛇身、蛇 尾等放入数组,再建立链表关系,
// 蛇的下一步:
// 蛇撞墙
// 蛇咬到自己
// 蛇要吃
// 蛇要移动:采用链表进行移动,参数为是否吃到食物,是就不 删除蛇尾,反之删除。
// 创建食物对象:随机产生,不产生在蛇的身上,当蛇撞上食物时,删除原先,
// 创建新食物对象
// 游戏流程:初始化,
var config={
sw : 20,
sh : 20,
tr : 30,
td : 30
}
var snake = null,
food = null,
game = null;
// 方块的属性:坐标和类名
function Square(x,y,classname){
this.x = x*config.sw;
this.y = y*config.sh;
this.className = classname;
this.Dom = document.createElement('div');
this.Dom.className = this.className;
this.parentNode = document.getElementsByClassName('innerSnake')[0];
}
Square.prototype.create = function(){
// 设置方块上的基本样式
this.Dom.style.position = 'absolute';
this.Dom.style.width = config.sw + 'px';
this.Dom.style.height = config.sh + 'px';
this.Dom.style.left = this.x + 'px';
this.Dom.style.top = this.y + 'px';
this.parentNode.appendChild(this.Dom);
}
Square.prototype.remove = function(){
this.parentNode.removeChild(this.Dom)
}
function Snake(){
this.head = null;
this.tail = null;
this.pos = [];
// 没有实例化对象,你建立什么建表结构
// this.head.next = null;
// this.head.prev = this.tail.next;
// this.tail.next.next = this.head;
// this.tail.next.prev = this.tail;
// this.tail.prev = null;
// this.direction = 'right';
this.directionKey = {
right:{
x:1,
y:0
},
left:{
x:-1,
y:0
},
up:{
x:0,
y:-1
},
down:{
x:0,
y:1
}
}
}
Snake.prototype.init = function(){
var snakeHead = new Square(2,0,"snakeHead");
snakeHead.create();
this.head = snakeHead;
this.pos.push([2,0]);
var snakeBody1 = new Square(1,0,'snakeBody');
snakeBody1.create();
this.pos.push([1,0]);
var snakeBody2 = new Square(0,0,'snakeBody');
snakeBody2.create();
this.pos.push([0,0]);
this.tail = snakeBody2;
this.head.next = null;
this.head.prev = snakeBody1;
snakeBody1.next = this.head;
snakeBody1.prev = this.tail;
this.tail.next = snakeBody1;
this.tail.prev = null;
// console.log(this.head.next,this.head.prev,snakeBody1.next ,snakeBody1.prev ,this.tail.next,this.tail.prev)
// 默认向右走,初始化
this.direction = this.directionKey.right;
}
Snake.prototype.nextStep = function(){
var nextSp = [
this.head.x/config.sw + this.direction.x,
this.head.y/config.sh + this.direction.y
]
// 是否要到自己
var note = false;
this.pos.forEach(function(value){
if(value[0]===nextSp[0] && value[1]===nextSp[1]){
// console.log('咬到自己了');
note = true;
// this.collide.end.call(this);
// return;
}
})
if(note){
this.collide.end.call(this);
return;
}
// 是否撞墙
else if(nextSp[0] < 0 || nextSp[0] >= config.td || nextSp[1] < 0 || nextSp[1] >= config.tr){
// console.log('撞墙了');
this.collide.end.call(this);
return;
}
//是否吃到食物
else if(food && nextSp[0]===food.pos[0] && nextSp[1]===food.pos[1]){
this.collide.eat.call(this);
return;
}
//蛇要移动
else {
this.collide.move.call(this,false);
}
}
//处理各个事件的函数集合对象
Snake.prototype.collide = {
move : function(isEat){
var x = this.head.x/config.sw + this.direction.x,
y = this.head.y/config.sh + this.direction.y;
var newBody = new Square(this.head.x/config.sw,
this.head.y/config.sh, 'snakeBody');
newBody.next = null;
newBody.prev = this.head.prev;
newBody.prev.next = newBody;
this.head.remove();
newBody.create();
var newHead = new Square(x,y,'snakeHead');
newHead.next = null;
newHead.prev = newBody;
newBody.next = newHead;
// console.log(newHead.next,newHead.prev,newBody.next,newBody.prev);
//忘记把新坐标放进数组了
this.pos.unshift([x,y]);
this.head = newHead;
newHead.create();
if(!isEat){
this.tail.remove();
this.tail = this.tail.next;
//这边也是,忘记删除数组末尾
this.pos.pop();
}
},
end:function(){
game.over();
},
eat:function(){
this.collide.move.call(this,true);
food.remove();
game.score++;
createFood();
}
}
snake = new Snake();
// snake.init();
// snake.nextStep();
//创建食物
function createFood(){
var x = null,
y = null;
var flag = true;
while(flag){
x = Math.floor(Math.random()*(config.td-1));
y = Math.floor(Math.random()*(config.tr-1));
snake.pos.forEach(function(value){
if(x!==value[0] || y!==value[1]){
flag = false;
// break;
}
})
}
// food.remove();
food = new Square(x,y,'food');
// food.remove();
food.pos = [x,y];
// console.log('食物坐标:'+food.pos);
food.create();
}
// createFood();
//游戏逻辑
function Game(){
this.score = 0;
this.timer = null;
}
Game.prototype.init = function(){
//在这里出了大问题,如果没有snake先初始化的话,createfood函数调用时无法获得snake里的pos数组,无法遍历,所以一直加载不出来 将init 和 createfood 更换位置就能正常实现了
snake.init();
createFood();
// console.log('here');
document.onkeydown = function(e){
if(e.which == 37 && snake.direction != snake.directionKey.right){
snake.direction = snake.directionKey.left;
}
else if(e.which == 38 && snake.direction != snake.directionKey.down){
snake.direction = snake.directionKey.up;
}
else if(e.which == 39 && snake.direction != snake.directionKey.left){
snake.direction = snake.directionKey.right;
}
else if(e.which == 40 && snake.direction != snake.directionKey.up){
snake.direction = snake.directionKey.down;
}
}
this.start();
};
// // console.log('开始');
Game.prototype.start = function(){
this.timer = setInterval(function(){
snake.nextStep();
},200);
}
Game.prototype.pause = function(){
clearInterval(this.timer);
}
// // console.log('结束');
Game.prototype.over = function(){
clearInterval(this.timer);
alert('Game over\n你的分数是:'+this.score);
// window.reload();
var innerSnake = document.querySelector('#content .innerSnake');
innerSnake.innerHTML = '';
snake = new Snake();
game = new Game();
var startBtn = document.querySelector('#content .startBtn button');
var startMark = document.querySelector('#content .startBtn');
startBtn.style.display = 'block';
startMark.style.display = 'block';
}
game = new Game();
// game.init();
function begin(){
var startBtn = document.querySelector('#content .startBtn button');
var startMark = document.querySelector('#content .startBtn');
// var self = this;
startBtn.onclick = function(){
startBtn.style.display = 'none';
startMark.style.display = 'none';
// console.log('1')
game.init();
}
}
function stop(){
var innerSnake = document.querySelector('#content .innerSnake');
var pauseBtn = document.querySelector('#content .pauseBtn button');
var pauseMark = document.querySelector('#content .pauseBtn');
innerSnake.onclick = function(){
game.pause();
pauseBtn.style.display = 'block';
pauseMark.style.display = 'block';
}
pauseBtn.onclick = function(){
game.start();
pauseBtn.style.display = 'none';
pauseMark.style.display = 'none';
}
}
begin();
stop();
</script>
</body>
</html>