* Clean up unused msgpack code for levels and doodads
* Fix the cosmetic bug where actors in your level would display wrongly
when scrolling off the top/left edges of the screen: they used to
anchor at their own 0,0 coordinate and crop their width/height leading
to a 'scrolling' effect that didn't happen on the right/bottom edges.
* If you open a wide unbounded level like Castle.level and zoom out and
scroll left (into negative world coordinates), the level chunks
display correctly now.
* Doodad outline while dragging is now sized properly for the zoom level
* Make doodad hitboxes for Actor/Link Tool more accurate while zoomed
* Fix chunks low on the level not loading while zoomed in
* Fix Link lines drawn between doodads while zoomed - they point to the
correct position and their DrawLine calls have been optimized so they
don't lag out the level when lots of them are drawn at once.
* When the Actor Tool or Link Tool is active, mouse-over hitboxes on the
level's actors now works correctly while zoomed and scrolling in the
level.
* Regression: Level chunks don't appear outside a certain range from
origin while zoomed in.
* Regression: Actors don't draw their sprite while zoomed in, but do
when zoomed out.
* Holding Shift while pressing arrow keys in the editor will scroll by
just 1 pixel per tick to aid in precise debugging with the Zoom In/Out
feature.
* The keybinds used in canvas_editable.go to catch the arrow keys are
updated to use our nice keybind package. As a consequence, the WASD
keys will also scroll the level.
* The "d for Doodads" keybind is renamed "q" so as not to open the
Doodads window whenever scrolling right using the WASD keys.
WorldIndexAt() translates the pixel below the mouse cursor in screen
space (0,0 at top-left corner of the application window) into a world
coordinate in the level shown inside the canvas, taking into account the
canvas's position on the window and the scroll position.
It now translates correctly when zoom In or Out, so the "Abs:" mouse
position level in the status bar shows correctly.
Zoom features that are still jank:
- Scrolling while zoomed in, the chunks to the top/left start unloading
too rapidly and outpacing the scroll, eventually level is invisible
- Drawing and committing pixels to the image while zoomed in/out is
unpredictable where the pixels actually land.
- Actors in the level don't move or zoom at all.
* Got the level chunks AND the wallpaper to both scale UP and DOWN
consistently together.
* Trying to draw new pixels while zoomed in/out ends up offsetting the
pixels by 2X still. Still seems an issue between screen coordinates
and world coordinates. Zoom in 2X and try and draw a line 64px from
the corners of the screen? The committed line appropriately lands at
the 64px coord on the level data but, zoomed in, it appears 2X to the
right on the screen from where I dropped the cursor!
* When zooming OUT, the limit on number of chunks the viewport will try
and render is not increased, leaving dead space in the screen; more
chunks should render when there's room.
* The crumbly floor doodad was made 50% larger.
* New doodad: Small Key and Small Key Door. These work like the colored
doors and locks except each Small Key is consumed when it unlocks a
door. The door's appearance is of iron bars.
* The inventory HUD displays a small quantity label in the lower-right
corner of items that have a quantity, such as the Small Key. This is
done as a Canvas.CornerLabel string attribute on uix.Canvas.
* The "give all keys" cheat adds 99 Small Keys to your inventory.
* Added Feature Flag support, run doodle with --experimental to enable
all flags. Eraser Tool is behind a feature flag now.
* + and - on the top row of keyboard keys will zoom the drawing in and
out in Edit Mode. The wallpaper zooms nicely enough, but level
chunkers need work.
* A View menu is added with Zoom in/out, reset zoom, and scroll to
origin options. The whole menu is behind the Zoom feature flag.
* Update README with lots of details for fun debug mode options to play
around with.
* Implement Brush Sizes for drawtool.Stroke and add a UI to the tools panel
to control the brush size.
* Brush sizes: 1, 2, 4, 8, 16, 24, 32, 48, 64
* Add the Eraser Tool to editor mode. It uses a default brush size of 16
and a max size of 32 due to some performance issues.
* The Undo/Redo system now remembers the original color of pixels when
you change them, so that Undo will set them back how they were instead
of deleting the pixel entirely. Due to performance issues, this only
happens when your Brush Size is 0 (drawing single-pixel shapes).
* UI: Add an IntVariable option to ui.Label to bind showing the value of
an int reference.
Aforementioned performance issues:
* When we try to remember whole rects of pixels for drawing thick
shapes, it requires a ton of scanning for each step of the shape. Even
de-duplicating pixel checks, tons of extra reads are constantly
checked.
* The Eraser is the only tool that absolutely needs to be able to
remember wiped pixels AND have large brush sizes. The performance
sucks and lags a bit if you erase a lot all at once, but it's a
trade-off for now.
* So pixels aren't remembered when drawing lines in your level with
thick brushes, so the Undo action will simply delete your pixels and not
reset them. Only the Eraser can bring back pixels.
* 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.
Fixes:
* Move the call to CollidesWithGrid() inside the Canvas instead of
outside in the PlayScene.movePlayer() so it can apply to all Actors
in motion.
* PlayScene.movePlayer() in turn just sets the player's Velocity so the
Canvas.Loop() can move the actor itself.
* When keeping the player inside the level boundaries: previously it was
assuming the player Position was relative to the window, and was
checking the WorldIndexAt and getting wrong results.
* Canvas scrolling (loopFollowActor): check that the actor is getting
close to the screen edge using the Viewport into the world, NOT the
screen-relative coordinates of the Canvas bounding boxes.