'Schmup hit detection
Monkey Forums/Monkey Programming/'Schmup hit detection
| ||
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. |
| ||
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. |
| ||
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). |
| ||
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. |
| ||
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! |
| ||
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. |
| ||
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 |
| ||
Ooh circular detection. Yes please! I understand what you're doing there now. I'l give it a try, thanks! |