* New doodads: Switches.
* They come in four varieties: wall switch (background element, with
"ON/OFF" text) and three side-profile switches for the floor, left
or right walls.
* On collision with the player, they flip their state from "OFF" to
"ON" or vice versa. If the player walks away and then collides
again, the switch flips again.
* Can be used to open/close Electric Doors when turned on/off. Their
default state is "off"
* If a switch receives a power signal from another linked switch, it
sets its own state to match. So, two "on/off" switches that are
connected to a door AND to each other will both flip on/off when one
of them flips.
* Update the Level Collision logic to support Decoration, Fire and Water
pixel collisions.
* Previously, ALL pixels in the level were acting as though solid.
* Non-solid pixels don't count for collision detection, but their
attributes (fire and water) are collected and returned.
* Updated the MenuScene to support loading a map file in Play Mode
instead of Edit Mode. Updated the title screen menu to add a button
for playing levels instead of editing them.
* Wrote some documentation.
* Add new pkg/drawtool with utilities to abstract away drawing actions
into Strokes and track undo/redo History for them.
* The freehand Pencil tool in EditorMode has been refactored to create a
Stroke of Shape=Freehand and queue up its world pixels there instead
of directly modifying the level chunker in real time. When the mouse
button is released, the freehand Stroke is committed to the level
chunker and added to the UndoHistory.
* UndoHistory is (temporarily) stored with the level.Level so it can
survive trips to PlayScene and back, but is not stored as JSON on
disk.
* Ctrl-Z and Ctrl-Y in EditorMode for undo and redo, respectively.
* In WASM build, user levels and doodads are written to localStorage
using their userdir path as keys (".config/levels/test.level")
* LoadFile() and WriteFile() for both Levels and Doodads interact with
the localStorage for WASM build instead of filesystem for desktop.
* userdir.ListLevels() and ListDoodads() for WASM scan the localStorage
keys for file names.
* userdir.ResolvePath() now works for WASM (previously was dummied out),
checks for the file in localStorage.
* Use `go-bindata` to embed built-in doodads and levels directly into
the Doodle binary. `make bindata` produces the bindata source file.
* Add `FromJSON()` method to Levels and Doodads to load objects from
JSON strings in memory (for bindata built-ins or WASM ajax requests)
* Update file loading functions to check the embedded bindata files.
* pkg/config.go#EditFile:
* Supports editing a level from bindata (TODO: remove this support)
* If the "assets/levels/%(simple-name.level)" exists in bindata,
edits that drawing.
* No such support for editing built-in doodads.
* WASM has no filesystem access to edit files except built-in
levels (yet)
* pkg/doodads#ListDoodads:
* Prepends built-in doodads from bindata to the returned list.
* WASM: no filesystem access so gets only the built-ins.
* pkg/doodads#LoadFile:
* Checks built-in bindata store first for doodad files.
* WASM: tries an HTTP request if not found in bindata but can go no
further if not found (no filesystem access)
* pkg/filesystem#FindFile:
* This function finds a level/doodad by checking all the places.
* If the level or doodad exists in bindata built-in, always returns
its system path like "assets/doodads/test.doodad"
* WASM: always returns the built-in candidate path even if not found
in bindata so that ajax GET can be attempted.
* pkg/level#ListSystemLevels:
* New function that lists the system level files, similar to the
equivalent doodads function.
* Prepends the bindata built-in level files.
* WASM: only returns the built-ins (no filesystem support)
* Desktop: also lists and returns the assets/levels/ directory.
* pkg/level#LoadFile:
* Like the doodads.LoadFile, tries from built-in bindata first, then
ajax request (WASM) before accessing the filesystem (desktop)
* Menu Scene: TODO, list the built-in levels in the Load Level menu.
This feature will soon go away when WASM gets its own storage for user
levels (localStorage instead of filesystem)
Since SDL2 is using in-memory bitmaps the same as Canvas engine, the
function names of the render.Engine interface have been cleaned up:
* NewTexture(filename, image) -> StoreTexture(name, image)
Create a new cached texture with a given name.
* NewBitmap(filename) -> LoadTexture(name)
Recall a stored texture with a given name.
* level.Chunk.ToBitmap uses simpler names for the textures instead of
userdir.CacheFilename file-like paths.
* Refactor texture caching in render.Engine:
* New interface method: NewTexture(filename string, image.Image)
* WASM immediately encodes the image to PNG and generates a JavaScript
`Image()` object to load it with a data URI and keep it in memory.
* SDL2 saves the bitmap to disk as it did before.
* WASM: deprecate the sessionStorage for holding image data. Session
storage methods panic if called. The image data is directly kept in
Go memory as a js.Value holding an Image().
* Shared Memory workaround: the level.Chunk.ToBitmap() function is where
chunk textures get cached, but it had no access to the render.Engine
used in the game. The `pkg/shmem` package holds global pointers to
common structures like the CurrentRenderEngine as a work-around.
* Also shmem.Flash() so Doodle can make its d.Flash() function
globally available, any sub-package can now flash text to the screen
regardless of source code location.
* JavaScript API for Doodads now has a global Flash() function
available.
* WASM: Handle window resize so Doodle can recompute its dimensions
instead of scaling/shrinking the view.
* Add RGBA color blending support in WASM build.
* Initial texture caching API for Canvas renderer engine. The WASM build
writes the chunk caches as a "data:image/png" base64 URL on the
browser's sessionStorage, for access to copy into the Canvas.
* Separated the ClickEvent from the MouseEvent (motion) in the WASM
event queue system, to allow clicking and dragging.
* Added the EscapeKey handler, which will abruptly terminate the WASM
application, same as it kills the window in the desktop build.
* Optimization fix: I discovered that if the user clicks and holds over
a single pixel when drawing a level, repeated Set() operations were
firing meaning multiple cache invalidations. Not noticeable on PC but
on WebAssembly it crippled the browser. Now if the cursor isn't moving
it doesn't do anything.
* Refactor the event system in the WASM render engine to serialize the
async JavaScript events into a channel, so that queued events are read
off serially in the main loop similar to SDL. This fixes keyboard
input issues, altho if you type really fast some input keys get lost.
* Fix the EditorUI not showing the correct palette baked into the level
and only showing the default. This was tricky because the palette UI
can only be configured at setup time but not updated later.
* Add a new default palette for the Blueprint theme. Blueprint has a
dark background, so the palette colors should be bright. This palette
is chosen when you start a map with the blueprint wallpaper.
* Add a background Canvas to the MenuScene. In the "New Level" screen,
the background canvas will update to show the wallpaper settings
you've chosen as a preview of the level theme you're about to create.
* Debug mode: no longer enables the DebugOverlay (F3) by default, but
does now insert the current FPS counter into the window title bar.
* ui.Frame: set a default "mostly transparent" BG color so the frame
background doesn't render as white.
* Add the MenuScene which will house the game's main menus.
* The "New Level" menu is first to be added.
* UI lets you pick Page Type and Wallpaper using radio buttons.
* Page Type: Unbounded, Bounded (default), No Negative Space, Bordered
* Fix bugs in uix.Canvas to fully support all these page types.
* On the Doodads tab is the Link button to enter the Link Tool.
* Click Link, then click the 1st doodad on the level, then click the 2nd
doodad to complete the link.
* The actors struct in the Level holds the link IDs for each actor.
* Add a Red Azulian as a test for mobile enemies.
* Its A.I. has it walk back and forth, changing directions when it
comes up against an obstacle for a few moments.
* It plays walking animations and can trigger collision events with
other Doodads, such as the Electric Door and Trapdoor.
* Move Gravity responsibility to the doodad scripts themselves.
* Call `Self.SetGravity(true)` to opt the Doodad in to gravity.
* The canvas.Loop() adds gravity to any doodad that has it enabled.
* Add some encoding/decoding functions for binary msgpack format for
levels and doodads. Currently it writes msgpack files that can be
decoded and printed by Python (mp2json.py) but it can't re-read from
the binary format. For now, levels will continue to write in JSON
format.
* Add filesystem abstraction functions to the balance/ package to search
multiple paths to find Levels and Doodads, to make way for
system-level doodads.
* Improve the `doodad convert` command to convert a series of input
images into multiple Frames of a Doodad:
`doodad convert frame1.png frame2.png frameN.png output.doodad`
* Add the initial round of dev-asset sprites for the default Doodads:
* Button, Button-TypeB and Sticky Button
* Red, Blue, Green and Yellow Locked Doors and Keys
* Electric Door
* Trapdoor Down
* Add dev-assets/palette.json that defines our default doodad color
palette. Eventually the JSON will be used by the `doodad` tool to give
the layers meaningful names.