1

我正在尝试制作一个简单的(或者我认为是这样的)记忆游戏。不幸的是,当用户点击卡片时,它不会更新卡片的状态。我的想法不多了,可能是因为这是我的第一个 javascript 游戏。估计是游戏循环有问题。谁能至少指出我正确的方向并帮助我了解需要更改/重写的内容?

//HTML5 Memory Game implementation

//main variables
var cards = [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8];
var exposed = [makeArray("false",16)];
var first_card = 0;
var second_card = 0;
var moves = 0;
var WIDTH = 800;
var HEIGHT = 100;
var state = 0;
var mouseX = 0;
var mouseY = 0;

//creating canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = WIDTH;
canvas.height = HEIGHT;
document.getElementById("game").appendChild(canvas);

//filling empty array with number,character,object
function makeArray(value, length) {
    var newArray = [];
    var i = 0;
    while (i<length) {
        newArray[i] = value;
        i++;
    }
    return newArray;
}

//shuffling algorithm
function shuffle(array) {
    var copy = [];
    var n = array.length;
    var i;

    while (n) {
        i = Math.floor(Math.random() * n--);
        copy.push(array.splice(i, 1)[0]);
    }

    return copy;
}

//where user clicks
function getClickPosition(event) {
    var X = event.pageX - canvas.offsetLeft;
    var Y = event.pageY - canvas.offsetTop;
    return mouse = [X, Y];
}

//read click position
function readPos(event) {
    mousePos = getClickPosition(event);
    mouseX = mousePos[0];
    mouseY = mousePos[1];
}

//initializing
function init() {
    state = 0;
    moves = 0;
    exposed = [makeArray("false",16)];
    cards = shuffle(cards);
}

//drawing cards
function draw() {
    ctx.clearRect(0, 0, WIDTH, HEIGHT);
    for (var i in cards) {
        if (exposed[i] === true) {
            ctx.fillStyle = "rgb(250, 250, 250)";
            ctx.font = "50px Courier New";
            ctx.fillText(cards[i], (i*50+12), 65);
        } else {
            ctx.strokeStyle = "rgb(250, 0, 0)";
            ctx.fillStyle = "rgb(0, 0, 250)";
            ctx.fillRect(i*50, 0, 50, 100);
            ctx.strokeRect(i*50, 0, 50, 100);
        }
    }
};

//update cards
function update() {
    if (exposed[parseInt(mouseX / 50)] === false) {
        if (state == 0) {
            state = 1;
            first_card = parseInt(mouseX / 50);
            exposed[parseInt(mouseX / 50)] = true;
        } else if (state == 1) {
            state = 2;
            second_card = parseInt(mouseX / 50);
            exposed[parseInt(mouseX / 50)] = true;
        } else {
            if (cards[first_card] != cards[second_card]) {
                exposed[first_card] = false;
                exposed[second_card] = false;
            }
            state = 1;
            first_card = parseInt(mouseX / 50);
            exposed[parseInt(mouseX / 50)] = true;
        }
    }
}

addEventListener('click', readPos, false);

setInterval(function() {
    update();
    draw();
}, 16);
4

3 回答 3

1

我会检查您的 addEventListener 方法:https ://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener 我还建议您考虑使用 jQuery。

于 2013-06-24T09:04:24.920 回答
0

你的整体逻辑很好。
“不好”的一点是您处理事件的方式:事件处理程序应该存储一些有价值的信息,以便更新稍后处理和清除。
在这里,您将更新与事件处理混合在一起,这无法正常工作,尤其是因为事件不会在每次更新时触发。

所以我做了一些小技巧来告诉你,主要的变化是点击事件处理程序,它更新了 var last_clicked_card :

http://jsfiddle.net/wpymH/

//read click position
function readPos(event) {
    last_clicked_card = -1;
    mousePos = getClickPosition(event);
    mouseX = mousePos[0];
    mouseY = mousePos[1];
    //  on canvas ?
    if ((mouseY>100)||(mouseX<0)||(mouseX>WIDTH)) return;
    // now yes : which card clicked ?
    last_clicked_card = Math.floor(mouseX/50);
 }

然后更新是处理这些信息:

