1.首先理了一下贪吃蛇的思想
用到了面向对象的思想,属性和方法见思维导图
2. html部分代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="content">
<div class="btn startBtn"><button ></button></div>
<div class="btn pause"><button></button></div>
<div id="snackWarp">
<!-- <div class="snackHead"></div>
<div class="snackbody"></div>
<div class="food"></div> -->
</div>
</div>
<script src="index.js"></script>
</body>
</html>
css部分
*{
padding: 0%;
margin: 0%;
}
.content{
height: 600px;
width: 600px;
background-color: yellow;
border: 20px solid skyblue;
position: relative;
margin: 0% auto;
}
.btn {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
left: 0;
top: 0;
z-index: 3333;
position: absolute;
}
.btn button{
background-size: 100% 100%;
border: none;
cursor: pointer;
outline: none;
left: 50%;
top: 50%;
position: absolute;
}
.startBtn button{
width: 238px;
height: 45px;
background-image: url(images/start.png);
margin-left: -119px;
margin-top: -22px;
}
.pause{
display: none;
}
.pause button{
height: 20px;
width: 20px;
background-image: url(images/pause.png);
margin-left: -10px;
border-radius: 50%;
/* margin-top: -10px; */
}
#snackWarp{
height: 600px;
height: 600px;
position: relative;
background-color: #225675;
}
/* 101 */
#snackWarp div{
width: 20px;
height: 20px;
border-radius: 50%;
}
.snackHead{
background-size: cover;
background-image: url(images/snackhead.png);
background-color: red;
}
.snackbody{
background-color: #9ddb11;
background-size: cover;
}
.food{
background-image: url(images/food-strawberry.png);
background-size: cover;
}
原生js部分
var he = 20, wi = 20;
var i = 30, j = 30;
var snack = null, food = null, game = null;
//创建方块开始啦/
//构造函数的属性
function Squre(x, y, className) {
this.x = x * wi;
this.y = y * he;
this.class = className;
this.viewContent = document.createElement('div');
this.viewContent.className = this.class;//直接等于classname呢?
this.parent = document.getElementById("snackWarp");
}
//添加dom元素的构造函数,不添加到原型身上new出来不能用
Squre.prototype.create = function() {
this.viewContent.style.position = "absolute";
this.viewContent.style.width = wi + 'px';
this.viewContent.style.height = he + 'px';
this.viewContent.style.left = this.x + 'px';
this.viewContent.style.top = this.y + 'px';
this.parent.appendChild(this.viewContent);
};
//删除dom元素
Squre.prototype.delete = function() {
this.parent.removeChild(this.viewContent);
}
//创建方块结束啦/
//创建蛇开始啦、
function Snack() {
this.head = null;//蛇头
this.tail = null;//蛇尾
this.pos = [];//蛇身
this.derectionNum = {//对象来存储蛇的走向
left: {
x:-1 ,
y: 0,
rotate: 180
},
right:{
x : +1,
y : 0,
rotate: 0
},
top : {
x : 0,
y: -1,
rotate: -90
},
down : {
x : 0,
y : 1,
rotate: 90
}
}
}
//初始化蛇
Snack.prototype.init = function() {
//创建蛇头
var snackHead = new Squre(2, 0,'snackHead');
snackHead.create();
this.head = snackHead;//!将squre和蛇关联了起来
this.pos.push( [2,0] );
//创建蛇身体1
var snackBody1 = new Squre(1, 0, "snackbody");
snackBody1.create();
this.pos.push( [1,0] );
//创建蛇身体2
var snackBody2 = new Squre(0, 0, "snackbody");
snackBody2.create();
this.pos.push( [0,0] );
this.tail = snackBody2;
//创建链表关系
snackHead.last = null;
snackHead.next = snackBody1;
snackBody1.last = snackHead;
snackBody1.next = snackBody2;
snackBody2.last = snackBody1;
snackBody2.next = null;
//给蛇添加属性表示默认情况下蛇走的方向
this.derection = this.derectionNum.right;
}
//获取蛇头下一个元素对应的位置de元素,并根据不同元素发生的情况
Snack.prototype.getNextPos = function() {
//下一个位置
var nextPos = [
this.head.x/wi +(this.derection.x) ,
this.head.y/he + this.derection.y,
]
//撞到了自己结束,
//对象比较相等与基本类型的数据相等不同,要比较内存中的地址是否相等
//所以不能直接value=nextPos,forEach是遍历
var selfColl = false;//默认没撞到
this.pos.forEach(function(value){
if(value[0] == nextPos[0] && value[1] == nextPos[1]){
selfColl = true;
}
});
if(selfColl){
console.log("撞到ziji");
this.thing.die.call(this);
return;
}
//撞到围墙游戏结束
if(nextPos[0] <0 || nextPos[1]<0 ||nextPos[0]>29||nextPos[1]>29){
console.log("撞到qiang");
this.thing.die.call(this);
return;
}
//下一个点是食物,吃
if(food && food.pos[0]== nextPos[0] && food.pos[1] == nextPos[1]){
this.thing.eat.call(this);
return;
}
//下一个点不是前面三个,走
this.thing.move.call(this,false);
};
//不同的情况要做的事情
Snack.prototype.thing = {
//随调用了这里面的方法,this就指向谁,所以this->this.thing.如果想改就可以用 call
move: function(formot) {
var newBody = new Squre(this.head.x/wi, this.head.y/he, 'snackbody');
//更新链表关系
newBody.next=this.head.next;
this.head.next.last = newBody;
newBody.last = null;
this.head.delete();
newBody.create();
//创建一个新蛇头
var newHead = new Squre(this.head.x/wi + this.derection.x, this.head.y/he + this.derection.y,'snackHead');
newHead.create();
//更新链表关系
newHead.next = newBody;
newHead.last = null;
newBody.last = newHead;
//蛇头旋转
//newHead.viewContent.style.transform='rotate('+this.derection.rotate+'deg)';
//更新蛇头
this.head = newHead;
//更新蛇身上每一个方块信息,最前面插入newhead
this.pos.splice( 0, 0, [this.head.x/wi,this.head.y/he ]);
//是否删除蛇尾
if(!formot) {
this.tail.delete();
this.tail = this.tail.last;
this.pos.pop();
}
},
eat: function() {
this.thing.move.call(this, true);
createFood();
game.score++;
},
die: function() {
console.log('die');
game.over();
}
}
snack = new Snack();
// snack.init();
// snack.getNextPos();
//创建蛇结束啦,
//创建食物开始啊
function createFood(){
//随机生成食物的坐标
var a = null, b= null;
var include = true;
while(include) {
a=Math.round(Math.random()*(i-1));
b=Math.round(Math.random()*(j-1));
snack.pos.forEach(function(value){
if(a !=value[0]&& b != value[1]) {
include = false;
}
});
}
//生成食物
food = new Squre(a, b,'food');
food.pos=[a,b];//存储生成食物的坐标
var foodDom = document.querySelector('.food');
if(foodDom){
foodDom.style.left = a*wi+'px';
foodDom.style.top = a*he+'px';
}else{
food.create();
}
}
//创建食物结束啦
//创建游戏逻辑开始
function Game() {
this.timer = null;
this.score = 0;
}
Game.prototype.init= function() {
snack.init();
// snack.getNextPos();
createFood();
document.onkeydown= function(e) {
if(e.which == 37&& snack.derection !=snack.derectionNum.right) {
snack.derection =snack.derectionNum.left;
}else if(e.which == 38&& snack.derection !=snack.derectionNum.down) {
snack.derection =snack.derectionNum.top;
}else if(e.which == 39&& snack.derection !=snack.derectionNum.left) {
snack.derection =snack.derectionNum.right;
}else if(e.which == 40&& snack.derection !=snack.derectionNum.top) {
snack.derection =snack.derectionNum.down;
}
}
this.start();
}
Game.prototype.start = function() {
this.timer = setInterval(function(){
snack.getNextPos();
},200);
}
//暂
var snackWarp = document.getElementById('snackWarp');
var pauseBtn = document.querySelector('.pause button');
snackWarp.onclick= function() {
game.Pause();
pauseBtn.parentNode.style.display = 'block';
}
pauseBtn.onclick = function(){
game.start();
pauseBtn.parentNode.style.display = 'none';
}
Game.prototype.over = function() {
clearInterval(this.timer);
alert('你的得分为:'+this.score);
//回到初始状态
var snackWarp = document.getElementById('snackWarp');
snackWarp.innerHTML = '';
snack = new Snack();
game = new Game;
var startButton = document.querySelector('.startBtn');
startButton.style.display = 'block';
}
Game.prototype.Pause = function() {
clearInterval(this.timer);
}
//开始游戏
game = new Game();
var startBtn = document.querySelector('.startBtn button');
startBtn.onclick = function(){
startBtn.parentNode.style.display = 'none';
game.init();
}
//创建游戏逻辑结束