Skip to content

Refactor hitboxes, adjusted hitboxes, and optimize their usage within spatial hashes #1568

Open
@cspotcode

Description

@cspotcode

Enhancement request:

Refactor hitboxes, adjusted hitboxes, and optimize their usage within spatial hashes.

What should be added/changed?

Broad goals

  • Avoid recomputing adjusted hitbox in broad-phase collision check
    • avoid left/right/top/bottom; use new hit_box.radius instead
  • Make HitBox its own class
  • Flyweight pattern to share single HitBox across many Sprite and Texture instances
  • Defer spatial hash updates until collision detection; do not eagerly update hashes when a sprite is moved

Further explanation

Why defer spatial hash updates?

Naive code will often do something like this:

sprite.center_x = new_x
sprite.center_y = new_y
if near_gravity_well:
    sprite.center_y -= 2
sprite.radians += angular

Today, this code triggers spatial hash removal and re-add 3-4 times per frame. We should avoid that. The first modification marks the spatial hash entry as "dirty." Then collision detection will fix the hash on-demand.

Class Diagram

This is not rigorous UML

classDiagram

Sprite -- SpatialHashEntry
SpatialHashEntry -- SpatialHash
Sprite -- SpatialHash
Sprite -- HitBox
Sprite -- AdjustedHitBox
Texture -- HitBox
class Texture {
    hit_box: HitBox
    ---
}
note for Texture "Gets an auto-computed HitBox automatically, as a convenience.\nOther code may or may not choose to use it.\nSprites can borrow this hit_box or have their own."

class Sprite {
    hit_box: HitBox
    adjusted_hit_box: AdjustedHitBox
    spatial_hash_entries: list[SpatialHashEntry]
}
class HitBox {
    points: list[Point]
    radius: int -- max radius for broad-phase collision checks
    ---
    flyweight, should be immutable and shared w/Texture.  Do *not* put adjusted_hit_box here!
}
class SpatialHashEntry {
    dirty: bool
    spatial_hash: SpatialHash
    min_point: hashed Point
    max_point: hashed Point
}
class SpatialHash {
    dirty: bool
}
class AdjustedHitBox {
    TBD is this merely a list of points like today?
}

note for Sprite "Any movement of sprite sets `dirty` to true\non all the sprite's `SpatialHashEntry`s and `SpatialHash`s"

note for Sprite "Consider renaming to Collidable to decompose monolithic Sprite"

note for SpatialHash "Any collision detection routines first check `dirty`\nand update hash positions for all `dirty` entries on-demand."
Loading

What would it help with?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions