2017-08-12 28 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”标志添加到任何东西。它只是不是你的代码在寻找它的地方。 –