Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Fast detection of many Sprite collisions

Author
Message
Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 19th Feb 2012 16:55
Hi All,

Is there any way of detecting which Sprites collide with a specific sprite WITHOUT having to use a loop to test every sprite?

I have a large number of sprites that form a tower, hundreds of blocks that make up the tower. I am using a For / Next loop to detect if there is a collision between my 'missile' sprite and every block sprite in the tower. The For /Next loop is running through hundreds of collision tests each frame and therefore must be very slow.

I have read something about the Physics Collision Contact List that records each contact between Physic Sprites but i have no idea how to use this to simplify and therefore speed up the collision test process.

Can anyone help please...

Rudders
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 19th Feb 2012 17:58
I'm not on my computer at the moment but I would loop through the collision list which only records active collisions. Then you aren't checking every sprite just every actual collision.

If I get time later I'll post an example.

Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 19th Feb 2012 18:26
Brilliant baxslash, thanks.

This will be a very useful example for everyone.

Rudders
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 19th Feb 2012 19:38
Sorry, off to the pub now. I'll post an example in the morning!

baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 20th Feb 2012 14:31
Here you go:


Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 20th Feb 2012 15:18
Thanks a million baxslash, this will really help to speed things up considerably.

I will Gallery the first level sson as.

Cheers

Rudders
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 20th Feb 2012 16:06
No problem

Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 20th Feb 2012 17:24
Hi baxslash, just one issue.. Is it possible to exclude a sprite (the background sprite) from the collision list. I have tried using the Sprite Groups but I guess the GetContactSpriteID1() / GetContactSpriteID2() function does not filter by Groups.

Basically I am testing if my missile sprite collides with my brick sprites but at the moment I am also getting collision with the background sprite.

Cheers for any hints?

Rudders
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 20th Feb 2012 17:47 Edited at: 20th Feb 2012 17:47
Are you saying your background sprite is set up for physics? If so why?

If it has to be just add a condition:


Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 20th Feb 2012 17:57
Hi baxslash, No the background sprite is not set up for physics and of course, as you suggest, should not be involved in the physics collisions. A 'rookey' oversight on my part... Derrrrr!

I have a non-visible baseline physics sprite that creates a false bottom edge for sprites to 'sit on' rather than the bottom of the screen, it must be this sprite that is causing the probs..

Thanks again for pointing me in the right direction, hope this is all helping others that read this thread..

Rudders
Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 21st Feb 2012 12:11
Hi AGAIN...

I have modified the collision test to only look at collisions for a specific sprite (my missile sprite). I have used GetSpriteFirstContact(my missile sprite ID) and GetSpriteNextContact() but it does not work, no contacts are printed on screen? Code is:



i = getspriteFirstContact(bolder1)
while i>0
spr1 = GetContactSpriteID1()
spr2 = GetContactSpriteID2()

if spr1>0 and spr2>0 and spr1<>baseline and spr2<>baseline

if GetPhysicsCollision(spr1,spr2)>0
Print("Sprite "+str(spr1)+" is touching sprite "+str(spr2))
endif

endif

i = getspriteNextContact()
endwhile


? Rudders
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 21st Feb 2012 13:44 Edited at: 21st Feb 2012 13:45
When you are specifying the first sprite you don't need to check for it (I assume the "GetContactSpriteID1" command returns zero when used after "getSpriteFirstContact"):


Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 21st Feb 2012 14:40
Thanks again baxslash,

Yes I got the code down to this realising that spr1 in the original was no longer required, however there is still no collision info being printed to screen?

I have 120 block sprites stacked up on screen and the bolder does collide with these and the expected physics occur but it appears that the Print("Sprite "+str(bolder1)+" is touching sprite "+str(spr2)) line is not being executed.

Initially the bolder sprite is resting on the baseline sprite so there is a collision here until the bolder is fired at the blocks but I assume this will make no difference as we have the exception spr2<>basline...

Not sure what I am missing here, it is simple enough code???

Cheers again,

Rudders
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 21st Feb 2012 16:05
Ah, it seems we are using the wrong command for the ID of the second sprite. Try this:


Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 21st Feb 2012 17:17
Hi baxslash,

No sorry.. Still no printing to screen.

I had to remove the

'if GetPhysicsCollision(bolder1,spr2)>0'

to get anything to print to screen and then it only displayed:

"Sprite 10004 is touching sprite 10004" for every collision

???
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 21st Feb 2012 18:00 Edited at: 21st Feb 2012 18:01
Out of interest try this:


EDIT: If I get a chance I'll do some proper tests later. I've been a bit too busy today!

Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 21st Feb 2012 20:37
Hi baxslash,

I have modified your original test program to add a Blue square sprite and changed the code as you suggested to test for only a collision between the Blue square sprite and any other sprite.

It works fine and prints on screen the collisions correctly. I will use this code and create a Function for this type of collision testing.

Thanks baxlash for all your help with this, much appreciated Maestro...



Code below:

rem AppGameKit Application
rem

rem Landscape App
SetDisplayAspect( 4.0/3.0 )

