【问题标题】:My right + left arrow keybinds aren't working我的右 + 左箭头键绑定不起作用
【发布时间】:2020-11-16 07:33:00
【问题描述】:

我正在尝试制作 HTML、CSS 和 JavaScript 游戏。当按下左右箭头键时,玩家应该左右移动。我不知道为什么,但这段代码没有添加事件监听器。有什么帮助吗?这是我的 index.html 文件中的代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>
            JavaScript Platformer
        </title>
    </head>
    <body>
        <canvas id="game" class="game" width="500" height="500"></canvas>
    </body>
    <script src="script.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css"/>
</html>

这是我的 script.js 文件中的代码:

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

var playerImg = new Image();
var player = {
    x: 225,
    y: 375,
    width: 50,
    height: 50
}

function draw() {
    playerImg.onload = function () {
        
        // draws the player image
        ctx.drawImage(playerImg, player.x, player.y, player.width, player.height);
    }
    
    playerImg.src = "images/player.png";
}

document.body.addEventListener("keydown", function (event) {
    event.preventDefault();
    
    if (event.keycode == 37) {
        
        // deletes the last image so the image doesn't get duplicated
        ctx.clearRect(player.x, player.y, player.x + player.width, player.y + player.height);
        
        // moves the player
        player.x -= 20;
    }
    if (event.keycode == 39) {
        
        // deletes the last image so the image doesn't get duplicated
        ctx.clearRect(player.x, player.y, player.x + player.width, player.y + player.height);
        
        // moves the player
        player.x -= 20;
    }
}, false);

setInterval(draw, 100);

这是我的 CSS 文件中的代码:

.game {
    border: 3px solid black;
    border-radius: 8px;
}

有什么帮助吗?我看不出这段代码有什么问题。

【问题讨论】:

  • 您是否尝试过调试代码以查看事件是否正在触发,以及它认为已按下的键码是否为?
  • 请使用 keyCode 而不是 keycode。一定有错别字。在更正您的错字后,我确认它可以正常工作。
  • 请在右箭头键事件中将您的代码更新为player.x += 20;(keyCode: 39)
  • KeyboardEvent.keyCode 是一个折旧的属性developer.mozilla.org/en-US/docs/Web/API/…,你不应该使用它。使用KeyboardEvent.codeKeyboardEvent.key

标签: javascript html css html5-canvas event-listener


【解决方案1】:

我认为您的代码中有一个小错字。它是event.keyCode == 39 而不是event.keycode == 39(注意keyCode 中的C 是大写的)

event.keycode == 39 也是如此。应该是event.keyCode == 39

【讨论】:

    【解决方案2】:

    不要使用keyCode

    answer by sagar1025 是导致该错误的原因,但 KeyboardEvent.keyCodeobsolete,应避免使用。

    宁可使用KeyboardEvent.codeKeyboardEvent.key

    IO 状态而不是 IO 事件

    还将玩家移动直接链接到 IO 事件(如键盘)会导致不同操作系统/设备/设置的行为不同。例如,按键重复率可能会有很大差异。

    这也使得对按键组合做出反应变得非常困难,因为按键事件是每个按键。您无法知道按下组合键是否会跟随按下组合键。例如,down and left 表示对角线。

    使用键盘事件来跟踪键盘的状态(仅限您需要知道的)。

    在游戏循环中读取键盘状态以执行动作。

    这意味着您的游戏行为在不同设备上是一致的。

    例如

    const keys = {  // name of key code you want to track state of
        ArrowLeft: false,
        ArrowRight: false,
    };
    function keyEventListener(event) {
        if (keys[event.code] !== undefined) {
            keys[event.code] = event.type === "keydown";
            event.preventDefault();
        }
    }
    document.addEventListener('keydown', keyEventListener);
    document.addEventListener('keyup', keyEventListener);
            
    

    然后在游戏动画循环中检查按键的状态

    // only when one move key is down
    if ((keys.ArrowLeft || keys.ArrowRight) && keys.ArrowRight !== keys.ArrowLeft) { player.x -= 5 }
        if (keys.ArrowLeft) { player.x -= 5 }
        if (keys.ArrowRight) { player.x += 5 }
    }
    

    请注意,如果玩家按住左右键,玩家将不会移动

    演示

    使用keyupkeydown 事件侦听器跟踪键盘状态并使用按键状态控制游戏行为的示例。

    // hold keyboard state
    const keys = {  // name of key codes you want to track state of
        ArrowLeft: false,
        ArrowRight: false,
        ArrowUp: false,
        ArrowDown: false,
    };
    function keyEventListener(event) { // simple state tracker
        if (keys[event.code] !== undefined) {
            keys[event.code] = event.type === "keydown";
            event.preventDefault();
        }
    }
    document.addEventListener('keydown', keyEventListener);
    document.addEventListener('keyup', keyEventListener);
    
    
    const player = {x: canvas.width / 2, y: canvas.height / 2, moving: false};
    const ctx = canvas.getContext("2d");
    function mainLoop() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        if (keys.ArrowLeft) { player.x -= 1; player.moving = true }
        if (keys.ArrowRight) { player.x += 1; player.moving = true }
        if (keys.ArrowUp) { player.y -= 1; player.moving = true }
        if (keys.ArrowDown) { player.y += 1; player.moving = true }
        drawPlayer(player);    
        requestAnimationFrame(mainLoop);
    }
    
        
    function drawPlayer(player) {
        if (player.moving) {
            player.moving = false;
            player.x = player.x < 0 ? 0 : player.x;
            player.x = player.x > canvas.width - 10 ? canvas.width - 10 : player.x;
            player.y = player.y < 8 ? 8 : player.y;
            player.y = player.y > canvas.height - 16 ? canvas.height - 16 : player.y;
            const footB = (player.x + player.y / 2) % 20;
            const footA = (player.x + player.y / 2+ 10) % 20;
            const head = ((player.x + player.y / 2)/2) % 8;
    
            ctx.fillStyle = "#666";
            if (footB > 10) { ctx.fillRect(player.x + 8 - (footB-10), player.y + 10, 4, 6) }
            else { ctx.fillRect(player.x - 2 + footB, player.y + 8, 4, 6) }
            ctx.fillStyle = "#888";
            ctx.fillRect(player.x, player.y, 10, 10);
             ctx.fillRect(player.x + 2 + (head < 4 ? head : (4 - head)), player.y -8, 6, 6);
            ctx.fillStyle = "#AAA";
            if (footA > 10) { ctx.fillRect(player.x + 8 - (footA - 10), player.y + 10, 4, 6) }
            else { ctx.fillRect(player.x - 2 + footA, player.y + 8, 4, 6) }
        } else {
            ctx.fillStyle = "#666";
            ctx.fillRect(player.x - 2, player.y + 10, 4, 6);
            ctx.fillStyle = "#888";
            ctx.fillRect(player.x, player.y, 10, 10);
            ctx.fillRect(player.x + 2, player.y -8, 6, 6);
            ctx.fillStyle = "#AAA";
            ctx.fillRect(player.x + 8, player.y + 10, 4, 6);
        }
    }
    
    addEventListener("click", () => {
        start.textContent = "Arrow keys to move"
        requestAnimationFrame(mainLoop);
    }, {once: true})
    canvas {
        border: 1px solid #000;
    }
    <div id="start">Click to focus</div>
    <canvas id="canvas"></canvas>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多