2017-08-12 56 views
0

我想創建一個非常基本的JavaScript遊戲使用html5畫布。所以,我創建了一個主要播放器「class」,它應該在實例化和調用「init方法」時在畫布上創建一個紅色圓圈。最後,它也應該可以通過箭頭鍵進行控制,爲此,我嘗試將事件監聽器添加到文檔中,檢查keydown/keyup,然後更改布爾值,如leftPressed = true;等等。基於此,位移方法(在setInterval函數繪製中調用)旨在更新紅色圓圈的位置,其中存在我的問題 - 在打開index.html文件時,會創建紅色圓圈,但當我擊中箭頭鍵,我無法讓它移動。任何幫助將不勝感激,請原諒我的無知,我一個星期前開始JavaScript。JavaScript事件監聽器不更新布爾值

下面是一個包含播放器 「類」 的JS代碼:

canvas = document.getElementById("surface"); 
ctx = canvas.getContext("2d"); 

//user controlled player class 

player = function(x,y,dx,dy,radius) { 
    this.x = x; 
    this.y = y; 
    this.speedx = dx; 
    this.speedy = dy; 
    this.radius = radius; 

    this.leftPressed = false; 
    this.rightPressed = false; 
    this.upPressed = false; 
    this.downPressed = false; 

    document.addEventListener("keydown",this.onKeyDown,false); 
    document.addEventListener("keyup",this.onKeyUp,false); 


    this.init = function() { 
     ctx.beginPath(); 
     ctx.arc(this.x,this.y,this.radius,0,Math.PI*2); 
     ctx.fillStyle = "red"; 
     ctx.fill(); 
     ctx.closePath(); 
    } 

    this.onKeyDown = function(e) { 
     if (e.keyCode == 37) { 
      this.leftPressed = true; 
     } 
     if (e.keyCode == 38) { 
      this.upPressed = true; 
     } 
     if (e.keyCode == 39) { 
      this.rightPressed = true; 
     } 
     if (e.keyCode == 40) { 
      this.downPressed = true; 
     } 
    } 
    this.onKeyUp = function(e) { 
     if (e.keyCode == 37) { 
      this.leftPressed = false; 
     } 
     if (e.keyCode == 38) { 
      this.upPressed = false; 
     } 
     if (e.keyCode == 39) { 
      this.rightPressed = false; 
     } 
     if (e.keyCode == 40) { 
      this.downPressed = false; 
     } 
    } 
    this.displace = function() { 
     if (this.leftPressed) { 
      this.x -= this.speedx; 
     } 
     if (this.rightPressed) { 
      this.x += this.speedx; 
     } 
     if (this.downPressed) { 
      this.y -= this.speedy; 
     } 
     if (this.upPressed) { 
      this.y += this.speedy; 
     } 
    } 

} 

這裏是main.js代碼:

canvas = document.getElementById("surface"); 
ctx = canvas.getContext("2d"); 

ctx.fillStyle = "black"; 
ctx.fillRect(0,0,canvas.width,canvas.height); 



player1 = new player(500,500,7,7,25); 


function draw() { 
    ctx.fillStyle = "black"; 
    ctx.fillRect(0,0,canvas.width,canvas.height); 

    player1.init(); 
    player1.displace(); 
} 

setInterval(draw,10); 

回答

0

這看起來像一個典型的JavaScript錯誤:在this沒有按關鍵字行爲就像你所期望的那樣。

在此代碼:

function C() { 
    this.prop = true; 
    this.get = function() { 
     return this.prop; 
    } 
} 
var obj = new C(); 

obj.get()將返回true,但var get = obj.get; get()將返回undefined。關於爲什麼要進入這裏的確切原因是什麼,但總的來說,最簡單的答案是不要引用成員函數以後執行。取而代之的是,做這樣的事情:

document.addEventListener("keydown", e => { 
    this.onKeyDown(e); 
}, false); 

這工作,因爲lambda語法不惹this。如果你想支持拉姆達預JS,你可以做到這一點稍微難看版本:

var self = this; 
document.addEventListener("keydown", function(e) { 
    self.onKeyDown(e); 
}, false); 

或使用bind修復它。

總之,有這許多解決方案,但要了解所有的人都需要JavaScript的略微古怪protoptypical繼承製度有很好的理解。

+0

lambda語法完美無缺地工作。 Tnx很多,我一直很擔心這個問題,因爲開發者控制檯沒有顯示任何錯誤。我想知道是否可以將我指向JS的學習資源,它涵蓋了像這樣的東西(lambda)。大多數情況下,我只是觀看只解釋絕對基本知識的視頻教程。再次,tnx很多! – TheLousyCoder

+0

我真的不知道最新的JS資源,對不起。但是,是的,控制檯不會顯示錯誤,因爲'this'仍然指向_something_,並且回調已經相當成功地將「leftPressed」標誌添加到任何東西。它只是不是你的代碼在尋找它的地方。 –