贪吃蛇

贪吃蛇思路

第一步:寻找对象

对象 ==> 属性 ==> 行为
蛇 ==> 长度、颜色、移动方向、位置 ==> 吃、变长、移动
食物 ==> 颜色、大小、位置 ==> 改变位置、出现
游戏引擎 ==> 场景、蛇、食物 ==> 开始、结束

第二步:实现对象
首先,游戏引擎的实现(因为,游戏引擎是一个全局对象,创建一个,所以我使用字面量的形式创建,游戏引擎对象类似一个小小的棋盘,有行、有列,所以我用表格完成)

设置CSS样式,让表格在页面显示

table{
    border -collapse : collapse;      // 让表格边框单线显示
    border: 1px solid black;            // 设置表格边框
    margin: 0 auto;        // 设置表格居中显示
}
td{          
    width: 10px;       // 设置表格大小
    hieght: 10px; 
}
// 添加食物样式
.food{
    background-color: plum;
}
// 添加蛇样式
.snake{
    background-color: plum;
}

JavaScript代码(创建场景):

var gGameBox = {
    rows: 20,         // 定义场景的行数
    cols: 20,          // 定义场景的列数(数值由自己定义)
    allTds: [],   // 创建一个数组用来存储所有单元格
    food: null,    // 存储食物对象
    snake: null,   // 存储蛇对象
    timer: timer,   // 定时器
    // 清空棋盘
    clear: function(){
        for(var i = 0; i < gGameBox.allTds.length; i++){
            for(j = 0; j < gGameBox.allTds[i].length; j++){
                // 设置棋盘所有节点元素样式为空
                gGameBox.allTds[i][j].className = "";
            }
        }
    },
    // 键盘按下操作
    keyControl: function(){
        window.onkeydown = function(e){
            // 向左移动
            if(e.keyCode == 37){
                if(gGameBox.snake.direction == "right"){
                    // 阻止蛇向右移动的时候按下左键直接向左移动,return 返回,函数不执行
                    return ;
                }
                gGameBox.snake.direction = "left";
            }
           // 向上移动
            if(e.keyCode == 38){
               if(gGameBox.snake.direction == "down"){
                    // 阻止蛇向下移动的时候按下上键直接向上移动,return 返回,函数不执行
                    return ;
                }
                gGameBox.snake.direction = "up";
            }
            // 向右移动
            if(e.keyCode == 39){
                if(gGameBox.snake.direction == "left"){
                    // 阻止蛇向左移动的时候按下右键直接向右移动,return 返回,函数不执行
                    return ;
                }
                gGameBox.snake.direction = "right";
            }
            // 向下移动
            if(e.keyCode == 40){
                if(gGameBox.snake.direction == "up"){
                    // 阻止蛇向上移动的时候按下下键直接向下移动,return 返回,函数不执行
                    return ;
                }
                gGameBox.snake.direction = "down";
            }
        }
    }
    // 开始执行函数
    start: function(){
        gGameBox.init();      //  游戏初始化
        // 游戏开始创建食物对象
        this.food = new Food();
        // 执行键盘操作
        gGameBox.keyControl();
        this.timer = setInterval(function(){
            // 1. 清空棋盘
            gGameBox.clear();
            // 2. 执行蛇移动操作
            gGameBox.snake.move();
            // 3. 显示食物
            gGameBox.food.show();
        },1000);
    },
    // 初始化
    init function(){
        // 创建表格,做场景
        var oTable = document.createElement("table");
        for(var i = 0; i < gGameBox.rows; i++){
            // 创建行
            var oTr = document.createElement("tr");
            var arr = [];    // 定义一个数组,用来存储每一行的单元格
            for(var j = 0; j < gGameBox; j++){
                // 创建列
                var oTd = document.createElement("td");
                arr.push(oTd);     // 将每一行内的 td 存入 arr 数组内
                oTr.appendChild(oTd);      // 向表格行内添加单元格
            }
            gGameBox.allTds.push(arr);   // 将 所有的arr 
            oTable.appendChild(oTr);    // 将行添加到表格内
        }
        document.body.appendChild(oTable);    // 将表格添加到页面
    }
}
gGameBox.start();          // 调用

