JavaScript游戏双按键码同时控制两物体持续移动问题求助
Hey there! I totally get where you're coming from—getting two objects to move continuously with simultaneous key presses can feel tricky if you're relying on one-off keydown events. The core issue with most initial attempts is that keydown events have a built-in delay and don't track sustained presses well. Instead, we need to track which keys are actively held down, then update positions in a steady game loop.
Let's break this down step by step with a working example:
Step 1: Track Key Press States
First, we'll create an object to keep track of which keys are pressed at any moment. We'll update this object on keydown and keyup events to reflect real-time input:
const keys = {}; // Mark keys as pressed when held down document.addEventListener('keydown', (e) => { keys[e.key.toLowerCase()] = true; }); // Mark keys as released when let go document.addEventListener('keyup', (e) => { keys[e.key.toLowerCase()] = false; });
Step 2: Set Up Your Game Objects
We'll define our objects' initial positions, movement speed, and grab their DOM elements (you can tweak the HTML/CSS to match your game's style):
<div class="game-container"> <div id="object1" class="game-object"></div> <div id="object2" class="game-object"></div> </div> <style> .game-container { position: relative; width: 600px; height: 400px; border: 2px solid #333; margin: 20px; } .game-object { position: absolute; width: 50px; height: 50px; } #object1 { background: blue; top: 50px; left: 50px; } #object2 { background: red; top: 150px; left: 150px; } </style>
const object1 = document.getElementById('object1'); const object2 = document.getElementById('object2'); // Track positions and movement speed let obj1Pos = { x: 50, y: 50 }; let obj2Pos = { x: 150, y: 150 }; const moveSpeed = 2; // Adjust this value for faster/slower movement
Step 3: Build the Game Loop
Using requestAnimationFrame, we'll create a steady loop that checks our key states every frame and updates the objects' positions accordingly. This ensures smooth, continuous movement even when multiple keys are pressed at the same time:
function gameLoop() { // Update Object 1 (WASD controls) if (keys['w']) obj1Pos.y -= moveSpeed; if (keys['s']) obj1Pos.y += moveSpeed; if (keys['a']) obj1Pos.x -= moveSpeed; if (keys['d']) obj1Pos.x += moveSpeed; // Update Object 2 (Arrow key controls) if (keys['arrowup']) obj2Pos.y -= moveSpeed; if (keys['arrowdown']) obj2Pos.y += moveSpeed; if (keys['arrowleft']) obj2Pos.x -= moveSpeed; if (keys['arrowright']) obj2Pos.x += moveSpeed; // Apply position changes to DOM elements object1.style.left = `${obj1Pos.x}px`; object1.style.top = `${obj1Pos.y}px`; object2.style.left = `${obj2Pos.x}px`; object2.style.top = `${obj2Pos.y}px`; // Repeat the loop for the next frame requestAnimationFrame(gameLoop); } // Start the loop! gameLoop();
Why This Works
- Key State Tracking: Instead of reacting to single keydown events, we're checking which keys are actively held every frame. This avoids the delay between initial keydown and repeated events, and lets us handle multiple presses simultaneously.
- Steady Game Loop:
requestAnimationFramesyncs with the browser's refresh rate, ensuring smooth movement without jank or stutter. - Independent Control: Each object's movement logic is separate, so pressing keys for both objects won't interfere with each other's movement.
Bonus Tips
- Add boundary checking to keep objects inside your game area (e.g.,
if (obj1Pos.x < 0) obj1Pos.x = 0to prevent it from moving left outside the container). - Adjust
moveSpeedto make objects move faster or slower based on your game's needs. - If you're using a canvas instead of DOM elements, the logic stays the same—just update the canvas drawing code instead of modifying DOM styles.
内容的提问来源于stack exchange,提问作者Matthew Demeter

