supce's blog

听指令的小方块(三)


任务描述

  • 根据之前的任务,对于正方形的移动增加相应动画,包括移动和旋转
  • 每个指令的执行时间是1s(可以自己调整)
  • 增加新的指令如下:
  • GO:向蓝色边所面向的方向前进一格(一格等同于正方形的边长)
  • TUN LEF:向左转(逆时针旋转90度)
  • TUN RIG:向右转(顺时针旋转90度)
  • TUN BAC:向右转(旋转180度)
  • TRA LEF:向屏幕的左侧移动一格,方向不变
  • TRA TOP:向屏幕的上面移动一格,方向不变
  • TRA RIG:向屏幕的右侧移动一格,方向不变
  • TRA BOT:向屏幕的下面移动一格,方向不变
  • MOV LEF:方向转向屏幕左侧,并向屏幕的左侧移动一格
  • MOV TOP:方向转向屏幕上面,向屏幕的上面移动一格
  • MOV RIG:方向转向屏幕右侧,向屏幕的右侧移动一格
  • MOV BOT:方向转向屏幕下面,向屏幕的下面移动一格

整体思路

上个任务中,分别使用了canvas和普通HTML元素。这次可以把两者结合起来。
对于棋盘背景,生成之后不会再进行变换,可以利用canvas实现;对于小方块,为了实现动画效果,可以用一个div来模拟。具体HTML代码和基本样式如下:

<div id="container">
    <canvas id="canvas_bg" width="441" height="441"></canvas>
    <div id="square"></div>
</div>
<div id="control_panel">
    <input type="text" id="order">
    <button id="btn_exe">执行</button>
</div>

<style type="text/css">
    #container{
        margin: 10px auto;
        position: relative;
        width: 441px;
        height: 441px;
    }
    #square{
        width: 40px;
        height: 40px;
        position: absolute;
        background: linear-gradient(red 20%,blue 0);
        background-size: 100%;
        transition-duration: 0.5s;
    }
    #control_panel{
        margin: auto;
        width: 400px;
        text-align: center;
    }
</style>

对于棋盘背景的生成代码可以直接拿来用。也可对其进行封装,添加行列参数,直接调用生成任意行列的棋盘背景。

(function(){
    var drawing = $("#canvas_bg");
    if(drawing.getContext){
        var context = drawing.getContext("2d");
        creataBg(context);
        createXY(context);

    }
    //创建棋盘背景
    function creataBg(context){
        context.strokeStyle = "#ccc";
        context.translate(0.5,0.5);
        context.lineWidth = 1;
        context.beginPath();
        var x = 40,y=40;
        for(var i=0;i<11;i++){
            context.moveTo(x,y);
            context.lineTo(x,440);
            x += 40;
        }
        x = 40;y=40;
        for(var j=0;j<11;j++){
            context.moveTo(x,y);
            context.lineTo(440,y);
            y += 40;
        }
        context.stroke();
        context.closePath();
    }
    //创建x,y坐标值
    function createXY(context){
        context.font = "normal 14px Arial";
        context.textAlign = "center";
        context.textBaseline = "middle";
        var x = 60,y=60;
        for(var i=1;i<11;i++){
            context.fillText(i,x,20);
            x += 40;
        }
        for(var i=1;i<11;i++){
            context.fillText(i,20,y);
            y += 40;
        }   
    }
})();

对于方块类,需要增加左侧和顶部偏移以及旋转角度三个属性。并且在原型方法中对指令进行了分解,提高代码的重用率。

function Square(square){
    this.square = square;
    this.left = 200;
    this.top = 200;
    this.deg = 0;  //旋转角度
}
Square.prototype = {
    init : function(){
        this.setPositon();
    },
    setPositon : function(){
        this.square.style.left = this.left + "px";
        this.square.style.top = this.top + "px";
        this.square.style.transform = "rotate("+ this.deg + "deg)";
    },
    move : function(commond){
        var preCommond = commond.split(" ")[0];
        var direction = commond.split(" ")[1];
        switch(preCommond){
            case 'TUN':
                rotate(direction,this);
                break;
            case 'GO':
                go(this);
                break;
            case 'MOV':
                moveTurn(direction,this);
                break;
            case 'TRA':
                trans(direction,this);
        }
        this.setPositon();
        function rotate(direction,that){
            switch(direction){
                case 'LEF':that.deg -= 90;break;
                case 'RIG':that.deg += 90;break;
                case 'BAC':that.deg += 180;break;
            }
        }
        function moveTurn(direction,that){
            switch(direction){
                case 'LEF':that.deg = -90;break;
                case 'RIG':that.deg = 90;break;
                case 'TOP':that.deg = 0;break;
                case 'BOT':that.deg = 180;break;
            }
            go(that);
        }
        function trans(direction,that){
            switch(direction){
                case 'LEF':
                    if(that.left>40){
                        that.left -= 40;
                    }else{
                        alert("到达左侧");
                    }
                    break;
                case 'RIG':
                    if(that.left<400){
                        that.left += 40;
                    }else{
                        alert("到达右侧");
                    }
                    break;
                case 'TOP':
                    if(that.top>40){
                        that.top -= 40;
                    }else{
                        alert("到达顶部");
                    }
                    break;
                case 'BOT':
                    if(that.top<400){
                        that.top += 40;
                    }else{
                        alert("到达底部");
                    }
                    break;
            }
        }
        function go(that){
            var deg = that.deg % 360;
            switch(deg){
                case 0:
                    if(that.top>40){
                        that.top -= 40;
                    }else{
                        alert("到达顶部");
                    }
                    break;
                case 180:
                case -180:
                    if(that.top<400){
                        that.top += 40;
                    }else{
                        alert("到达底部");
                    }
                    break;
                case 90:
                case -270:
                    if(that.left<400){
                        that.left += 40;
                    }else{
                        alert("到达右侧");
                    }
                    break;
                case -90:
                case 270:
                    if(that.left>40){
                        that.left -= 40;
                    }else{
                        alert("到达左侧");
                    }
                    break;
            }
        }
    }

}

最后创建类对象,绑定事件就可以了

var square = new Square($("#square"));
square.init();

addHandler($("#btn_exe"),"click",function(e){
    var value = $("#order").value.toUpperCase();
    var order = value.trim();
    square.move(order);
});

最终代码

最终代码
demo