supce's blog

听指令的小方块


任务目的

  • 练习JavaScript在DOM、字符串处理相关知识
  • 练习对于复杂UI,如何进行数据机构建模

任务描述

  • 实现一个类似棋盘的格子空间,每个格子用两个数字可以定位,一个红正方形的DOM在这个空间内,正方形中的蓝色边表示这是他的正面,有一个input输入框
  • 可以通过键盘对方块下达指令,按下按钮后,使得正方形做相应动作
  • 回车或者空格:向蓝色边所面向的方向前进一格(一格等同于正方形的边长)
  • ←:向左
  • →:向右
  • ↑:向右
  • ↓:向下
  • 移动不能超出格子空间

整体思路

要实现上面的效果,可以通过canvas也可以通过对页面元素操作来实现。下面采用的是对元素操作来实现的。

首先是最基础的HTML代码,我们设置一个背景容器div,用来存放背景。

<!DOCTYPE html>
<html>
<head>
    <title>听指令的方块</title>
    <link rel="stylesheet" type="text/css" href="css/task33.css">
    <script type="text/javascript" src="js/task33/utils.js"></script>
</head>
<body>
    <div id="table_container"></div>
    <div id="control_panel">
        <span>上下左右改变方向,回车空格移动</span>
    </div>

    <script type="text/javascript" src="js/task33/createTable.js"></script>
    <script type="text/javascript" src="js/task33/Manipulate.js"></script>
    <script type="text/javascript" src="js/task33/app.js"></script>
</body>
</html>

然后可以通过js来创建我们的棋盘背景。将这段代码放在createTable.js中

//创建背景
(function(){
    var container = $("#table_container");
    var table = document.createElement("table");
    var tbody = document.createElement("tbody");
    for(var i=0;i<11;i++){
        var tr = document.createElement("tr");
        if(i == 0){
            tr.setAttribute("axle","y");
        }
        for(var j=0;j<11;j++){
            var td = document.createElement("td");
            td.setAttribute("index",j);  //标注该td为tr的第几个子节点
            if(i===0 && j!==0){   //添加横轴坐标
                td.innerHTML = j;
            }
            if(j===0 && i!==0){   //添加纵轴坐标
                td.innerHTML = i;
            }
            if(i===5 && j==5){    //添加初始化方块
                var square = document.createElement("div");
                square.setAttribute("id","square");
                square.className = "bottom";
                td.appendChild(square);
            }
            tr.appendChild(td);
        }
        tbody.appendChild(tr);
    }
    table.appendChild(tbody);
    container.appendChild(table);
})();

写一个操作类,存放页面中的方块,并且给方块添加go方法(前进)和turn(转变方向)方法

function Manipulate(square){
    this.square = square;
};
Manipulate.prototype = {
    go : function(){
        console.log("gogogog");
        var direction = square.className;
        var td = this.square.parentNode;
        switch(direction){
            case 'right':
                var target = td.nextElementSibling;
                if(target){
                    target.appendChild(this.square);
                    td.innerHTML = "";
                }else{
                    alert("到达最右侧了");
                }
                break;
            case 'left':
                var target = td.previousElementSibling;
                if(target && (target.innerHTML == "")){
                    target.appendChild(this.square);
                    td.innerHTML = "";
                }else{
                    alert("达到最左侧了");
                }
                break;
            case 'bottom':
                var index = td.getAttribute("index");  //获取索引值
                var tr = td.parentNode.nextElementSibling;
                if(tr){
                    var target = tr.children[index];
                    target.appendChild(this.square);
                    td.innerHTML = "";
                }else{
                    alert("到达最底部了");
                }
                break;
            case 'top':
                var index = td.getAttribute("index");  
                var tr = td.parentNode.previousElementSibling;
                if(tr && (tr.getAttribute("axle") != "y")){
                    var target = tr.children[index];
                    target.appendChild(this.square);
                    td.innerHTML = "";
                }else{
                    alert("到达顶部了");
                }
                break;
        }
    },
    turn : function(direction){
        switch(direction){
            case 'top':
                this.square.className = "top";
                break;
            case 'right':
                this.square.className = "right";
                break;
            case 'bottom':
                this.square.className = "bottom";
                break;
            case 'left':
                this.square.className = "left";
                break;
        }
    }
}

最后创建对象,绑定相关事件即可

var square = $("#square");
var manipulate = new Manipulate(square);
//绑定键盘事件
addHandler(document,"keydown",function(e){
    // console.log(e.keyCode);
    switch(e.keyCode){
        case 37:
            manipulate.turn("left");
            break;
        case 38:
            manipulate.turn("top");
            break;
        case 39:
            manipulate.turn("right");
            break;
        case 40:
            manipulate.turn("bottom");
            break;
        case 32:   //按回车和空格前进
        case 13:
            manipulate.go();
            break;
    }
});

最终代码

最终代码
demo