'Schmup hit detection

Monkey Forums/Monkey Programming/'Schmup hit detection

Sensei(Posted 2014) [#1]
Guys, I'm pondering a change in my game for the bullet hit detection.
Basically, at the moment I'm using a simple method of if the bullet is within the image x and y range of the enemy graphic(ie, imageWidth and imageHeight), it counts as a hit.(simply put).
Long story short, I've implement some fancypants sine/cosine maths to the enemy movements and even though I've accounted for that in the detection logic, I still sometimes seem to be getting bullets going through the enemy and not being detected as a hit, even though I can visually see it.

So, due to this, I was thinking of using the readpixel method on the enemies, but I'm concerned about the additional CPU and resources hit this method will take, as it seems to be far more intensive.
Have any of you done the readpixel method before and found a good compromise for speed as well as pixel perfection hit detections?

Thanks in advance.


Paul - Taiphoz(Posted 2014) [#2]
if your visually seeing your sprites overlap and not detecting a collision then your logic is out, dry drawing some additional debug info, when dealing with distance or oval>oval collisions I often render a green or red circle at the position the logic thinks the ship or bullet is at as well as rendering the sprite where the render method thinks its at, you will find that your logic has a different idea on where the ship or object is from where you think it should be.

This is probably down to the order in which your code is executing it could be that your logic is just wrong, or that your collision check is being called in the wrong order or out of sync with your rendering code.


Sensei(Posted 2014) [#3]
Thanks Paul.
I was thinking of doing just that tonight, ie drawing a rectangle or something over the sprite image to compare where it thinks it is to what I see. Like you said, I suspect my logic is possibly wrong (very likely, hoho) but I'd still be curious to know about the readpixels method and how much more intensive that becomes. (even if I fix this issue, I might need/want to use readpixels in a future game where I need exact hit detection, since sprites aren't square but have several transparent bits that shouldn't account for hits - consider a platform game where the platforms are slanted etc).


Paul - Taiphoz(Posted 2014) [#4]
the problem with readpixels is that the more pixels you need to check the slower everything gets and the less active chexk your going to be able to have, one solution to this is to check only a few key points around your sprite cutting down the number of pixel reads to a bare minimum, I guess it all depends on the number of game objects your going to be checking collisions against and or how frequently your going to test for those collisions.

Another option once you fix your logic may be to do small rect>rect collision checks and map your sprites out with a selection of small rects for example if your sprite is a ship have a long rect to cover its main body and then two smaller rects to cover its wings, making sure to fit them inside the sprite but in such a way to make sure that you have the coverage that you require.

I know for my shooter's I'm currently only checking distance or circle to circle collisions, and even tho its not pixel perfect its more than good enough.


Sensei(Posted 2014) [#5]
Yeah I've been finding I don't really need pixel perfect collison detection either, which is why it worked so great up until now. I just need to fix the flaws in my logic.
Doing rect>rect collisions could be painful as each sprite is animated and sometimes the visual differences between frames are sufficient to make that idea not work too well.
I like the idea of circular collision detection but frankly I'm not even sure how one would go about doing that.
Back on the Amiga I can use xor collision detection which is good as that does pixel perfect stuff but with Monkey that doesn't exist. :)

You have brought up one good point though. Collisions are detected every frame, in my case, 60 FPS, but that might be overkill too. I could add a basic counter to only do detections when the counter hits a certain amount, so you could say every 6th frame, so only 10 times a second instead. I will keep that in mind if it comes down to that, thanks!


Gerry Quinn(Posted 2014) [#6]
Don't use ReadPixel(). If you must do that kind of pixel-testing, you should emulate it in arrays without involving the graphics subsystem IMO.


Paul - Taiphoz(Posted 2014) [#7]
Sensei is this any use to you ?

'summary: return the distnace between two x,y postions
Function emDistance:Float(p1x:Float,p1y:Float,p2x:Float,p2y:Float)
		Local Distance:Float
		Distance = Sqrt( ((p1x-p2x)*(p1x-p2x)) + ((p1y-p2y)*(p1y-p2y)) )
		Return Distance
End Function

'summary: return true if both circles are overlapping each other.
Function emCirclesOverlap:bool(p1x:Float,p1y:Float,p1r:float,p2x:Float,p2y:Float,p2r:float)
	if emDistance(p1x,p1y,p2x,p2y)<=p1r+p2r then
		return True
	else
		return false
	endif
End Function



Sensei(Posted 2014) [#8]
Ooh circular detection. Yes please! I understand what you're doing there now. I'l give it a try, thanks!