A simple solution might involve checking the distance between each enemy and generating a force to push them apart if they get too close. There may be cases where this strategy will fail, but if you tweak it enough it might be useful.
Here's some awful code I hacked up in the middle of the night to show you the general idea:
Quite a lot of optimization could be done. For one thing, there's no real need to take square roots. Also, there's no need to calculate the distance from B to A if you've already done A to B.
Here's some awful code I hacked up in the middle of the night to show you the general idea:
Type goblin Field x#, y# End Type Type player Field x#, y# End Type Graphics 800, 600 SetBuffer BackBuffer() Global p.player = New player p\x = GraphicsWidth()/2 p\y = GraphicsHeight()/2 For i = 1 To 50 g.goblin = New goblin g\x = Rand(0, GraphicsWidth() - 1) g\y = Rand(0, GraphicsHeight() - 1) Next While Not KeyHit(1) update() render() Flip True Cls Wend Function update() p\x = p\x + KeyDown(205) - KeyDown(203) p\y = p\y + KeyDown(208) - KeyDown(200) For g.goblin = Each goblin dx# = p\x - g\x dy# = p\y - g\y dist# = Sqr(dx*dx + dy*dy) dir# = ATan2(dx, dy) force# = 1.0 If dist < 10 Then force = 0 If dist < 5 Then force = -1.0 g\x = g\x + Sin(dir) * force g\y = g\y + Cos(dir) * force For other.goblin = Each goblin If g <> other Then dx# = other\x - g\x dy# = other\y - g\y dist# = Sqr(dx*dx + dy*dy) dir# = ATan2(dx, dy) If dist < 20 Then force# = -(10.0/dist) ;Line(g\x, g\y, g\x + Sin(dir) * force * 100, g\y + Cos(dir) * force * 100) g\x = g\x + Sin(dir) * force g\y = g\y + Cos(dir) * force EndIf EndIf Next Next End Function Function render() Color 255, 255, 255 Oval(p\x, p\y, 10, 10, True) Color 0, 255, 0 For g.goblin = Each goblin Oval(g\x, g\y, 10, 10, False) Next End Function
Quite a lot of optimization could be done. For one thing, there's no real need to take square roots. Also, there's no need to calculate the distance from B to A if you've already done A to B.