Javascript记忆游戏 - 图像交换

时间:2013-12-10 14:38:35

标签: javascript memory

这是我正在处理的内存游戏的当前代码。我正在使用纯JavaScript,而且我的a-tags的onclick功能遇到了问题。我想要的是游戏将点击的图像(问号)与分配给点击图像的类号的图像交换,从而产生翻转效果。

我目前得到的是,无论我在哪里点击,只有最后一张图片被交换。

"use strict"

var newDiv = null;
var innerDiv = null;
var table = null;
var row = null;
var cell = null;
var aTag = null;
var image = null;

// Use this to put class names on the images.
var boxCounter = 0;

// Static memory-object.
var Memory = {

    memoryArray: [],

    init: function (e) {

        // Calls a separate js-file which generates a random numbers.
        Memory.memoryArray = RandomGenerator.getPictureArray(4, 4);

        // Calls the rendering method
        Memory.renderArray(Memory.memoryArray);
    },

    renderArray: function (myArray) {

        // Creates and places div-tags in the HTML-document.
        newDiv = document.createElement("div");
        document.getElementsByTagName("body")[0].appendChild(newDiv);
        innerDiv = document.createElement("div");
        newDiv.appendChild(innerDiv);

        // Creates a table and places it in the HTML-document.
        table = document.createElement("table");
        table.border = 1;

        // Generates rows and cells, swap the 4's to change the size of the gameboard.
        for (var i = 0; i < 4; ++i) {
            row = document.createElement("tr");
            table.appendChild(row);

            // Creates a cell, each with its own respective random number.
            for (var j = 0; j < 4; ++j) {
                cell = document.createElement("td");

                // Adds a "Question-mark"-picture to the cell and places them in a-tags.
                image = document.createElement("img");
                image.className = myArray[i * 4 + j];
                image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/0.png?raw=true";
                aTag = document.createElement("a");
                aTag.onclick = function () {

                    Memory.flipTile(image.className);
                };

                // Places the pictures in the document, along with its random number for easier testing purposes.
                aTag.appendChild(document.createTextNode(myArray[i * 4 + j]));
                aTag.appendChild(image);
                cell.appendChild(aTag);
                row.appendChild(cell);
            };
        };
        innerDiv.appendChild(table);

    },

    flipTile: function (imageClass) {
        console.log(imageClass);

        // This should flip the tiles if the number matches the class name.
        if (imageClass == 1) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/1.png?raw=true";
        };
        if (imageClass == 2) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/2.png?raw=true";
        };
        if (imageClass == 3) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/3.png?raw=true";
        };
        if (imageClass == 4) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/4.png?raw=true";
        };
        if (imageClass == 5) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/5.png?raw=true";
        };
        if (imageClass == 6) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/6.png?raw=true";
        };
        if (imageClass == 7) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/7.png?raw=true";
        };
        if (imageClass == 8) {
            image.src = "https://github.com/1dv403/1dv403-laborationer/blob/master/3-gameon/memory/pics/8.png?raw=true";
        };

    }

};
window.onload = Memory.init;

2 个答案:

答案 0 :(得分:1)

这是一个涉及闭包和循环的经典问题。考虑函数表达式

创建的闭包
aTag.onclick = function () {
    Memory.flipTile(image.className);
};

它从更高的范围引用image,那么循环中的下一次迭代会发生什么?

image = document.createElement("img");

image现在指向不同的对象,因此在循环的最后一次迭代中,所有image指向相同的(最后一个)<img>元件。

您需要为image创建一个闭包,这样才不会发生。您可以通过编写一个函数来生成所需的函数

function makeClickListener(elm) {
    return function () {
        Memory.flipTile(elm.className);
    };
}

现在,使用它来创建单击监听器

aTag.onclick = makeClickListener(image);

这可以通过仅传递 String 而不是整个 Object 进一步优化(需要更少的内存)。

答案 1 :(得分:0)

所有点击处理程序都引用相同的图像变量(在for循环结束后将是最后一个图像)。您需要每个处理程序引用不同的图像变量。您可以通过将其作为参数传递给函数来创建它的副本来完成此操作。

替换它:

function () {
  Memory.flipTile(image.className);
};

有了这个:

function(classname) {
  return function () {
    Memory.flipTile(className);
  };
}(image.classname);

第二个问题:全球形象。 flipTile函数对图像变量执行某些操作,但在其中没有声明。您实际上想要将图像作为参数传递,如下所示:

为:

flipTile: function (imageClass) {

好:

flipTile: function (image, imageClass) {

现在您还需要更改对函数的调用以传递图像:

function(img, classname) {
  return function () {
    Memory.flipTile(img, className);
  };
}(image, image.classname);

考虑到您将图像作为参数传递给flipTile,看起来您不需要传递image.classname,因此您可以更改函数以使用image.classname。 Thais步骤是可选的,没有它,代码应该可以正常工作。