diff --git a/assets/process_sprites.py b/assets/process_sprites.py index a2fdcf1..b68d026 100644 --- a/assets/process_sprites.py +++ b/assets/process_sprites.py @@ -8,7 +8,7 @@ Output filename = the texture key GameScene.js loads. /opt/homebrew/bin/uv run --with pillow --with numpy python assets/process_sprites.py """ from pathlib import Path -from PIL import Image +from PIL import Image, ImageFilter import numpy as np HERE = Path(__file__).resolve().parent @@ -18,19 +18,19 @@ OUT.mkdir(parents=True, exist_ok=True) # game texture key -> (source file, size px, is_tile) TABLE = { - "floor": ("floor_parquet.png", 64, True), - "wall": ("wall_crate.png", 32, True), - "player": ("player_digger.png", 32, False), - "poser": ("enemy_poser.png", 32, False), - "nerd": ("enemy_gearnerd.png", 32, False), - "soundguy": ("enemy_soundguy.png", 32, False), - "generator": ("gen_discount_bin.png", 32, False), - "exit": ("prop_djbooth.png", 32, False), - "door": ("prop_velvet_rope.png", 32, False), - "espresso": ("pickup_espresso.png", 26, False), - "lanyard": ("pickup_lanyard.png", 26, False), - "airhorn": ("pickup_airhorn.png", 26, False), - "vinyl": ("pickup_vinyl.png", 18, False), + "floor": ("floor_parquet.png", 96, True), + "wall": ("wall_crate.png", 48, True), + "player": ("player_digger.png", 48, False), + "poser": ("enemy_poser.png", 48, False), + "nerd": ("enemy_gearnerd.png", 48, False), + "soundguy": ("enemy_soundguy.png", 48, False), + "generator": ("gen_discount_bin.png", 48, False), + "exit": ("prop_djbooth.png", 48, False), + "door": ("prop_velvet_rope.png", 48, False), + "espresso": ("pickup_espresso.png", 38, False), + "lanyard": ("pickup_lanyard.png", 38, False), + "airhorn": ("pickup_airhorn.png", 38, False), + "vinyl": ("pickup_vinyl.png", 24, False), } @@ -56,6 +56,8 @@ for key, (fname, size, is_tile) in TABLE.items(): canvas = Image.new("RGBA", (size, size), (0, 0, 0, 0)) canvas.paste(im, ((size - im.width) // 2, (size - im.height) // 2), im) im = canvas + # crisp up the LANCZOS-softened downscale + im = im.filter(ImageFilter.UnsharpMask(radius=1.2, percent=150, threshold=1)) im.save(OUT / f"{key}.png") print(f"{key:10s} <- {fname:24s} {size}px {'tile' if is_tile else 'keyed'}") diff --git a/public/sprites/airhorn.png b/public/sprites/airhorn.png index 57dd4e6..b72474f 100644 Binary files a/public/sprites/airhorn.png and b/public/sprites/airhorn.png differ diff --git a/public/sprites/door.png b/public/sprites/door.png index 5484e5f..6ee825e 100644 Binary files a/public/sprites/door.png and b/public/sprites/door.png differ diff --git a/public/sprites/espresso.png b/public/sprites/espresso.png index 5d1d7ab..7cfa15c 100644 Binary files a/public/sprites/espresso.png and b/public/sprites/espresso.png differ diff --git a/public/sprites/exit.png b/public/sprites/exit.png index 760f08e..f4fd58e 100644 Binary files a/public/sprites/exit.png and b/public/sprites/exit.png differ diff --git a/public/sprites/floor.png b/public/sprites/floor.png index 7c87aba..31c8618 100644 Binary files a/public/sprites/floor.png and b/public/sprites/floor.png differ diff --git a/public/sprites/generator.png b/public/sprites/generator.png index 1021106..acebc35 100644 Binary files a/public/sprites/generator.png and b/public/sprites/generator.png differ diff --git a/public/sprites/lanyard.png b/public/sprites/lanyard.png index a04818a..a7e92ea 100644 Binary files a/public/sprites/lanyard.png and b/public/sprites/lanyard.png differ diff --git a/public/sprites/nerd.png b/public/sprites/nerd.png index 0ac9dfe..20f0419 100644 Binary files a/public/sprites/nerd.png and b/public/sprites/nerd.png differ diff --git a/public/sprites/player.png b/public/sprites/player.png index d0605c7..c8595ca 100644 Binary files a/public/sprites/player.png and b/public/sprites/player.png differ diff --git a/public/sprites/poser.png b/public/sprites/poser.png index ebe3d6a..56cc118 100644 Binary files a/public/sprites/poser.png and b/public/sprites/poser.png differ diff --git a/public/sprites/soundguy.png b/public/sprites/soundguy.png index 6202074..2869148 100644 Binary files a/public/sprites/soundguy.png and b/public/sprites/soundguy.png differ diff --git a/public/sprites/vinyl.png b/public/sprites/vinyl.png index 9e4f03f..d7bcd56 100644 Binary files a/public/sprites/vinyl.png and b/public/sprites/vinyl.png differ diff --git a/public/sprites/wall.png b/public/sprites/wall.png index bf13e4f..5873bcc 100644 Binary files a/public/sprites/wall.png and b/public/sprites/wall.png differ diff --git a/src/GameScene.js b/src/GameScene.js index cac4ab6..a5e0e04 100644 --- a/src/GameScene.js +++ b/src/GameScene.js @@ -2,7 +2,7 @@ import Phaser from 'phaser'; import { LEVELS } from './levels.js'; import { announce, LINES } from './announcer.js'; -const TILE = 32; +const TILE = 48; const VIBE_MAX = 2000; const VIBE_DRAIN_PER_SEC = 1; // the Gauntlet heartbeat const ESPRESSO_VIBE = 500; @@ -11,12 +11,12 @@ const NERD_TOUCH_DAMAGE = 80; const SOUNDGUY_DRAIN = 10; // per 250ms tick while overlapping const GEN_HP = 3; const GEN_SPAWN_MS = 2500; // base; effective interval shrinks with density -const GEN_RANGE = 700; -const PLAYER_SPEED = 180; -const POSER_SPEED = 120; -const NERD_SPEED = 70; -const SOUNDGUY_SPEED = 55; -const VINYL_SPEED = 400; +const GEN_RANGE = 1050; // px; scaled with TILE so range stays ~same in tiles +const PLAYER_SPEED = 270; +const POSER_SPEED = 180; +const NERD_SPEED = 105; +const SOUNDGUY_SPEED = 82; +const VINYL_SPEED = 600; const VINYL_LIFE_MS = 1200; const FIRE_COOLDOWN_MS = 180; const TRAINSPOT_MS = 3000; @@ -51,7 +51,7 @@ export default class GameScene extends Phaser.Scene { this.player = this.physics.add.sprite(100, 100, 'player'); this.player.setCollideWorldBounds(true); - this.player.body.setSize(22, 22, true); // body smaller than 32px sprite -> fits corridors + this.player.body.setSize(34, 34, true); // body smaller than 48px sprite -> fits corridors // Colliders / overlaps (persistent group refs). this.physics.add.collider(this.player, this.walls); @@ -301,7 +301,7 @@ export default class GameScene extends Phaser.Scene { e.setTexture(poser ? 'poser' : 'nerd'); e.setActive(true).setVisible(true); e.body.enable = true; - e.body.setSize(22, 22, true); // body smaller than 32px sprite + e.body.setSize(34, 34, true); // body smaller than 48px sprite e.setPosition(g.x, g.y); e.setData('touch', poser ? POSER_TOUCH_DAMAGE : NERD_TOUCH_DAMAGE); e.setData('speed', poser ? POSER_SPEED : NERD_SPEED);