Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 24 additions & 17 deletions game.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -679,6 +680,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();

Expand All @@ -691,9 +695,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)}`);
Expand Down Expand Up @@ -987,6 +988,8 @@ class CommitRunnerScene extends Phaser.Scene {
let standingOnObstacle = false;
let highestObstacleY = screenHeight;

const overlapBias = GAME_CONFIG.COLLISION_AXIS_BIAS;

// Check ONLY green obstacles
for (let i = 0; i < this.greenObstacles.length; i++) {
const obstacle = this.greenObstacles[i];
Expand All @@ -1011,24 +1014,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 shouldResolveVertically = 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 (shouldResolveVertically) {
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);
Expand Down