8.0 KiB
Adding real art
Nothing in the code needs to change to swap in real art. src/util/assetManifest.js
lists every image the game expects, with an exact path. PreloadScene tries to
load each one; if the file doesn't exist (or fails to load), it falls back to a
synthesized colored placeholder shape instead. Drop a real PNG at the exact path
below, refresh the page, and it's used automatically.
Where files go
All paths are relative to the project root (/home/brianfertig/git/monsterplex/).
The folders already exist and are currently empty.
| key | path | size used in-game | shape | notes |
|---|---|---|---|---|
bus_chassis |
assets/sprites/bus_chassis.png |
340 x 128 | rectangle | see "Bus" below |
bus_wheel |
assets/sprites/bus_wheel.png |
104 x 104 | circle | one image, used for both wheels |
kid_idle |
assets/sprites/kid_idle.png |
56 x 56 | circle | passenger while aboard the bus |
kid_ejected |
assets/sprites/kid_ejected.png |
56 x 56 | circle | passenger after being thrown off |
bg_far |
assets/backgrounds/bg_far.png |
tiled, 512 x 1080 native | - | slowest-scrolling parallax layer (sky/distant) |
bg_mid |
assets/backgrounds/bg_mid.png |
tiled, 512 x 1080 native | - | mid-speed parallax layer |
bg_near |
assets/backgrounds/bg_near.png |
tiled, 512 x 1080 native | - | fastest-scrolling parallax layer (closest) |
icon_kid |
assets/ui/icon_kid.png |
48 x 48 | - | small HUD "kids aboard" icon, top-left |
favicon |
assets/favicon.png |
32 x 32 | - | browser tab icon - see caveat below |
"Size used in-game" is the size the game actually displays the image at
(setDisplaySize), not a requirement on the source file's resolution - see
"Resolution" below.
These numbers are the game's current 1920x1080 resolution (WORLD_SCALE = 2
in src/config.js) - if that changes again, every size in this table changes
with it (same ratios, just re-derive from that one constant).
Bus
bus_chassis.pngandbus_wheel.png, transparent background (PNG alpha).- The bus always faces right (nose/front toward positive x - the direction it drives at level start) and there's no left/right flip when reversing, so draw the chassis facing right.
- The chassis's rectangle is the physics hitbox (with rounded corners baked in by the physics engine, not the art). Keep the bus's silhouette roughly filling a 340x128 box so the visual matches where it actually collides.
bus_wheel.pngis used for both wheels (front and rear) - same image, no separate left/right variant needed. It's a real physics body, so it visually spins as the bus drives; a plain hubcap/circle reads better at speed than fine detail.- If you want a bus with different proportions (longer, taller, etc.) than
340x128, tell me the size you want art at - that number is also the physics
body size in
src/config.js(BUS.chassisWidth/chassisHeight), so it needs a matching code change, not just a differently-shaped image.
Kids
kid_idle.png(aboard) andkid_ejected.png(mid-air after being thrown off) - two separate images, swapped automatically when a kid is ejected.- Physics shape is a circle, but the image itself renders as a full square at 56x56 - draw the character centered in a square canvas with transparent padding around them rather than filling every corner, or they'll look like they're poking out past their own collision circle.
kid_ejectedis a good place to show some "yikes" energy (arms out, startled face, etc.) since it only appears for the ~2 seconds after a kid gets thrown clear.
Parallax backgrounds
bg_far/bg_mid/bg_nearare rendered as horizontally tiling strips (TileSprite), not single stretched images - whatever you supply repeats sideways as the camera scrolls.- Make the left and right edges match so the seam is invisible when it tiles (or design something patternable, like scattered clouds/hills on a transparent background).
- far/mid/near are layered back-to-front and scroll at different speeds for depth (far moves slowest, near moves fastest) - a plain sky for far, hills or treeline silhouettes for mid, and closer foreground detail for near works well.
- Native resolution isn't locked to 512x1080 the way the bus/kid sprites are - a wider or taller source image just changes how often the tile repeats, so use whatever gives a clean seamless loop.
Level select map
The level select screen is a map per campaign: a themed background with a road ribbon snaking between level nodes, a finish flag past the last node, and a banner plate behind the campaign title. There is one of each of these per campaign, plus the shared node/flag/plate sprites.
Important convention for node/flag/plate sprites: they are drawn centered on a 960x540 transparent canvas (1920x1080 at 2x) and displayed full-frame at a position, so where you draw the art on that canvas is where it appears in the game. Keep the subject centered in the frame, or it will show up shifted.
| key | path | subject size (design units) | notes |
|---|---|---|---|
campaign01_bg |
assets/backgrounds/campaign01_bg.png |
full frame 960x540 | Campaign 1 "Sunny Suburbs" background |
campaign02_bg |
assets/backgrounds/campaign02_bg.png |
full frame 960x540 | Campaign 2 "Dusk Junction" background |
map_node |
assets/ui/map_node.png |
~450x450 badge centered | completed level node (number badge) |
map_node_current |
assets/ui/map_node_current.png |
~450x450 badge centered | the next level to play ("start here" node) |
map_node_locked |
assets/ui/map_node_locked.png |
~450x450 badge centered | locked level node |
map_finish |
assets/ui/map_finish.png |
~440x560 centered | flag past the last node |
map_campaign_tag |
assets/ui/map_campaign_tag.png |
~1440x300 plate centered near top | banner behind the campaign title text (title is drawn on top at y≈82/540) |
Per-campaign notes:
campaign0X_bg.png- full 960x540 (or 2x) scene, no transparency needed. The top ~150 units are behind the title plate, so keep that area fairly quiet. Leave the bottom 60% open road/grass for the path to sit on. The node positions live insrc/data/levels/index.js(positions, or auto-layout viasrc/data/levels/positioning.js) - check where your nodes will land before you paint, and keep that corridor readable.- Node states share one silhouette (same size/placement) in three moods:
map_node(cleared, e.g. blue with the level number),map_node_current(the one to play next, e.g. gold - this one gets a gentle idle pulse),map_node_locked(greyed out, e.g. a padlock). If you want the badge to be a different size than ~450 units, also adjustBADGE_FRAC_OF_FRAMEinsrc/util/mapArt.js. map_finish.png- the flag sits just past the last node, on the road, so a base/mound that grounds it looks best; don't rely on the bottom of the 960x540 canvas being the ground line.map_campaign_tag.png- a plate/banner with empty center space; the game writes"<name> x/y cleared"on top of it in dark ink (#1a1f29), so the middle should be a light, uncluttered fill.
Favicon
favicon.pngis the one asset without a placeholder fallback for its actual purpose - the browser tab icon comes from a plain<link>tag inindex.html, not from Phaser's loader, so until a real file exists atassets/favicon.pngthe browser just shows its default icon (nothing broken, just nothing shown).
Resolution
Supply art at the "size used in-game" from the table above, or a clean multiple of it (2x/3x) for a crisper look on high-DPI screens - everything gets scaled to the table's size regardless of the source file's actual pixel dimensions, so it won't come in stretched or huge, but a very different aspect ratio than the target box will get squashed/stretched to fit.
Testing
Just refresh the browser tab after dropping files into assets/ - no build
step, no server restart needed (unless the static server itself isn't
running yet, in which case see README.md).