From 0921385f859139d18d5c87bd91a2be384eeaae4d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Jul 2026 18:29:48 +0000 Subject: [PATCH 1/2] Stabilize collision timing and axis resolution --- game.js | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/game.js b/game.js index 4ce6302..c5c60f0 100644 --- a/game.js +++ b/game.js @@ -679,6 +679,9 @@ class CommitRunnerScene extends Phaser.Scene { // Update charge bar display this.updateChargeBar(); + // Scroll the world to the left before collision checks + this.scrollWorld(deltaSeconds); + // Check if player is on the ground FIRST (before handling jumps) this.checkGrounded(); @@ -691,9 +694,6 @@ class CommitRunnerScene extends Phaser.Scene { // Recharge jump when grounded this.handleJumpCharge(deltaSeconds); - // Scroll the world to the left - this.scrollWorld(deltaSeconds); - // Update score based on distance survived this.score += deltaSeconds * 10; // 10 points per second this.scoreText.setText(`Score: ${Math.floor(this.score)}`); @@ -987,6 +987,8 @@ class CommitRunnerScene extends Phaser.Scene { let standingOnObstacle = false; let highestObstacleY = screenHeight; + const overlapBias = 0.5; + // Check ONLY green obstacles for (let i = 0; i < this.greenObstacles.length; i++) { const obstacle = this.greenObstacles[i]; @@ -1011,24 +1013,28 @@ class CommitRunnerScene extends Phaser.Scene { const overlapTop = playerBottom - obstacleTop; const overlapBottom = obstacleBottom - playerTop; - const minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom); + const minHorizontalOverlap = Math.min(overlapLeft, overlapRight); + const minVerticalOverlap = Math.min(overlapTop, overlapBottom); + const prefersVerticalResolution = minVerticalOverlap <= (minHorizontalOverlap + overlapBias); - // Push out in direction of smallest overlap - if (minOverlap === overlapTop && this.player.body.velocity.y >= 0) { - // Landing on top - if (obstacleTop < highestObstacleY) { - highestObstacleY = obstacleTop; - standingOnObstacle = true; + // Push out with stable axis selection (prefer vertical when nearly equal) + if (prefersVerticalResolution) { + if (overlapTop <= overlapBottom && this.player.body.velocity.y >= 0) { + // Landing on top + if (obstacleTop < highestObstacleY) { + highestObstacleY = obstacleTop; + standingOnObstacle = true; + } + } else if (this.player.body.velocity.y <= 0) { + // Hit bottom (jumping into ceiling) + this.player.y = obstacleBottom + (GRID.TILE_SIZE / 2); + this.player.setVelocityY(0); } - } else if (minOverlap === overlapBottom && this.player.body.velocity.y <= 0) { - // Hit bottom (jumping into ceiling) - this.player.y = obstacleBottom + (GRID.TILE_SIZE / 2); - this.player.setVelocityY(0); - } else if (minOverlap === overlapLeft) { + } else if (overlapLeft <= overlapRight) { // Hit from left side this.player.x = obstacleLeft - (GRID.TILE_SIZE / 2); this.player.setVelocityX(0); - } else if (minOverlap === overlapRight) { + } else { // Hit from right side this.player.x = obstacleRight + (GRID.TILE_SIZE / 2); this.player.setVelocityX(0); From defeb1d7dbd91c0c0c6aa02b83fbdaf5ecd9cef7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Jul 2026 18:31:45 +0000 Subject: [PATCH 2/2] Fix collision ordering and stable overlap resolution --- game.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/game.js b/game.js index c5c60f0..63168c4 100644 --- a/game.js +++ b/game.js @@ -57,7 +57,8 @@ const GAME_CONFIG = { CHARGE_JUMP_MIN_VELOCITY: -400, // Minimum jump velocity CHARGE_JUMP_MAX_VELOCITY: -700, // Maximum jump velocity when fully charged CHARGE_JUMP_HORIZONTAL_VELOCITY: 150, // Horizontal velocity boost when fully charged - CHARGE_JUMP_SQUASH_HEIGHT: 0.1 // Squash to 10% of original height + CHARGE_JUMP_SQUASH_HEIGHT: 0.1, // Squash to 10% of original height + COLLISION_AXIS_BIAS: 0.5 // Pixel bias for vertical resolution on near-tie overlaps }; class CommitRunnerScene extends Phaser.Scene { @@ -987,7 +988,7 @@ class CommitRunnerScene extends Phaser.Scene { let standingOnObstacle = false; let highestObstacleY = screenHeight; - const overlapBias = 0.5; + const overlapBias = GAME_CONFIG.COLLISION_AXIS_BIAS; // Check ONLY green obstacles for (let i = 0; i < this.greenObstacles.length; i++) { @@ -1015,10 +1016,10 @@ class CommitRunnerScene extends Phaser.Scene { const minHorizontalOverlap = Math.min(overlapLeft, overlapRight); const minVerticalOverlap = Math.min(overlapTop, overlapBottom); - const prefersVerticalResolution = minVerticalOverlap <= (minHorizontalOverlap + overlapBias); + const shouldResolveVertically = minVerticalOverlap <= (minHorizontalOverlap + overlapBias); // Push out with stable axis selection (prefer vertical when nearly equal) - if (prefersVerticalResolution) { + if (shouldResolveVertically) { if (overlapTop <= overlapBottom && this.player.body.velocity.y >= 0) { // Landing on top if (obstacleTop < highestObstacleY) {