For Loop Problems.

Blitz3D Forums/Blitz3D Programming/For Loop Problems.

WERDNA(Posted 2009) [#1]
Hey, I'm having a problem with some enemy types that I use
a For Loop to control. This is in a 2D game by the way.

I first created the Enemy Type.
Then I generated about 100 of them.
Then I use a For Loop to control them all.
What I need to do, is to check each enemy,
to see if he has overlapped with any of the
other enemies, and then do stuff if they
have overlapped.

How do I check to see if several enemies of the same
type, in the same For loop, have overlapped with each
other? I tried creating a different set of types that move
along with the enemies, and then I could check to se
if the enemies overlapped with Those, but it doesn't

Work out so well :(
A For loop with over 100
guys, running inside Another
For loop with over 100 guys,
really slows things down ba-
-dly. Thanks if anyone can
answer this, its

really driving me nuts, lol.


RifRaf(Posted 2009) [#2]
well, the double loop is the only straight forward way.. especially if you are doing pixel perfect checking. but you dont need two types
For s.ship = each ship
    for check.ship=each ship
       if checkoverlap(s.ship,check.ship)=true then dosomthing()
    next
next


If you dont care about pixel perfect then you could simply make a world
psuedo grid. Lets call it World(1000,1000) where each space represents
the size of a character.. for this example lets say characters are 10x10
units big.

Then each psuedo grid can have a value that represents how many entities
are within it.

When a ship moves you check the grid to see if other entities are already
there if so.. they collided.

heres some pseudo code, for the pseudo grid


Const GridSize=10
Dim WorldGrid(1000,1000,3) ; the 3 is there because we have 3 collision types.. so 3 cells per grid

Type Ship
 Field entity
 Field collision_type%
 Field OldGridx%,OldGridy%
End Type



Function Shiphasmoved(s.ship)
;the ship is moving, lets make sure we flag the world grid with our location
 NewGridx=Int(Floor(EntityX(s\ent)/gridsize))
 NewGridy=Int(Floor(EntityY(s\ent)/gridsize))
 ;see if we are now in a new grid
 If newgridx<>s\oldgridx Or newgridy<>s\oldgridy Then 
 ;we moved.. so remove our flag from old grid space
 WorldGrid(s\oldgridx,s\oldgridy,s\collision_type)=WorldGrid(s\oldgridx,s\oldgridy,s\collision_type)-1
 ;ideally if you do things right per entity, this should never drop below 0.. 
 If WorldGrid(s\oldgridx,s\oldgridy,s\collision_type)<0 Then WorldGrid(s\oldgridx,s\oldgridy,s\collision_type)=0
 ;ok we removed old location.. put in new one
 s\oldgridx=newgridx 
 s\oldgridy=newgridy 
 WorldGrid(s\oldgridx,s\oldgridy,s\collision_type)=WorldGrid(s\oldgridx,s\oldgridy,s\collision_type)+1
End Function 

Function TestCollision(s.ship)
 ;now check to see if anythine else is there
 If WorldGrid(s\oldgridx,s\oldgridy,1)<>0 Then  
	;do somthing if you want to act on colliding with object type 1
 EndIf
 If WorldGrid(s\oldgridx,s\oldgridy,2)<>0 Then  
 	;do somthing if you want to act on colliding with object type 2
 EndIf
 If WorldGrid(s\oldgridx,s\oldgridy,3)<>0 Then  
 	;do somthing if you want to act on colliding with object type 3
 EndIf
End Function 





WERDNA(Posted 2009) [#3]
Wow thanks!

That should work perfectly.
I didn't know that I could use the same type in a double For loop like
that.

I like the grid idea as well. I'll try both, and see which works faster.
Because I am aiming for speed in this game, and have to execute
things as quickly as possible.


Thanks for your help!

WERDNA


RifRaf(Posted 2009) [#4]
Well the more ships you have the faster the psuedo grid will be by comparison, as you can do it per entity not a loop within a loop

You could tweak it, to get collisions a little more accurate.. simply by making the grid size say 1/3rd the size of the ship but having the ship effect (or place itself in ) a 3x3 block of grid spaces.. wich would be slightly larger than the ship in actual space used, but would work on smaller steps (more accurate)