Skip to content

Latest commit

 

History

History
138 lines (120 loc) · 4.59 KB

README.md

File metadata and controls

138 lines (120 loc) · 4.59 KB

利用设计模式开发贪吃蛇游戏 项目效果:https://aaliny.github.io/snake-game/ 1、定义一个base类包含 height、width、color、x、y、viewportElement等属性

function Base(width,height,x,y,color){
    this.width=width;
    this.height=height;
    this.x=x;
    this.y=y;
    this.color=color;
    this.viewportElement=document.createElement("div")
}

2、定义子类(地板、蛇头、蛇尾、围墙、食物)集成base类

var Ground=jsUtil.extends(Base);
var Floor=jsUtil.extends(Base);
var Wall=jsUtil.extends(Base);
var Food=jsUtil.single(Base);//通过单例模式生成
var SnakeHead=jsUtil.single(Base);
var SnakeTail=jsUtil.extends(Base);

3、定义一个工厂类,工厂的原型上定义多个方法(通过生成子类的实例,修饰当前实例的viewportElement属性)用于生成不同的实例

Square.prototype.init=function(obj,msg){
    obj.viewportElement.style.backgroundColor=obj.color;
    obj.viewportElement.style.width=obj.width+'px';
    obj.viewportElement.style.height=obj.height+'px';
    obj.viewportElement.style.left=obj.x*sqWidth+BASE_X_POINT+'px';
    obj.viewportElement.style.top=obj.y*sqHeight+BASE_Y_POINT+'px';
    obj.viewportElement.style.position="absolute";
    obj.touch=function () {
        return msg;
    }
}
Square.prototype.Floor=function (x, y, color) {
    var obj=new Floor(sqWidth, sqHeight,x, y,color);
    Square.prototype.init(obj,STRATEGYENUM.move);
    return obj;

}
Square.prototype.Food=function (x, y, color) {
    var obj=new Food(sqWidth, sqHeight,x, y,color);
    obj.x=x;
    obj.y=y;
    Square.prototype.init(obj,STRATEGYENUM.eat)
    return obj;

}

4、初始化生成地板,每一块地板都是由一个个小方块拼接而成的,循环调用工厂里的对应的生成地板的方法生成dom元素append到界面上

var ground=new Ground(sqWidth*sceneXNum,sqHeight*sceneYNum,BASE_X_POINT,BASE_Y_POINT,'#d400ff');
// console.log(ground)
ground.init=function () {
    .....
    this.squareTable=[];
    document.body.appendChild(this.viewportElement)
    for(let i=0;i<sceneXNum;i++){
        this.squareTable[i] = new Array(sceneXNum); //让每一排的数组都有XLEN个;
        for(let j=0;j<sceneYNum;j++){
            let item
            if(i===0||j===0||i===sceneXNum-1||j===sceneYNum-1){
                item=Square.create("Wall",i,j,"black")
            }else{
                item=Square.create("Floor",i,j,"orange")
            }
            this.squareTable[i][j]=item;
            document.body.appendChild(item.viewportElement)
        }
    }
};

5、生成一个蛇,初始化根据自己的类生成蛇身、蛇头,对应的调用工厂里的方法生成dom节点append到界面上

snake.init=function () {
    this.snakeHead=Square.create("SnakeHead",3,1,"red")
    this.snTail1=Square.create("SnakeTail",2,1,"yellow")
    this.snTail2=Square.create("SnakeTail",1,1,"yellow");
    ......
    ground.remove(3,1)
    ground.remove(2,1)
    ground.remove(1,1)
    ground.add(this.snakeHead)
    ground.add(this.snTail1)
    ground.add(this.snTail2)
    this.direction='RIGHT';
};

6、开始游戏时,设置一个定时器去进行蛇的移动,通过蛇本身定义的方向,计算出下一次蛇头将要到达的位置,在判断下一个位置的触发事件(吃食物、碰到墙壁),从而进行蛇的动作,如果是继续移动,将蛇头当前的位置替换成蛇身,蛇头移动到下一个位置,蛇尾根据是否吃食物进行改变,如果吃了食物,蛇尾不变,没吃的话,蛇尾部分要变成地板

snake.move=function(ground){
    var dir=DIRECTIONENUM[this.direction];
    var square=ground.squareTable[this.head.x+dir.x][this.head.y+dir.y];
    if(typeof square.touch==="function"){
        snakeStrategies[square.touch()](this,square,ground)
    }
}

7、当下一个移动位置是墙壁或者自己的话,则停止循环,结束游戏

MOVE:function (snake,square,ground,fromEat) {
    //新建蛇身
    var snTail1=Square.create("SnakeTail",snake.head.x,snake.head.y,"yellow")
    ground.remove(snake.head.x,snake.head.y);
    ground.add(snTail1);
    ...
    //新建蛇头
    var snakeHead=Square.create("SnakeHead",square.x,square.y,"red");
    ground.remove(square.x,square.y);
    ground.add(snakeHead);
    ...
    if(!fromEat){//如果没有吃食物
        ground.remove(snake.tail.x,snake.tail.y);
        // return
        var floor=Square.create("Floor",snake.tail.x,snake.tail.y,"orange")
        ground.add(floor);
        snake.tail=snake.tail.last;
    }else{
    }

},