If sprite sensors were set up based on your "partitions" u could know what sprites were in each, as u are already doing but without "each enemy" keeping track of anything. I dont know if there are predictors in box2d (our version) that help (further) efficiency. This is theory. If i get time, i'll try to write a demo. But Im sure your method is working great. It just stirred the theory back up for me and am curious about your thoughts on it/if u'd tried it
back with a quick demo:
// Project: Sensors
// Created: 2021-07-09
// By: Virtual Nomad
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Sensors" )
SetWindowSize( 1280,720, 0 )
SetWindowAllowResize( 1 )
// set display properties
SetVirtualResolution( 1280,720)
SetOrientationAllowed( 1, 1, 1, 1 )
SetSyncRate( 30, 0 )
SetScissor( 0,0,0,0 )
UseNewDefaultFonts( 1 )
SetPhysicsGravity(0,0)
GLOBAL PathX# = 100.0
GLOBAL Range# = 50.0
GLOBAL SpawnRate# = 1.0
GLOBAL NextSpawn# : NextSpawn# = Timer()
Type Tower
ID as Integer
TXT as Integer
EndType
GLOBAL Towers as Tower []
For x = 1 to 5
AddTower(x)
Next x
GLOBAL Enemies as Integer []
SetPhysicsDebugOn()
do
If GetRawKeyState(27) then End
If NextSpawn# < Timer()
SpawnEnemy()
NextSpawn# = Timer() + SpawnRate#
Endif
If Enemies.Length > -1 then EnemyMarch()
CheckTowers()
Print( ScreenFPS() )
Sync()
loop
Function CheckTowers()
For x = 0 to Towers.Length
ThisTower = Towers[x].ID
Enemies$ = ""
If GetSpriteFirstContact(ThisTower)
Enemies$ = "" `Enemies$ + STR(GetSpriteContactSpriteID2())
Repeat
Enemies$ = Enemies$ + CHR(10) + STR(GetSpriteContactSpriteID2())
Until GetSpriteNextContact() = 0
EndIf
SetTextString(Towers[x].TXT, Enemies$ )
Next x
EndFunction
Function AddTower(x)
This as Tower
This.ID = CreateDummySprite()
SetSpriteSize(This.ID,30,30)
SetSpritePositionByOffset(This.ID, 200.0 + (x*100.0), 120.0)
SetSpritePhysicsOn(This.ID, 1) : SetSpriteShapeCircle(This.ID,0,0,Range#)
SetSpritePhysicsIsSensor(This.ID,1)
This.TXT = CreateText("Tower" + STR(x))
SetTextPosition(This.TXT, 200.0 + (x*100),170.0)
SetTextSize(This.TXT,32) : SetTextAlignment(This.TXT,1)
Towers.Insert(This)
EndFunction
Function SpawnEnemy()
This = CreateSprite(0)
SetSpriteSize(This,16,16)
SetSpritePosition(This,100,80)
SetSpritePhysicsOn(This,2)
SetSpriteShapeCircle(This,0,0,8.0)
Enemies.Insert(This)
EndFunction
Function EnemyMarch()
For x = Enemies.Length to 0 Step -1
SetSpritePhysicsVelocity(Enemies[x], 30, 0)
`SetSpriteX(Enemies[x], GetSpriteX(Enemies[x]) + 1)
If GetSpriteX(Enemies[x]) > 800.0
DeleteSprite(Enemies[x])
Enemies.Remove(x)
Endif
Next x
EndFunction
(continually setting Velocity = 30 just to show that you can change that anytime - ie, follow a path)
it works but not quite like i expected it to where anything passing through the shape of the sensor HAS to be under Box2d control. IE, i thought i could march the enemies thru with normal SetSpritePosition but the sensor does not sense Contact or Collision when i do. Hence why i gave the enemies Velocity to march.
i know its not quite the same implementation of your spatial partitions but the functionality is? IE, "what's within" or "what's around" (this defined shape). and since Box2d already has some "magic" under the hood, along with being multi-threaded, i figure it SHOULD be max efficiency/performance?