//update cards
function update() {
    // return if no new card clicked
    if (last_clicked_card == -1) return;
    // read and clear last card clicked
    var newCard = last_clicked_card;
    last_clicked_card=-1;
    // flip, store it as first card and return 
    // if there was no card flipped
    if (state==0) {  exposed[newCard] = true;
                     first_card = newCard; 
                     state = 1 ;
                     return;        }
    // just unflip card if card was flipped
    if ((state = 1) && exposed[newCard]) {     
                     exposed[newCard]=false ;
                     state=0;
                     return;
    }
    // we have a second card now
    second_card = newCard;
    exposed[second_card] =  true;
    draw();
    // ... i don't know what you want to do ...
    if (cards[first_card] == cards[second_card]) { 
         alert('win'); } 
    else {
         alert('loose'); }

    exposed[first_card]=false;
    exposed[second_card]=false;
    state=0;

}
于 2013-06-24T09:39:27.230 回答
0

复制并粘贴您的代码后,我发现了几件事:

  1. 您没有向任何内容添加事件侦听器,您应该将其添加到某事中,因此我将其添加到 document.xml 中。
  2. 您使用值“false”初始化公开的数组,然后检查它们是否为假。这些不一样,字符串“false”不是布尔值 false。
  3. 您将暴露的数组初始化为多维数组 [[false,false,false ...]] 这应该是一维数组,因为稍后您会检查暴露的 [1] (1 取决于鼠标 x 位置。
  4. 无需每 16 毫秒调用一次绘制和更新,您可以在有人点击后调用它。
  5. 将整个事情包装在一个函数中,因此没有创建全局变量。

这是更改这些明显错误后的代码。可能有优化的空间,但现在我已经解决了问题。

<!DOCTYPE html>
<html>
 <head>
<title>test</title>
</head> 
 <body> 
<div id="game"></div>
 <script type="text/javascript">

     (function(){
         //HTML5 Memory Game implementation

         //main variables
         var cards = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8];
         var exposed = makeArray(false, 16);
         var first_card = 0;
         var second_card = 0;
         var moves = 0;
         var WIDTH = 800;
         var HEIGHT = 100;
         var state = 0;
         var mouseX = 0;
         var mouseY = 0;

         //creating canvas
         var canvas = document.createElement("canvas");
         var ctx = canvas.getContext("2d");
         canvas.width = WIDTH;
         canvas.height = HEIGHT;
         document.getElementById("game").appendChild(canvas);

         //filling empty array with number,character,object
         function makeArray(value, length) {
             var newArray = [];
             var i = 0;
             while (i < length) {
                 newArray.push(value);
                 i++;
             }
             return newArray;
         }

         //shuffling algorithm
         function shuffle(array) {
             var copy = [];
             var n = array.length;
             var i;

             while (n) {
                 i = Math.floor(Math.random() * n--);
                 copy.push(array.splice(i, 1)[0]);
             }

             return copy;
         }

         //where user clicks
         function getClickPosition(event) {
             var X = event.pageX - canvas.offsetLeft;
             var Y = event.pageY - canvas.offsetTop;
             return mouse = [X, Y];
         }

         //read click position
         function readPos(event) {
             mousePos = getClickPosition(event);
             mouseX = mousePos[0];
             mouseY = mousePos[1];
             update();
             draw();
         }

         //initializing
         function init() {
             state = 0;
             moves = 0;
             exposed = makeArray(false, 16);
             cards = shuffle(cards);
         }

         //drawing cards
         function draw() {
             ctx.clearRect(0, 0, WIDTH, HEIGHT);
             for (var i in cards) {
                 if (exposed[i] === true) {
                     ctx.fillStyle = "rgb(150, 150, 150)";
                     ctx.font = "50px Courier New";
                     ctx.fillText(cards[i], (i * 50 + 12), 65);
                 } else {
                     ctx.strokeStyle = "rgb(250, 0, 0)";
                     ctx.fillStyle = "rgb(0, 0, 250)";
                     ctx.fillRect(i * 50, 0, 50, 100);
                     ctx.strokeRect(i * 50, 0, 50, 100);
                 }
             }
         };
         //update cards
         function update() {
             if (exposed[parseInt(mouseX / 50)] === false) {
                 if (state == 0) {
                     state = 1;
                     first_card = parseInt(mouseX / 50);
                     exposed[parseInt(mouseX / 50)] = true;
                 } else if (state == 1) {
                     state = 2;
                     second_card = parseInt(mouseX / 50);
                     exposed[parseInt(mouseX / 50)] = true;
                 } else {
                     if (cards[first_card] != cards[second_card]) {
                         exposed[first_card] = false;
                         exposed[second_card] = false;
                     }
                     state = 1;
                     first_card = parseInt(mouseX / 50);
                     exposed[parseInt(mouseX / 50)] = true;
                 }
             }
         }
         document.body.addEventListener('click', readPos, false);
         init();
         draw();
     })();
 </script>
 </body>
</html>
于 2013-06-24T09:27:50.373 回答