具有2D阵列的HTML / JavaScript Tic Tac Toe

时间:2014-06-22 11:37:21

标签: javascript html5 multidimensional-array

我是HTML5和JavaScript的新手,我正在尝试学习游戏编程。所以我决定尝试制作一个Tic Tac Toe游戏,其中棋盘是从2D阵列渲染的。我将它设置为使用CSS更改颜色:悬停但现在我只是想让每个框在点击时更改为红色,这就是我被困住的地方。

我不是在寻找任何人为我完成我的代码它只是我试图把事情放慢(ish)并且我想自己解决这些问题。我的问题是当你点击时我如何让每个盒子改变颜色?目前我让数组的每个元素创建一个,然后我定位它们并在它们的类中添加一个addEventListener。我的代码KIND-OF的工作原理是,当您单击它时,最后一个元素会改变颜色,但其他元素都没有。

这是我的代码。

<!doctype html>
<title>Tic Tac Toe</title>

<style>

#stage
{
    position: relative;
}

.cell
{
    position: absolute;
    width: 100px;
    height: 100px;
    border: 1px solid black;
    background-color: white;
}

.cell:hover
{
    background-color: blue;
}

</style>

<div id="stage"></div>

<script>

//get a reference to the stage
var stage = document.querySelector("#stage");

//the 2d array that defines the board
var board = 
[
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
];

//the size of each cell
var SIZE = 100;

//the space between each cell
var SPACE = 10;

//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;

for(var row = 0; row < ROWS; row++)
{
    for(var column = 0; column < COLUMNS; column++)
    {
        //create a div HTML element called cell
        var cell = document.createElement("div");

        //set its CSS class to cell
        cell.setAttribute("class", "cell");

        //add the div HTML element to the stage
        stage.appendChild(cell);

        //position the cell
        cell.style.top = row * (SIZE + SPACE) + "px";
        cell.style.left = column * (SIZE + SPACE) + "px";
    }
}

cell.addEventListener("click", clickHandler, false);

function clickHandler()
{
    cell.style.backgroundColor = "red";
    console.log("worked");
}

</script>

任何帮助将不胜感激!谢谢!

4 个答案:

答案 0 :(得分:1)

有一个简单的错误,你将点击处理程序绑定在循环之外。当您在循环中移动它时,您需要将cell.style更改为this.style,因为cell将在循环之后引用变量的最后一个值而不是当前单元格

由于addEventListener方法,您当前的代码与Internet Explorer 8及更低版本不兼容也值得注意。如果您计划在页面上操作元素,建议您使用jQuery,这会使这些兼容性问题在某种程度上无关紧要(在这种情况下,您需要v1.xx版本的jquery,因为v2.xx已经放弃了对IE 8的支持

var stage = document.querySelector("#stage");

//the 2d array that defines the board
var board = [
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
];

//the size of each cell
var SIZE = 100;

//the space between each cell
var SPACE = 10;

//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;

for(var row = 0; row < ROWS; row++){
    for(var column = 0; column < COLUMNS; column++){
        //create a div HTML element called cell
        var cell = document.createElement("div");

        //set its CSS class to cell
        cell.setAttribute("class", "cell");

        //add the div HTML element to the stage
        stage.appendChild(cell);

        //position the cell
        cell.style.top = row * (SIZE + SPACE) + "px";
        cell.style.left = column * (SIZE + SPACE) + "px";

        //handle click
        cell.addEventListener("click", clickHandler, false);
    }
}

function clickHandler(){
    this.style.backgroundColor = "red";
    console.log("worked");
}

答案 1 :(得分:0)

这里的解决方案很简单:

  • 首先为每个元素注册事件(因此它在循环中)
  • 在事件发送中使用参数 event

所以我得到了这个:

//get a reference to the stage
var stage = document.querySelector("#stage");

//the 2d array that defines the board
var board = 
[
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
];

//the size of each cell
var SIZE = 100;

//the space between each cell
var SPACE = 10;

//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;

for(var row = 0; row < ROWS; row++)
{
    for(var column = 0; column < COLUMNS; column++)
    {
        //create a div HTML element called cell
        var cell = document.createElement("div");

        //set its CSS class to cell
        cell.setAttribute("class", "cell");

        //add the div HTML element to the stage
        stage.appendChild(cell);

        //position the cell
        cell.style.top = row * (SIZE + SPACE) + "px";
        cell.style.left = column * (SIZE + SPACE) + "px";
        cell.addEventListener("click", clickHandler, false);
    }
}


function clickHandler(event)
{
    console.log(event);
    event.currentTarget.style.backgroundColor = "red";
    console.log("worked");
}

以下是我的测试:http://jsfiddle.net/DSNLR/

答案 2 :(得分:0)

最简单的方法: 1.把

cell.addEventListener("click", clickHandler, false);

进入循环,因为每个单元格应该拥有它自己的监听器。 2.处理程序应该使用适当的单元格,但不能使用一些通用的CELL

function clickHandler()
{
    this.style.backgroundColor = "red";
    console.log("worked");
}

如果你想提高性能,那么你应该听父元素(包含所有单元格)和调度事件。

答案 3 :(得分:0)

我对JavaScript一无所知,但对Java有所了解。

cell.addEventListener("click", clickHandler, false);

必须在for循环内部:

for(var row = 0; row < ROWS; row++)
{
  for(var column = 0; column < COLUMNS; column++)
  {
    //create a div HTML element called cell
    var cell = document.createElement("div");

    //do your stuff here

    //now the event listener
    cell.addEventListener("click", clickHandler, false);
  }
}

那应该有用。您只将它添加到最后一个单元格中。