From 0c8e13d6309afe33ee15f56b4ad1075a373a95c2 Mon Sep 17 00:00:00 2001 From: "Kacper Kostka (aider)" Date: Sat, 5 Apr 2025 18:29:24 +0200 Subject: [PATCH] feat: Improve player sprite rendering with pixelation and animation fixes --- js/entities/player.js | 22 +++++++++++++--------- js/main.js | 4 ++-- js/render.js | 3 +++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/js/entities/player.js b/js/entities/player.js index 9bae22f..4b8351e 100644 --- a/js/entities/player.js +++ b/js/entities/player.js @@ -94,10 +94,10 @@ class Player extends Entity { // Only change animation frame at fixed intervals to prevent blinking if (this.animationTimer >= this.animationSpeed) { - // Update animation frame if moving - if (this.isMoving || Math.abs(this.vy) > 0.1) { + // Only update animation if actually moving horizontally + if (Math.abs(this.vx) > 0.005 && this.isMoving) { this.currentFrame = (this.currentFrame + 1) % this.frameCount; - } else { + } else if (!this.isMoving || Math.abs(this.vx) < 0.005) { // Reset to standing frame when not moving this.currentFrame = 0; } @@ -107,7 +107,7 @@ class Player extends Entity { } // Only update direction when it actually changes to prevent flipping - if (this.vx !== 0) { + if (Math.abs(this.vx) > 0.005) { const newDirection = this.vx > 0 ? 1 : -1; if (newDirection !== this.lastDirection) { this.direction = newDirection; @@ -121,13 +121,15 @@ class Player extends Entity { const screenY = (this.y - offsetY) * PIXEL_SIZE; if (this.sprite && this.sprite.complete) { + // Set pixelated rendering (nearest neighbor) + ctx.imageSmoothingEnabled = false; + ctx.save(); ctx.translate(screenX, screenY); - // Use fixed dimensions based on the actual sprite size - // Maintain the 32x32 aspect ratio - const spriteDisplayWidth = 32 * (PIXEL_SIZE / 2); // Scale based on pixel size - const spriteDisplayHeight = 32 * (PIXEL_SIZE / 2); + // Use smaller dimensions for the sprite + const spriteDisplayWidth = 24 * (PIXEL_SIZE / 2); // Smaller sprite (was 32) + const spriteDisplayHeight = 24 * (PIXEL_SIZE / 2); // Smaller sprite (was 32) // Flip horizontally based on direction if (this.direction < 0) { @@ -140,11 +142,13 @@ class Player extends Entity { this.sprite, this.currentFrame * this.frameWidth, 0, this.frameWidth, this.frameHeight, - -spriteDisplayWidth / 2, -spriteDisplayHeight / 2 + 4, // Offset to align feet with ground + -spriteDisplayWidth / 2, -spriteDisplayHeight / 2 + 2, // Reduced offset for smaller sprite spriteDisplayWidth, spriteDisplayHeight ); ctx.restore(); + // Reset image smoothing for other rendering + ctx.imageSmoothingEnabled = true; // Draw collision box in debug mode if (debugMode) { diff --git a/js/main.js b/js/main.js index 3c77c39..afac328 100644 --- a/js/main.js +++ b/js/main.js @@ -102,8 +102,8 @@ function spawnPlayer() { PIXEL_SIZE = 6; // Create player at specified coordinates - // Position adjusted for proper sprite alignment - player = createEntity(ENTITY_TYPES.PLAYER, 229, 50); + // Position adjusted for proper sprite alignment with smaller sprite + player = createEntity(ENTITY_TYPES.PLAYER, 229, 45); // Focus camera on player worldOffsetX = player.x - (canvas.width / PIXEL_SIZE / 2); diff --git a/js/render.js b/js/render.js index bedd6dd..d0827ad 100644 --- a/js/render.js +++ b/js/render.js @@ -6,6 +6,9 @@ function render() { // Clear the canvas ctx.clearRect(0, 0, canvas.width, canvas.height); + // Set pixelated rendering for the entire canvas + ctx.imageSmoothingEnabled = false; + // Draw animated sky background renderSky();