Outstanding stuff... Long time business programmer but wanted to dabble a bit in gaming and this content is really well done. Thanks for taking the time.
Hi, I just discovered your channel, very good videos there :) What you should do for performance when using mask is: -First check for a rectangle collision -If there is one check masks -else do nothing
+Yvon LE GALL I was under the belief that the pygame.mask.overlap function did that for you. I'll run some timings on it tomorrow and see. If it does do it automatically then they'll be a tiny lag between the two mask rectangle's overlapping and not overlapping because when they do overlap the function will have to do a bitwise collision check on it. If it doesnt check rectangular collision first then the timings will be the same either way.
Yes you are absolutely right my friend! There is a significant performance increase when rect detection is done first. Thank you for bringing that to my attention :)
Hey, happy to hear I was right (I had a little doubt after your comment). Can you please tell me which module you use for test? I remember using one but I can't find his name :/
+Sausage Fingers Hi Sausage, good question. You can bit instead of creating a list rectangles you need to create a list of images with it's corresponding mask. For that I'd recommend defining a class called sprite which contains the image and the mask. Hope that helps 👍
Ok Duck-Billed, I've run two tests, each at 100,000,000 cycles. The first test was this: result = bx1 > ox2 or bx2 < ox1 or by1 > oy2 or by2 < oy1 bxy1/2 are the blob rectangle coords and oxy1/2 are the obstacles. In 100,000,000 cycles this method took 17.6408686894s The second test was: result = obstacle_mask.overlap(blob_mask, offset) # offset has been calculated before entering the cycles In 100,000,000 cycles this method took 40.4696911013s. In the test no other calculations took place within the 100,000,000 cycle loop. So to answer your question, the rectangle based collision detection is the faster than the mask method by 129.4% :O Thanks for the question, I enjoyed that!
Quite clearly, one requires 4 calculations and the other requires x pixels * y pixels of calculations (worst case). Computationally, one is significantly lighter than the other.
Wouldn't it be faster to use rectangle collision to detect when two objects are near each other and only when that is true run the mask overlap detection? probably would speed it up a bit.
How do I implement this into your sprite class? I don't quite get how to implement this anywhere else. EDIT: You said somewhere about instead of creating a list of rectangles, to create a list of images. How would I go about doing that?
thanks for the nice explanation. I also saw the sprite animation video which you made and was helpful. I've been looking for collision with animated sprites and this doesn't work for them as the sprite keeps changing ( as we store the sprites in a list and keep changing them). Can you help me with this?
+Ravi Kiran an option is to split the spritesheet up after loading into individual sprites and create a mask from each and store in a list so spritesheet ID also indexes the list of masks.
It basically converts an image to the current display surfaces pixel format and preserves the alpha channel (transparency). Blitting converted surfaces is faster than blitting non-converted surfaces.
That's because pygame's mask object doesn't have the get_rect() method. To get the dimensions of the image you need to call get_rect for a surface object like this: img = pygame.image.load("image.png").convert_alpha() img_rect = img.get_rect() img_width = img_rect.width img_height = img_rect.height img_width, img_height = img_rect.size hope that helps :)
Can I create a mask of a surface where it only masks one colour in the surface? And can I change the colour using the mask? I know this video is 3 years old but I hope someone answers
Thank you for this video I had trouble understanding what masks are by just reading through the docs!
This one worked magic for me! I was using distance and rect collisions only! thanks!
Outstanding stuff... Long time business programmer but wanted to dabble a bit in gaming and this content is really well done. Thanks for taking the time.
Hi, I just discovered your channel, very good videos there :)
What you should do for performance when using mask is:
-First check for a rectangle collision
-If there is one check masks
-else do nothing
+Yvon LE GALL I was under the belief that the pygame.mask.overlap function did that for you. I'll run some timings on it tomorrow and see. If it does do it automatically then they'll be a tiny lag between the two mask rectangle's overlapping and not overlapping because when they do overlap the function will have to do a bitwise collision check on it. If it doesnt check rectangular collision first then the timings will be the same either way.
Yes you are absolutely right my friend! There is a significant performance increase when rect detection is done first. Thank you for bringing that to my attention :)
Hey, happy to hear I was right (I had a little doubt after your comment). Can you please tell me which module you use for test? I remember using one but I can't find his name :/
Yeah sure it's
from timeit import default_timer as timer
start = timer()
[code]
end = timer()
duration = end - start
:)
Ok, I'll use that, thank you and keep doing those worked and good qualities videos :)
Can I combine this with the sprites sheet class you did?
+Sausage Fingers Hi Sausage, good question. You can bit instead of creating a list rectangles you need to create a list of images with it's corresponding mask. For that I'd recommend defining a class called sprite which contains the image and the mask. Hope that helps 👍
Firstly great video :) secondly which quicker the rectangle collision detection or this one? thanks
+Duck-Billed Platypus erm, not sure! I'll test and let you know :D
Ok Duck-Billed,
I've run two tests, each at 100,000,000 cycles. The first test was this:
result = bx1 > ox2 or bx2 < ox1 or by1 > oy2 or by2 < oy1
bxy1/2 are the blob rectangle coords and oxy1/2 are the obstacles. In 100,000,000 cycles this method took 17.6408686894s
The second test was:
result = obstacle_mask.overlap(blob_mask, offset) # offset has been calculated before entering the cycles
In 100,000,000 cycles this method took 40.4696911013s.
In the test no other calculations took place within the 100,000,000 cycle loop.
So to answer your question, the rectangle based collision detection is the faster than the mask method by 129.4% :O
Thanks for the question, I enjoyed that!
Cool thanks. I guess both have there advantages :)
Quite clearly, one requires 4 calculations and the other requires x pixels * y pixels of calculations (worst case). Computationally, one is significantly lighter than the other.
Wouldn't it be faster to use rectangle collision to detect when two objects are near each other and only when that is true run the mask overlap detection? probably would speed it up a bit.
How can I get the distance between the sprite and the mask's closest collision point?
How do I implement this into your sprite class? I don't quite get how to implement this anywhere else.
EDIT: You said somewhere about instead of creating a list of rectangles, to create a list of images. How would I go about doing that?
For Sprite class, I think spritecollide method is good..
Excellent videos. Thank you for your time and effort. It helped!!!!
thanks for the vid. is there a way to make a mask for a pygame.draw though? I have been searching for a bit but couldn't find any way to do it
i'm looking for that too
Thank you, very well expained !!!
Obrigadão, my thanks for your very much
thanks for the nice explanation. I also saw the sprite animation video which you made and was helpful. I've been looking for collision with animated sprites and this doesn't work for them as the sprite keeps changing ( as we store the sprites in a list and keep changing them). Can you help me with this?
+Ravi Kiran an option is to split the spritesheet up after loading into individual sprites and create a mask from each and store in a list so spritesheet ID also indexes the list of masks.
Thank you very much. I just tried and it works fine. AMAZINGLY fast reply though!!!!
Wow, nice Video :)
Thanks a lot! Very helpful!
Thank you
Why do I get this error "argument 1 must be pygame.Surface, not pygame.Rect
"?
I set image to rect by accident
WHY IS PROGRAMMING SO DIFFICULT
hey I got it to work! that's never happened to me before!
hm, the hitbox is still too large! darn
what does the convert_alpha in the obstacle variable do?
convert the image with a format that pygame like more
Thanks a lot , Sir
what does the .convert_alpha() do?
It basically converts an image to the current display surfaces pixel format and preserves the alpha channel (transparency). Blitting converted surfaces is faster than blitting non-converted surfaces.
why your script in my computer not work
TypeError: integer argument expected, got float
please help me
is when i enter the part of result = obstacle_mask.overlap(blob_mask, offset.
+Legends JD it'll be in the circle draw function. Try putting (int(x), int(y)) instead
code.Pylet where i put that on result or offset plz
Hi i m making collision simulator i want to do it without using vectors..but just plain maths and geometry
vectors are plain maths and geometry.
I got
AttributeError: 'pygame.mask.Mask' object has no attribute 'get_rect'
That's because pygame's mask object doesn't have the get_rect() method. To get the dimensions of the image you need to call get_rect for a surface object like this:
img = pygame.image.load("image.png").convert_alpha()
img_rect = img.get_rect()
img_width = img_rect.width
img_height = img_rect.height
img_width, img_height = img_rect.size
hope that helps :)
the 3.6 we have to download the 2.7?
+Legends JD the script is written for 2.7, I will write it again and upload to Google Drive. :)
Hi JD, I written the code so it'll now work for Python3. Download pixelperfect3.py from here drive.google.com/open?id=0BwDJQBs1OukNY2lmWnlsaWI0WTQ
code.Pylet thank you
Can I create a mask of a surface where it only masks one colour in the surface? And can I change the colour using the mask? I know this video is 3 years old but I hope someone answers
I think you'll be able to do that in verion 2 of Pygame but not currently. To do that now you should use PixelArray
code.Pylet where i put that
+Legends JD are you using Python 3 or 2.7?
code.Pylet, one more question we can do a pixel perfect collision without the pos of mouse. So the move of player with keyboard
no work
Amoebae in pygame 🤣🤣😂😂