如何通过上键实现myGamePiece跳跃?求解决方案及原因解析
Hey there! Let's figure out why your current approaches aren't working and get that jump function smoothly running.
Why Your Original Attempts Failed
1. Setting myGamePiece.speedY = 1 did nothing
Most game gravity systems work by continuously applying downward acceleration every frame. If you only set speedY = 1 once when the key is pressed, the next frame's gravity calculation will overwrite this value (or add downward speed on top of it) before you can see any visible movement. It's like pushing a ball up for a split second, then immediately letting gravity yank it back down—you won't notice the upward push at all.
2. Reversing this.gravitySpeed didn't work
gravitySpeed is usually a cumulative value that increases over time (e.g., gravitySpeed += gravity each frame). Reversing its sign just flips the current downward speed to upward, but the next frame will add gravity again, pulling it back down immediately. Worse, if you don't have a check for whether the piece is on the ground, you might end up with weird behavior like infinite mid-air jumps or the piece bouncing uncontrollably.
Working Jump Solution (With Explanation)
Here's a reliable approach that adds proper jump physics and prevents unwanted behavior like double-jumps:
Step 1: Add a Ground State to Your Game Piece
First, give myGamePiece a property to track if it's standing on the ground—this stops players from jumping mid-air:
myGamePiece = { x: 100, y: 300, // Assume ground is at y=300 speedX: 0, speedY: 0, gravity: 0.2, // Downward acceleration gravitySpeed: 0, onGround: true, // Track if we're on solid ground draw: function() { // Your existing draw logic here } };
Step 2: Handle the Jump Input
Listen for the up arrow key press, but only trigger a jump if the piece is on the ground:
document.addEventListener("keydown", function(e) { if (e.key === "ArrowUp" && myGamePiece.onGround) { myGamePiece.speedY = -5; // Negative = upward (since canvas y increases downward) myGamePiece.onGround = false; // Lock jumping until we land } });
Step 3: Update Physics Every Frame
In your game loop (the function that runs every frame, like updateGameArea), apply gravity and handle ground collision:
function updateGameArea() { // Clear the canvas first (your existing code) // Apply gravity: increase downward speed over time myGamePiece.gravitySpeed += myGamePiece.gravity; myGamePiece.speedY += myGamePiece.gravitySpeed; // Update position myGamePiece.y += myGamePiece.speedY; // Check if we've hit the ground if (myGamePiece.y >= 300) { myGamePiece.y = 300; // Snap to ground level myGamePiece.speedY = 0; // Stop vertical movement myGamePiece.gravitySpeed = 0; // Reset gravity accumulation myGamePiece.onGround = true; // Allow jumping again } // Redraw the game piece myGamePiece.draw(); // Call the next frame (your existing requestAnimationFrame logic) }
How This Works
- When you press up, we give the piece an instant upward speed (
-5). Since canvas y-values increase downward, negative speed moves the piece up. - Gravity continuously adds downward acceleration each frame, slowing the upward movement until the piece stops, then pulls it back down.
- The
onGroundcheck ensures you can only jump when standing on solid ground, avoiding broken mid-air jumps. - When the piece hits the ground, we reset all vertical physics values to lock it in place and re-enable jumping.
内容的提问来源于stack exchange,提问作者Marckosaurus

