HTML5 Canvas - 键盘键不响应

时间:2016-01-24 11:41:07

标签: javascript html5 canvas

我试图在乒乓球游戏中实现键输入。重点是上下箭头键根本不起作用。我的浏览器控制台没有显示任何错误消息。

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;
      }
    };

2 个答案:

答案 0 :(得分: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;
      }
    }
}

进一步审查后,还有其他一些问题。首先,实际更改paddle的X和Y的逻辑应该在更新方法中(因为那是通常用于更改对象属性的内容),而render方法应该简单地绘制使用对象的更新属性的形状和图像。

其次,你试图在渲染方法中访问this.playerBat.y,但是这个'这个'实际上是playerBat。因此,为了正确定位“'您需要写下这个属性。

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

答案 1 :(得分:0)

我重新实现了您提供的代码,并向init添加了playerBat函数,该函数附加了keydownkeyup事件的事件侦听器。我只保留相关位并将对象实现为函数,但这个概念应该仍然适用。

传递到addEventListener的回调函数需要绑定this,否则回调内的this值(this.UP_DOWNthis.DOWN_DOWN)将不会与封闭范围中的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>