pythonarcade / arcade

Easy to use Python library for creating 2D arcade games.
http://arcade.academy
Other
1.68k stars 320 forks source link

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

Open cspotcode opened 1 year ago

cspotcode commented 1 year ago

Enhancement request:

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

What should be added/changed?

Broad goals

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."

What would it help with?

Cleptomania commented 1 year ago

@cspotcode Is any of this still applicable with the new hitbox system?

cspotcode commented 1 year ago

Yeah, the performance improvements from #1601 were never merged, and the concepts are still relevant to the new hitbox system.

I can link to some descriptions from Discord:

https://discord.com/channels/458662222697070613/458662458198982676/1111322355785011321

https://discord.com/channels/458662222697070613/1085299745116917851/1117975229185134635