Make Collision Detection more active wrt. actors #15
Labels
No Milestone
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: SketchyMaze/doodle#15
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Currently the Collision Detection in Doodle is handled in two phases:
This two-phase system isn't suitable for fast-moving actors. For example, trapdoors have a ~6 pixel region that they define for themselves as "solid" and should prevent actors from crossing through; but if an actor was moving more than 6 pixels per tick they might completely phase through the solid part before the Trapdoor is notified about the movement. And so the moving actor clips straight through the trapdoor, even though the doodad itself is a large 72px square, because the OnCollide handler isn't called until after the movement step.
Instead, implement a more active collision detection where actors' OnCollide handlers can be called as part of the Phase 1 collision detection.
The collision code is currently kept in a sub-package that deals only with the collision math and has no access to any of the game's structures. So a callback-based method may be used to work around it.
Current function signature:
Update the function to also accept an
actorBoxes map[string]render.Rect
so the game can pass in all of the actor boxes (excluding thed
Actor being moved), and a function to call when a collision has occurred. The map can be keyed off the actors' ID strings in the level (UUIDs by default).The onBoxCollision callback would have a function signature like:
The calling function (uix/actor_collision.go) can then be pinged every pixel-of-movement when actors are overlapping and call the OnCollide handlers and have a more precise method to detect collision between actors.
The CollidesWithGrid() function will handle the "moving back" of the actor in case the collision is protested, the same as it does when the actor bumps against a solid wall in the level.
The Phase 2 collision detection above might be obsoleted by this, making collision a single phase operation.
Took a different approach.
Stage 1 is left unchanged. Actors move and collide with the level geometry and we note their Original and New Location.
In Stage 2, we re-trace the steps of each actor who's moved. For each step, if the actor (player) intersects with another actor (doodad) we call its OnCollide handler but pass a new property
Settled: false
(we're calling this handler rapidly as the player passes into the actor during their movement this tick).OnCollide handlers can
return false
if they want to block the player. As Stage 2 retraces your steps, it will drop you in the Last Good Location before an actor protested your movement.Finally (Stage 3) if the player is still intersecting actors, their OnCollide handler is called one last time with
Settled: true
to indicate "movement and collision checking is done."Doodad Scripts should check for
e.Settled === true
before they fire off actions based on the collision (i.e. broadcast messages to linked doodads, change their state, etc.)