feat: Improve player sprite rendering with pixelation and animation fixes

This commit is contained in:
Kacper Kostka (aider) 2025-04-05 18:29:24 +02:00
parent f592c74412
commit 0c8e13d630
3 changed files with 18 additions and 11 deletions

View File

@ -94,10 +94,10 @@ class Player extends Entity {
// Only change animation frame at fixed intervals to prevent blinking // Only change animation frame at fixed intervals to prevent blinking
if (this.animationTimer >= this.animationSpeed) { if (this.animationTimer >= this.animationSpeed) {
// Update animation frame if moving // Only update animation if actually moving horizontally
if (this.isMoving || Math.abs(this.vy) > 0.1) { if (Math.abs(this.vx) > 0.005 && this.isMoving) {
this.currentFrame = (this.currentFrame + 1) % this.frameCount; 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 // Reset to standing frame when not moving
this.currentFrame = 0; this.currentFrame = 0;
} }
@ -107,7 +107,7 @@ class Player extends Entity {
} }
// Only update direction when it actually changes to prevent flipping // 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; const newDirection = this.vx > 0 ? 1 : -1;
if (newDirection !== this.lastDirection) { if (newDirection !== this.lastDirection) {
this.direction = newDirection; this.direction = newDirection;
@ -121,13 +121,15 @@ class Player extends Entity {
const screenY = (this.y - offsetY) * PIXEL_SIZE; const screenY = (this.y - offsetY) * PIXEL_SIZE;
if (this.sprite && this.sprite.complete) { if (this.sprite && this.sprite.complete) {
// Set pixelated rendering (nearest neighbor)
ctx.imageSmoothingEnabled = false;
ctx.save(); ctx.save();
ctx.translate(screenX, screenY); ctx.translate(screenX, screenY);
// Use fixed dimensions based on the actual sprite size // Use smaller dimensions for the sprite
// Maintain the 32x32 aspect ratio const spriteDisplayWidth = 24 * (PIXEL_SIZE / 2); // Smaller sprite (was 32)
const spriteDisplayWidth = 32 * (PIXEL_SIZE / 2); // Scale based on pixel size const spriteDisplayHeight = 24 * (PIXEL_SIZE / 2); // Smaller sprite (was 32)
const spriteDisplayHeight = 32 * (PIXEL_SIZE / 2);
// Flip horizontally based on direction // Flip horizontally based on direction
if (this.direction < 0) { if (this.direction < 0) {
@ -140,11 +142,13 @@ class Player extends Entity {
this.sprite, this.sprite,
this.currentFrame * this.frameWidth, 0, this.currentFrame * this.frameWidth, 0,
this.frameWidth, this.frameHeight, 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 spriteDisplayWidth, spriteDisplayHeight
); );
ctx.restore(); ctx.restore();
// Reset image smoothing for other rendering
ctx.imageSmoothingEnabled = true;
// Draw collision box in debug mode // Draw collision box in debug mode
if (debugMode) { if (debugMode) {

View File

@ -102,8 +102,8 @@ function spawnPlayer() {
PIXEL_SIZE = 6; PIXEL_SIZE = 6;
// Create player at specified coordinates // Create player at specified coordinates
// Position adjusted for proper sprite alignment // Position adjusted for proper sprite alignment with smaller sprite
player = createEntity(ENTITY_TYPES.PLAYER, 229, 50); player = createEntity(ENTITY_TYPES.PLAYER, 229, 45);
// Focus camera on player // Focus camera on player
worldOffsetX = player.x - (canvas.width / PIXEL_SIZE / 2); worldOffsetX = player.x - (canvas.width / PIXEL_SIZE / 2);

View File

@ -6,6 +6,9 @@ function render() {
// Clear the canvas // Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
// Set pixelated rendering for the entire canvas
ctx.imageSmoothingEnabled = false;
// Draw animated sky background // Draw animated sky background
renderSky(); renderSky();