03 June 2018, 07:29 | #1 |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
Quickest way to test collisions
What's the quickest way to test collisions between objects?
Using DoColl/PColl is incredibly fast if you poke one sprite against 1 single bitplane. This is great if you don't have to test what collided with what (example: every enemy has an outline drawn with color 1, if touches player, player dies. You don't need to know what touched the player, you just need to know an enemy touched it and now he's dead ). Preliminary tests I made indicate this is faster than comparing a Word with a Word 5 times. Now if you have a space ship that can shoot up to 8 bullets at the same time on screen, and you have 30 enemies on screen, each one will die if hit by one of the bulelts.... what's the fastest way to do that test? I am really scratching my head trying to figure out a fast way, anything I try seems to be slow as hell. (I am badly used to work with super fast CPUs, coding for a 7mhz one is very challenging ). If anyone can could come up with ideas (if possibly ,please, with examples ), I'll be very grateful. |
03 June 2018, 10:24 | #2 |
Registered User
Join Date: Oct 2008
Location: Finland
Posts: 643
|
This thread discusses bounding box collision methods, maybe it can help:
http://eab.abime.net/showthread.php?t=91067 Interesting question, I will follow this thread. |
03 June 2018, 17:22 | #3 |
Banana
Join Date: Jul 2016
Location: Darmstadt
Posts: 1,213
|
I've been pondering the same thing. Comparing everything with everything else is O(n²) - exponential computing cost. Probably there's some optimisation to be done by first filtering by general area (if all the bullets are in the left and all the enemies are on the right there can't be a collision).
I wonder whether some sort of binary search would speed it up, at the cost of maintaining the enemy list in a sorted order? |
03 June 2018, 17:37 | #4 | |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
Quote:
This thread had LOTS of considerations I had never even thought about, like using pointers So far I've been trying to check collisions using the same method Daedalus suggested that, with 4 ifs. Problem is, 8 bullets * 30 enemies * 4 ifs = 960 possible checks. It's a shitload of stuff to check on the worst case scenario, this alone will take a whole frame. I guess I'll post there to see if I can get any help. Thank you for point me out for that thread. |
|
03 June 2018, 17:41 | #5 | |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
Quote:
I was thinking about trying to use some kind of grid structure... my screen is 320x256. I divide this maybe ine 10x8 32 pixels cells. Bullet check collisions only against enemies on the surrounding cells it is right now. But I just can't wrap my mind on how to make something like this work anyway. |
|
03 June 2018, 19:17 | #6 |
Registered User
Join Date: Nov 2004
Location: Germany
Posts: 629
|
well, then each bullet shall have grid position coordinates px,py
The enemy ship has, as well, px,py Grid - coordinates. So when you save the coordinates for each bullet, you check if bullets px/py coordinate are near ship px,py , something like pseudo code: Code:
if abs(bulletPX(x)-EShip_px(x))<=2 and Abs(BulletPY(y)-EShip_Py(x))<=2 then check for colision endif Last edited by Dan; 03 June 2018 at 19:26. |
03 June 2018, 19:22 | #7 |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
I'm already doing 2 checks there, before I move to the other 4 checks. Ok, this may halve the overload, but still seems to be a lot, isn't it? And it's 2 more checks for each grid check that is "validated"
Well, I can do just one grid check on the Y axis first and only if this one is valid, I go for the X axis check. This may give me up to 50% less overload. EDIT: Also I can't think of any way of keeping the grid position without doing a division ( px = x / cellsize) , and from what I hear, divisions are slow as hell. |
03 June 2018, 19:27 | #8 |
Phone Homer
Join Date: Jun 2006
Location: 5150
Posts: 5,773
|
Can't you just do
If Bullet X,Y = Player X,Y Then Hit ? |
03 June 2018, 19:29 | #9 | |
Registered User
Join Date: Nov 2004
Location: Germany
Posts: 629
|
Quote:
Yeah. On the today's PC this wouldn't be a prob, but on the amiga ... |
|
03 June 2018, 19:32 | #10 |
Phone Homer
Join Date: Jun 2006
Location: 5150
Posts: 5,773
|
If your going to have to increase your Bullet X,Y anyway you might a well just add an If it's hardly cpu intensive.
But Blitz probably has some kind of Bob collision check anyway. Most Amiga games probably use blocking anyway for the Map the Enimies everything. |
03 June 2018, 19:32 | #11 |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
|
03 June 2018, 19:34 | #12 |
Phone Homer
Join Date: Jun 2006
Location: 5150
Posts: 5,773
|
If bullet X+0 or If Bullet X+16 or If Bullet Y+0 etc etc
|
03 June 2018, 19:34 | #13 | |
Banana
Join Date: Jul 2016
Location: Darmstadt
Posts: 1,213
|
Quote:
Pseudo code : Code:
For each bullet b do Enemy e = BinarySearch(L, bullet.x) If e != null then CheckBounds(e, bullet) End if Next Assuming blitz's list sort function is something sensible, it's quick to sort an already sorted (or mostly sorted) set. |
|
03 June 2018, 19:38 | #14 | |||
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
Quote:
Quote:
Quote:
I have no idea of what you meant here. |
|||
03 June 2018, 19:38 | #15 |
Phone Homer
Join Date: Jun 2006
Location: 5150
Posts: 5,773
|
Ok but a grid could work well like you say that way you don't won't have to check them all however I assume most Games know exactly where on screen everything is at all times incase Bullet hits wall etc
I don't know enough about Blitz can you not do If Baddy BOB 1 collide and IF Bullet 6 BOB collide. |
03 June 2018, 19:40 | #16 |
Registered User
Join Date: Nov 2004
Location: Germany
Posts: 629
|
Or you divide the Main Loop into 2 sections/part.
The First section/part does the movement The Second section/part does the collision check something like Code:
a=1 ;main loop do a=-a if a=1 PlayerMovement() Enemymovement() Playerbullets() Enemybullets() else CollisionCheck() endif flip ; or whatever the blitz uses to redraw the screen. loop Last edited by Dan; 03 June 2018 at 19:47. |
03 June 2018, 19:40 | #17 | |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
Quote:
I probably have to write a sort method myself. |
|
03 June 2018, 19:47 | #18 |
Phone Homer
Join Date: Jun 2006
Location: 5150
Posts: 5,773
|
And don't check them all at once check them 1 by 1 in your loop
If Bullet X[N]+0 or BulletX[N]+16 = Ship[N]+0 or Ship[N]+16 then = Hit N=N+1 Loop So 30.checks after 30 Loop etc |
03 June 2018, 19:56 | #19 |
Banana
Join Date: Jul 2016
Location: Darmstadt
Posts: 1,213
|
You'd need nested loops, which gives exponential running times. The cpu will be mostly checking things that are nowhere near each other. There must be a better way.
|
03 June 2018, 20:02 | #20 |
Phone Homer
Join Date: Jun 2006
Location: 5150
Posts: 5,773
|
Yeah it's a bit of a waste but 4 checks or up to 15 maybe max per Game Loop is hardly CPU intensive I think a ZX80 could do it.
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
SetCol/DoColl-How to test collisions with different sprites against different colors? | Shatterhand | Coders. Blitz Basic | 1 | 12 January 2017 18:51 |
Quickest code.... | Galahad/FLT | Coders. Asm / Hardware | 10 | 01 January 2017 17:23 |
[REQ:ASM] Sprite collisions basics | jman | Coders. Tutorials | 5 | 03 September 2011 00:07 |
What is the quickest way | Doc Mindie | support.WinUAE | 6 | 17 October 2007 21:15 |
Disable Sprite Collisions | DeAdLy_cOoKiE | Retrogaming General Discussion | 4 | 24 March 2006 17:56 |
|
|