2013-08-02 42 views
0


我是JS新手,但想寫Snake遊戲。在過程中遇到了一個問題:我使用requestAnimationFrame爲div動畫,一切正常(我的div正在移動),但是當我開始爲改變方向編寫切換語句時,我的代碼會中斷。
結果我可以達到以下兩個要求之一:使用requestAnimationFrame移動我的div,而沒有機會使用keybord箭頭更改方向,或者移動並更改方向,但不使用動畫,如果我停止按下keybord箭頭。有人可以幫助我將動畫和鍵盤操作結合起來嗎?用鍵盤移動div(requestAnimationFrame不工作)

這裏是我的代碼:

// field object 
    var fieldObj = { 
     field: document.getElementById("field"), 
     w: 480, 
     h: 580 
    }, 
snakeObj = { 
    snake: document.getElementById("snake"), 
    p: { 
     x: 0, // position x 
     y: 0 // position y 
    }, 
    v: { 
     x: 2, // velocity(here you can change speed) 
     y: 2 
    }, 
update: function(event) { 
     event = event || window.event; 
     switch(event.keyCode) { 
     case 40: 
      this.p.x += this.v.x; 
      break; 
     case 38: 
      this.p.x -= this.v.x; 
      break; 
     case 39: 
      this.p.y += this.v.y; 
      break; 
     case 37: 
      this.p.y -= this.v.y; 
      break; 
     } 
    this.snake.style.top = this.p.x + "px"; 
    this.snake.style.left = this.p.y + "px" 
    } 
} 

window.addEventListener('keydown', function gameLoop() { 
    snakeObj.update(); 
    requestAnimationFrame(gameLoop); 
}, false); 

Codepen的問題(這裏的div movung但沒有機會操縱)http://codepen.io/Kuzyo/pen/esFbf
感謝每個幫助

有了幫助,我實現了當我按下左div向左移動,比我可以將方向切換到右側,但如果我想讓他再向左移動,他會繼續向右移動。上下相同。

下面是更新後的代碼:http://codepen.io/Kuzyo/pen/esFbf

+0

您要搜索的[KEYDOWN鍵盤事件](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent)。 – Broxzier

+0

您的'keydown'和'keyup'事件應該只將某些開關設置爲true,但更新應獨立於它們並始終在'requestAnimationFrame()'中調用。更新功能然後讀取開關並執行必要的操作。所以,運動增量應該在更新中執行,這在每個幀中都被調用,而不是在keydown中。 –

+0

@Broxzier我知道,我可以移動,但如果我停下來按下鍵我的div也停止了,但我希望div進一步移動 – kuzyoy

回答

0

首先,打電話給你的更新請求動畫幀後,這給你稍微平滑倍。

//declare and start the game loop 
(function gameLoop(){ 
    requestAnimFrame(gameLoop); 
    snakeObj.update(); 
})(); 

我們現在已經設置了我們的動畫幀。這意味着update()將被調用每一幀,而不管你的關鍵事件。現在,我們所要做的就是在關鍵事件中設置一些開關。

window.addEventListener('keydown', function() { 

    switch(event.keyCode) { 
    case 40: 
     snakeObj.keys.left = true; 
     break; 

    ... 

    } 
}, false); 

你還需要一個keyup事件來設置的標誌爲假。更新時,只需讀取關鍵數據並移動即可。喜歡的東西:

this.update() { 

    //read the keys and move accordingly 
    if(this.keys.left) { 
     this.p.x -= 5; 
    } 

    ... 

} 
+0

謝謝@Andrei。幾乎,但不超過兩個按鍵http://codepen.io/Kuzyo/pen/esFbf。 Спасибозапомощь。 – kuzyoy

+0

你還在做錯了!如果你在'keydown'事件處理函數中調用'update()',那麼當你按下按鍵**時,它只會被調用**。無論您是否按下任何按鍵,更新都應該始終發生!您的遊戲循環需要獨立執行,就像我在頂部解釋的那樣。按照我的指示 –

+0

我將console.log添加到gameLoop,它顯示gameLoop和我的update()獨立運行的結果。感謝您的helphttp://codepen.io/Kuzyo/pen/esFbf – kuzyoy