【注】对象属性之间有逗号隔开(,)除最后一个外都必须写。。。经常忘记的我多注意!!!

其次,食物对象的实现
// 构造食物对象函数
function Food(){
    // 食物位置
    this.x = 0;
    this.y = 0;
    // 一开始就在随机位置显示
    this.change();
}
// 食物对象行为:场景中显示食物
Food.prototype.show = function(){
    // 设置食物显示样式
    gGameBox.allTds[this.x][this.y].className = "food";
}
// 食物对象行为 改变位置
Food.prototype.change = function(){
    this.x = parseInt( Math.random()*gGameBox.rows );       // 位置随机出现行数范围
    this.y = parseInt( Math.random()*gGameBox.cols );        // 位置随机出现列数范围
    this.show();    // 随机位置食物显示
}
最后,蛇对象的实现;把蛇的所有节点都存储下来(用数组存储);数组中的元素:每个节点的坐标,是一个整体,考虑使用对象{x:0,y:0}
// 构造蛇对象函数
function Snake(){
    // 存储蛇的节点坐标,蛇的长度就是this.arr.length
    this.arr = [
        // 默认this.arr[0] 位蛇头 
        {x : 1 , y : 1},      // x 行  ,  y 列
        {x : 1 , y : 2},
        {x : 1 , y : 3},
        {x : 1 , y : 4},
        {x : 1 , y : 5}
    ];
    // 蛇移动方向 left、right、down、up
    this.direction = "right";
    this.refresh();
}
// 蛇的位置更新到场景中  (refresh 更新)
Snake.prototype.refresh = function(){
    for(var i = 0; i < this.arr.length; i++){
        var x = this.arr[i].x;
        var y = this.arr[i].y;
        gGameBox.allTds[x][y].className = "snake";
    }
}
// 蛇移动操作
Snake.prototype.move = function(){
    // 获取蛇头坐标
    var x = this.arr[0].x;
    var y = this.arr[0].y;
    // 判断蛇移动方向 左
    if(this.direction == "left"){
        y--;
    }
    // 判断蛇移动方向 上
    if(this.direction == "up"){
        x--;
    }
     // 判断蛇移动方向 右
    if(this.direction == "right"){
        y++;
    }
     // 判断蛇移动方向 下
    if(this.direction == "down"){
        x++;
    }
    // 判断蛇吃到食物
    if(x == gGameBox.food.x && y == gGameBox.food.y){
        // 蛇的长度增加
        this.arr.unshift({x : x , y : y});
        // 更新蛇
        gGameBox.snake.refresh();
        // 更新食物的位置
        gGameBox.food.change();
        // 直接返回,不执行函数后面的内容
        return ;
    }
    // 判断蛇撞到墙上之后,结束游戏
    if( x < 0 || x >= gGameBox.rows || y < 0 || y >= gGameBox.cols){
        alert("Game over");
        // 游戏结束,清除定时器
        clearInterval(gGameBox.timer);
        // 游戏结束后直接退出函数
        return ;
    }
    // 向蛇头添加元素   unshift() 给数组前面添加元素
    this.arr.unshift({x : x , y : y});
    // 删除蛇尾元素    pop() 删除数组最后的元素
    this.arr.pop();
    // 更新蛇的位置
    this.refresh();
}

关于this的理解

this 是函数内部的一个特殊变量(系统规定的)

  1. 当一个函数用( )调用时,this表示的是window对象;
  2. 当一个函数用对象方法调用的时候,this就是这个对象;
  3. 当一个函数绑定给一个HTML元素事件的时候,this就是这个HTML元素;
  4. 当一个函数用定时器调用的时候,this就是window;
  5. 当一个函数用apply、call调用的时候,this就是你指定的这个对象;
  6. 当一个函数用new调用的时候,this就是隐藏创建的空对象;
    【注】new 一个对象是会执行四步操作:
    1. 隐秘的创建一个空的对象;
    2. 将这个函数里面的this绑定到刚才创建的隐秘新对象上(this 指向创建的这个对象);
    3. 执行构造函数体里面的代码;
    4.返回这个新的对象;

你可能感兴趣的:(贪吃蛇)