JavaScript实现的贪吃蛇算法及其研究(一)

贪吃蛇游戏相信各位读者都玩过,本系列文章将解析贪吃蛇游戏的算法及其在JavaScript语言中的实现. 首先回忆一下我们玩过的贪吃蛇游戏,它是由三个部分组成的:蛇,食物,背景.其中背景在实际的算法中只起装饰性的作用,所以我将背景替代为另一个词”场景”,下面将这三个部分拆分开来讲解,逐个完成我们的贪吃蛇算法.

场景

要完成贪吃蛇游戏,首先要给贪吃蛇一个活动的空间,这个活动的空间,就是”场景”.

贪吃蛇游戏中的世界是一个二维的世界,而二维平面通常使用网格来进行区分,所以我们创建一个名为World的静态类,为这个世界设定大小以确定其边界.

var World={  
    Size:{
        width:20,
        height:20
    }
}

这样我们就创造了一个大小为20×20的空间,这是在游戏中贪吃蛇可以进行活动的区域.

食物

食物是游戏的目标,它是随机生成在世界上的,所以我们干脆把食物放进World类.

食物有2个坐标属性和1个用于生成食物坐标的方法.

Food:{  
    x:undefined,
    y:undefined,
    generate:function(){}
}

在贪吃蛇游戏的规则中,蛇被以下几个规则约束:

  • 蛇头不能咬到蛇身,咬到则游戏结束.
  • 蛇撞到墙壁会死,撞到则游戏结束.
  • 蛇只能朝三个方向移动,不能直接调头.
  • 蛇吃掉食物后蛇身会变长.
  • 蛇身随着蛇头的轨迹进行移动.

这几个规则都围绕着蛇本身展开,其中还有2个规则是造成游戏结束的,显然我们需要使用面向对象编程来设计代码.我们将蛇头和蛇身视为两个对象,创建一个Snake类,在Snake类中创建Head类和Body类.

function Snake(){  
    function Head(){}
    function Body(){}

    this.body=new Body();
    this.head=new Head();
}
var snake=new Snake();  
蛇头

蛇头应该包含一个坐标属性,说明蛇头的位置,所以我们给Head类添加上x和y属性,并赋予它们初始值,x和y应该对应于World中所规划出的空间.

this.x=9;  
this.y=9;  

我们知道,如果你不控制贪吃蛇的方向,贪吃蛇会自动向蛇头所在的方向前进,蛇头的方向也是你最后一次控制贪吃蛇时的方向.所以我们再给蛇头添加direction属性,由于最开始蛇的方向未知,我们给它赋予undefined的初始值(在JavaScript中,如果不给变量赋值,初始值即为undefined,此处是为了突出蛇头朝向的未知性).

this.direction=undefined;  

除了这3个属性,蛇头还应该有2个动作:move和eat,分别完成”移动”和”吃”.

this.move=function(){};  
this.eat=function(){};  

2个游戏结束的判断:hitCheck和eatSelfCheck,分别用来判断”撞墙”和”自食”.

this.hitCheck=function(){};  
this.eatSelfCheck=function(){};  

至此蛇头可能需要用到的元素都已经定义完毕了.

蛇身

蛇身相对于蛇头来说,结构要简单一点.

存储蛇身部分坐标的数组part:

this.part=[];  

完成蛇身移动的动作move:

this.move=function(){};  

完成蛇身增长的动作increase:

this.increase=function(){};  

Next

现在,我们的代码是这样的,虽然各部分功能还没有完成,但看起来总算还是有些条理.

var World={  
    Size:{
        width:20,
        height:20
    }
    Food:{
        x:undefined,
        y:undefined,
        generate:function(){}
    }
}

function Snake(){  
    function Head(){
        this.x=9;
        this.y=9;
        this.direction=undefined;
        this.move=function(){};
        this.eat=function(){};
        this.hitCheck=function(){};
        this.eatSelfCheck=function(){};
    }
    function Body(){
        this.part=[];
        this.move=function(){};
        this.increase=function(){};
    }

    this.body=new Body();
    this.head=new Head();
}
var snake=new Snake();  

在下一章中,将完成Head类.

JavaScript实现的贪吃蛇算法及其研究(二)