Made some fixes to touchscreen control detection:
* TouchScreenMode is activated on the first SDL2 FingerDown
* TouchScreenMode deactivates after the last finger is removed, and a
mouse event happens at least 5 ticks later.
* Touchscreen mode used to be detected based on SDL2 GetNumTouchDevices
but on a Macbook, the trackpad registers as a touch device - worse,
GetNumTouchDevices will only start returning 1 the first time some
devices are touched.
* The result was that on macOS the custom mouse cursor was drawn by
default, but on the first trackpad touch, would disappear in favor of
assuming the game is running on a touch screen device (which is not
the case).
* New method: the render engine has an IsFingerDown boolean which will
be true as long as at least one finger has registered a FingerDown
event, but not yet a FingerUp event.
* So as long as one finger is down, the mouse cursor can disappear and
then it comes back on release. This isn't perfectly ideal for pure
touch devices (ideally the cursor remains hidden until a mouse
movement without touch occurs).
* Fix collision detection to allow actors to walk up slopes smoothly, without
losing any horizontal velocity.
* Fix scrolling a level canvas so that chunks near the right or bottom edge
of the viewpoint were getting culled prematurely.
* Centralize JavaScript exception catching logic to attach Go and JS stack
traces where possible to be more useful for debugging.
* Performance: flush all SDL2 textures from memory between scene transitions
in the app. Also add a `flush-textures` dev console command to flush the
textures at any time - they all should regenerate if still needed based on
underlying go.Images which can be garbage collected.
* Rework the Story Mode UI to display level thumbnails.
* Responsive UI: defaults to wide screen mode and shows 3 levels horizontally
but on narrow/mobile display, shows 2 levels per page in portrait.
* Add "Tiny" screenshot size (224x126) to fit the Story Mode UI.
* Make the pager buttons bigger and more touchable.
* Maximize the game window on startup unless the -w option with a specific
window resolution is provided.
* Add an exception catcher that pops open a UI window showing errors that
occur in doodad scripts during gameplay.
* Shows a preview of the header of the error (character wrapped) with a
Copy button to copy the full raw text to clipboard for inspection.
* Buttons to dismiss the modal once or stop any further errors from
opening during this gameplay session (until next restart).
* Add developer shell commands to test the exception catcher:
- 'throw <message>' to throw a custom message.
- 'throw2' to stress test a "long" message.
- 'throw3' to throw a realistic message copied from an actual error.
* Scripting engine: console.log() and friends will now insert the script
VM's name in front of its messages (the filename + actor ID).
Added a new level property: Difficulty
* An enum ranging from -1, 0, 1 (Peaceful, Normal, Hard)
* Default difficulty is Normal; pre-existing levels are Normal by
default per the zero value.
Doodad scripts can read the difficulty via the new global variable
`Level.Difficulty` and some doodads have been updated:
* Azulians: on Peaceful they ignore all player characters, and on Hard
they are in "hunt mode": infinite aggro radius and they're aggressive
to all characters.
* Bird: on Peaceful they will not dive and attack any player character.
Other spit and polish:
* New Level/Level Properties UI reworked into a magicform.
* New "PromptPre(question, answer, func)" function for prompting the
user with the developer shell, but pre-filling in an answer for them
to either post or edit.
* magicform has a PromptUser field option for simple Text/Int fields
which present as buttons, so magicform can prompt and update the
variable itself.
* Don't show the _autosave.doodad in the Doodad Dropper window.
Two new tools added to the Level Editor:
* Pan Tool: left-click to scroll the level around safely.
* Text Tool: write text onto your level.
Features of the Text Tool:
* Can choose from the game's built-in fonts, size and enter the message
you want to write.
* The mouse cursor previews the text when hovered over the level.
* Click to "stamp" the text onto your level. The currently selected
color swatch will be used to color the text in.
* Adds two new fonts: Azulian.ttf and Rive.ttf that can be selected in
the Text Tool.
Some implementation notes:
* Added package native/engine_sdl.go that handles the lower-level
SDL2_TTF logic to rasterize the text into a black&white image.
* WASM not supported yet (if the game even still built for WASM);
native/engine_wasm.go stubs out the TextToImage() call with a "not
supported" error just in case.
Other changes:
* New Toolbar icons: they are 24x24 instead of 32x32 to make more room
for more tools.
* The toolbar now shows two buttons per row for a more densely packed
layout. For very narrow screen widths (< 600px) the default Vertical
Toolbar layout will use one-button-per-row to not eat too much screen
real estate.
* In the Horizontal Toolbars layout there are 2 buttons per column.