pygame collision detection question

Posted 26 February 2013 - 12:41 PM

Hi, I am creating a quite simple platformer style game. I have added collision detection so the player stops when he walks into a crate but though I've added the same thing for the top of the crate, the collision detection seem's to be ignored for a few frames and the player only stops when a bit of him is in the crate.
I'm using this code to detect the collision

Replies To: pygame collision detection question

Re: pygame collision detection question

Posted 27 February 2013 - 12:29 AM

I feel that this is still really messy and a bit twitchy but perhaps it will help you. Here I use mask collision rather than rectangle collision (rectangles are still crucial mind you). It can be done either way, but eventually you will need to understand bitmasks anyway. As last time, the images are loaded from my photobucket so the code won't work if your computer isn't online when you run it.

Re: pygame collision detection question

Posted 27 February 2013 - 03:51 PM

Masks and rectangles and surfaces are different types of objects. When you want to do pixel perfect collision in a game you will have to use masks. A mask is an array bits set to zero or one corresponding to the pixels in your image.

Mask collision produces much more accurate results (assuming your sprites aren't just rectangles, but it takes slightly longer. The error you got happened because you called a Mask method with a Surface. I create my sprite masks with:

Re: pygame collision detection question

Posted 27 February 2013 - 04:31 PM

slidon said:

What caused the weird rect collision problems?

Sorry forgot to answer that. You were probably having strange collision issues because you moved your sprite first, then checked for collisions; rather than check collisions at where your sprite was going to move to, and then move it if it was clear. Also because the sprite doesn't just move single pixels per frame you have to use while loops to check numbers lower than the initial amount it wants to move.

i.e. If you do a collision test asking if a collision will occur if your sprite falls 5 pixels and it comes back positive, you still have to test what will happen if it only falls 4 pixels. You have to continue that until either the test returns negative, or the sprite decides it can't move.

Re: pygame collision detection question

Posted 28 February 2013 - 09:38 AM

Hmmm. I think I will have to do more research to be able to create a working collision detection system with masks.
I've messed around with it but there's quite a bit that I would need more help on, will it work if I try the same thing with rects?

Re: pygame collision detection question

Posted 01 March 2013 - 01:00 AM

The same basic idea will work with rects but...

I would actually say that it is a little trickier to do with rectangles personally. The reason for this is you can make one mask that contains all the "solid" objects on the screen (although sometimes this isn't efficient) and just check collisions against that one object. If you want to do it all with rectangle collision however, you have to check collisions against every single object individually.

Regardless I rewrote my code to use rects so you can see for yourself:

Re: pygame collision detection question

Posted 01 March 2013 - 05:09 AM

I'm going to need to see more of your code than that to understand what you are doing.

My self.Obstacles attribute of class Control is a list of Block instances. The __init__ for my blocks asks for a location. I am instantiating several Blocks and placing them in a list at the same time.

The line:

self.Obstacles = [Block((400,400)),Block((300,270)),Block((150,170))]

Assigns a list of three Block instances to the attribute self.Obstacles.

Please let me see your crate class and I will attempt to figure out what is going wrong.

Edit: Do you by any chance have a file called crate that you are importing? The interpreter thinks that crate refers to a module, not a class.

Re: pygame collision detection question

Posted 01 March 2013 - 05:39 AM

Yeah a little more code would help, but assuming that is the same function I wrote, that should be checking if there is a block beneath the player, and if there is it should print. Unfortunately I can't tell if that is the case. Can you condense your code to a working example I can look at?

Re: pygame collision detection question

Posted 01 March 2013 - 05:56 AM

Yeah. I will need to see more than that. The way I wrote make_bg_mask it returns both the mask and the background image (no sense in blitting the same thing to two separate surfaces). So I don't understand why you have to blit the obstacles to it again (also the Blocks have an update function so you can just call that passing it the desired surface).