Pygame Platformer Part 17: Using Collision Masks
Skills:
Frontend Performance60%
Key Takeaways
Uses collision masks for pixel perfect collisions in a Pygame platformer
Full Transcript
welcome back to game development with pame this is part 17 of our platformer game and in this video we're going to talk about how to use masks to do what's called Pixel Perfect Collision okay in the last video we added some enemies to our game and if you've played it very much you've probably noticed that the enemy collisions don't work quite right if I can get an example here I'll see if I can get the a collision to happen like I'm talking about maybe yeah there was one let's try again there we go did you see that so looked like I died even though the two Sprites didn't touch and the reason that's happening is because of the type of collision we're doing you might remember this slide if you watched the video where we made the shooter game the standard Collision in pame is called an AABB Collision axis align bounding box we use the bounding box of the Sprite Which is the rectangle that encloses the entire Sprite and we just see if those two rectangles overlap and this is great because it's really fast so the computer can do a lot of these comparisons really fast without introducing any lag or uh or slowing down your game and that's fine but like in our jumper game you get this situation where the player dies and they feel bad because it doesn't look like they got hit and so one solution to that which is what we did in our shooter game was we used um circular bounding boxes and so it's a collision if the two circles intersect and you can set the size of the circle to be something reasonable and um and get collisions that look a little better but this also has a problem because not every not every Sprite fits well inside a rectangle or a circle so you need some more options so one option you can do is you can use another type of collision which is uh a ratio so you can take the rectangle or the circle ratio I mean the rectangle or the circle Collision function and you can pass in a ratio and what this does is just scale the circle or the Box by whatever number you pick and and you know 7even 7 here would be 70% and so you can see the boxes got smaller the circles got smaller and that can work but you're still having to deal with things like the Box being centered on the Sprite Which might not align it right you don't get a lot of control so in the cases where this isn't enough then we have a third option and that third option is something called a mask okay to demonstrate the mask I've made a little example program here so we have our player the bunny and we have the the enemy and I've shown the bounding Boxes by these little white rectangles so right now our problem is if I move this over that this is a collision in our current setup this is a collision so you're hit even if you have this much space in between and we don't want that so to do what's called Pixel Perfect Collision meaning I want to know if exact this bunny shape hits exactly this enemy shape we can create something called a mask and a mask looks like this so when we tell pame to create a mask it looks at the pixels of the of the object and it ignores the background so remember we said set the color key to Black so it's ignoring this black background and it's just keeping track of where the pixels are in the shape okay and so I'm actually going to turn that off and I'm just going to put on I'm just going to show the outline of the Mask so this is the outline of each sprite's mask and now you can see if you look up here where it says whether we've hit or not we're not going to detect a hit until those two masks intersect like that and so now this is a hit if I were to be down lower this would be a hit there and so what the computer is doing is it's going along and looking at the bunny and saying where's the first point where I see the bunny pixels overlap with or the bunny's mask overlap with the enemy's mask and that's what this point is here and it can even tell us what point that was this is the coordinates on the bunny uh Sprite so it's 10 pixels over and 83 pixels down now we don't really need to know this location but you can imagine sometimes if you have things hitting you might want a little explosion to to show over here or something to happen at the location of the hit we don't really need that we just want to know that we actually had these two Sprites run into each other okay and so that's what we're going to set up on our game right now the only other thing you need to know about mask collisions is compared to the rectangle they are very expensive and what I mean by expensive is they take a lot longer for the computer to calculate so it's having to do a lot more checking now in our case for this uh jumper game we're never going to have more than one or two enemies on the screen at the same time so checking the the player against two of these enemies we're never going to notice any kind of slowdown but if you had a game where you had hundreds of bullets flying around and enemies and lots of stuff going on uh you could start to have this create lag really fast so the way that uh people typically solve that problem when they they want Pixel Perfect Collision but they also want it to be fast is you do rectangle collisions first so in case of here there was no Collision we just move on if there was a rectangle Collision then you do a mask Collision so that way if this situation happens you'll find it but you're not doing any mask testing when things are way out here like this so you get to you get the speed of the rectangle Collision kind of narrowing down your options and then you if two things are close to each other like this then you check to see if they actually collided um we don't need to do that in this program because we're not going to have that performance problem but it's something to keep in mind if you decide to do any mask style collisions like this okay so let's go and add this to our code so you'll see this is going to be really easy we just need to go over to our Sprites and we're going to go to the player Sprite and now the player Sprites the player sprite's image changes all the time right so depending on what we are doing as we're moving so I'm going to go down to where we do the anim right so here is where we pick which image we're going to use right we either load the walking frames or the standing frames do the idle animation and we pick whichever one of those that is and we set our image to that so since we've changed our image I'm just going to put at the end here we're going to set our mask and it just has to be called self. mask if it's called self. mask the Collide function will find it and so you can create the mask in a couple of different ways but the easiest way is to just say create it from surface and tell it to use the self. image okay and we don't need the threshold option we can go into that later so this is just going to make a mask from whatever our image is which we've Now set to whichever frame we're on so we do that that with the player and then we're actually going to do the same thing with the mob uh it has the same issue because we're changing the the the image it only has two but we are changing them so we're going to make our mask update to match the frame we're on this is the same thing from surface from our image and I don't need that okay so now both of these Sprites have masks and all we have to do is go over to our Collision here in the update to see if we hit a mob and say now we want to collide the player with the mobs but we want to use the pg. sprite. Collide mask um we want to use the Collide mask function okay and now if we run this we will see what happens [Music] okay so let's wait for a mob to spawn that I can run into there we go you see how it overlapped so let's try a couple more so our collisions are working H did you see how close I got there so I was really close I was inside the bounding box for sure on that one but it didn't count as a Collide yeah see I'm not colliding until I actually M intersecting so that's all there is to mass collisions so hopefully you're thinking to yourself that was pretty easy all we did was really three lines of code adding a mask on each Sprite was one was one command and then we just use the Collide mask function and we instantly get that much better Collision so if you want to try this out and do this on your game if you're making something else uh just remember to keep in mind that performance issue if you have tons of Sprites flying around the screen uh this can start to get slow and really hurt your frame rate so uh if you if you do have that problem remember to just do go back to doing a a rectangle Collision if you have a rectangle Collision then do a mask collision and that should help quite a bit with your performance all right I hope you enjoyed the video I hope you learned something uh please like the video below that helps other people find it and make sure you subscribe so you can see the next video when it comes out all right thanks for watching
Original Description
In this video we'll learn how to used "pixel perfect" collisions to give us more accurate gameplay. If you've never worked with a collision mask before, this is the video for you!
In each video in this series, we'll add another feature to our platformer until we have a full game experience with graphics, animations, sound, and much more!
Code for this part:
https://github.com/kidscancode/pygame_tutorials/tree/master/platform/part%2017
If you like these videos please consider supporting me on Patreon: https://www.patreon.com/kidscancode
Other helpful links:
* Installing Python: http://kidscancode.org/python-install.html
* Installing Pygame: http://kidscancode.org/blog/2015/09/pygame_install/
* Setting up Atom: https://www.youtube.com/watch?v=uve1tjVIQ6c&ab_channel=KidsCanCode
Playlist
Uploads from KidsCanCode · KidsCanCode · 50 of 60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
▶
51
52
53
54
55
56
57
58
59
60
Learning to Code with Python: Lesson 1.1 - What is Programming?
KidsCanCode
Learning to Code with Python: Lesson 1.2 - Drawing with Turtles
KidsCanCode
Learning to Code with Python: Lesson 1.3 - Variables
KidsCanCode
Learning to Code with Python: Lesson 1.4 - Loops (and more turtles!)
KidsCanCode
Learning to Code with Python: Lesson 1.5 - Saving and Running Programs
KidsCanCode
Learning to Code with Python: Lesson 1.6 - Functions
KidsCanCode
Learning to Code with Python: Lesson 1.7 - Input and Conditional Statements
KidsCanCode
Learning to Code with Python: Lesson 1.8 - Number Guessing Game
KidsCanCode
KidsCanCode - Patreon Intro Video
KidsCanCode
Learning to Code with Python: Lesson 1.9 - Rock Paper Scissors Game
KidsCanCode
Learning to Code with Python: Lesson 1.10 - Secret Codes
KidsCanCode
Learning to Code with Python: Lesson 2.1 Creating Computer Graphics
KidsCanCode
Learning to Code with Python: Lesson 2.2 Simple Animation
KidsCanCode
Learning to Code with Python: Lesson 2.3: Animating More Objects
KidsCanCode
Learning to Code with Python: Lesson 2.4: More Fun with Animation
KidsCanCode
Extra: Setting up the Atom Editor for Python
KidsCanCode
Game Development 1-1: Getting Started with Pygame
KidsCanCode
Game Development 1-2: Working with Sprites
KidsCanCode
Game Development 1-3: More About Sprites
KidsCanCode
Pygame Shmup Part 1: Player Sprite and Controls
KidsCanCode
Pygame Shmup Part 2: Enemy Sprites
KidsCanCode
Pygame Shmup Part 3: Collisions (and Bullets!)
KidsCanCode
Pygame Shmup Part 4: Adding Graphics
KidsCanCode
Pygame Shmup Part 5: Improved Collisions
KidsCanCode
Pygame Shmup Part 6: Sprite Animation
KidsCanCode
Pygame Shmup Part 7: Score (and Drawing Text)
KidsCanCode
Pygame Shmup Part 8: Sound and Music
KidsCanCode
Pygame Shmup Part 9: Shields
KidsCanCode
Pygame Shmup Part 10: Explosions
KidsCanCode
Pygame Shmup Part 11: Player Lives
KidsCanCode
Pygame Shmup Part 12: Powerups
KidsCanCode
Pygame Shmup Part 13: Powerups (part 2)
KidsCanCode
Pygame Shmup Part 14: Game Over Screen
KidsCanCode
Pygame Platformer Part 1: Setting Up
KidsCanCode
Pygame Platformer Part 2: Player Movement
KidsCanCode
Pygame Platformer Part 3: Gravity and Platforms
KidsCanCode
Pygame Platformer Part 4: Jumping
KidsCanCode
Pygame Platformer Part 5: Scrolling the Window
KidsCanCode
Pygame Platformer Part 6: Game Over
KidsCanCode
Pygame Platformer Part 7: Splash & End Screens
KidsCanCode
Pygame Platformer Part 8: Saving High Score
KidsCanCode
Pygame Platformer Part 9: Using Spritesheets
KidsCanCode
Pygame Platformer Part 10: Character Animation (part 1)
KidsCanCode
Pygame Platformer Part 11: Character Animation (part 2)
KidsCanCode
Pygame Platformer Part 12: Platform Graphics
KidsCanCode
Pygame Platformer Part 13: Improved Jumping
KidsCanCode
Pygame Platformer Part 14: Sound and Music
KidsCanCode
Pygame Platformer Part 15: Powerups
KidsCanCode
Pygame Platformer Part 16: Enemies
KidsCanCode
Pygame Platformer Part 17: Using Collision Masks
KidsCanCode
Pygame Platformer Part 18: Scrolling Background
KidsCanCode
Pygame Platformer Part 19: Wrapping Up
KidsCanCode
Gamedev In-depth Topics: 4-way vs. 8-way Movement
KidsCanCode
Gamedev In-depth Topics: Time-based vs. Frame-based Movement
KidsCanCode
Gamedev In-depth Topics: Non-integer Movement
KidsCanCode
Tile-based game Part 1: Setting up
KidsCanCode
Tile-based game Part 2: Collisions and Tilemap
KidsCanCode
Tile-based game Part 3: Smooth Movement
KidsCanCode
Tile-based game Part 4: Scrolling Map / Camera
KidsCanCode
Tile-based game Part 5: Player Graphics
KidsCanCode
More on: Frontend Performance
View skill →Related Reads
🎓
Tutor Explanation
DeepCamp AI