Commit Graph

10 Commits

Author SHA1 Message Date
08e65c32b5 Overhaul the Platformer Physics System
* Player character now experiences acceleration and friction when
  walking around the map!
* Actor position and movement had to be converted from int's
  (render.Point) to float64's to support fine-grained acceleration
  steps.
* Added "physics" package and physics.Vector to be a float64 counterpart
  for render.Point. Vector is used for uix.Actor.Position() for the sake
  of movement math. Vector is flattened back to a render.Point for
  collision purposes, since the levels and hitboxes are pixel-bound.
* Refactor the uix.Actor to no longer extend the doodads.Drawing (so it
  can have a Position that's a Vector instead of a Point). This broke
  some code that expected `.Doodad` to directly reference the
  Drawing.Doodad: now you had to refer to it as `a.Drawing.Doodad` which
  was ugly. Added convenience method .Doodad() for a shortcut.
* Moved functions like GetBoundingRect() from doodads package to
  collision, where it uses its own slimmer Actor interface for just the
  relevant methods it needs.
2020-04-04 21:00:32 -07:00
3cb99ad5f8 New (Colored) Locked Door Doodads
* Revamped the sprites for the four colored locked doors. They now have
  a side-view profile perspective rather than a front view.
* Doors open facing the left or the right based on what direction the
  colliding actor approached it from.
2020-04-02 21:43:41 -07:00
b4922edf5d Doodad Tool: Add Tag Support for edit-doodad
* The `doodad edit-doodad` command now allows setting custom key/value
  tags in doodad files, for extra data storage useful to their scripts.
* Colored keys and doors now store a `color` tag with the appropriate
  color so that their scripts don't have to parse their Title to find
  that information.
* Trapdoors now store a `direction` tag to hold the direction the door
  is facing.
2020-01-02 22:12:20 -08:00
6af60f1128 Improve Collision Detection: More Active w/ Actors
* Improve the collision detection algorithm so that Actor OnCollide
  scripts get called more often WHILE an actor is moving, to prevent a
  fast-moving actor from zipping right through the "solid" hitbox and
  not giving the subject actor time to protest the movement.
* It's implemented by adding a `Settled` boolean to the OnCollide event
  object. When the game is testing out movement, Settled=false to give
  the actor a chance to say "I'm solid!" and have the moving party be
  stopped early.
* After all this is done, for any pair of actors still with overlapping
  hitboxes, OnCollide is called one last time with Settled=true. This is
  when the actor should run its actions (like publishing messages to
  other actors, changing state as in a trapdoor, etc.)
* The new collision detection algorithm works as follows:
  * Stage 1 is the same as before, all mobile actors are moved and
    tested against level geometry. They record their Original and New
    position during this phase.
  * Stage 2 is where we re-run that movement but ping actors being
    intersected each step of the way. We trace the steps between
    Original and New position, test OnCollide handler, and if it returns
    false we move the mobile actor to the Last Good Position along the
    trace.
  * Stage 3 we run the final OnCollide(Settled=true) to let actors run
    actions they wanted to for their collide handler, WITHOUT spamming
    those actions during Stage 2.
* This should now allow for tweaking of gravity speed and player speed
  without breaking all actor collision checking.
2019-07-16 21:07:38 -07:00
99eab19c5b Pub/Sub Messages Between Linked Actors (JavaScript)
* Implement the pub/sub message passing system that lets the JavaScript
  VM of one actor (say, a Button) send messages to other linked actors
  in the level (say, an Electric Door)
* Buttons now emit a "power(true)" message while pressed and
  "power(false)" when released. Sticky Buttons do not release and so do
  not send the power(false) message.
* Electric Doors listen for the "power" event and open or close
  themselves based on the boolean value received.
* If a Sticky Button receives power and is currently pressed down, it
  will pop back up (reset to "off" position) and notify its linked
  actors that they have lost power too. So if a Sticky Button held an
  Electric Door open, and another Button powers the Sticky Button, it
  would pop back up and also close the Electric Door.
2019-06-23 17:34:11 -07:00
567b3158f1 Minor Tweaks 2019-06-08 17:02:28 -07:00
1523deeb9c Return False: Solid Collision Between Actors
* Implement the handler code for `return false` when actors are
  colliding with each other and wish to act like solid walls.
* The locked doors will `return false` when they're closed and the
  colliding actor does not have the matching key.
* Add arbitrary key/value storage to Actors. The colored keys will set
  an actor value "key:%TITLE%" on the one who touched the key before
  destroying itself. The colored doors check that key when touched to
  decide whether to open.
* The trapdoor now only opens if you're touching it from the top (your
  overlap box Y value is 0), but if you touch it from below and the door
  is closed, it acts like a solid object.
2019-05-28 21:43:30 -07:00
a2e1bd1ccb Improve OnCollide Doodad Script Handling
* Events.OnCollide now receives a CollideEvent object, which makes
  available the .Actor who collided and the .Overlap rect which is
  zero-relative to the target actor. Doodad scripts can use the .Overlap
  to see WHERE in their own box the other actor has intruded.
  * Update the LockedDoor and ElectricDoor doodads to detect when the
    player has entered their inner rect (since their doors are narrower
    than their doodad size)
  * Update the Button doodads to only press in when the player actually
    touches them (because their sizes are shorter than their doodad
    height)
  * Update the Trapdoor to only trigger its animation when the board
    along its top has been touched, not when the empty space below was
    touched from the bottom.
* Events.OnLeave now implemented and fires when an actor who was
  previously intersecting your doodad has left.
* The engine detects when an event JS callback returns false.
  Eventually, the OnCollide can return false to signify the collision is
  not accepted and the actor should be bumped away as if they hit solid
  geometry.
2019-05-06 22:58:09 -07:00
a73dec9f31 Doodad Animations Managed In-Engine
* Add animation support for Doodad actors (Play Mode) into the core
  engine, so that the Doodad script can register named animations and
  play them without managing all the details themselves.
  * Doodad API functions on Self: AddAnimation, PlayAnimation,
    StopAnimation, IsAnimating
* CLI: the `doodad convert` command will name each layer after the
  filename used as the input image.
* CLI: fix the `doodad convert` command creating duplicate Palette
  colors when converting a series of input images into a Doodad.
2019-05-06 15:30:43 -07:00
258b2eb285 Script Timers, Multiple Doodad Frames
* CLI: fix the `doodad convert` command to share the same Palette when
  converting each frame (layer) of a doodad so subsequent layers find
  the correct color swatches for serialization.
* Scripting: add timers and intervals to Doodad scripts to allow them to
  animate themselves or add delayed callbacks. The timers have the same
  API as a web browser: setTimeout(), setInterval(), clearTimeout(),
  clearInterval().
* Add support for uix.Actor to change its currently rendered layer in
  the level. For example a Button Doodad can set its image to Layer 1
  (pressed) when touched by the player, and Trapdoors can cycle through
  their layers to animate opening and closing.
  * Usage from a Doodad script: Self.ShowLayer(1)
* Default Doodads: added scripts for all Buttons, Doors, Keys and the
  Trapdoor to run their various animations when touched (in the case of
  Keys, destroy themselves when touched, because there is no player
  inventory yet)
2019-04-18 18:15:05 -07:00