rem create some objects
for x=1 to 10
spr = createSprite(0)
setSpriteSize(spr,5,-1)
setSpritePosition(spr,random(5,95),random(5,95))
setSpritePhysicsOn(spr,2)
next

missile = createsprite(0)
setspritesize(missile,5,-1)
setspritecolor(missile,0,0,255,255)
setspritephysicson(missile,2)



do

gosub mouse_grab:

i = getspriteFirstContact(missile)
while i>0
spr2 = GetSpriteContactSpriteID2( ) rem changed this line

if spr2>0

if GetPhysicsCollision(missile,spr2)>0
Print("Sprite "+str(bolder1)+" is touching sprite "+str(spr2))
endif

endif

i = getspriteNextContact()
endwhile

Sync()
loop

mouse_grab:
px#=getPointerX()
py#=getPointerY()
if mousejoint=0
if getPointerPressed()>0
hit=getSpriteHit(px#,py#)
if hit>0
mousejoint = createMouseJoint(hit,px#,py#,100000)
endif
endif
else
if getPointerState()>0
setJointMouseTarget(mousejoint,px#,py#)
else
deleteJoint(mouseJoint)
mousejoint=0
endif
endif
return
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 21st Feb 2012 21:26
Glad to help

It's a good idea to put code into code brackets like this (but without the full stops):
[code.]
Write your code here...
[/code.]

That way it doesn't take up too much space, looks better and people can read your posts without having to read the code.

Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 22nd Feb 2012 16:58
Hi All,

Sorry to continue the 'saga' of this fast detection of multiple sprite collision thread but I am still having real problems!

I am using the code from the 'Test' program that baxslash provided. I modified this slightly to create a Blue square sprite that is tested for collisions with the other White sqaures and it prints on screen all collisions perfectly.. See below:



However when I try to use the same 'Collision Test' code in my game the collisions with my 'bolder' sprite are not reported correctly.

I have attached the work in progress game exe for you to see the issue. Just click your mouse on the far right of the screen about half way up to fire the bolder.

Any Ideas? Here is the Collision Test code in the game:

Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 22nd Feb 2012 17:00
Sorry forget Game exe... Now attached

Rudders

Attachments

Login to view attachments
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 22nd Feb 2012 17:17
The exe won't work without the media folder and the setup.agc file.

My guess is that maybe you need to add this line before you create your "bolder":


Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 22nd Feb 2012 18:04
Hi Baxslash,

No I have added the Global as Integer but no help.

When blocks are sitting on top of the bolder the print on screen shows both the bolder sprite Id as 10 (which I set in the code) and the spr2 (collided sprite) as 10...

I have zipped the correct files and attached for you to see the level and on screen print...

Have a look if you have the time, much appreciated. I am sure when resolved, this will make a great Function for games.

Cheers Rudders

Attachments

Login to view attachments
Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 23rd Feb 2012 15:17
Hi, I have attached a screeshot of the multi-collision detection problem that shows a 'bolder' sprite sitting on top of two 'block' sprites... As you can see the print at the top of the screen is showing that sprite 10 is touching sprite 10 in both contacts?

Sprite 10 is the bolder..

Any further assistance in understanding the GetSpriteFirstContact and GetSpriteNextContact would be much appreciated...

Thansk Rudders

Attachments

Login to view attachments
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 23rd Feb 2012 16:06
Rudders, if you don't want to share your code it will be hard to solve this. In the example you have posted I don't get any collisions with sprite 10 but I do get a few with sprite 10006.

If you like you could send me the code and I'll debug it for you? My email is linked at the bottom of this post.

Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 23rd Feb 2012 16:27
Hi baxslash,

No problem with sharing code at all, here it is so far:



And many thanks for this....
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 23rd Feb 2012 17:22
Hi Rudders, a few issues with your coding. I couldn't work out the problem, looks like a bug so I've added the solution I would use.

1-You are using a goto in the loop that feeds back outside the loop. This can cause memory issues as you are effectively creating a new loop inside the existing one each time you reset your game I would suggest you just create a separate sub-routine for resetting the position of your sprites when the button is pressed.

2-You are using the same sprite numbers as image numbers IE.createSprite(floorline,floorline) This is very confusing and also can cause other issues. It's better to either manually enforce a numbering system or let AppGameKit tell you what numbers it is going to use IE.floorline = createSprite(floorImage)

Try the code attached and read through my changes:


Rudders
12
Years of Service
User Offline
Joined: 20th Jan 2012
Location: Oxfordshire UK
Posted: 23rd Feb 2012 18:09
Thanks baxslash,

Very much appreciated and thanks for the coding advice. I will use the new collison testing and build the game around this.

hope I can return a favour to you one day (perhaps not coding but maybe Graphics or Music.... My son is a Music Producer)

Regards

Rudders
baxslash
Valued Member
Bronze Codemaster
17
Years of Service
User Offline
Joined: 26th Dec 2006
Location: Duffield
Posted: 23rd Feb 2012 18:15
Any time!

Glad to help

I might take you up on that offer one day but I enjoy helping people too.

Login to post a reply

Server time is: 2024-05-02 07:11:13
Your offset time is: 2024-05-02 07:11:13