简单记忆游戏不会更新其状态。糟糕的游戏循环?

时间:2013-06-24 08:55:33

标签: javascript game-loop

我正试图制作一个简单的(或者我认为的)记忆游戏。不幸的是,当用户点击它们时,它不会更新状态卡。我的想法已经不多了,可能是因为这是我的第一个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);

3 个答案:

答案 0 :(得分:1)

我会检查你的addEventListener方法:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener 我还建议你研究一下jQuery。

答案 1 :(得分:0)

复制并粘贴代码后,我发现了一些事情:

  1. 您没有向任何事物添加事件监听器,您应该将其添加到某些内容中,因此我将其添加到文档中。
  2. 使用值“false”初始化公开的数组,然后检查它们是否为false。这些不一样,字符串“false”不是布尔值false。
  3. 您将曝光的数组初始化为多维数组[[false,false,false ...]]这应该是单维数组,因为稍后您会检查已曝光的[1](1取决于鼠标x位置。< / LI>
  4. 无需每隔16毫秒调用绘图和更新,您可以在有人点击后调用它。
  5. 在函数中包含整个内容,因此没有创建全局变量。
  6. 以下是更改这些明显错误后的代码。可能存在优化空间,但现在我已经解决了这些问题。

    <!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>
    

答案 2 :(得分:0)

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

所以我向你展示了一点小提示,主要的变化是 click事件处理程序,它更新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;

}