The ultimate introduction to Pygame

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello there in this tutorial we are going to be making this game however the game itself isn't really the point of the video instead it is more of a vehicle to explore pygame essentially this is an introduction to all the major components of pygame that you need to start making games in python and by the end of it you should have all the tools to approach any 2d game starting from text adventures and pong going all the way to the first generation of doom and wolfenstein games and i do plan to make more advanced games in pygame so get subscribed if you don't want to miss those and really quickly before i start you should know some python already it doesn't have to be much but i do assume that you know how to use functions and simple classes so nothing fancy but the basics of python and if you want to code along you can find all the assets in the description so i hope you enjoy alrighty so before we get into any actual code let's first talk about how video games work on a general level that is really going to help us understand what pygame does and how it actually works so how do video games work and i think the best way to think about that is to start with movies because that is the technology video games leaked off from essentially a movie is really just a ton of images playing really fast after each other so for example here's a movie and all i have to do is to slow it down and you can see individual images although for movies these are usually called frames but it's well it's the same thing and most of the time a movie has 24 frames per second so you see 24 images per second and your eye perceives this as a moving image at least in most situations and if you do this long enough you eventually have a movie that lasts about an hour and a half and that's essentially it the only real difference between different kinds of movies is how each individual image is being made and there are basically three different ways to approach this number one you could get a camera and just point it at something and record it number two you could draw an image or number three you could use a computer to create a 3d image and each of these approach would give you a very different look of your movie but at the end of the day all we're doing is creating lots of individual images and playing them really fast after each other and that's literally it so with that we have movies and video games are quite similar to that and in the most basic sense a video game basically works like a movie that you have lots of individual images being played really fast after each other but obviously there need to be a couple of differences to really make all of this work number one and i guess the most important one is that on a video game each individual image isn't set in stone instead it's dynamic meaning that each individual image is created on the fly and plays dynamically depending on what the game needs so for example is the enemy in a certain position or did the player press a certain kind of button to move in a certain direction and then each individual frame is being updated automatically whereas for a movie each individual image is basically always the same so this already makes video games different that you have dynamic content and that already brings us to the second point that for video games we are checking player input which means that at the beginning of each image that we are drawing we are first checking the input from the player so we are checking if the player presses the button on the keyboard or moves the mouse or says something into a microphone lots of different things that we could be checking and then we are using that information to place something dynamically on the screen and well once we have accounted for those two differences we basically have a video game so let's give how a video game works on a conceptual level we always start by taking the player input and this is usually called an event loop so each kind of event could be a different kind of thing a player does it could also be something else for example a timer running out but essentially we are taking all the necessary inputs we need to draw the current image and once we have all that information we are actually placing all the relevant parts on the screen so we are placing the player in a certain position we are placing all the enemies we are drawing the health indicator the coin indicator whatever we really need and well once we have all of that we have one finished frame so this is one image the player is going to see now once this process is finished we are getting rid of the entire image again and starting this process from scratch and we are doing this multiple times per second usually about 30 to 60 times depending on how fast the computer is now that is really it and this applies both to 2d and 3d games so it doesn't really matter if you have a 2d image or 3d object to generate each individual frame at the end of the day you are just putting different elements together and displaying them to the player so with that let's talk about how pygame comes into this and well pygame has a couple of key functionalities that we can use to make a game and it doesn't necessarily have to be a game we could also make a movie in pi game or we could display some graphs this would also be possible so what does pygame actually do in the most basic sense pygame gives you a really good way to display images and this might be relevant if you just started with python development you might have realized that drawing anything on the screen is actually really hard and most of the time you just work with a console where you can see text but displaying actual images and animations is not that easy and this is the first thing that pygame is really good at that it helps us create a window and it helps us display images something that is well important for video games and along with that pie game can also play sounds this goes along with that quite well now the second point pygame can do well is to look for player inputs so pygame can help you get the mouse position or get keyboard inputs or even get gamepad input lots of different things that it can do and again in standard python you have the input method but this one stops the entire code if you want to get input which would break any kind of game so this would be the second important part of pygame that we can get actual player input and those are the two really important parts that pycam helps us with but there are a couple more that are general helpful things for a video game for example pygame is really good to help us with collision detection or pygm can help us create text and timers lots of things that are important for a video game but these are things you could also do in standard code but pygame has lots of ways to make it easier when it comes down to it pygame is a very simple module now there's one important thing i do want to address that if you want to make really sophisticated games let's say a dark souls or an assassin's creed then you would not use something like pygame because it doesn't really give you too many tools for this kind of thing instead you would use a proper game engine and this would be something like unreal unity godot and there are quite a few more and the game engine has a lot of additional tools that make game developments significantly easier for example there's gravity detection there's support for 3d objects there's lots of inbuilt stuff that makes game development very easy and along with that there's also graphical user interface that allows you to place elements on the screen and you see the game as you develop it and pygame doesn't have any of that it's well not really designed for that sort of purpose so just keep that in mind now this already brings us to the first important point why would you want to use pygame over something like unreal or unity and this is actually bringing us to one of the important parts of pygame that most of the time pie game isn't used for actual game development at least for games that you want to publish instead pygame is incredibly good to learn how to code and to create systems yourself so if you only ever use a proper game engine and you have all the systems in place for you you don't really learn good programming instead you learn to rely on external tools that somebody else provides for you but if you develop all of this in py game yourself you become a much better programmer and later on if you have more experience in programming you can very easily switch to other engines and actually make professional games but to get started working in pygame is really useful because you learn very good practices and become a much better programmer so now let's actually get started in pygame and before we can start with pygame we first have to install it because pygame does not come with python automatically but installing it is super easy all you have to do is either go to the terminal or the powershell and type pip install pygame and then you should be seeing a short animation and after that you should get the message that the module was installed successfully so with that let's actually get started by creating a window in pi game so here i have an entirely empty sheet of code and the first thing i want to do is to import my game and at this stage i would already recommend to run the code here we can see we have pygame version 2.0.0 you can see our python version and then you have a hello from the pygame community and a link where you can contribute so if you can see this message you have installed pygame successfully if at this stage you get some kind of error message you probably didn't install pygame successfully so check that stage so now we have pygame how can we actually use it and well the first line we need is pygame.init and don't forget to call it that's really important and pygame.init is incredibly important and absolutely necessary to run before any other pygmy code so pi gamma knit essentially starts pygame and initiates all the sub-parts of pygame that you need to make a game for example this init helps us render images and play sounds and stuff like that basically and while it does lots of complicated stuff you don't really have to worry about this at all all you really have to do is to call it in the first place but once you have called it it's basically good to go think of it like starting the engine of a car that when you actually do that lots of really complicated stuff happens but for you as a driver well you turn around the keys and that's basically it that's essentially the same principle here now on the next line we have to create what is called a display surface and a display surface is basically the window the player is going to see in the end and this we have to store in a variable that is usually called screen and to create a display surface we need pygame.display.set mode and into this set mode we have to place at the very least one argument and this has to be a tuple and this one should contain the width and the height of our game window so essentially later on when we create our window the width is going to be this part and the height is going to be this part so uh well that's all we really need and in this case i want to go with a width of 800 pixels and a height of 400 pixels and now once we have that we can actually run the code and let's see what happens and there you could see a window for just about one frame and this is the intended behavior for now so if you get the same result you have done everything correct and let me explain why this is happening what happens right now is that we are importing pygame we are initializing pygame and we are creating a display surface but after that is done our code ends and our computer stops running this python code and as a consequence of the code ending this display surface also disappears so we are seeing it for a second because pygame is starting to run it but then closes it basically immediately afterwards and this is why we only see it for a second or so and well the solution to that is that we need to figure out some kind of way to keep our code running forever and well for that all we really need is a wild true loop so this while true loop is going to run forever for the simple reason that this condition in here is never going to be false and we have to break the while loop from the inside so basically our entire game is going to run inside of this well true loop and in here we are going to draw all our elements and also update everything so this is all going to happen inside of a while loop and there is one important line we have to add in here as well and that is pygame dot display dot update and all that bond is really doing is it updates this display surface so that anything we have drawn inside of this while loop we actually want to display to the player so we have to take it and actually put it on the display surface and this is what this line here is for so don't forget this one either but again just like with pygame.init you only really have to call it and then you don't really have to think about it that much more so all right now we could be running this code now and we would get a window that would stay open forever however please do not call the code right now because you wouldn't be able to close it by itself for the simple reason that right now we do not check for any kind of player input and one type of player input would be to close the window so keep that in mind as well that if you didn't check specifically for closing the game well the player wouldn't be able to close the game so let's add that one first and this again happens in the well true loop and really what we want to do here is to check for all the possible types of player input and this is called an event loop and more practically this is just a for loop we are looking at all the possible types of player input and see if one of them is happening right now so what we want to do is for event so all the possible events and to get the events we use pygm.event.get so this method here would get us all the events and this part here just loops through all of them that's really all that's happening here and for now all we want to check is if the event type we are looking for is equal to pygame dot quit so this pygame.quit here is a constant that is synonymous with the x button of the window so if the type of the event is equal to pygm.quit we are indicating what to close the window and if that is the case we want to do pygame dot quit and let me add a proper double colon and indent everything so now this is working and well now we run the code this should be working much better and now you can see the actual window and i can also close it so let me close it and we're getting an error message that we are getting the error you can see it right here that we have a pygame error video system is not initialized and let me explain what's going wrong here whenever we call pygame.quit we are basically doing the opposite to pygame.init so these two are essentially polar opposites that pygame.net initializes all of pygame pygm.quit uninitializes everything so once we're running this code we can't display anything anymore so we couldn't for example run this method here because pygame needs to be initialized for this to be possible and basically what happens here is that we are calling this method and then we continue down our code and then python encounters this line and it can't run it so it throws an error so the problem here is that we are closing pygame but we still keep this while loop open and this is causing the problem so really what we have to do is to end this well true loop on the spot and well you could call something like a break statement in here but the most secure way to close pygame is to use the sys module and the sys module is something inbuilt into python and it gives you access to different system commands one of these commands is to close any kind of code you have opened entirely which is exactly what we want so well i want to import another module and i only want to import one specific part from it so i use from sys import exit and this exit method closes any kind of code once you call it so well i just want to do that so i call exit and once we have called this exit here this weld true loop will also be gone so then we are not calling this pygame dot update anymore and our code is just going to end so now let's try all of this again so i can still see the window if i close it now our code just finishes and we don't get an error message so this is working pretty well now with that we have a basic setup for our game although there are two more things i would like to add one is very simple the other is slightly more complex so let's start with the most simple one and well what i want to do is to give our game a title because if you check right now we just call it pygame.window so we can see it up here in the title we have pygame.window which well doesn't sound particularly good and we can update this title let's say do it right up here all we have to do is call display dot set caption and in here you have to pass in a string with the name of the game in my case i just called it runner and now if you run it again you can see runner in the top left now you could also change the icon but in my case i don't really care so much but okay this is a pretty good start now for the next part we have to talk about something really important and that is the frame rate or how fast our game is going to run and this is something really important to keep in mind so let me illustrate in a movie the speed is always the same usually 24 frames per second and this stays constant but for a video game the framerate can fluctuate quite a bit so for example if you try to run a modern game on a computer from 25 years ago you would probably only get one to two frames even at the best computer from that time and this would basically make it impossible to play that game but there's also the other side that if you have a modern computer your computer might be able to run the game at something like a thousand or two thousand frames per second and if the game wasn't optimized to handle these kind of frame rate differences the game might run incredibly fast and this might be a problem because our animation speed depends on how fast we're updating the game so think of it like this we have a main player character and let's say we are moving him 10 pixels to the right on every single frame now if you are doing this with 1 frame per second you are moving him by 10 pixels every second now if you are doing this with 100 frames per second you're moving him a thousand pixels per second so you have a massive difference in speed and this is something we have to be able to address because you want your game to run consistently on basically any platform at least within reason and in our case we just want to keep the frame rate constant so we don't want our game to run too fast and we also don't want to run it too slow ideally we would like to run our game at 60 frames per second constantly so we have to create a ceiling and a floor for our frame rate and well creating the ceiling is very easy but creating the floor is much more difficult for the simple reason that you can just tell your computer not to run the game faster than a certain speed and if your computer can run a game at 100 frames per second you could just tell it to run slower that shouldn't really be a problem however if your computer is too slow to run the game then well you couldn't magically tell it to run faster and be more capable so to account for the minimum frame rate you just have to be a good video game developer and ensure that there's never too much on the screen at the same time for example something that video game developers are very much concerned with but setting the maximum frame rate is very easy to do so let's actually do that so here i'm back in pi game and what i want to do is to create a clock object because the clock object helps us with time and this also helps us with well controlling the frame rate and this usually put in a separate variable that i have called clock and to create a clock object we need pygame.time.clock and make sure that the c in clock is capitalized that is really important and now this is going to give us a clock object now by itself it doesn't really do anything but when we call it in our while loop we can call clock.tick and in here you can add an integer in my case 60 and this 60 is telling pygame that this wild true loop should not run faster than 60 times per second or about one while loop for every 17 milliseconds and that way our game is not going to run too fast i will illustrate later on in this tutorial how this is actually making a difference for the animation but alright so with that we have set a maximum frame rate now the minimum frame rate we can't set with one line of code we just have to make sure our game doesn't become too complex now that being said we are only going to create basic 2d games in pygame and those are basically never going to run to promise for even reasonably modern computers so we don't really have to worry about a minimum frame rate but it is something to keep in mind if you want to make more sophisticated games but alright so with all of that we finally have our basic setup for our window so obviously this still isn't great because we are not displaying anything so let's actually start working on that and let's put some basic images on our display surface so how can we actually draw anything in pygame and well to draw any kind of image we need one important concept and that is called a surface and there are two different kinds of surfaces in pie game and the one we have already seen was the display surface so a surface can just be the main window the player can see but there's another kind of surface that we are going to use much more so let me explain if you want to display anything in pygame you essentially always put it on some kind of surface what the player is going to see at the end is anything that was put on the display surface so this is the actual window that we are going to display but to display anything on this display surface we need regular surfaces and a regular surface or just a surface is basically just an image and this image can be different kind of things it could for example be an image you have imported it could just be a plain color or it could be some kind of text these are basically the three different kinds of possibilities and then you could place a surface with some content on the display surface and that way you would actually display the regular surface i think the best way to understand this is like this imagine you want to create a really big post and present it to people the actual canvas you are putting stuff on is the display surface so this is what you are going to present at the end but by itself just having a canvas doesn't really help you all that much so instead you have to place individual post-it notes and pictures on this display surface and each individual post-it note and image is going to be a regular surface and if you place enough surfaces on the display surface at the end you are going to have something that hopefully looks quite nice so that really is all the difference here that we have to worry about but just to mention it we can only have one display surface and the display surface is always shown so we can basically never hide it however for regular surfaces we can have as many as we want there's no limitation to it however a regular surface is only displayed if we actually put it on the display surface so you could have created a thousand surfaces unless they are specifically attached to the display surface they will not be visible so all right that was again quite a bit of theory so let's actually get into our code and let's create a basic surface and for this section i want to create three different kinds of surfaces one with a plain color one with an image that we imported and one with text and they all work by creating first the surface and then placing the surface on the display surface let's start with the simplest one to just create a surface with a plain color here i'm back in my code and i want to create a new variable and let's just call this test surface so we are going to play around with this one and then later on we are going to delete it to replace it with something more proper and to just create a plane surface we need pygame dot surface and here again make sure that this s is capitalized otherwise it is not going to work and this surface is going to need a tuple with the width and the height so here we want to get width and height and this is very similar compared to what we have seen for the display surface and this is something you are going to see very often that the display surface and the regular surface have lots of things in common and this would be just one of them and in my case i want to give this surface a width of 100 and a height of 200. so now we have created a surface now the next thing we have to do is to actually display this and this is going to happen in this well true loop and let me get rid of the comments they don't really help us all that much so in the first indentation of this well true loop i want to actually attach this test surface to our display surface and this happens by first calling our display service itself and then using the blit command and blitz stands for block image transfer which is essentially a fancy way of saying you want to put one surface on another surface and in here we need two arguments we first need the surface we want to place and then the position and well the surface we already have is just our test surface and for position for now i just want to place it in position 0 and 0. and you are going to see in a second what that actually means but now let's run the code and well what we can see is that we well can't see anything and there's a specific reason for that and the reason is quite simple actually that right now both our surfaces are plain black so this surface here is black and this surface here is black and if you put something black on something else that is black you just get more black it doesn't help you all that much so what we have to figure out is how to add color to either of these surfaces and well fortunately that is very easy to do because there's a specific command for it and let me just run this on test surface because all we need is the fill command and in the fill command we can add a specific color and pie game has a couple of ways to add color and the simplest way is to use a couple of named arguments that are predefined for pygame and there's a long list online that you can find that i would recommend to check out i'll put a link in the description of the video and one that we could use is just red so that we want to fill this test surface with a red color and now let's run the code and now we can actually see our red surface in the top left of the screen and now i really want you guys to think about why is this thing in the top left that is really important to understand and well i guess let me actually explain what's happening here most importantly our main window is this display surface and is 800 pixels wide and 400 pixels high so this here would be the height and let me actually put it down here so this would be 400 and our width would be this entire width and this would be 800. so this is just the arguments we specified up here but there's one super important thing you have to understand about this that you have to think about this window as a coordinate system think of it like in basic math where you had a coordinate system that looked something like this and on this you could have displayed a graph or something like this and the really important part of this coordinate system is that the origin point was always in the bottom left so this point was always 0 and 0. and if you wanted to go either to the left or upwards you had to increase either of these numbers now in the case of pygame this is slightly different so what you have to be aware of for pygame is that the origin point is in the top left so this point here is the point zero and zero so if you want to go to the right you still have to increase x so let's call it plus x however if you want to go downwards you have to increase y whereas in the system you learned in high school if you wanted to go downwards you had to decrease y so this is slightly different for pi game and this is also something you see in lots of other game engines and especially in the beginning unfortunately this is really confusing and you will need some time to get used to it for basically any game engine so something important to learn so this is the first thing you have to understand here that this is our origin point so now when we place something at zero and zero we are looking at this point up here now this brings us to the second point that when we have this test surface there's one specific point we place when we place this surface and the specific point we are placing is always the top left so when we specify this 0 and 0 here we are saying essentially that we want to get the top left position of this test surface and place it right in the top left of our display surface and that way we have our surface right in the top left so this is really important to understand for pygame to understand how the coordinate system works with a bit of practice this should come quite naturally to you and let's actually do an exercise if you want to follow along that right now i don't want this surface to be in the top left anymore instead i want it to be 200 pixels from the left and 100 pixels from the top so try to implement this yourself all right welcome back so let's try to do this together now so right now we are placing the top left position in 0 and 0 which is not appropriate anymore instead i want this to be 200 pixels from the left and 100 pixels from the top and now if i run the code again we can see let me draw on this again we have this distance here is 200 pixels from the left and we have 100 pixels from the top so this is what these two numbers here illustrate and again we are placing this point here so actually this line here should have been rather right on top of that so i hope that makes sense and if you get stuck on this definitely play around with the different kind of points it's really important to understand and later on we are going to learn a specific method to help us place something more deliberately but for now this should be good to go so that way we can create a basic surface that has a plain color but obviously that still isn't all that great because well our game isn't going to consist out of plain colors instead we want to have actual images and well for that we want to import some images and well the first we need for that is to actually have some images and in my case i have a couple of folders that are in the same folder where my code is so let me open that one and in here we have our runner code and then we have three more folders we have graphics we have font and we have audio and well each of these contain what the name implies they contain so let me open graphics and there we have for example a ground and the sky these are what we are going to use in just a second but there's also a couple of enemies and the player itself so these are the tools i'm going to work with for now and i will always assume that our actual code is in the same top folder as these three other folders so when we import something we have to specify a specific path and if you want to follow along keep the same folder set up but right let me go back to the code and now i want to get rid of all of this and instead import an image and to import an image we need pygame.image.load and in here we have to specify a path and in my case i want to go into the folder called graphics and in that folder we have an image called sky and don't forget we need the file ending so my case this is dot png and well with that we have imported an image so now let's run the code again and we have our background and right now you can actually see the offset really well let me get rid of the offset entirely so i just want to place this background on position 0 and 0. we can see the actual background so this way it's super easy to import an image and one important thing to keep in mind here every time you import an image into pygame you are putting this new image on its separate surface so any kind of graphical import is going to be a new surface and in this case i guess we can call this our sky surface because we can actually keep it this one works pretty well already so sky surface and with that we have our sky and now actually this is something we can practice really well because there's another image inside of the folder that is called ground.png and i want you guys to import this and place it somewhere in the bottom of the screen so we actually have something that looks halfway decent already so try this yourself if you want to code along let's first create a new variable that i called ground surface and to import this one we are going to need the same setup so pygame dot image to load i want to look at graphics and in there we have a file called ground.png and i guess something slightly tricky about this that this ground is not capitalized whereas this sky is and uh well that's just my mistake sorry about that but now we have our ground surface so this is just another image and let me place this right before our sky so i again want screen.lit this time i want ground surface and for now let me place it at position zero and zero just to see what happens and another one the code we can see an error because i made a typo so this should be graphics so now let's run it again and now we can see that we can't see the background and this again is intentional so right now the problem here is that we have our sky that's the main image we have and our ground is right behind it so our ground would basically be somewhere here ish but we can't see it because the sky image is right on top of it so it overlaps it entirely and the reason for that is that we first create our ground and then we put the sky on top of that and pygame always draws an order of when you call the code so in this case we first draw the ground and then we put the sky on top of that which doesn't really help us all that much but we can fix that very very easily all we have to do is to first draw the sky and then the ground and now we run the code again you can see the actual ground so now we're drawing the ground on top of the sky surface and okay right now we can see that our ground is way too high so we have to place it a little bit further down and well in here you can just play around with this and see what looks good let's try 300 this i think looks pretty good so with that we already have a fairly basic setup by just importing two images so with that we have basically already covered the two most basic kinds of surfaces we have a surface with a plain color and a surface with an image now there's a third kind that you can have a surface with some text and here the really important thing to understand is that every time you want to create text you first have to create an image of the text and place that on a surface and then you place that surface on the screen and this is a slightly cumbersome process although it is quite workable but to work with text you essentially need three different steps number one you first have to create a font that stores your basic font information so the style of the font and the font size then in the next step you use that font information to create some actual text and this text is going to be on the surface and then in the third step you're placing that surface on the actual image and that's really all you need so let's actually implement all of this so here i'm back in the code and the first thing i want to do is to create a font and i'm going to place this right in our starting variables but you could basically place it wherever you want and let's just call it test font for now and to create a font in pi game we need pygame.font.font and here again the first letter of the second font has to be capitalized otherwise this is not going to work and in here we have to specify two arguments the first one is the font type you want to use and the second one is the font size that we want to have and for the font size that's the easier one it's just an integer i went with 50. and for the font type for now i'm just going to use none so we are using the default font of pie game but we are going to change this in just a second so now we have a font and later on we are going to use that to display the score but for now i just want to write some basic information so we know it's working so that brings us to the second step and let me place this right below our other surfaces and in here i want to create a new surface and let's call this one the text surface and to create this surface we first need our test font and then the method render and render is going to need three bits of information number one is the text information number two if you want to anti-aliase it and number three is the color let's go through those one by one first up is the text and this one literally is just the text we want to display and in my case i am just going to call this my game for now next up is anti-aliasing and anti-aliasing basically means that we are going to smooth the edges of the text which in this case is not something we want to do because we are working with pixel art but if you are working with any text that's not pixel art you basically always want this to be true because it makes your text look a little bit better and then finally we have our color and here again we can use the same kind of approach we have seen earlier so in this case i want to go with let's go with green this time so essentially i'm going to create some text that says my game and it's green that's really all that's happening here and with that we have a surface so now all we have to do is to use screen dot blit again use our text surface and now place this somewhere in the middle of the screen at the top and the numbers here don't have to be specific we are learning later on a better way to place text but i know in this case our window is 800 pixels wide and 400 pixels high so i want to place this roughly at 300 from the left and 50 from the top and now let's actually run this and there we go we can see my game right in the top of the screen now obviously the font doesn't really match the rest of the game and this we can work on right now actually so right now we have the problem that we are using the default font of pygame which is none up here which well doesn't look particularly good but if we specify a specific file in here we can use a much better looking font and again if you look at the folder there's one specific file that we can use so so all i have to do is go to font and in front we have a file called pixel type and this is a ttf file so this specifies a font and all i want to do is to import this file so i specify it in here so we have our font and then pixeltype.ttf and now we're on the code we can see a very different looking text and this one i think looks much better and i guess the green color doesn't work too well with it so let's go with black for now and yeah this is looking much better now so with that we have the three different kinds of surfaces that we can draw some text we can draw a basic color and we can also import some images and display them and this is already bringing us so much closer to an actual working game but obviously right now nothing is moving which isn't great for a game so let's actually start animating some of this and the logic to animate something in pygame is actually fairly straightforward and here again you have to remember the basic logic about video games i talked about earlier so right now we are drawing three different images our sky our ground and our text and we always place them in the same position and the important thing you really have to understand here is that we are not drawing a static image right now it just looks like a static image to us but essentially we are updating this entire image over and over again 60 times per second now the problem for us right now is that we are placing all of these images always in the same position and this is what it looks static to us but if we were to update the position of each of these surfaces we would get a moving image so really all we have to do in the most basic sense is when we use screen.blit we don't use one constant position instead we use a variable that we continuously update and once we have that we have a moving image that's literally all it is so what i want to do in this section is to get our snail enemy and move it from the right of the screen to the left of the screen so well let's actually jump into our code and let's have a look at this here i'm back in my code and the first thing i want to do is to import our snail image so let me call this snail surface and here again we need pygame.image.load and the path to the snail is graphics snail and snail one there are multiple snail images because they show an animation of the snail itself we're going to cover that later on but for now just work with snail one so this would give us our snail surface and let me actually draw this on the screen so again i want screen dot blitz i want our snail surface and let's place this about 600 pixels from the left and 250 pixels from the top so now if i run this we can see our snail so this one is already working fairly well and the problem here right now is that this is static because these two numbers are never going to change we always place the snail in the same position and well we are placing all of this always in the same position but we don't necessarily have to do that what we could do for example is create another variable let's call this snail x position and by default this is going to be 600 so i just copy this 600 and place it in here and then call snail x position so all we really did is move this 600 into a specific variable so right now if we run the code we are going to get the same result our snail is still static but now what we can do is every time this while loop is running we want to increase our snail x position by one so that every time we come to this line here our snare lacks position is going to be increased by one and if we run the code now we can see our snail moving to the right because the x position is going to be greater on every single cycle of this while loop and now if you want to move this nail to the left all we need is minus equal 1 and now our snail is going to move to the left and this is already working pretty well and well minus one is probably a bit slow let's go with four and yeah this looks like a decent speed cool but now obviously once the snail is leaving the screen this snail is going to keep on moving to the left and we will never see it again so this isn't great yet but really all we have to do to overcome this is use an if statement that if our snail exposition is too low we want to again put our snail exposition on a higher number and this is a very simple if statement and this could actually be an exercise try to figure out how you could place the snail on the right of the screen if it crosses the left side of the screen let's try together now so i want to use an if statement and i want to look at my snail x position and really i want to do is to check if this is smaller than let's say minus a hundred and if that is the case i want to get my snail x position and set it to something like 800 and now if i run the code i can still see the snail if it moves too far to the left now it reappears on the right and well really all that's happening here is we look at this point here so about minus 100 and if our snail x position so this point here gets further to the left than that we are putting this position all the way over here so this way it looks like our snail is looping but really all we're doing is we're looking at this snail x position and we are updating it and then placing the snail in a specific part so really all we are seeing right now is that our snail is continuously updated and our brain interprets all of this as a moving image but okay and i guess now what we can actually do just to illustrate how the animation works is this clock.tick right now is at 60. but if i set it to 1 you can actually see what's happening so now let me run the code again and now you can see the snail is just being updated a little bit further to the left every single time and we're just drawing a new image every single time and if this is slow enough it looks like well our snail is very sloppy and on the counter side if i set this to something like 600 then our snail is going to be significantly faster so because of that our frame rate is really important and we really want to make sure that this stays at least somewhat constant so all right with that we have a basic animation so this is already going pretty well now before we continue there's one more thing i do want to show you guys and let me just comment out all the images we have drawn earlier so right now we have no sky we have no ground and we have no text the only thing we are drawing is the snail and now we run the code we get a very strange looking result and the reasons for that should make sense if you think about it for a tiny bit that right now all we are drawing is the snail and the snail doesn't cover the entire screen so every time we are updating this surface we don't really get rid of the previous frame we're just drawing on top of it and since we are not drawing on the entire surface we can still see the previous frame and as a consequence it just looks like we are stretching out something which well looks terrible so always keep in mind that you want to draw a proper background for your display surface otherwise you will be able to saw the previous frames you are drawing which looks very strange unless well it's something you actually want to achieve but okay so with that we have our basic animation and this is already looking pretty good i think and there's one more thing i would like to talk about before we get into the next section and that is converting our surfaces so let me go to the surfaces right now we have imported three different surfaces we have our sky we have our ground and we have our snail and right now all of them used to be png files and this is fine for basic setup however ideally we would like to convert all of them into something pygam can work with more easily and this we can do very easily all we have to do is to add the line.convert after we are importing an image and this i do want to do for all of the imported images and all this really does is it converts the image to something pi game can work with more easily so our game is going to run faster that's really all that's going to happen here but now if i run this we're going to see something strange so now our snail is going to look well slightly weird and the problem here is that we didn't respect the alpha values so this is all the white and black stuff behind the snail and to get rid of that all we have to do is change convert to convert alpha and that way we are removing the alpha values enough around this now we can see our snail properly and you can't really see a difference however now our game should be running faster at least in theory and especially once we have more stuff on the screen this might become important although in our case it really shouldn't make that much of a difference but it's generally good practice so don't forget to add this line every time you import an image so with that i do want to start working on the player character however there's one more really important concept we have to cover to really make the player character work and that is called a rectangle and rectangles in pygame essentially have two different functions at least in the most basic sense they can do quite a few more things but the two core functions of rectangles are this number one is that they're helping you place a surface much more efficiently and much more precisely and number two rectangles are going to help you detect collisions something we are going to see very soon but for now i do want to focus on using rectangles to place a surface on the screen so let me explain what we are going to do right now when we place the snail we couldn't really place it precisely because we can only ever place the top left which made it very difficult to place the bottom of the snail right on the ground so ideally we would like to grab a point on the bottom of the snail and place that point which we couldn't do with surfaces by themselves but something we could do with rectangles and this is something that you see all the time in pygame that you separate placing images in two different steps the actual image information is placed on the surface but then the position information is placed in a rectangle so essentially you are splitting your image into two different variables that you then have to control together and much later on in this tutorial we are going to see the sprite class and this one combines these two so you can work with them more efficiently so then how does a rectangle work well a rectangle is a well rectangle but this rectangle has a couple of points that we can work with we can either get points that are a tuple so they have an x in the y position or we can have points that are individual positions like left and right you can see all of them on the screen right now and we can grab each of these points and either measure or move them and if we move any individual point on a rectangle we move all the other points as well so the points always stay relative to each other and then we can use a rectangle to place a surface right in the middle of the rectangle so a rectangle we could place for example in the top left or in the center on the bottom mid or on the mid right we could literally place all of these points and then we can use that information to place the surface right into this rectangle and that way we are going to have much more control over how our surface is going to be placed and later on we can also use that rectangle to detect collisions but that's coming later for now let's just use a rectangle to place a surface so here i'm back in the code and the first thing i would like to do is to import the surface of the player so let's call this for now player surface and this again we just have to go with pygame.image.load and here the path is in graphics and for this one the path is graphics player player walk1 so again we have multiple images that we are later going to use for animation but for now we're just going to use one and this again i want to use with convert alpha so it's going to run slightly faster and let's just put this on the screen so we can see it so i want to use screen dot blit again i want to place my player surface and for now let's place it let's say 80 pixels from the left and 200 pixels from the top and now let's see how it looks now we can see our player and here you can already tell that there's a distance between the bottom of the player and the ground so this area here we want to bridge but the problem is that well we don't really know how big this area here has to be so placing just the top left of the player is very difficult and to fix that we are going to use a rectangle so step number one for this is we have to create a rectangle and there are different ways to do that so for now let's just call it the player rectangle and in the most basic sense you could create a rectangle by using pygame.rect and in here you could specify a left a top the width and the height and then this would create a rectangle however this is not something you see all that often actually because ideally you want to have a rectangle that is the exact same size as this surface and this we can create all we're going to need is our player surface so player surface and then the method get rekt so all that this get rekt does is it takes a surface and then it draws a rectangle around it and then for this rectangle we can specify a specific position where we want to place it so in here we could for example use top left and then give it an x and a y position so here for example i could copy the information from down here and just place it in there and let's just start with that so let me copy all of this and now we have a rectangle that is in the same position as our surface used to be and now when we use blit we can use a rectangle to place this surface so all i have to do in here is insert player right so now essentially what we are doing we are taking a player surface and we're placing it in the position of this rectangle so now if i run this we can see no real difference because the rectangle is in the same position where the surface used to be but what we can do for example now use a different position on this rectangle for example we could use mid left instead of top left and now if we run this our player is slightly higher or we could also use mid bottom and now our player is again in another position and really what you have to understand about this is that we are placing this point here right at the bottom of the player whereas for surface we always grab this point up here so let me draw a rough rectangle around it so for surface we always place this point but for a rectangle we can grab any of these points around it there are lots of points we can grab and that way we can have much more control over what point we want to place so this is super useful and now we can use that to place the player right on the ground and we know where the bottom of the player has to be because we know the ground is at position 300 so that's when the ground starts so the bottom of our player has to be on this position as well so let's say for the mid bottom i want to go with 300 and now let's run this and now we can see our player is touching the bottom perfectly and here again you might be wondering that this setup is kind of tedious and time consuming so that whenever we want to place a surface and have any control over how it's going to be placed we always have to create two variables first a surface and then a rectangle and i agree it is quite cumbersome and later on in this tutorial we are going to see a sprite class and a sprite class essentially combines a surface and a rectangle and places them in one class and this makes it much easier to work with them so later on we are going to make all of this much more streamlined but for now i do want to work with them separately so you understand them better so with that we have our player rectangle and now what we can do with this player rectangle we could move every single point of this rectangle and then use that to control the surface so for example what i could be doing right in our game loop i want my player rectangle and i want to grab any individual point from it so for example i could get the left of the player and this i could either measure or move so really what i could do here for example is just move this to the right so add plus one to it and now if i run this we can see our player moving to the right so this is how you would actually move something in pygame that you don't move the surface instead you move the rectangle that contains the surface but what you can also do is you can print this information so i just want to print it and now you can see that the left of our players are position 48 so we know that this line here is 48 which can be really useful to measure different things so this is stuff that is going to be really useful but for now i don't really going to need it but something i do want to do and this could be a really good exercise for you as well is that i want you guys to update this snail that we don't just use the surface to move it instead i want you guys to place a rectangle around the snail and then influence that rectangle to move the snail so if you want to code long pause the video now and try this yourself all right let's try together now so my snail is this line here and this net exposition i don't need anymore instead i want to create a snail rectangle and let me use the surface line a bit more consistently so instead of writing surface i always write surf because it's a bit shorter and i really like to keep this a bit more consistent so faster surface i just write snail surf that makes it a bit easier to read i think but okay now to get this rectangle i want to get my snail surface again and call get wrecked on it and now again in here i have to specify a position where i want to place this rectangle and here again i could use mid bottom again but just to mix things up a bit i could use the bottom right for example although in this case it really doesn't make much of a difference and where i used to place this was at position 600 and now for the height i want to go with 300 so again the important coordinates that we have to worry about is this ground here this is where our snail has to be on top so when we specify the bottom of our snail it has to be the same position so just keep that in mind and now we just have to use that rectangle to place the snail and that happens on this line here so now instead of placing it in this one position i just want to use my snail rectangle and along with that we don't need all of this information anymore so let me get rid of it and instead i want to do all of this with a rectangle but let's first try if it works in the first place and there we go now we can see our snail right on the ground this already looks much more realistic but now i do want to move the snail and well for that all i need is my snail rectangle and then get one of the points that we want to move so here you can really pick any point you like let's say in my case i want to go with x and this i just want to move by minus equal let's say 4. and now if i run this we can see our snail moving again and now if you want to move the snail back to the right of the screen all i need is an if statement and get my snail wrecked again and here we want to measure if our snail leaves the screen so effectively what i want to know is when the right side of the snail is smaller than zero because then i know the snail has left the screen so what i want is to get the right side of the snail and check if this is smaller or equal to zero and if that is the case i want to get my snail wrecked again and now i want to place the left and this is supposed to be at position 800 because 800 is our right side of the screen it's that position up here and well with that line this snail should be working okay so let's try this now and we can see our snail moving to the left and now it reappears and this way we have much more control over the different points of our snail so this is super useful but this is essentially it when it comes to using rectangles to position surfaces it really is quite tedious especially early on but once you get used to this this is actually quite a powerful system but alright with that one we can learn about this second aspect of rectangles where they are really useful and that is collisions so what i want to do for this section is to get a collision between our snail and our player and this is actually super easily done with rectangles because all i really want to do is to check if there's a collision between the player and the snail or the rectangles that contain them and this can be done with the collide rect method which just checks if one rectangle is colliding with another rectangle that's really all that's happening here so let's jump right into our code and let's implement this so here i'm back in the code and all i want to do is go right to the bottom and in here i want to check if my player rack is colliding with the snail right and really all i have to do is to get my player rectangle and use collide rect and in there i have to place the other rectangle i want to check against so this would be my snail rectangle and this method returns either a zero or a one so if there's no collision we get a zero if there is a collision between these two rectangles we are going to get a one and that information we can then use in an if statement but first let me print the entire thing so just you can see what's actually happening here so now if we run this we can see lots of zeros but once the snail is colliding with the player we can see once then we go back to zeros then we go back two once all the way down here and this happens over and over again so we can tell that this here is returning one so this i can then use an if statement so in here you could write if this is equal to one but since python automatically converts a zero to false we don't really need that so this line here by itself is fine as well and well if that is the case let me just print collision just to see if it works and now if i run this we can see a collision once the snail is colliding with the player so we know this line here is working but there's one thing you really want to keep in mind here that this might trigger multiple times because right now when our snail is overlapping with the player pygame checks every single frame of the game if there's a collision or not so if we just had this line then this collision might trigger multiple times which if you have some kind of health system would be a big problem because later on we are going to end the game once there's a single collision but if you have a hard system or some kind of health bar you really want to make sure you only have a single collision and then you have some kind of invincibility frames something lots of games actually have but in our case this kind of collision system is fine and this would be then the basics of collision now there's a different kind of collision that you can use with rectangles and that's collide point and this is not something we are going to use too much but it is also quite important so i do want to talk about it and all that collide point really does is it checks if one point collides with a rectangle the name should kind of make sense here and this isn't something you are going to use too often however if you ever want to click with a mouse on something then collide point is incredibly important and this is kind of why i'm going to talk about it so in this section we are going to talk about collide point and using the mouse and pygame just as a small interlude we're not going to use it too much so let's go for both of these and let's first talk about politepoint we are basically calling this like collide right so we first need our rectangle and then calling this as a method but now as an argument into collide point we don't pass in a rectangle instead we have to pass in a tuple with an x and a y position and then pygame checks if this one position is inside of the rectangle or not and then it again is going to return something that we can use in an if statement so far so good but now how can we get individual points or rather how can we measure the mouse position and for that pi game has two different approaches we could either target the mouse with pygame.mouse or we could look in the event loop and check the events that check the mouse position those basically get you the same position but there are two different ways to approach it and well i'm going to demonstrate both so the first one is pygame.mouse and this one gives you lots of information about the mouse for example the position or what buttons are being pressed you could also set the position of the mouse or if the mouse is visible in the first place and if you check the documentation there is quite some more stuff you could be working with but in my case i am only going to work with get pressed and get position so get the mouse buttons pressed and get the position of the mouse now besides that approach you could also use the events so when we have the event loop in there you could also work with the mouse position but that was quite a bit of talk let me actually implement all of this so here we are back in the code but now what i want to do is to check if our mouse is also colliding with the player and just to make this a bit easier to see i'm going to comment this one out for just a second so we don't get too much at the same time so i again want to get my player rectangle and i want to get collide point and in here we have to pass in a tuple that has x and y positions so this is the point we want to measure if it is inside of the player rectangle and then again we can use this inside of an if statement and check and print if there's a collision now then the important question is how do we get this x and y position so let me put this inside of a new variable that i'm going to call mouse position and to get the x in the y of the most position all we need is pygame.mouse.getposs and this would give us an x and the y position that we can then use inside of this so what i want to do is to copy my mouse position and place it in here so now let me activate the mouse and now if i run the game now i can see my mouse and if i hover over the player with my mouse you can see collision so this one is already working quite well so really all we have done here is we have used this pygame.mouse and used getpost to get the position of the mouse this one should be quite straightforward now pygame.mouse has quite a few more methods that we can use and one would be get pressed so let me call this one if we are hovering over playerrec so pygame.mouse.get pressed and of course i do want to print all of that information and now we run the code again and you can again see my mouse i hover over the player and now you can see faults falls and faults and this is a boolean value for each of my mouse buttons so if i press any of the mouse buttons and let me scroll down a tiny bit here actually so now you can see all of my mouse buttons and if i press the left mouse button you can see true if i press the right mouse button you can see true on the final boolean statement and if i press the middle mouse button you can see true in the middle so this is basically which mouse button i am pressing so that way you could check if i am pressing different mouse buttons so that way you could check what the mouse position is and what buttons are being pressed so this would be one way to approach this now what we can also do in the event loop we can also access the mouse position so we want to check for a different kind of event and this would be if event dot type is equal to pygame dot mouse motion all in uppercase letters and this would give us the mouse position and this would only trigger if we move the mouse so if you don't move the mouse this is not going to give you anything but once you do have it you can print the event position so this would then give us also the mouse position and now let me run this code again now i can see my mouse again and now okay let me scroll down again now you can see wherever i move my mouse you can see the actual position so if you move to the top left you can kinda get closer to zero and zero and if i get to the bottom right you can see close to eight hundred and four hundred and well that way we can also get our mouse position so this would be another way to approach this now another thing that you could use in here is mouse button up and mouse button down so this would ever check if we are pressing the mouse button down or if we are releasing it so let me start with mouse button down and if that's the case i just want to print mouse down so now let me run this again and let me spell all of this correctly now this works and now whenever i click we get mouse down and now if we change this to mouse button up this is only going to be triggered once we release the mouse button so let me go with mouse up and if i run this now well you can't really see it but now i'm pressing the button and nothing happens only if i release the button we can see mouse up so this would be a good way to check if the button is pressed or released but this is basically all you have to know to use pygame with a mouse if you check the documentation there's quite a bit more about small details but this is the basic and the most important stuff and let's do one small exercise to finish this part off that i want you guys to use the event loop to check if the mouse is over the player rectangle and well pause the video now and see if you can figure this out let's try together now obviously i want to work in this line here and figure out how i can use that information to check if my mouse is over the player rectangle and well the first thing i need to get is the mouse position so i want to go with mouse motion and once i have that i can print the event position so this would be the first step to approach this and this is what we have seen earlier but now what you have to be aware of that this event position is also going to give us an x and a y position so this is something we can use in collide point with a rectangle so all we have to do in here is to check our layer rectangle and then use collide point with the event position and use this in an if statement and if that is the case i want to print let's call it collision and let me disable and comment out all of this down here so we don't get confused with that line so now in theory this should print a collision and let's try this and now we can indeed see collision all right and with that we would be having our mouse collision now for now i am going to comment all of those out but we will later on revisit them to implement a proper collision for our player and our obstacles but before that there's one more thing i would like to address and that's the score and right now the score or my game is not really centered in the middle of the window so this is something i would like to address and well this we can also use with rectangles quite easily but along with that i would also like to highlight another functionality of rectangles because rectangles can be used to draw images on the screen but let's talk about that after we have centered the score so we go step by step so let's get started by centering the score and this again could be a challenge for you so if you want to go long try this yourself right now all right so let's try to do it together and here we have our text surface and let me put this in like a separate paragraph and again i don't want surface as a whole word i just want surf i think that's a bit more readable so a bit further down we have our text surface here and actually i think a better way to call this would be score surface that's making more sense so let's call this score surface sorry about the renaming i should have really thought about this earlier but never mind so now we have our surface again and the first thing i want to do is to create a rectangle so i have score rect and this is going to be our score surface and i want to get get rekt and this score rectangle i want to be right in the center of the screen and roughly in the top of the screen with a little bit of an offset between the top of the window so the point i want to place is the center and in here again we need x and y and we know our entire window is 800 pixels wide so half of that is going to be 400 and i think the original offset of 50 so the value we have specified down here should still be fine so all i'm going to do is to place this 50 in here and we're good to go so all i need is 50 and then i want to get this score rectangle and place it in the score surface and now if i run this we can see my game right in the middle of the screen so this is working quite well so far we have used rectangles for two different purposes we have used them for positioning and for collisions but there is a third one that you also see fairly regularly although not as often as the first two and that is you can use rectangles to draw or at least rectangles are part of the drawing module you can use other tools to draw as well so let me explain within pygame there's a sub module called draw and in draw you could for example pass in a rectangle and then you would be drawing this rectangle you could also be passing in a rectangle and then you would draw a circle inside the boundary box of that rectangle but you don't necessarily have to use a rectangle you could also draw a line from one point to another where you would just specify two points you wouldn't need a rectangle for that and this is also quite a useful thing to work with so how i want to illustrate this is i am going to give our score some background color so it looks a little bit nicer oh yeah and along with that we are also going to talk about colors after that but step by step so the first thing i want to do is i want to draw this score rectangle and well all i have to do for that is in the line before that i have to call pygame.draw.rect and all that's happening here is the first help again we want to draw a certain thing with the draw module and then we want to specify what kind of shape we are drawing in this case it's going to be a rectangle but if you look at the documentation there are quite a few more shapes that you could be drawing for example a polygon or an ellipse but in my case i will just draw a rectangle and in here we have to specify three different arguments we first need the surface we want to drawn so our display surface in this case then we need a color and then the actual rectangle we want to draw so in my case this is actually quite easy so i want to start with the screen itself that's our display surface then i'm going to need a color and for now we are just going to use the default colors so let's go with pink it's going to look terrible but that doesn't matter for now and then i want to draw the actual rectangle so score rectangle and now if i run out of this we can see a pink background that doesn't actually look all that bad and in here well you can see that the background covers the text just about there's no margin whatsoever and that isn't great and well you can work with that quite a bit more so if you go to the documentation there are quite a few more arguments that you could be passing into this the one you are probably going to see the most are width and border radius so let's specify both of those just to see how they look like so argument number four that you could pass in here but don't have to repeat with and let's just pass in is six for now and let's just see what happens and now we can see something probably slightly weird that we only get the surrounding we don't get the actual rectangle itself anymore so this is something you should be aware of when you work with this that once you specify a line width pi game stops drawing the center of the rectangle so this is a little bit annoying but now i can also specify another argument and this would be the border radius so let me put it 20 in here and now we have quite a bit of rounding but in my case i don't want to have any border rounding i just want to keep the border with so now how could you draw a rectangle that both has a border width and a center that's colored and well all you really have to do is to copy this line and then add one without a width and one with one so now if i run this we can see that we have a bit more of a margin around the text and let me change this to a 10 and now let's try this again and this is looking marginally better not great but i would say good enough so this is something you could work with to draw different kind of shapes and let's just play around with this and this could be a really good exercise so i want you guys to look at the documentation and just draw a line from the top left of the screen to the bottom right of the screen so check out the documentation and see if you can figure this out yourself right welcome back so right now here's the documentation and in there we have two methods that can be used with us we have pygm.draw.line and pygm.draw.antialias line or aa line and those two basically do the same thing except one line is anti-alias the other one isn't and those two for the most part are going to be identical so i'm just going to work with line and if we look at this one in more detail this one is going to need five different arguments we have a surface a color a start position and end position and a width so that's really all we need and well let's implement that so here i'm back in the code and let me add a new line with pygm.draw.line and in here we are going to need five different arguments so the first one is this green or what surface we want to draw on then we need a color for now let's go with gold and then we are going to need two points so the start point and the end point and both have to be two builds and since i want to start in the top left and end it in bottom right i have to start with zero and zero so the top left and the bottom right is 800 and 400 and now i have to specify a width so let's go with 10 but you could leave out this argument but let's specify it and if we run this we can see a line going from the top left to the bottom right and even better what you could for example be doing in here is replace this with pygame dot mouse dot get pause and now what you would get is a line that always follows the mouse which is kind of cool i think but we don't really need it so let me get rid of it and let's do one more that i just want to draw a circle and this would be an ellipse and for the ellipse we would again need the surface to drawn now we need a color let's go with brown and this rectangle is going to be the bounding box for the surface and really what we can do in here is generate this surface on the fly and we could do one of the rectangles we have created earlier although what i also want to cover is that we haven't created a rectangle from scratch yet which can also be useful sometimes so what i want to do in here is pygame.rect so we are creating a rectangle right inside of the method and this is going to need four arguments we need the left argument the top the width and the height so let's place this i don't know 50 pixels from the left let's say 200 pixels from the top i want this to be a hundred pixels wide and 100 pixels high and now let's run this and now we are getting a circle or well an ellipse with an equal width and height but that doesn't really matter but we do have a problem right now that the colors don't really match up so when i open this again the black text and the pink background just don't look very good and the problem here is that for now we always rely on the predefined colors which can be okay for starting point but don't look too great so how could we specify more specific colors and there are two ways to specify colors in pygame and this also applies to basically any other program and they're called rgb colors and hexadecimal colors and they do essentially the same thing so let me start with rgb colors all that rgb stands for is red green and blue that's really all it means and all we are doing here is that we are specifying how much of each color we would like to have and then pie game mixes all of them together and we are getting one customized color out of that that's really all we are doing and for each color you can choose between 0 and 255 with 0 being the absence of the color and 255 being the full color so for an rgb value we would specify a tuple with three different values one with the amount of red one with the amount of green and one with the amount of blue and for example if you had an rgb tuple with 255 0 and 0 you would have a plain red color because we would have only red and no green or blue and now for hexadecimal colors we are basically doing the same thing we just write it down in a slightly different way so we don't have a tuple anymore instead we have the hash symbol followed by six numbers and the first two numbers are for the red color the third and the fourth number are for the green color and the final two are for the blue color and then for each of these two we can specify the amount of each color we want to have and with that you basically have the same outcome as rgb now how you count how much of each color you have for this is slightly weird because the lowest possible value is 0 and 0 and the highest possible one is f and f so the counting here is slightly different if you want to read more on this i put a link in the description but essentially you are never going to create your own code instead you would use something like photoshop or some kind of website to create a color for you nobody ever really reads these things by themselves they're not really made for that so with that we have some colors let's actually implement them and there are two colors that we are going to need one is the color for the text and the other is the color for the box behind it and i'm going to use an rgb color for the text and a hexadecimal color for the box just to show you how both are going to look like and here are the two colors i am going to use so you can see what they look like so let's implement all of this so here i am back in the code and if i run out of this we can still see our pink box with the black text and let's start working on the text itself and to change the color of the text we have to work up here and we have to update the text when we create the surface and right now we are just creating a black text inside of a surface and i'm going to get rid of that and instead replace it with an rgb tuple and this one is going to have 64 for all three colors so we have 64 for red 64 for green and 64 for blue which gives us a fairly darkish gray so this would then be the text and that's really all we had to do now if i run this again now our text is looking slightly more grayed out it still doesn't look all too good because the background is pink so let's work on that one and for that i have to scroll down a little bit and now i want to change this pink here to a different kind of color and this happens with a hexadecimal string although you could also use an rgb string and in my case i have a string that looks like this and really important here do not forget the hashtag in the beginning that one is super important if you don't include that one it's not going to work but this is well it's a bluish color let me run the code and now you can see that this color of the text box is the same color as the background so this is i think the best kind of color for this and here again if you want to choose your own colors either for rgb or for hexadecimal there are loads of programs that you can be using for example in photoshop you can see both the rgb and the hexadecimal color but alright so with that we have the different colors next up i want to start working on the player and this is going to involve a couple of different steps number one is i want keyboard input and well most games are used with a keyboard so this one should be quite straightforward but what i essentially want to achieve is that if the player presses space our player is going to jump so we have to implement a jump mechanic but to implement that we are also going to need gravity so those two things are going together that you can both jump and fall at the same time but once we have that there's one more thing that we do need and that is some kind of floor because if we can jump and fall down if we don't continuously jump our player would eventually fall into nothingness so this is then the third one we have to implement and these are three things that are kind of independent of each other so i go for them step by step and let's start with keyboard input because this should be the simplest one by now because we have already seen something similar with mouse input and keyboard input isn't all that different from that and here again we have two different ways of getting input we could either get all of the keyboard inputs with a specific method or we could use the event loop and well there isn't really all that much to talk about let's actually go straight into the code and let's implement all of this and then we are going to look at both kinds of inputs so here i'm back in the code and it is already taking shape quite a bit but now what i want to do is to get all the keyboard input and let's start with the first one that we want to use the sub module called keys and to access that we need pygame dot key and in there we have a method called get underscore pressed this one is going to return an object that contains all the buttons and their current state so if they are being pressed or not and well let's just print the entire thing and see what's going to happen and right now you can see a ton of different zeros and each of these zeros is going to stand for one button with zero meaning the button is not pressed and the one meaning the button is pressed so this is very similar compared to the mouse and that information we can use to well access the button and see if it's pressed or not and how you would usually do that let me stop all of this is you would use this kind of like a dictionary that you would first store it in a variable let's say in my case i'm going to call it keys and then you can use keyword arguments to find specific buttons inside of this object so what we could for example do is look for one specific button and if you look online in the documentation you can find all the constants that represent specific keys there's quite a long list of different things you can do the one i want to look for is called pygame dot k space which stands for the space button and this one is going to return either a 0 or 1 and that information we can again use an if statement so if that is the case let's say i want to print jump and now let's run this and let me press space and here again we can see jump so this is working pretty well so this would be one way to access all the different keys that you can have but again this we don't really want to do right now so let me comment it out and let's look at the other way because you can achieve the same thing in the event loop as well so in here and let's work on that actually and in here you have a little bit more control over what you do with the keyboard because in here you wouldn't just check for what button was being pressed instead you would go for a two-step process number one is you would first check if any button was pressed in the first place and only then would you check the specific button that was pressed and then you can do the same way with a button being released this is again kind of similar compared to what we have done with a mouse click but all right let's implement it here so i want to look for an event dot type that is equal to pie game dot key down and if that is the case for now let's just print key down and just to illustrate what we can also do we can print key up so this would be releasing the key and then we can print key up and now let me run all of this our game is still working and now let me just press a button and we can see key down on the bottom of the window and i keep the button pressed for now and this is why you can't see key up but now if i release the button now i can see key up so this way we can separate if the button is being pressed or released which can be quite useful in some instances so this would then be one way to check if a button was pressed in the first place what if i want to check for a specific key here well all we would have to do is look for the event key and this would compare with the same keyword arguments that we have seen down here so here again we could use pygame.kspace and if that is the case no i want to print let's call it jump again and now if i press space we can see jump and also key up so this one is working super well and well with that you basically have all the different ways that a player could enter information into the game so you have seen different ways to work with the mouse and also with the keyboard now and you can do this either in the event loop or you could do this inside of the game itself and now i guess there's one question that's been looming over input so far that why do you have two different methods in the first place why do you need that and the answer here is actually quite obvious that later on we are going to learn about classes that are ideally self-contained and this would also include input methods and for that it is super useful to have input that we can work separately from the event loop but for most of the time the event loop should be the good way to go because then we have all of our input nicely organized in one place so it's easy to work with but again this is something you are going to understand later on once you actually work with it so for now just don't worry about it too much so now we have all the input we need and i don't think there's too much we need to practice with this so let's go straight to the next part and that is that i want to give our player the ability to jump and also to fall so what do we need for that and well the first thing that we are going to need is some kind of gravity because well our player needs to be able to fall and here's a slight problem that we are going to have that in reality gravity isn't a linear function instead it's exponential which basically means that the more you fall the faster you fall and if that doesn't happen falling is going to look really weird it looks like we're in space so we have to create some kind of method that looks like our player is going to fall in an exponential speed which is kind of annoying to do so we are only going to imitate that we're not going to replicate it although it's something you could be doing but essentially all we're going to do is we're going to separate this process into two different parts where number one we're going to create a variable that has a gravity and this gravity is going to increase so it's just the number for now that just increases constantly and then we're going to add this number to move our player downwards and since our gravity is getting larger and larger it looks like our player is falling at a faster and faster speed it's not exponential but it starts to look quite a lot like it and especially since we are not falling that far this is not something that a player would notice and this is something you see really often in video games that game developers just don't really care about physics as long as it looks and feels good if it's actually physically accurate nobody really cares but alright that was again lots of talk let's actually implement all of this so here we are back in the code and the first thing i want to do is to create some kind of variable that tracks gravity and this let me put it right below the player so let's call this player gravity and by default this is going to be zero but now what's going to happen in our game loop and let me separate the player a little bit and let's add a comment here so we know we're always working with the player that should organize our code a little bit better at least so before we are drawing our player i want to increase the gravity by one so player gravity plus equal one so on every single cycle of the game loop we are going to increase our gravity by a bit but right now this isn't going to do anything because this player gravity and this player rectangle are well they're not connected so they don't influence each other whatsoever and well let's change that so what i want to do is this increase in gravity i want to use that to move the player downwards and this could actually be a really good exercise for you guys so i want you guys to use this player gravity to move the player downwards continuously so pause the video now if you want to code along and implement this yourself all we have to do is to get our player rectangle and then target one of the vertical attributes doesn't really matter which one in my case i'm just going to go with y and here all we have to do is to plus equal this with player gravity and now let's try this and now we can see our player falling downwards obviously this isn't going to look too great because our player just disappears immediately but let me explain what's happening here that at the beginning our player gravity is zero and then we add plus equals one to it so we will get one out of it and this is then what we would add to our player gravity so then our player gravity would be 301 but on the next cycle of the loop let me use a different color for that we would start with one already and we would add one towards it so now we will get to two and now if we add this to the player gravity we would get 303 so we have an increase in speed in terms of how fast we are falling down and this is going to look very much like our player is falling in real world gravity and this to our primitive brains looks like the player is falling at the natural speed although it's not real gravity so with that we have to find a counter measure that our player has to jump upwards and this is also something we can implement quite easily because right now this player gravity is moving our player downwards because it's positive but if this number were to become negative our player would move upwards and let me actually demonstrate this so when i set this player gravity right now 0 but i could set this to minus 20. another on the code we can see we have one jump because we initially move the player upwards but then we're moving it downwards at an increasing speed and this we don't want to do when we create a player gravity we only want to do when we are pressing a button so in here we want to do it and well this is then all we have to do so we have to get our player gravity and set this to negative 20. and let me get rid of key up because we are really not going to need it and now if i try this again i can see if i keep on pressing space we have a jumping player still not particularly realistic but we are definitely getting there so with that we have gravity and the ability to jump and actually on that note i also want to reactivate this mouse motion to click on the player so what i want to do in here is if the player is clicking on the player i want the player to jump as well and this could again be a good exercise for you that just implement some kind of system that if the user clicks on the player then the player jumps as well so pause the video now and try this yourself so to fix this kind of problem we have a couple of different ways to go for example we could check our most position and then check if there is a collision and we are pressing the mouse button or we could check if we are pressing the mouse button and then there is a collision and that's basically the same result in my case i first check if the mouse button was pressed in the first case and then i checked for a collision and the different approaches here really aren't going to make a big difference although they might make a small difference and keep that in mind that if we first check for mouse button press and then we check a collision is more efficient at checking for a collision and then for a mouse button press because checking for a mouse button is much easier than checking a collision and it's not going to make much of a difference but if you have 20 or 30 of these small differences they might actually add up to a faster game so just keep that in mind for actual games that you always want to have the most efficient way to run your game which can make a difference but alright let's actually implement all of this so here i'm back in the code and i first want to check for mouse button press so this is mouse button down so we check if any mouse button was being pressed and i'm not going to care which mouse button so any mouse button is fine and then i actually already have all the code we are going to need so if if player collide point event pause this still works because the event position we can always check and well if that's the case let me put it on the next line i just want to copy this code here and then add it in there and let me actually try if this is going to work this is going to be slightly difficult to do and yeah now if i click on the player we can indeed see that the player is jumping if i click on it although it's much harder to do than just pressing space alright this is indeed working so with that we have some kind of gravity and a proper jump mechanic and there's one more thing i do want to do and that is to get rid of all of this stuff down here because we are not going to use any of those for a while and i want to keep my code clean so all right with that we have quite a bit of progress now there's one more thing i do want to achieve that i want to create some kind of ground for the player and here you might be tempted to do something very inefficiently that you might want to check the collision between the ground and the player and anytime the player is colliding with the ground we want to move the player up and this would be possible but it also wouldn't be a good solution for the simple reason that is complete overkill that we don't really have to check for collision with the ground because we effectively only need one point and that is the point 300 on the y-axis and if the player is going below that we want to move the player on top of it so effectively we don't want to check a collision we just want to check if the player is on that point so here we are only going to simulate a collision there's no actual collision all we really are going to do is if the player is below 300 we are going to put the player at position 300 and that way it's going to look like the player is standing but in reality it really isn't the case so here back in the code i want to add one more line before we draw the player and that is if player rect dot bottom so we check the bottom of the player is greater or equal than 300 so this position here and this is why i've chosen 300 that the top of the ground and the bottom of the player once those two are identical of the players overlapping with the ground if that is the case i want to get my player rectangle and the bottom of it and set this to 300. so every time our players exceed in the ground we are going to set the player on top of the ground and well that's all we have to do so now our player is going to stand and if i jump we are falling down and well the player is still standing on the ground so now it looks like there's a collision with the ground on the player but in reality there really isn't and again this is a common thing for video games that you just simulate something that looks realistic to us but well we're not really creating the real thing because that would be really difficult to do so all right with that we are almost done there's one more thing that we have to address and that is let me run the game again now if i keep on pressing space while we are in the air our player keeps on jumping so effectively we are flying and well this i want to get rid of and this we can do quite easily all we have to do is in these two lines we have to add one more condition that we are only able to jump if we are touching the floor and this again could be a small exercise for you so again if you want to code along try to figure this out yourself that how can we check if the player is touching the ground right so all we really have to do in here is to check if our player rectangle and the bottom of it is greater or equal to 300. effectively the same condition we have used down here and well that's literally it and don't forget an end between the two so it works and this we have to do for both of these if statements you could also put all of this inside of an if statement it really doesn't matter but now let me run all of this again and now i keep on pressing space but the player is only going to jump if we actually touching the floor so this is then getting much closer to an actual game and in here i can almost try to play the game where we are well having almost a game nothing really happens yet if our player touches the snail but that comes next so let's talk about that part that i want to end our game if our player touches one of the snails and well we already have the collision mechanics so this is something we can already implement and let's actually do this right now so here i'm back in the code and again somewhere in our game loop i want to implement a function that ends the game if our player touches the snail and let me add a comment first so we have collisions here and all i want to check for now is if our snail rectangle is collide wrecked with the player rectangle and this has to be an if statement of course and if that is the case for now i just want to end the game so i just copy those two lines and if this is working then our game should just end if these two collide so let's run all of this and we can see our game is ending once the player is touching the snail so this would kind of work and we would actually have a game at this point obviously not a very good game but this is kind of working but instead i want to do something slightly different that i have two states in my game one is the actual game we have already seen but then i want to have some kind of start screen so that if the player is colliding with an object we are coming to an overview screen where the player can see the score and press a button to start again so for that we have to figure out how can we have different states in our game and well the answer here is actually surprisingly simple that right now in our game loop we are drawing and checking certain things and all we really have to do is to put all of this inside of an if statement so for example if our game is active we want to draw all the stuff we have seen so far however once we are colliding we are setting this game active to false and then we have an else statement that draws something else that's literally all we have to do now obviously this is a very simple setup and not particularly good for really complex games but it is the basic logic you have to understand to basically create any kind of multi-level system so let's start by implementing that one so here i'm back in the code and right at the top because it's an important variable i want to create game active and this by default for now is going to be true and then further down all of the stuff we have drawn so far so literally all of this bit here we only want to do if our game is active and actually if i go further up this part here as well i only really want to do if our game is active although that we are going to work on later for now i just want to put all of this here into an if statement so i'm going to indent all of it and add an if statement so if our game is active then i want to do all of this and since this game active right now is true i can run the game and we have the same outcome cool so this is still working but now what i can do is if i was nervous colliding with the player i want to set my game active to false and now if i run this and our player is colliding with this nail well nothing is going to happen anymore our game stops for the simple reason that we don't update any of this anymore but we don't draw anything on top of it so all we can really see is the last frame of this game loop but now what we could for example do is add an else statement in here and let's say for now i just want to screen dot fill and let's add yellow just to see what happens so now i use the game and now we have yellow and then here we could literally add any kind of code we want so this could be much more extensive and we are going to add quite a bit on this later on but for now this would be pretty good way to separate our game that all of this code here is going to be our actual game or the game part of our game and all the stuff down here is going to be some kind of intro or menu screen and that way we can separate our game into logical parts that are also going to be easier to work with and well with that the one thing we have left to do for this part is to set up some kind of way to restart our game and well all really have to do for that is if our game active is false we have to check for some kind of player input and if that's the case we're going to restart the game and this is then going to bring us up here that right now we only want to check all of this if our game is active and then we want to do something else down here if the game is not active anymore and this could be a good challenge for you that if game active is false and we're pressing the space button we want to restart the game try to implement this yourself and see how far you get the first thing we have to do just like with our main code we want to put all of this inside of an if statement that if game active we are checking all of this and what we can do now is add an else statement in here and i just want to check if we are pressing the space button so let me copy this line here so right now we're checking if our key is down and we could also put these two lines here on the same line just to save some space and let me do that now so i want to check if the event type is key down and the event key is case space and if that is the case i want to get my game active and set this to true again and well let's trial of this now that's kind of all we needed so now our game stops and now i press space and okay this kind of almost worked that right now our game goes straight back because our snail if you can see it is overlapping with the player so now it stopped and now we can play again and i can jump over the snail this is actually working really well but now i collide it again and now we go to the game over state but a problem here is if i start the game again our player is still overlapping with the snail and hence the game stops after one frame so this is something we do have to work on but at least in theory for now this is working and actually what we could be doing is we can set our snail rectangle dot left to something like 800 just to make it work for now so now let's try this again so now we go to game over and now i can start again and we have a proper working game so at this point we actually have a really working game where you have a failed state where you have a challenge it's not a very good game but well it does work so for the rest of this tutorial it's basically all about making this more interesting and making our code better organized but you really have all the basics you need to create basic games so well done so far so for the next part let's start working on the score and all i really want to display here is the amount of time the player managed to stay alive so for this one we have to figure out how to measure time and for that we are going to need a new method and that one is called pygame.time.getticks and all this one is doing is it gives us the time since we started pygame in milliseconds and that is really all we are going to need to create our timer although the actual logic to implement all of this gets a little bit more complex but we get to that when we get to that so let's go into our code and let's have a look at this so here i'm in the code and right now we are creating our text right here so right now we are only displaying my game and it doesn't really do anything and further down in the game right here we are putting that text on the surface but obviously this doesn't really help us all that much so we have to make a couple of updates here and let me start by just commenting out all of this because we are going to make some changes and here's what we want to do we want to continuously update our score which means that in our game loop we have to continuously create a new score surface and put that on the screen so that every time we are creating a new frame we are also creating some new text and to keep our code a bit more organized i'm going to put all of this into its own function so here i'm back in the code and i want to create a new function and let's do it right at the top and let's call this one display score we are not going to need any arguments so let's go straight into the body and the first thing we are going to need is our current time and that we are going to achieve with pygame.time.getticks and this is going to give our time in milliseconds and let's actually for now just print it and see what's going to happen and let me actually put it into its own variables so you can work with it a bit easier let's call it current time so i just want to print my current time and now if i go down we are drawing all of our stuff in these three lines so what i want to do with them is to just comment them out for now and now let's run this and now we can see that we have a time that continuously updates at least as long as our game is active and that is our time so we can see that our game roughly ended two seconds after it started and that is information we can use very well so let me close all of this and let me go back to the top so that's the information that we want to use and all we really have to do is to put this on a new surface and put that surface on the display surface so let's create a new variable that i call score surface and for this one we are going to need our test font and render again and in here for now all i really want to display is our current time then i needed two hour arguments which is false for anti-aliasing and then i'm going to need the color which was 64 64 and 64. so now we have a new surface now with that we have to create a score rectangle and this one is just going to be our score surface with get rekt and in here the center is going to be 450 the same position we had earlier and now the final step we have to go with is screen dot blit and we want our score surface and our score rectangle and then i can get rid of our print statement and we should be good to go at least in the most basic sense and we are getting an error because this right now is an integer and this function here wants to have a string so we can approach this in a couple of ways in my case i'm going to put this into an f string so that way it's going to be converted to a string anyway and now let me run all of this and you can see a score and if i keep on running the game this is still working however here's one problem right now the game ended but now if i restart it the score has continued to increase which obviously doesn't work too well and here it's really important to understand what get ticks does and what it does is it gives us the time since pygame started or more specifically since we called pygame.init but obviously in our current setup this causes a problem because we only check the current time we don't really adjust this for restarting the game which is what's causing the problem here so how can we adjust for this and well the answer here is kind of simple all we really have to do is when we are restarting the game we are taking the time when the game is restarting and then when we are calculating our score we are always subtracting that beginning time from our actual score and that way we are always starting from zero and going from there so let's implement that and the first thing i want to do is to create a new variable that i'm going to call start time and by default this one is going to be 0. and now essentially what i want to do is when i'm getting this number i want to subtract my start time from it so i'm going to subtract my start time from it now right now this really isn't going to do much because we just subtract 0 from this number but now what i can do if i scroll down a bit in this bit here i am checking for keyboard input to restart the game and what i want to do in here once this is activated i want to set my start time to pygame dot time thought get ticks and that in the most basic sense is all we needed so let's try this now so a game still works properly well now i failed and let's try it again now and again we start from zero it's very hard to see because our counter starts too fast but it does work and let's try it again let's restart and this is still working pretty well so this is actually working really well cool and let me just go through what happens here now every time we are looking for our current time we are checking in this bit here our current time since the beginning of our game so since this line here has run however from that number we are going to subtract the start time so when the current iteration of our game has started so that way every time the player starts the actual game part of our game we are going to have a zero for our score and then we're adding towards that score which is then giving us a proper scoring system now there's one more problem that right now if i run it again i think the score adds up a bit too fast and it's very hard to read so i don't really want that high of a number i want this to look more like one two three and four and so on and that could actually be a really good exercise for you try to change our current time in such a way that you get more manageable numbers now for this exercise i think it was very easy to overthink the problem which is a common issue in programming so let me explain my approach essentially this pygame.gettix gives us the milliseconds so if we add second one we would have a number of 1000. now this number i want to get to look like a one and really all we have to do for that is to subtract this thing by one thousand and that literally is all we had to do in here so what i want to do is to subtract this number by 1000 and let's put it into brackets just to be a bit more clear and what you can also do to avoid floating point numbers is to set this to an integer so this way this number here would always become a zero or one or two and that is then the number we want to go for now there's one important thing you have to be aware of that let me copy it that right now when we set our start time this has to look the same actually let me demonstrate what happens if we don't do it so let me run the game now we get 0 1 and this is working really well but now i failed let's start again and now we get negative 5000 so this is well kind of weird and the reason for it is that this number here returns numbers in the thousands this one here returns numbers from 0 to 10 basically so that's something to keep in mind but alright so if i add this in here now our game should be running pretty well and the score is updating properly and if our game ends and i start again we start again with zero so this is working quite well and i think i have to increase the speed of the snails that's a bit annoying but okay i'm gonna work on that in a bit there's one more thing i would like to add and that i want to actually call this score just to be a bit more clear so now if i run this again you can see score at the top but let's well it's up to you if you want to add it now next up i think the next big issue is that our game over screen looks kind of empty so i want to add a couple of things to make it look a bit nicer which is going to end up looking like this that we have our player in the middle we have the name of the game and we have a short line at the end that tells the player how to restart the game none of this is particularly fancy and you should already be able to do most of this although there's one more important concept i would like to add in here and that is how to transform surfaces so for example if you want to increase the size or rotate the surface that's what transform is all about and well pygame has a transform method and if you look in the documentation this part of pygame has lots of different methods that you can use for example you can rotate something you can scale some you can flip something you can do lots of different things with surfaces now in my case all i really want to do is to scale up our player to make it look a little bit nicer but all of the transfer methods work in basically the same way so let's actually jump into this so here i'm back in my code and let me minimize our display score first because we're not going to need it anymore now next up i want to create our game over screen in here and all of this our game so far we can ignore because we're not going to work on it so i am going to minimize all of this and let me also minimize the event loop so all of this is a bit easier to see and first of all i don't want this to be yellow anymore instead i'm going to add a tuple that is 94 129 and 162 and actually just to test all of this i'm going to set game active to false when we start our game so that way we go straight to the game over screen so let's run this and now you can see a much nicer color and again if i press space our game starts as always so this one is working pretty well cool and i guess with that we can add the player in the middle of the screen and for that i first want to import our player and let me do this right in the beginning so i already have my player variables and i want to create a new one here let's call this player stand and all we have to do in here is pygame.image.load as always and there's one file that is just called playerstand and i am going to import is like all the other ones and i'm going to convert alpha this as well and now on the next line i'm going to call this player stand a rectangle and this one is just going to be player stand and get rekt and then the center is going to be right in the middle of our screen so 400 and 200 and let me actually add some comments um i think that's a bit easier to see so let's call this intro screen now this is then what i want to display in the game over screen so all we have to do in here is to use screen dot blit and our player stand and our player stand rectangle so now let's try this and then we can see our little player this works pretty well so far so now i want to scale this one up and how would i do that and to scale something in py game we actually have a couple of different methods so if you open the documentation we have scale we have rotozoom we have scale to x and we have smooth scale and they all essentially do the same thing that they are changing the scale but they do it in slightly different ways and the result is going to look different depending on what method you are using but for now let's keep things simple so i just want to use pygame.transform.scale the simplest one i would say and if you open this one it tells you to add at very least two arguments the surface you want to scale up and then a new width and a new height both inside of a tuple and then this one is going to return a new surface and then you can use this surface like any normal surface so let's have a look at that now when i import our player stand i want to create a new player stand and just for clarity let's call this scaled and really all i want to do in here is to get my pie game transform and scale and now i am going to need a tuple with my wife and my height and unfortunately here right now i have no idea about the dimensions of our player um so let's go with random numbers let's say for the weft i want to go with 200 and for the height i want to go with 400 and well now for our player stand rect we also have to update this but all we have to do is to get a new variable so now i am simply updating this line here to get a rectangle around this new scaled surface instead of our player stand and besides that i also have to update the player stand down here to have this scaled one in there so let's do that as well so we want player stand scaled and now this should already be working so let's try it and there you can see our player is very obviously scaled up really doesn't look all that good so let's close this one but this would be one approach with scale although not a very good one and not the one i would recommend to use however before we are learning a better way to scale something there's one more update i want to make because right now this here doesn't feel like good code because we are creating more variables than we really need to so let me update this slightly before we get into the proper bit and really all we have to do is to get rid of this scaled and then again we want to get rid of this scale as well and this scale at the bottom here and uh well that's all we have to do so let me go for what happens here that's kind of important to understand we are starting number one by importing this image now on the next step so this number two here we are taking the image and then updating it with this pygame.transform.scale and this one is returning a new surface and we're using that new surface to overwrite the initial surface and that's perfectly fine to do that you take one surface you scale it and then you assign it to the variable that you originally used and then we are creating the rectangle in step number three and then in step number four you are drawing all of this so i hope that makes sense and this is something you see fairly often and also what you see fairly often is that you could just take all of this and paste it directly into the scale method and if i run this this would also still work although the downside of that is you would get one very long line that i think would be quite hard to read so i'm not going to do that and i think this is a fairly good middle ground between readability and efficiency of code so i'm going to go with that one however the problem now is that this scaling just doesn't look very good because it well it distorts the image a lot and there are two methods that would be better here the first one is called scale 2x and this one is a really simple scale method all it does is it takes a surface and makes it twice as large and this one works by just calling scale 2x and this one needs only one argument and that's the surface you want to scale so now let's have a look at this and now we can see a much better player but there's one more method that i do want to show you and that is called row to zoom and rotozoom is a more complex method because it does three different things that you have to be aware of number one it rotates the surface number two it scales the surface and number three it filters the surface and the filter here is intended to make the resulting surface a bit smoother so to make it look a bit better in some instances and to call rotozoom we are going to need three different arguments we need the surface the rotation and the scale so let me update this to row to zoom we are still going to need our player stand for angle for now i'm going to go with zero and then for the scaling let's go with two and that literally is all we needed so let's run this and now we can see a surface that looks very similar although if i compare these two images side by side you can tell some very slight differences and this is because of the filtering and i actually think this rotozoom looks the best so i am going to stick with this one and actually what you can also do with rotozoom you can change the angle so if i change this to for example 90 we would also get a rotated surface so this is a very easy way to both scale and rotate something and still have the resulting surface look quite good but i don't want to rotate it so this one is perfectly fine by itself so alright with that we have learned about the basics of influencing a surface now next up we do have to add a couple of lines of text so we do have to add the name of the game the score and the instructions to start the game and this could actually be a really good exercise for you that try to implement all of this yourself and see how far you get but at this point you know all the tools to make this work so here we are back in the code and i am going to go to our intro screen and in here i just want to create a new variable called game name and for this one we need our test font.render again and now we have to specify the name of our game and i just called this one pixelrunner but well give it whatever name you want then for ntl you're saying i want false and for the color i go with one one one one nine six and one six nine so with that we would have the surface of our text next up we would need our game name rectangle and this one is just going to be game name dot get wrecked and this i want to place at position 400 and 130 so in the middle of the screen slightly to the top and that is all we needed to get the name of the game so now in our game over loop we have to draw all of this so we just need screen dots blitz then game name and game name rectangle and now let's see and that is a little bit too far down so let me go up again and let's put this to let's go with 80. and that is looking much better all right so with that we have the name of the game in there everything else still works just the same cool and now i'm going to add a second bit of text and this one is going to pull double duty if there's no score it is just going to tell press space to run however if there is a score it just shows the score and to implement all of that all we really need is an if statement that cycles between two different text surfaces so let's start with the first text and this i called game message and this again we need to test font.render and test font really isn't a good name but i guess now we're stuck with it and this is press space to run then i want false again and now for the text color i just want to copy the text we had above so with that we have our surface and now i want my game message rectangle and this one again is going to be game message dot get wrecked and here once more i want to place the center and now in here i want to put it in the middle and no for the y position let's go with 320 let's see if that one is going to work and well now again we have to go with screen dot blit i called this game message and game message rect and let's see if this one is working and it does not let's see what went wrong here oh and the reason is that i have the wrong rectangle so this should be game message wrecked there we go this is much better and i think i could move this text slightly further down so let's go with 340. now this one is again and uh okay tiny bit higher so now the last thing that we have to do is to add some kind of if statement that we only show the text if there's no score and if there is a score we don't want to show the game message instead we want to show the score and for that we do have to make a couple of changes so let me go through them one by one and i think it's best to explain it first and then we get into it so right now we are keeping all of our score instead of the update score function which works fine by itself but we want to access the score to display it in our game over screen so we have to get the current time variable inside of the update score function and for that we could either create a global variable or we could return the value and both would be okay i'm going to go with the return statement but once we have that all we have to do is to put this current time on its own surface and then display it that's literally all we have to do so let's go back in the code and let's have a look at this so here i'm back in the code and right now the variable that we have to access is this current time here because that effectively is our score so how can we access this we could either go with global current time [Music] to make it accessible everywhere or what we could also do is after this function is run we can return current time and this is the one i'm going to go with because it's a bit more focused so now that we have that i can create another variable let's call it score and this by default is going to be zero however now every time our update or display score is going to run this score is going to get the value of whatever is being returned by this display score which is going to be our actual score so this way we can access the value of our score basically any time so now what we have to do in the game over screen we have to turn this into a surface and well this is going to work in exactly the same way as before so i create a new variable let's call it score message and this one again i want my test font.render and in this case i want to go with an f string that says your score and then we put our actual score in there then again we need false and for the color i am just going to copy this same one again and then after that you should know this by now really well we want to turn this into a rectangle or we want to put a rectangle around it rather so i want score message dot get rekt and for the center i'm going to go with 400 400 and 330 so now this is going to give us our score and now this score i only want to print when there actually is a score so when we are starting the game this isn't visible however as soon as we have a score all of this is going to replace this game message here and well to achieve all of that all we need is an if statement so if our score is equal to zero we know we don't have a score yet and then i want to display my game message and if that is not the case so else i want to go with screen dot blitz and score message and score message wrecked and well let's try so i can run the game we can still see our basic setup now let me run it now we get a score of 2 and there we can see it so now every time we have a score we can see it and this is looking really well then so i can also jump over snail or i can't and now we get a score of four so this one is indeed working very nice and let me just update them ever so slightly to put them on the same line because that feels better cool so all right with that we have all the text that we are going to need so with that let's work on another really important topic to make the game look better and that is to spawn different kinds of obstacles so right now we only ever have a snail and i want to mix this up a tiny bit that we have a chance to ever get a snail or a fly so the player has to make a choice between jumping or well not jumping and this is going to be a really good opportunity to work on something a bit more complex to spawn our enemies because right now this is a bit overly simplistic that we don't really spawn multiple enemies instead we have a snail we keep on moving from the right to the left and then we just place it back to the right and the problem here is that we have very little control for example we don't have control how fast the snail is moving and we also don't really have control over how often it's spawning so it's always the same interval which is kind of boring and to update it we are going to need one new concept and that is a timer so that we can tell pygame to run a certain kind of code in certain time intervals and this timer is going to be quite simple because all we really are going to do is to create a new user event that's triggered by pygame and so far all of our user events were something the player is doing but that doesn't necessarily have to be the case because a user event could also be triggered by pygame and a timer is one of those instances where we tell pygm to trigger a user event at certain intervals which is what a timer really is and there are three steps to doing all of this number one we have to create a custom user event number two we have to tell pygm to trigger this user event at a certain interval and then number three we have to add code in our event loop to do something when this event is being triggered but that is all we needed so let's actually implement this so here i am back in the code and let me add a new section with a comment let's call it timer and in here i want to have an obstacle timer and all we need to create a custom user event is pygame dot user event all in uppercase letters and here one important thing is to add plus one the reason for it is that there are some events that are already reserved for pygame itself and to avoid a conflict with those we always have to add plus one to each event we are going to add and if you want to read more on that there's quite a bit more in the documentation on this but by itself that's all we need here so this would be step number one that we have created a custom user event now what we have to do is to trigger this event in certain intervals and this happens with pygame.time.set underscore timer and this is going to need two different arguments number one the event we want to trigger and number two how often we want to trigger it in milliseconds so in my case i want to trigger my obstacle timer and i want to trigger this every 900 milliseconds so a bit shy of one second but with that we have a timer so now in my event loop i want to go all the way to the bottom and here we are going to add a new event so here if event dot type is equal to obstacle timer and if that is the case for now let's just say print test and now let's run it and we can see test just about every second so this one is already working pretty well so with that we have a timer and i guess one thing we can add already here that we only want to run this if our game is active because if it's not active we don't have to spawn an enemy so now let's trace again now we can't see anything and if i run the game we can see test every just about one second cool so now we have a timer but how can we use that timer to work with our obstacles and well here we have to make quite a few changes so let me explain this first and then we are going to implement it but before that let me go down a tiny bit i want to get rid of this snail movement we had so far because this one is not going to be needed anymore so let's talk about how all of this is going to work now first of all we have to create a list that is going to contain all the rectangles of the obstacles and every time our timer triggers we are going to add a new rectangle into this list and then on every single cycle of our game loop we are going to move every single rectangle inside of that list a little bit further left and if any of these rectangles goes too far to the left we are going to delete it and that way we can continuously create new enemies and move them to the left and if they get too far to the left we just make them disappear so ultimately a fairly simple idea so let's implement it so here i'm back in the code and right now we have all of our enemies in here or our one enemy right now and let me add a section here as well let's call it obstacles just to keep the code a bit more organized and all i want to do in here is to get an obstacle wrecked list and right now this is just going to be an empty list and now when we go to our timer so down here all i want to do is to get this obstacle racklist and append something new and what i want to append is the rectangle and this we already have so this is going to be this rectangle here so i can just copy it and paste it in here although we have to make one update that right now this 600 needs to be higher so it just snails outside of the screen and i want to have a value between 900 and 1100 and for that we are going to need a random number so let's import one so at the top i want from random import rand and this is just going to give us a random integer between two boundaries and that is exactly what i needed so now in here all i want is to get my rent int and this is supposed to be between 900 and 1100 so that way the snail is going to be spawned slightly to the right of the screen and then we are moving it further to the left so this is then going to give us our list but obviously right now nothing is going to move so to fix that we have to create a function that takes care of all of that and well let me put it somewhere in our game active loop and let's put it right after the player so let's call it here obstacle move mint it doesn't really matter where you put it just whatever makes the most sense to you and in here i want to create a new function that is called obstacle movement and in here i want to add one argument and that is the obstacle rack list so we know exactly what we are working with and well let's create this function so at the top of the code i want to create obstacle underscore movement and in there we need an obstacle list and now we have to work with this list however we first have to check if there's something in the list in the first place and that we can just do if obstacle list so this here is going to work because python if it finds an empty list is going to evaluate that to false so if our list is empty this if statement is not going to run but if it is going to run we want to cycle through all of our rectangles inside of that list so let's call it for obstacle rect in obstacle list and then we want to move with every single of these obstacles so obstacle rect let's call it dot x minus equal and now we have to define a certain kind of speed let's say i want to go with five and that way every single obstacle would be moved to the left by a tiny bit on every cycle of our game loop so this is exactly what we needed but right now obviously you can't see any of this so this is something i also want to put right inside of here although you could also place it in a separate function but in my case i'm going to be a little bit lazy but all i want to do here is screen dot blit and for now i just want to get my snail surface and then go with my obstacle rect so that way we are moving our rectangle and drawing the surface in the same position all in one go but right now we have a little bit of a problem that right now all the stuff inside of this function here is going to be a local variable and we want to make sure that we are targeting the global scope and really all we have to do to fix that is after we have done all of this we are returning a new list so the list we just created so return obstacle list and then in our game loop when we do all of this here i want to get my obstacle right list and overwrite it so let me explain what happens here we first run this function here and this is going to take our obstacle rack list and move every single rectangle inside of it a bit further to the left and after that's finished we are going to take this new list and overwrite the previous list and that way we can continuously update our list and not worry about scope in too much detail right so let's try all of this and we are getting an error and the reason for it is that python told us that non-type has no attribute append and you might already be able to figure out what went wrong here and let me explain basically if we run this in the beginning there's nothing inside of this obstacle list because our timer hasn't triggered yet and as a consequence this entire thing is going to return none and none doesn't have the append method so what we have to do if there's nothing inside of this list we have to else return an empty list that's not an empty list that's one and that way our append method should still work so now let's try this and let me run this and now we can see our snails obviously they're all way too fast right now or the collision doesn't work anyway but now you can already tell that some of these snails move slightly differently because we have changed the starting position so cool this is already working and i guess what we can do is that this 900 is probably a bit low let's go with a thousand four hundred let's try this now and let's see uh potentially still a little bit fast but i think this is kind of workable um okay let's go with 1500 so with that we have a slightly more robust system to work with our obstacles but there are a couple of problems with this and let me go through them one by one number one the one problem we have already seen is that our collisions do not work anymore so that's one thing we have to work on number two is right now when our obstacle leaves the screen we don't delete it so we are going to end up with a longer and longer obstacle rack list something we really want to avoid because it would eventually slow down our game and number three is we only have one type of enemy so that's also something we have to work on so let's start with number two that we want to delete a rectangle if the rectangle goes too far to the left and this we can do inside of our function so inside of this function we want to check if any of these rectangles is going too far to the left so if this number here goes to let's say lower than negative 100 and if that's the case we want to kill it and all of that we can achieve fairly easily with list comprehension so what i want to do is to get my obstacle list and assign it a new list already and this list comprehension is going to check all of our rectangles and then see if they're too far to the left so all we have to do in here is to go obstacle for obstacle in obstacle list so this right now would only copy the existing list so it wouldn't do all that much however what we can do now is we only want to copy an item if obstacle dot x is greater than zero so that way we are only going to copy an existing item in the list if x is greater than zero so that way we are only going to copy every single item of the list if the condition is true that the x attribute is greater than zero so if the obstacle is on the screen and if that is not the case we are not going to copy the item and the item is going to disappear and actually let me go with minus 100 so we know that the obstacle is off the screen for sure so this would already be the first problem we had to target that we wanted to delete the rectangles if they leave the screen so with that let's go to the next point that right now we only have one type of obstacle which really isn't looking all that good so instead i want to have two different kinds of obstacle and if you check out the folder there are two different types we have a snail and a fly and i want to randomly spawn either a snail or a fly and this isn't very difficult to achieve but it does need a couple of steps to work through it so let me explain it while i implement it i think that is going to be the best way to approach this so all right let me minimize the function we are not going to need it for a bit and instead in my rectangles i want to import a new variable and let's call this fly underscore surface and this is just going to be pygame dot image dot load and the path towards this fly is going to be graphics.fly.fly1 again we have several images to get an animation we are going to cover that very soon but next up i need convert alpha and that is all we needed oh and actually i just realized this snail rectangle we don't need anymore so all right now we have our fly surface and now we have to add this to our obstacle rack list so right now we always add the fly towards this and here we want to randomly assign either the snail or the fly however there is going to be a problem that the fly cannot be on the same y position so while the snail is on position 300 the fly has to be higher up because it's well flying so we can't just add a random statement in here but we can overcome this fairly easily because all we have to do is to run an if statement that randomly triggers either true or false and in my case i'm going to use rand in to do this so here we have rent in from 0 to 2 and this is going to give us a value that's either 0 or 1 and 0 would evaluate to false and 1 would evaluate to true so that way we have an if statement and randomly triggers true or false and if it is true i want to create a snail and if it's not true i want to create a fly so let me just copy this entire line here and now i want to get my fly surface and the x position for that is still perfectly fine but what i want to change is the y position because this one has to be high up and in my case i went with 210. so this way would be slightly higher up and now let's actually run this and see what's going to happen it's not going to work perfectly just yet oh and we're getting an error because this snail rect.left shouldn't be in there anymore now let's try this again and we are getting another error somewhere down here oh but we have the collision so this one should also go because we don't need it anymore and i hope now it's working there we go so now we can see a snail we can see another snail and now we can see a flying snail um i guess that also kind of works so the problem here now is that we always draw the surface of the snail on top of the screen and that would be a problem so let me go to the part in the code in our function that right now it doesn't really check in our function if we are drawing a fly or a snail we are always drawing our snail and this is something that we have to change so we have to figure out in this function if the obstacle rectangle is for a fly or for a snail and the problem here is that the rectangle by itself has no information if it belongs to a snail or to a fly it is literally just a rectangle of a size and a position but that information we can use because we know it at the bottom of the snail is at position 300 and the bottom of the fly is at position 210 so really all we are going to do in here is if the bottom of the rectangle is at position 300 we are going to draw a snail and if it is not the case we are going to draw a fly and that way we are going to draw only this surface that's appropriate so let me cut this out here for now and i want to get an if statement that if obstacle rect.bottom is equal to 300 and if that is the case i want to draw my snail and if that is not the case i want to draw my fly surface and i guess again i can put them all on one line that tends to make it look a bit cleaner and now let's try all of this again now we get a snail and now we get a fly cool so this is working pretty well oh yeah i don't actually have to jump it still works just fine and uh we are getting a lot of snails but we do get the odd fly eventually cool so let me remove a bit of the white space here and now we can close our function and never think about it again so with that we have different kinds of obstacles now the final thing i want to work on is a collision between the obstacles and the player and this i want to put in a whole new function because that i think is going to make the most sense but really all that we are going to do in here is we are going to check the player and the obstacle rack list and if the player is colliding with any of the rectangles inside of that obstacle rack list then we want to end our game and that is going to work in a very similar way compared to the obstacle movement function that we are just going to use a for loop to get every single rectangle inside of the list and then on every single rectangle we are going to call collide rect so let me start by creating a new function so let's call this collisions i guess that kind of works and in here i want to have two arguments first one is the player and then i want to have the obstacles and in here again i first want to check if there are obstacles in the first place so if obstacles very similar compared to what we have done earlier so let me actually open both functions so right now this one here is pretty much the same thing we have done up here now next up i want to cycle through every single rectangle inside of this list so for obstacle underscore act in obstacles and now i want to check if any of these obstacles is colliding with the player so if player dot collide rect with the obstacle rectangle and if that is the case i want to do a certain thing and now we have to figure out what certain thing i want to do and here let me explain the problem that right now we have all of our code inside of this function in the local scope so all of this here is the local scope but the problem with that is that we let me go down a tiny bit that here again we have our global scope and the problem is that this game active controls if our game is active or false and this game active is in the global scope so we have to work out how to get from a local scope to the global scope and well here again i'm just going to use a return statement so i'm just going to return false so as soon as our player collides with any of the rectangles this value is going to return false and all of this here runs without doing anything then we want to return true and now all we have to do is to either assign this return false or return true to gameactive.false to gameactive in our game loop so all i have to do is to go down to my game loop and in here we still have our collisions let me put it below there and there i want game active and this is going to get collisions collisions this one and here the two arguments we are going to need is our player rectangle and we are going to need our obstacle rect list and that should be all we needed so now let's run this and let's see if this is working and yeah there we go so now our game is going to end if we collide with any of the obstacles and just to explain what happens here that this collisions can either return true or false if there's a collision with an obstacle it is going to return false so this game active here is going to become false and we are going to the else statement because this game active all the way to the top is not true anymore however if that is not the case and no collision triggers this collision here is going to return true so this game active stays true and we just keep on going back to game active so that way we have a proper collision mechanic however now we have one more problem and let me run the game again and let me just collide with one of the snails and never run the game again we still have to snail in the same place so this is crashing our game immediately to account for that when our game is over i want to empty our obstacle reckless and well all we need is to get our obstacle rack list and clear it so that way we are going to so that way we are removing every single item inside of it and now let's try this again and now we crashed and now let's rerun the game and now the game restarts properly so this is working quite well cool and actually while we are in here there are two more things i would like to add number one is i want to put my player rectangle at the bottom again so dot mid bottom is going to be 80 and 300 the same positions we have specified earlier so that way the player is always going to start at the bottom of the screen so for example if we jumped into a fly at the end of the game and crashed because of that our player would restart at the bottom so that i think makes it look a bit better and along with that my player gravity should also be zero so that way we start at the bottom and don't fall any further it just makes the game a little bit cleaner so alright with that we have made pretty good progress that now our game has multiple types of obstacles and everything else is still working just the same cool now with that we can start addressing something slightly more complex and that is to animate the fly the player and the snail so that we don't have a static image instead we have an animated image that looks significantly better however to achieve that we are going to need a couple of different things but in the most basic sense we don't really do anything complicated so let me explain what we are going to do in the most basic sense all we are going to do is to update the surface we are putting on the screen every few milliseconds so for example for the snail sometimes we are drawing one image and sometimes we are drawing an other image and these images are very very similar but slightly different and if you put them together fast enough it looks like the snail is actually slivering walking moving well moving in an animated way whatever you want to call it and all we really have to figure out is how to update the surface every few milliseconds and this can be done in a couple of different ways as a matter of fact our player animation and our obstacle animation works in different ways for our player animation we're going to create a random timer that updates on every single cycle of the game loop and if that number becomes too large we are going to change the image we are going to placing on the screen and for our obstacles we are going to create a new timer so that we are changing every few milliseconds what kind of surface we are going to put on the rectangles and that again was me talking way too much let's actually look at this in code and let's start with the player i think that's going to be the easier one so here we are back in the code and the first thing i have to do is to import a couple more images because that's what we need for animation so if i scroll down a bit in this part here we have imported the player image so far which is player walk one and what i want to do for now is to import more and put all of this into a list so let me rename a couple of things first of all this isn't supposed to be player surf anymore this is supposed to be player walk 1 or underscore 1. then i want to copy the entire thing and have player walk 2 and this is going to be the other image so our play has walk 1 and walk 2 and if you play those two fast after each other you have a walking animation and those two surfaces i want to place into a list that i call player walk and this is literally just a list with player walk 1 and player walk and then besides that i also want to import a file that i called player jump and this is just going to be another surface so let me copy the entire import line this is just going to be jump.png and with that we have a surface that we want to display when our player is jumping and when our player is walking i want to alternate between these two different surfaces but there's one more variable that we are going to need and let me place it right under the player walk list and i've called this one player index and by default this is going to be zero and what this number is going to be is later on we're going to use it to pick either this surface here or this surface here and i have just realized that this should be player walk one and player work two so basically this player index is what we are going to change to pick either the first work surface or the second work surface and we don't need that for player jump because we only have one surface for the jumping and we can actually start using our player index right away because right now we need a player surface to get the player rectangle and this i just want to get back with player serve and when we start the game i just want to go with player walk and from that i want my player in this one so all this one right now is going to do because it is zero it is going to pick the first player walk surface so right now we haven't really accomplished anything we just imported a couple more images that don't really do too much right now so to actually make all of this work we have to create a function and let me go all the way to the top and create a new function here and i have called this one player underscore animation spelled correctly really helps and in here we want to do a couple of things we want to play walking animation if the player is on floor or we want to display the jump surface when player is not on floor so yeah i hope that makes sense and this player animation i want to call in our main game loop so all the way down here let's say we can place it right before we bled the player's surface that kind of makes sense i think so now we have to create this function properly and the first thing we have to do is to declare a couple of global variables because we want to work very much outside of this function and the two variables that we need is player surface and player index so we want to work with this player index here and this player surface those are the only two that we really have to influence from inside of the function okay so with that we first have to figure out if the player is on the floor or not so that we can either display a jumping animation or walking animation and well this is literally just an if-else statement so if player rectangle dot bottom is let's say smaller than 300 then i want to show the jump animation and if that is not the case i want to show the walk animation and in here the jump animation isn't actually animation it's just the surface that we are displaying so all we have to do here is to set our player surface to our player jump i start to have a ton of variables but this is literally all we have to do to get the jump animation so if our player is not touching the floor or is above this y position we are just displaying the jump image so that's literally it but now for the walking animation this gets a little bit more complicated because in here we want to alternate between work surface 1 and work surface 2 at a fairly slow speed and this i want to do with the player index so the variable we cleared earlier so i want to first target that one so player index and i just for now just want to add not one but 0.1 so i want to slowly increase this number and let me explain what i'm actually going to do so let's say here we have our list with our two work surfaces so we have w1 and w2 short for walk one and walk two and by default walk index is going to be zero and let me use a different color for this actually so by default this walk index is going to be right here because it's zero and then i don't want to jump straight to the next frame to walk two because that's going to be too fast instead i want to increase walk index only by smaller increments so it takes a couple of frames to get to work to which will be our index one this is why i'm only adding 0.1 but if i were to add 1 here we would straight jump to the next walk cycle but that would be too fast instead i just want to go much slower so i hope that makes sense so with that what i want to do now is to get my player surface again and just look at my player walk list and from there i want to take the index of the integer of player in dex for the simple reason that we can only take the index with an integer and this would already kind of work with the simple problem that we would very fast run out of this list so this number here would go to one and then would go to two then we go to three and so on but our list so this player walk only has two elements zero and one so what we want to do is after we reach one we want to go back to zero so we have to add a bit more code to make sure that we get this border here that we don't cross and this is fortunately very easy to achieve all we need is an if statement between these two that if our player index is greater or equal than the length of our player walk and if that is the case i want to set my player index back to zero and that is literally all the logic we needed for this thing to work and we are already calling the function so let's actually trial of this so it still works and now we have a walking animation and now if i jump we have a jumping animation so this is working really well let me just go through this really quickly again i think this needs a bit of explanation so when we are starting our game we are simply picking the first item here from our player walk animation so we just get one of the walking animation however now in our game loop further down here before we blit the player we are running our player animation and if i look at this this player animation looks at a couple of different things first of all it looks if the player is on the ground or not so here the first line or the first if statement if the player is not on the ground or smaller than position 300 we want to change the player's surface so the player image to play a jump and this way we give the illusion that the player is jumping because we changed the image but that's literally all that's happening here however if that is not the case so if the player is on the floor we want to show either walk one or walk two and to get these two surfaces we use player index and increase this number very slowly and if this number gets too large so with this if statement here we are setting it back to zero and then we use that to animate the player although animate here literally just means we have a pick walk 1 or walk 2. that's really all that's happening here but alright with that we have our player animation cool now next up i want to animate all of the snails and all of the flies and for this we have a minor problem that for the player we only had to worry about a single surface but we have lots of flies and snails on the screen so animating all of those with this method would be a little bit annoying however we can approach this slightly differently and what we're actually going to do is use a timer both for the snails and for the flies and essentially all we're going to do is we're going to create a timer that runs pretty fast so it's going to trigger multiple times per second and every time it triggers we're going to change all of the surfaces for either the flies or the snails each of those have their own separate timer and well that's all we need let's actually have a look at this so here i'm back in the code and let me first import a couple more images so for the snail we have snail serve let's call this snail frame 1 and i want snail frame 2 as well and this is literally just going to be snail 1 and snail 2. and then for the fly we have the same thing we have frame 1 and then we have frame 2 and it probably is going to make sense to separate them a bit more consistently so this is going to be snail and this is going to be fly and in here we have to do the same thing we did for the player so we want a list with all the different frames so this would be snail frame one and snail frame two and then the same for the fly so fly frames is going to be a list with fly frame 1 and fly frame 2 and then both are also going to be needing an index so let's call it snail frame index and by default this one is also going to be 0. so fly frame index going to be zero as well and then finally we are going to need a default snail so i call this one snail surface and all we need here is our snail frames and then snail frame index and then the same for the fly so fly surface and this is going to be our fly frames and fly frame index so this is pretty much the same thing we did for the player you can actually see it right below and we could update each of these flies and snails in the same way we updated the player although this would be kind of annoying because we would have to do it for every single fly or snail on the screen so that's not great so instead i'm going to create a couple more timers so here we have our timers and i want to create a couple more so the first one is the snail animation timer and i'm really bad at spelling animation i realized and this is going to be pygame dot user event plus two and then we need pygm.time.settimer and here we have our snail animation timer and for the snail i went with let's say 500 and now we need this same thing for the flies so let me just copy all of this and this is going to be our fly animation timer it's going to be plus and this one have set to 200 because i think the fly should animate a bit faster than the snail and now if i go down a bit i just want to add a couple more if statements for um updating these timers and first of all i want to check if our game is active because i only want to do this if the game is actually running as a matter of fact let's make some changes here so i realized when we call our obstacle timer we already check if game is active so i just want to take this out here and check all the timers only if our game is active so if game is active then i want to run the obstacle timer and i also want to check if event.type is equal to let's start with the snail animation timer snail animation time this one and all i have to do in here is to change our snail frame index either to zero or to one depending on what we need for the animation so if our snare frame index is zero i want it to be one and if it's one i want it to be zero and this is literally a very simple if statement so if our snail frame index is equal to zero then i want my snail frame index to be one and if that is not the case then i want my snail frame index to be zero and once i have all of this information i want to get my snail surface again and i want my snail frames and pass in there my snail frame index so this way every time this timer is running we are updating all of the surfaces for the snail so once this timer is running we are going to update all of the snail frames and well that's all we have to do and now we have to do the very same thing for the fly and i haven't done an exercise in quite a while so let's do one now that i want you guys to create a timer for the fly and this is going to work in exactly the same way as we did for the snail so if you want to go long pause the video now and try this yourself alrighty so let's copy all of our snail timer and really all i have to do is to change snail to fly so we have this fly we have this flight this is going to be a fly frame index this is also going to be fly from index then this is a fly and two more to go we have fly here and we have fly here and already so this is done all we needed for the fly animation timer and now once we have that let's try to run the code and it's still running that's a good sign and now you can see animations for the snails and i hope i get a fly soon there we go the flies are not animating so let's have a look at those and i have found the error if we go up right now we call for both timers the snail animation timer so whenever we actually call the fly animation timer i just made a typo but that's very easy to fix fortunately because this needs to be fly animation timer and now let's start off this again and let's hope i get a fly fairly soon and there we go now we have flies that also animate and this is making the entire game look much more realistic and much more well animated cool so with that we have our animation and this is another major step towards the good looking game so with that we basically have a working game but there are two more things we really want to add to this number one is music and adding music in pie game is super simple the only reason i haven't done this is because i don't want to have music in the background every time i run the game but you could add the entire music in a couple of lines of code that's not the problem however there's one more topic i really want to cover that's fundamental to pygame but unfortunately this is going to be quite a large topic so this is going to be a larger section that is going to change our code quite substantially and that is going to be the sprite class and the sprite class you see all the time in our code so far we haven't really used any kind of class but it might be really useful for example for our player we have lots of different code snippets throughout our code to make our player work but if we wanted to make changes to the player it would be kind of annoying to do because we constantly have to look around our code to find different things we want to work on and our code is still very simple so if you get a more complex game this sort of setup would be a nightmare to maintain and it would be a much better idea to have all of our player in one player class so this would contain all the surfaces the rectangle the player input all the animations all of that stuff basically anything for the player is in one class and pygame is fully aware of that and that's why the sprite class exists because all it really is is a class that has a surface and a rectangle and these are being drawn automatically in the right spot and this makes it very easy to work with all of this and in our code more specifically i want to change a couple of things into its own separate class most importantly our player is going to be its own class however i also want each fly and each snail to be its own sprite as well and this would be the most common way to organize this sort of game and well that is what we are going to implementing before we work on the music and this is going to be a larger section so well let's go through it slowly and i explain why i implement it that's probably going to be the best so all right here we are back in the code and let me give some space right at the top and i want to create a class and let's call it player and this player has to inherit from another class that's called pygame.sprite.sprite and make sure you get the capitalization right so this second sprite here has to be uppercase and next up we have to create an init method so whenever this class is created we want to do something and this needs the usual self and in here the first line that's very easy to forget we need super and then the dunder ended as well so that we are initializing the sprite class right inside of this class as well so we can access it and this class is now going to need two attributes at the very minimum one is called self.image and the other is self.rect and the image is the surface that is going to be displayed by default and direct as well the rectangle to figure out where it's going to go so we need self.image and self.rect so in here what you could be doing for example is use pygame.image.load and load for example our player walk 1 and we still need to convert the alpha of it and then for the self.rectangle we could get our self.image and then get wrecked again and in here let me for now just place the mid bottom at position let's go with 200 and 300. for now i just want to place it somewhere so i can show you what's going to happen so now we have an image and we have a rectangle so what we could do now let me scroll down a tiny bit and let me create our player is equal to layer so that way we're creating an instance of this class however if we're going to run the code now oh and i'm getting an error this needs to be called so now it's right again and now if we run the code we can't see anything but the game well still works perfectly fine so nothing is going wrong so why can't we see this class here and the reason why we can't see it is that pygame doesn't draw sprites automatically for the simple reason that a sprite is basically just a surface and a rectangle combined but we also can't use screen.blit because that isn't going to work with a sprite instead we have to do it differently instead what we have to do is take all of our sprites and place them inside of a group and then this group can do two different things they can one draw all of the sprites inside of it and it can also update all of these sprites which is going to be really useful for us later on and pygame has two different kinds of groups number one is a regular group and this one can contain multiple kinds of sprites and this would be perfect for our flies in our snails because they can all be in one big group and they are not going to interact with each other however for the player it's not really going to work because the player is supposed to be in its own group and self-contained and for that pie game has a different kind of group and that's called group single which is a group for a single sprite it's kind of weird but well it is what it is so our player is going to be in single group and all the other sprites will go in the normal group and the major reason why i put them into different groups is when we are checking for the collision we need to have them in different groups that's really important but that's going to come later for now let me first get rid of this player here and instead i want to for my player create pygame.sprite dot group single and into this group so player i want to add an instance of my player and this way we are going to have a group that is going to contain a sprite and this sprite is going to contain all of this stuff here and that way we are able to access it so now if we run the code we still can't see the player however now if i go to my code all the way down in our game loop our game is getting quite long here we have the player now i want to get my player and on this i can call the draw method and in here i have to specify one argument and that's the surface i want to draw on so in this case screen so now now we can see our actual player and well this is going to be there forever it doesn't do anything right now but well it's going to do very soon so this way once you have a bit of setup you can add all of your code for the player in here and then just add this to a group and then call the group later in the code down here and this is going to clean up our code considerably however we will have to recreate the entire player inside of this class so this is going to be a slightly longer thing so let me go through step by step and the first thing i want to do is to get my player input so player underscore input needs itself as before and in here we have to get our player input and here it's really useful what we learned like two hours ago that we can get all of the keys being pressed by pygame so pygame dot key dot get underscore pressed and this is then going to give us all the possible key inputs and we can just go through them so if keys pi game dot k underscore space and self.rect.bottom is greater or equal than 300. then we want to jump so self.gravity is going to be minus minus 20. so this is pretty much the same thing that we have seen a bit further down here all of this so this is just making the player jump but now obviously we need a gravity for all of this so we have to set self.gravity to 0 by default and now since we have gravity we also have to apply it so define apply gravity again with itself and in here i want to go self.gravity is plus equal 1 and then self.rect.y so here again we are just picking the rectangle to move it and we just apply the gravity towards it so plus equal self dot gravity and this should be it dot and then to make sure that our player isn't going to fall outside of the game we need self dot wrecked dot bottom if that is greater or equal than 300 so our floor then i want self.direct.bottom is going to be equal to 300 and this is going to be we have put all of this that is essentially this line here or these lines rather and we are essentially going to do the same thing the only difference now is instead of player rect we have self.right but that's literally the only difference that we really have to worry about so with that we have our gravity and our jump mechanic however now if we run the code nothing's going to happen for the simple reason that we don't call any of these methods and you might be tempted here to go with let me find it in the code here we have our player and you might be tempted to do something like player dot jump or something but that would be the wrong way to go on about it instead what we're going to do is use player dot update and this is what i mentioned earlier that sprite groups in pygame have two main functions one is to draw all of the sprites and the other one is to update all of the sprites and well this is what we are going to make use of here so instead of calling each method individually what we are going to do is inside of our player class we are going to define an update method it still needs self but in here we are going to run self.player input not index input and we are going to run self dot apply gravity and if you now go down a little bit further this play update here is going to call the update method inside of our player class so that way we are going to use that update method to run all of the other code and now let me go all the way to the top again the code is getting quite extensive so now if i run the code this should be working and i made a typo this should be self now let's try it and now we can see that we have two players that will work together and this is looking kind of freaky and here you can see quite well there's a very slight delay but in our case this isn't going to matter too much but if you use different methods of input so in this case this key.get pressed is going to make a very minor difference so just be aware of that but in our case it really doesn't matter so with that we have most of the player the one thing that's missing is the animation frames and well that is going to be the longest part and the first thing that we need to do is to import all the images inside of this class so let me go down a bit and here we have all the frames that we want to import and let me just copy them and now when we call the init method i still want to import all of these so what i want to do in here and i also want to keep myself.playerindex and i also need self dot player jump so let me go through what's happening here first of all we're going to import these two frames and place both of them inside of the player walk frames and this needs self because we want to access it outside of this init method then we have our self.player index this also needs to be available in the entire class and we need our self.jump so this is just the jump frames so this is very similar compared to what we did earlier mostly because i just copied all of it and now when we are loading our self.image i don't just want to have walk frame one for it instead i want to add myself dot player walk and from there i want myself dot player index and this is going to give us right now the index 0 so we would be picking this surface here so still if you are running all of this it is not going to make any noticeable difference we still have the same setup however what we can do now is to declare another method and this i called animation state um couldn't think of a better name and what we are going to do in here is we are essentially going to copy this player animation however now we don't need the global methods anymore because we can work with self so let's work through this step by step first of all again we want to check if the player is on the floor or in the air so this is ifself.rect.bottom is going to be smaller than 300 then we want to do one thing and if that is not the case we want to do something else and well all we want to do in here is to go with self.image and self dot player jump i think i called it uh yeah this one player jump and if that is not the case i want to get myself dot player index and add 0.1 towards it and then again i'm going to need the if statement to check if this index is still inside of this list here so if it is going to be 0 or 1 and well for that i need self dot player index is greater or equal to the length of our self dot player walk and if that condition is true i want to set myself dot player index back to zero and then finally self dot image is going to be self dot player walk then we want to take the index this needs to be an integer and self dot player index so all of this is essentially identical to what we have done down here the only difference now is that we add itself to all of the statements before but in terms of basic logic this is identical so with that we have our animation state and all we have to do now is to call it so dot animation state and now let's try off this again and now we have two walking players and they also jump together so this is working pretty well so this is basically covering the player now what is missing is that we don't have any collisions with the flies or the snails but for that we first have to create the sprites for all of these so well that's going to be the next big step that i want to minimize this class and create another class and this class i have called obstacle and also it needs to inherit from pygm.sprite.sprite and in here again we have to define an init method that needs self and this time we also want to have another argument and that's the type of obstacle so if it is going to be a fly or a snail and then on the first line of the init method we need super and then init again if you don't do that pi game is going to throw an error and it's very easy to forget and in here again we are going to need a self.image and a self.rect those are always needed you can't have a spread class without these two and in here i want to run an if statement to import different kinds of images depending on what i get so if this type is going to be snail i only want to import this stuff here and if it's a fly i want to input all of this so before i create my image i want to run an if statement that if my type is let's say fly so this would look something like this so we are still importing two different surfaces and we place both of them inside of a list that are called frames so this is still very similar compared to the player but now we are also going to need another thing and that is going to be the y position because the flies need to be higher than the snail so in this case let's go with 210 and this is the number if you remember from a couple of hours ago that we have specified here so 300 or 210 and well that is going to be the y position for the fly and now all i have to do is if that is not the case so if we don't type fly and type anything else i want to have an else statement and this is then going to do the exact same thing except for the snail so it's going to look like this and that way when we create the obstacle we can just type in what kind of obstacle we want and finally we are going to need self dot animation underscore index and that needs to be zero and now we can create our image and our rectangle so for the image we need self dot frames and here we need self dot animation index and then for rectangle all we really need is self dot image dot get underscore act and then mid bottom is going to be random dot rand this was between 900 and 1100 and then the y position all we really do is to set a certain kind of type and then use that type to either import all of this or all of this and this is just going to give us a list with our frames and a y position and then later on we are going to use that list to get an image and then we use that image to get a rectangle that's really all that's happening here now we do need a couple of other things now the first one is let's call it the animation state again it needs self as usual and in here i want to do basically the same thing i did for the player and this could be a really good exercise for you guys then i want you to pause the video and try to figure out the animation for both the flies and for the snails so pause the video now and try to implement all of this yourself alrighty let's do it together now so first of all i need to get myself dot animation index and now i just want to add plus equal and let's say 0.1 again although what you could be doing is that this animation index to a different kind of speed depending if you get a fly or snail but in my case i'm not going to care and now i just want to get myself dot animation index is greater or equal to the length of our self dot frames and if that is the case i want to set myself dot animation index back to zero and then finally my self.image is going to be dot frames then i take the index of integer and self dot animation index and this is going to be pretty much the exact same logic we have seen a couple of times now so if i compare to the play animation we basically did this part here and all right with that we have our animation state now again we have to declare an update method that needs self and in here i want to call myself dot animation state so this would be giving us the basic animation for the fly or for the snail and let me minimize a couple of things in here so it's a bit easier to see what we are doing and all right so now i have my obstacle class and i want to add it to a group so let me go down and let me properly add my groups here and this i just call obstacle group and this needs to be pygame dot sprite dot group however now we couldn't just add each of the obstacles right away because we only want to do that when the timer ticks so this is going to happen if i go all the way down that is going to happen in this part here where earlier we just had an obstacle wrecked list and we appended stuff towards it but i don't want to do that anymore and instead i want to get my obstacle group and in here i want to add one instance of my obstacle and for now let's just call it fly and now let's try and see what happens and we can't see anything and the reason for that should make a lot of sense so if i go all the way up again when we are initiating our class we are putting our fly at position 900 to 1100 and slightly above the ground so it's outside of the screen and it doesn't move into the screen so that really doesn't help us and just to illustrate that it is working let me place it somewhere between 100 and 200 and now if you run the code again we still can't see it and the reasons for that also makes sense because when i go all the way down we are not drawing this group so what we have to do is to get our obstacle group dot draw and this needs to be on the screen and now it should work for real and there we go now we can see that whenever the timer ticks we are getting another fly which right now looks kind of strange but we can work with this so now let me get all the way back to the top and change this back to 900 to 1100 but now what we want to do is to move this fly a little bit to the left on every cycle of our game loop and literally all we have to do to make that work is to get our rectangle again so self.rect and now we need to target one of the points in my case i went with x and then we need to subtract a couple of pixels every single time our game updates so let's go for now with six and that way this entire sprite is going to be moved to the left however there's one thing we still have to do let me go all the way down right now we're only drawing the sprite we're not updating it so we need obstacle group dot update and now we should be seeing a ton of flies and there we can see one and well quite a lot more and well now the game becomes really hard uh i well it's basically unplayable at this point but okay we are going to clean this up in a little bit so okay so with this we have our class properly now and there's only one more thing that i do want to do that whenever our fly or our snail is moving outside of the screen it should be destroyed and how we handled this earlier if i go down a tiny bit we used this line here to remove any kind of rectangle that is too far to the left but if we have a class all of this is much easier to do because all we have to do is to define another method that i'm going to call destroy and self and in here i want to look for self.rect.x and if this is smaller or equal to negative 100 i want to run self.kill and this self.kill is going to destroy this obstacle sprite and then all we have to do is in our update method called self.destroy so this way whenever this sprite goes too far outside of the screen it's going to destroy itself and we don't have to worry about it at all anymore although you can't really see it in our game itself so there's no point in running it however there's one thing that you are going to see that we are missing right now and if i go down a little bit further i can actually copy all of this out because we don't really want to look at it so these were the earlier sprites that we looked at and we don't need those anymore and what i want to work on right now is that we are always spawning a fly but i also want to spawn snails once in a while actually i want to spawn mostly snails so i have to figure out some kind of mechanic here to spawn mostly snails and sometimes a fly and there are quite a few different ways to make this work in my case i went with a little bit of a hack so let me explain first of all i imported besides rent int also choice and choice allows us to pick a random item from a list that's all it does so now that i have that i can when i pass on the fly i can pass in choice and this choice is going to pick from a couple of different items and in this list i have one fly and then i have a couple more snails let's put three in there so how this is going to work is whenever we are calling our obstacle this choice method is going to pick one of these four items and since we have our snail three times there's a 75 chance to get a snail and a 25 chance to get a fly and well let's trail of this so now we should only be seeing our sprites and well now our collision is broken but we should be seeing a fly and there we go and now we can only see our sprites and this is working pretty well cool and now let me actually hide the earlier player we created so all of this here we don't need any more and literally all we are going to need is these four lines that's literally how we need we also don't need our obstacle list anymore and we also can comment out our game active and i think if you followed along this code might look very confusing but the main problem right now is that we are both having a sprite setup and a functional setup and this can get really confusing but if you were to actually work on a code you would only look at these two classes which is much easier to organize and the only reason why all of this became so complex is because well i went through every single step but in an actual game all of this could be deleted and you would only have the classes but in my case well the code got quite long but if you look at this here all the stuff i commented out you could just get rid of and well that would make our code significantly more readable but alright let me update the player so all the way at the top let me hide all of this when i initiate the player it is supposed to be at 80 pixels from the left so now let's run this again and now we have the same setup except with sprites and well the one thing missing now is that we don't have collisions so that's the last one we have to add in here and this fortunately is also very easy to achieve because sprites have their own collision mechanics and the most common one is called sprite collide and what this one does is that it takes a sprite and it checks if this sprite is colliding with any other sprite in another group and if that's the case it's going to return a list with all the collision sprites which is super useful and this we can then work with in a function and as a matter of fact we already have our collision function and let me open it and what i want to do is to somewhat copy this so let's call this collision sprite and for this one now we don't need any arguments and really all we want to do is to first check pygame dot sprite dot sprite collide and in here we are going to need three different arguments we first need a sprite then we need a group and then we need a boolean we're going to explain that one in just a second but first of all we need a sprite and in my case i want to get my player and here you have to be careful because this player is not a sprite it is a group single that contains a sprite so that can be quite confusing so this player by itself would not be enough however we can access the sprite very easily all we need is dot sprite and since this class only has a single sprite this is quite workable however in a regular group this sprite would not work you could only get a list of all the sprites you could not get an individual sprite so this is why we have group single here all right but then for the group this is much easier all we need is our obstacle group and now we have the group that we need now for this boolean here what this effectively does is that if this sprite here is colliding with a sprite in this group we can check if this spread is going to be destroyed or not and this is what the boolean here is for so if you're going to set this to true every time our snail will collide with the player the snail will be deleted and if we set this to false the snail would not be deleted and in my case i want to go with false but in our case it really doesn't matter all that much but all right now this entire statement is going to return a list and if it doesn't collide with anything it's going to return an empty list and that we can use an if statement so if there's anything in this collision list we want to run some code and well all we really want to do is to return false and if that is not the case i want to return true and this is going to be very similar compared to our collision function so all right now all i have to do if i go down quite a bit by now we have down here our collisions i still have our game active variable and now we want to check collision sprite and well with that we should have our collisions back so let's check if this is working and there we go it's still working but now we have the same problem again that if i run the game again the snail is still in the same position so well our game would crash right away so whenever let me go all the way up again whenever this collision sprite triggers we want to delete all of the sprites inside of our obstacle group and this is very easy to achieve because all we need to do is to get the obstacle group and empty it and now if i run all of this this should be working pretty well so now if i collide with a fly the game stops and now it starts again with no sprites in there and well this is working pretty well cool so now we have our game working again so with that we have made quite some noticeable changes and there's a ton of redundancy in our code now which isn't great but i hope you get the principle following along and i'm going to upload all of the code in the proper way for the class-based approach that's going to help understand all of this i think but if you could follow along i hope this makes sense but alright there's only one more topping left to do and that's to add the sound and this is going to be a super easy part and well the audio part is going to be really quick because there's only really two steps that are both really easy we first have to import a sound and then we have to play it at certain parts in our game and all of that happens with the pygame dot mixer module and this really isn't all that complicated so i think the best way to approach this is to jump straight into our code and then let's do all of this so specifically i want to work with two sounds one is the background music and one is a jump sound so here we are back in the code and the first thing i want to do is to add the player jump sound and for that i am opening a player and when we initiate this class i want to also import the sound and let's call this jump underscore sound and now to import a sound we need pygame dot mixer dot sound and as always make sure the s is capitalized that's really important but now all you have to do is to add a path to what file you want to import and in this case we have audio jump.mp3 and that's all we needed to import is sound so that's the first step and now we only want to play this sound when our player is jumping and that happens in this player input that whenever we play the button we want to jump so we could play this sound ideally in here and that would make the most sense so let's play there and to play the sound literally all that we have to do is to get our self.jump sound and then add play that is literally all we have to do so now if i run the code we can still see our game that's a good start and now you should be able to hear a jump sound so it's really as simple as that now there's one problem with this that i think this sound is kind of loud and annoying so i want to make it less loud and this we can also do very easily all we need is to target our jump sound again and then add set volume and in here we choose a value between 0 and 1 with 1 being the full sound and 0 being the sound muted and in my case i went with 0.5 and now this should sound significantly better but do play around with it i guess um whatever you think is perfect so that's all we had to do for the jump sound now next up let me minimize all of this because we don't need it anymore and next up i want to have an actual game sound and let me import it right when we initiate the game and let's call this bg music for background music and this could be a really good exercise for you try to import this music and play it once once our game has started so all i want to do is pygame.mixer.sound and now the file that we are going for is this one audio slash music or wav and that is the music that we want to play and now we have to figure out two things number one is where do we have to add the code to play this music and number two is how can we loop this music so this track here is only a couple of minutes long and once it's over i want to restart it so that's another thing we have to figure out but first let me change this to lowercase music so it looks a bit more consistent but right now i want to target my pg music again and again what i want to do is to play this music and now as soon as our game starts we are going to play the music so let's try this you can play with the ball a little bit it's up to you i am not going to worry too much and now if you want to loop this all we have to add is one argument in here and that's called loops and in here we can tell pygm how often to loop this so for example if i were to add a six in here we would loop this track six times but in our case we don't want to loop it a certain amount of times instead we want to loop it forever and for that we need -1 and this is telling pygam to play this sound forever and once it's over to just restart and well you can't really see this in the game [Music] now with that we do have the entire game and if you have gotten this far you have basically learned all the fundamentals of pygame so at this stage you should be able to approach most 2d games now obviously you do have to practice using all of these concepts but this is essentially all the concepts you need to make them so i hope that was helpful
Info
Channel: Clear Code
Views: 99,202
Rating: 4.9668641 out of 5
Keywords:
Id: AY9MnQ4x3zk
Channel Id: undefined
Length: 227min 58sec (13678 seconds)
Published: Sun Jul 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.