2016-01-24 114 views
0

我试图在乒乓球游戏中实现按键输入。重点是上下方向键不起作用。我的浏览器控制台不显示任何错误消息。HTML5画布 - 键盘按键不响应

Here is my code, this is WIP some Objects are not implemented yet

var playerBat = { 
     x: null, 
     y: null, 
     width: 20, 
     height: 80, 
     UP_DOWN: false, 
     DOWN_DOWN: false, 

     update: function() { 
     // Keyboard inputs 
     window.addEventListener('keydown', onKeyDown, false); 
     window.addEventListener('keyup', onKeyUp, false); 

     var key = { 
      UP: 38, 
      DOWN: 40 
     }; 

     function onKeyDown(e) { 
      if (e.keyCode == 38) 
      this.UP_DOWN = true; 

      else if (e.keyCode == 40) 
      this.DOWN_DOWN = true; 
     } 

     function onKeyUp(e) { 
      if (e.keyCode == 38) 
      this.UP_DOWN = false; 

      else if (e.keyCode == 40) 
      this.DOWN_DOWN = false; 
     } 

     this.y = Math.max(Math.min(this.y, Canvas_H - this.height), 0); // Collide world bounds 
     }, 

     render: function() { 
     ctx.fillStyle = '#000'; 
     ctx.fillRect(this.x, this.y, this.width, this.height); 

     if (this.UP_DOWN) 
      this.playerBat.y -= 5; 

     else if (this.DOWN_DOWN) 
      this.playerBat.y += 5; 
     } 
    }; 

回答

0

事件被解雇,问题是​​,你将他们在每次更新。你想要做的是在addEvents之类的方法外部使用回调函数和addEventListener,这些方法在初始化时应该被称为ONCE。目前,大量的事件处理程序被触发杀死了页面。

function addEvents() { 

     window.addEventListener('keydown', onKeyDown, false); 
     window.addEventListener('keyup', onKeyUp, false); 

     var key = { 
     UP: 38, 
     DOWN: 40 
     }; 

     function onKeyDown(e) { 
     if (e.keyCode == key.UP) { 
      playerPaddle.UP_DOWN = true; 
     } 

     if (e.keyCode == key.DOWN) { 
      playerPaddle.DOWN_DOWN = true; 
     } 
    } 

    function onKeyUp(e) { 
     if (e.keyCode == key.UP) { 
     playerPaddle.UP_DOWN = false; 
     } 

     if (e.keyCode == 40) { 
     playerPaddle.DOWN_DOWN = key.DOWN; 
     } 
    } 
} 

进一步审查后,还有一些其他问题。首先,实际更改桨的X和Y的逻辑应该在更新方法中(因为这通常用于更改对象属性),而渲染方法应该只使用对象的更新属性绘制形状和图像。

其次,您正尝试在render方法中访问this.playerBat.y,但是'this'实际上就是playerBat。因此,为了正确定位'y'属性,您需要编写this.y。

我还注意到你已经有了一个关键的地图,定义了UP和DOWN键码,但实际上并没有使用它,而是使用了数字。也许你打算做什么?

0

我重新实现您所提供的代码,并添加了init功能playerBat,重视对​​和keyup事件的事件侦听器。我只是保留了相关的位和实现的对象作为函数,但这个概念仍然适用。

送入addEventListener需要结合this回调函数,否则回调(this.UP_DOWNthis.DOWN_DOWN)内的this值将不相同,在封闭范围的this值;你想要的一个价值。

<canvas id='canvas' style="background:#839496">Your browser doesn't support The HTML5 Canvas</canvas> 
 

 

 

 
<script> 
 
    var canvas = document.getElementById('canvas'); 
 
    canvas.width = window.innerWidth-20; 
 
    canvas.height = window.innerHeight-20; 
 

 
    var ctx = canvas.getContext('2d'); 
 

 
    var Canvas_W = Math.floor(canvas.width); 
 
    var Canvas_H = Math.floor(canvas.height); 
 

 

 

 
    /* 
 
    * Define a Player object. 
 
    */ 
 
    function PlayerBat(){ 
 

 
    this.x = null; 
 
    this.y = null; 
 
    this.width = 20; 
 
    this.height = Canvas_H/3; 
 
    this.UP_DOWN = false; 
 
    this.DOWN_DOWN = false; 
 

 

 
    this.init = function() { 
 
     console.log('init'); 
 

 
     // MUST bind `this`! 
 
     window.addEventListener('keydown', function(e){ 
 
     console.log('keydown'); 
 

 
     if (e.keyCode == 38) this.UP_DOWN = true; 
 
     else if (e.keyCode == 40) this.DOWN_DOWN = true; 
 
     }.bind(this), false); 
 

 
     // MUST bind `this`!   
 
     window.addEventListener('keyup', function(e){ 
 
     console.log('keyUp') 
 

 
     if (e.keyCode == 38) this.UP_DOWN = false; 
 
     else if (e.keyCode == 40) this.DOWN_DOWN = false; 
 
     }.bind(this), false); 
 
    }; 
 

 

 

 
    this.update = function() { 
 
     var key = {UP: 38, DOWN: 40}; 
 
     this.y = Math.max(Math.min(this.y, Canvas_H - this.height), 0); 
 
    }; 
 

 

 
    this.render = function() { 
 
     // Clear the canvas 
 
     ctx.clearRect(0, 0, canvas.width, canvas.height); 
 

 
     // Redraw paddle 
 
     ctx.fillStyle = '#00F'; 
 
     ctx.fillRect(this.x, this.y, this.width, this.height); 
 

 
     this.y = (this.UP_DOWN) ? this.y - 5 : ((this.DOWN_DOWN) ? this.y + 5 : this.y); 
 
    }; 
 

 
    } 
 

 

 

 

 
    function GameRunner(){ 
 
    // Create instance of player 
 
    var playerBat = new PlayerBat(); 
 
    playerBat.init(); 
 

 

 
    // Execute upon instantiation of GameRunner 
 
    (function() { 
 
     playerBat.x = playerBat.width; 
 
     playerBat.y = (Canvas_H - playerBat.height)/2; 
 
    })(); 
 

 

 

 
    function step() { 
 
     playerBat.update(); 
 
     playerBat.render(); 
 
     requestAnimationFrame(step); 
 
    } 
 

 

 

 
    // Public method. Start animation loop 
 
    this.start = function(){ 
 
     requestAnimationFrame(step); 
 
    } 
 
    } 
 

 

 

 
    // Create GameRunner instance 
 
    var game = new GameRunner(); 
 

 

 
    // Start game 
 
    game.start(); 
 

 

 
</script>