原生js贪吃蛇,详细注释,思维导图

697 阅读4分钟

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();

}

//创建游戏逻辑结束

效果图