Make Your First 2D Game with Godot: Player and Enemy (beginner tutorial part 1)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

We've been creating this course together with Pigdev, Aditia, and Razcore.

This is the first part of a ~4 hours free, beginner-friendly series that we are looking to add to the official Godot docs as its first video course. It would be a special version hosted on e.g. Peertube that does not showcase our paid courses. We will talk about that at the upcoming Godot sprint in Poznan, with other contributors.

It's something I always wanted to do, but also we lacked experience making beginner-friendly content. That's why it took us so long.

You have timecodes to jump around this long video in the description on youtube!

👍︎︎ 23 👤︎︎ u/NathanGDquest 📅︎︎ Oct 03 2019 🗫︎ replies

Godot REALLY needs some advanced tutorials.

👍︎︎ 8 👤︎︎ u/dejvidBejlej 📅︎︎ Oct 03 2019 🗫︎ replies

While going through this tutorial I ran into a problem, I can't see the Script Variables in the Inspector. Timestamp of the video for context.

Edit: Solved!

👍︎︎ 1 👤︎︎ u/Brock_L 📅︎︎ Oct 03 2019 🗫︎ replies

I'll really need to upgrade my GPU for being a dev on Godot and gaming...

👍︎︎ 1 👤︎︎ u/BubsyFanboy 📅︎︎ Oct 03 2019 🗫︎ replies

This is really well done. I watched through some of your vids starting out.

Seeing this one again though. It's really well explained, and you help guide people towards best practices and shit. It's sweet!

👍︎︎ 1 👤︎︎ u/Ucenna 📅︎︎ Oct 03 2019 🗫︎ replies
Captions
in this complete free course you're going to learn to create your first 2d game with godot a platform game inspired by mario with levels with coins with a player you can control with the ability to stomp enemies level transitions as you will see in a second and a lot more you're going to learn good practices programming games with the go to game engine this is a course for programming beginners where while going really step by step while going fairly slowly to show you every bit along the way getting you started making games and yet still showing you really good practices creating games with godot coding games in general if you have no experience with game programming i invite you to watch our intro to gdscript for beginners it's completely free link in the description below in this first part that is two hours long you're going to learn to make the player the enemy from zero every step of the way to make the smooth camera you can see on screen the base level and all that with a lot of details about how good it works in the next part we will do level design create the coins create the portal that takes you between two levels and more importantly learn more about working with the camera transitioning between scenes those kinds of things before we start i'd like to say that this series is sponsored by our premium courses if you want to go further with game development create more polished games or just support our work we have a more advanced site view character course available right now this beginner series also has an extended edition that comes with bonus content like this lesson on adding slopes assignments challenges quizzes more information in general the sales we make with these courses really allow us to create all that free content so if you're interested you will find links in the video description below but now let's get started by creating the project enjoy the source code for this project along with the material to get started is on github link in the description below you'll want to download the start assets.zip file then head to your file manager to your explorer right click extract it here to have the sprites that you will need to make the game you can create your own but this will help you get started faster so i'll go back up and rename this folder to just assets then i'm going to create a new folder to store my go to project let's say platformer and copy the path to it i'm going to open godot create a new project and let's call it platformer as well i'll just write for myself that this is for the tutorial and paste the path to the folder where i want to install that project you can also click the browse button and navigate your computer to the folder that you want to create the project in it has to be empty then select the current folder and you'll want to create and edit your project this will open the 3d viewport we want to work with the 2d one here so click on the 2d at the top of the screen and we are going to go back to our file manager i'm going back to the place where i have my assets folder and drag and drop the assets folder in the platformer one so we have our sprites accessible from the godot editor once you've done that and you go back to godot you will see in the file system tab the assets with the sprites inside of them we are going to start the project by creating the character and start with character movement we want a folder a new folder in our file system tab to store our scenes the characters we are going to create the code we are going to write i recommend that we use a folder called source to represent the source code for that so right click on res here this is the root of your project and new folder called the folder source are abbreviated to src there will store every gdscript file but also the scenes we will create with godot's interface as these are parts of your game's source code now let's get started creating the character the player we want to create a 2d scene but we will use a custom node to do that so click on custom node on this button and at first you want to create a kinematic body 2d kinematic body 2d is a node that you can control that can move around the world and that can detect collisions that can detect hitting a wall the ground those kinds of things let's rename it to player in this case and a node like this needs a collision shape a geometric shape to detect collisions with the world so we're going to add one select the player node click the plus button at the top and this time you want to look for collision shape 2d so start by typing collision and you will find it at the bottom of the list create one of these there you want to add a geometric shape a resource to that node to do so we have to head to the right side in the inspector next to the shape click the empty label and you want to create a new rectangle shape 2d once you have it here created you will see a small rectangle appear in the view so you can use your mouse wheel to zoom onto it and you can click and drag on the points to edit the shape note that to do so you need your select tool the select mode to be active in the top left of the interface to set the size of this rectangle we are going to first place our player's sprite so select the player node at the top we are going to add the sprite as a child of it we need it selected to do so and click to expand assets go find the player.png file and drag and drop it on the view it will automatically add it as what you select in there we want a sprite click ok to add a sprite and you will see it added as a child of the player node under the collision shape 2d now the node that's at the bottom of the list will be in front of all the others the rendering older the layering of the nodes is from top to bottom by default so you can click and drag the player above the collision shape 2d to make it so we can see the rectangle in front of it then we want to place our player so that the two axes that cross here are at the bottom of the sprite we will use them to represent the origin of the player you can click and drag with again the select mode active to move your sprite when you do that by default it's a bit imprecise because you can move your sprite very smoothly but we want to precisely place our character on the origin to do so we need to use the snapping feature so in the toolbar you want to click the magnet to activate snapping and then click the three dots to configure it by default while snapping to the grid you can toggle it on and off with the g key as you can see it will draw there then when you move your character the center point here will snap to the grid the thing is it's not what we want just yet want to place the bottom of the character and align it with the origin of the scene so click the three dot and deactivate snap to grid want to use pixel snap instead press g again to hide the grid and then you can click and drag and you will see that the character moves in small increments increments of one pixel at a time and then you can place it so it really matches like aligns with that x-axis that we have here drawn in red you want to take the collision shape 2d and move it so it is centered with the character so move it up you can press the shift key to constraint the movement to one axis and align it with the character's center then click and drag on one handle to expand it you will see that it expands on both sides at the same time right it increases the extents of your rectangle not just one side and you want to do the same for the y-axis now the thing is you don't want it to be all around your character this represents the collision of the player the part that will stop against walls and in general we cheat a bit we want to make these a bit smaller than the game sprite so you don't have the character getting stuck if the part that's in the rounded angle of the character hits a wall or something so we're going to make it a bit smaller than our character sprite you can make it something like that finally we want to add a script to our character just to get it started this is the place where we are going to add two scripts to our project one for the player that is specific to the player and one that will be shared between the enemy and the player the enemy and the player will both move in the game so they will have some similar code logic and we can add a parent script that they will both inherit or extend and that will allow us to share some code between the two instead of repeating the code writing it twice once in the player script and once in the enemy script anyway to get started let us save the scene so you press ctrl s to do so go in the source folder and we are going to create a folder let's say actors or actor where we will stall all the actors in our game the player and the enemy in this case click ok you will end up in that actors folder and save your file as player.tscn then with the player node selected you want to use the icon to add a script in the top right of the scene tree click that and it will automatically set the path here to be in the actors folder and the name of the script will be the same name as your node here player.gd we will use the gdscript language it will automatically inherit kinematic body 2d the type of the node and for the template we are going to use an empty template click the create button to create that script file i'll zoom in just a little bit here and we have our player script right there now i'm going to create a second script from that script editor so you can see well in the script view at the top of the editor go to the file menu in that script view and create a new script we'll save it change the path click on the folder icon to do that in our actors folder and we will call it actor.gd it will be the base class that both the player and the enemy will extend click the open button to set that path and create the actor script you automatically jump to that actor.gd script in the script view we can register that class as a type that we can use after the extends keyword that extends keyword says this script is going to have all the functionality that what is after here that this class node in this case has to register your actor as a script that we can use in our player and the enemy under the extends note line use this class underscore name keyword and then you can type the name that you want to use in our case it will be actor save and once you've done so you can go back to the player script and instead of extends kinematic body 2d you're going to write extends actor now we have to make one change in our actor class the type that your node extends is very important if your node is of type kinematic body 2d your script must extend kinematic body 2d or one of its child node we want to type extends kinematic body 2d here at the top of our actor script so that way while creating a new actor nodetype actor class that is of type kinematic buddy2d that has all the features that if we go in the docs we can see in that node and all of its ancestors you can see after inherits physics body 2d collision object 2d node 2d etc up to object so it will have all the features from all these classes plus everything that we will write in that actor.jd script i'm going to close the kinematic body to the full now and we can start coding our actor.gd i'll close the player script as well for now let us start coding our character's movement while really going to take it step by step really slowly so our first going to make our character move somehow and then we will improve that because player has a script that extends our actor script it will run all the code that we will write in actor.gd we'll start by adding a function that is specific to godot that is built into the engine called physics process type the func keyword to define the function and then underscore physics process if you don't have the auto completion like me the column float and the arrow after that it's because of your editor settings so go to editor editor settings and look for type and in the completion category add type hints should be on once you've done that and you you type the function name you will get these type hints inside of there we are going to work with these so i invite you to set that setting to on physics process is a function that if you define it in one of your nodes godo will automatically call it every frame in your game typically 30 to 60 times per second this is generally where you want to place the player movement note that you have two one is called process and the other is called physics process for characters like your player everything that involves physics objects that will collide that have to detect the floor the walls you want to use physics process now we will make our character move here and to do so we have a function that is defined on the kinematic body 2d it's called move and slide this one asks you for a linear velocity of type vector2 so we're going to create that vector2 above the movement slide here in a new variable you can press ctrl shift enter to create a new line above the one where you have the cursor while creating a new variable here that we'll call velocity that will be our linear velocity and it's going to be a vector2 so you can press colon then you add an equal sign to ascodo to set the type of that variable to what we're going to type after the equal sign in this case it's going to be a vector2 a vector2 has two values one on the x-axis and one on the y-axis that represents either a position or it can represent a length if you want in our case a velocity on the x-axis we are going to put let's say 300 and on the y-axis zero this means that we want our character to move at 300 pixels per second on the y-axis and zero pixels per second on sorry on the x-axis and zero on the y and in our move and slide inside the parentheses you want to enter velocity we'll move the character using that value stored in the velocity variable now going back to the scene we can play it using the f6 key to preview the movement the thing is the character here if you zoom back and you look at the frame it's outside of that frame that represents your view so i'm going to move the character inside the view to do so press the w key or select the move mode in the toolbar and click and drag to place your character in the view then press f6 to play this scene and you will see your character move to the right at a constant speed you can click at the top on script or press f3 as a shortcut to do that f1 f2 f3 f4 are shortcuts to switch the views and open the help f3 for the script editor and we are going to improve our code a little bit we don't want the character to move to the right all the time this is a little silly instead we would like to apply some gravity to it we could hard code it in there in our velocity but instead we are going to store that gravity in a variable and while not going to define that variable in physics process when you define a variable here this variable only exists in that function and you can't access it in other functions that we will add later so instead select your velocity here press control x to cut it then you want to paste it outside the physics process function and you will see that you don't have an error it's okay to use it in your move and slide call here our velocity is going to be a vector2 of length 0 by default so by default the character will not move then we will add some variables to update that velocity every frame so we'll create a new one called gravity and this one is going to be a decimal value the gravity is just going to be applied on the vertical axis in our game and it's an acceleration a vertical acceleration so let's say 3000 i'm going to add a zero at the end to tell godow that this is a decimal value that i want and not an integer not a whole number so we're going to have that the gravity and what we can do here is in our physics process function we're going to add the acceleration or gravity here to our velocity's y component so you do velocity dot y and to add to it instead of using the equal sign you can do plus equal this is a shorthand for add to what's on the left here add gravity times delta delta is a value that the engine is going to give us on every tick in that physics process function it represents the time elapsed since the previous frame so you want to use that delta value to make your code frame rate independent in other words if the game slows down the character should still move at the same speed if someone has a slow computer or you know a certain scene is a bit heavy you don't know what's happening you want the movement of the character to be constant so you can do it with the delta value here one technical detail is that your velocity is a vector that represents a speed so a certain amount of pixels you want to move per second in a given direction so to get a motion the amount of pixels that we want to move the character in one frame we need to multiply that velocity by that delta time but the engine does it for us in the move and slide method this is why while not multiplying our velocity by delta okay so this will make the character move down you can press f6 to play the scene and see your character fall now we can make our gravity configurable that would be the next step to do so add the export keyword before your variable and once you've done so you will see the gravity appear on the right in the inspector if you have the player selected here so then you can modify the gravity say we are going to make it very small 500 pixels per second squared press f6 and now the character will slowly fall and you can see that our gravity has some kind of acceleration to it we are going maybe to set the maximum speed for the character right we may not want it to accelerate to infinity which it can do right now so we're going to do two things first we'll add a speed variable that will export from the start so let's call it just speed here and this will be a vector 2 as well why because you want a maximum speed on the horizontal axis when the player will press the left and right arrow keys and you want one on the y-axis the maximum fall or jump speed in the parentheses on the x-axis we're going to set it let's say 300 pixels per second and on the y-axis we'll say 1000 and once you save you will see the values update on the right in the inspector so then you will be able to customize that in your player so you can use the speed value like so you can say if velocity dot y is greater than speed dot y so it's greater than 1 000 here we are going to set velocity.y back to speed dot y another way to write it with a thematical function in a single line is to say velocity.y is equal to the maximum max is a built-in math function the maximum of velocity dot y and speed dot y that way you don't have to add a new block this will cap the false speed here and then we move and slide using the velocity vector and that function will calculate a new velocity for the character if you hit a wall if you hit a slope or something like that it will return a new vector 2. you can control click on move and slide to see its documentation so you can see it's a bit complex it does quite a few things but at the bottom you'll see returns the linear velocity vector rotated and all scaled if a slight collision occurred this means if your character hits something good will try to smoothly move it along the surface that it hit and this will modify the velocity of the character so then we want to add velocity equals and we'll get the value returned by that function call note one less detail that line that we have here we might want to move it to the player and the enemy's specific script and logic so we're going to remove it from here for now and maybe we'll move it somewhere else later okay so if you play the game you will see your character just fall down now we want it to fall onto something to fall onto some floor we're going to do that and to do so we want to go back to the 2d view so click 2d on press f1 and while going to put the player back to the origin and the inspector with the player selected go down to the transform category and click the reset icon next to the position it's going to reset it to zero and we're going to create our level go to scene new scene it's going to be a let's say let's start with a 2d scene for now and we are going to call it level let's say template or test level something like that save this with control s as far as the path is concerned you want to create a new folder in your source folder call it levels okay and save your level template there we are going to add a tile map in our level so select level template click the plus button or press the shortcut control a to add a node and search for tile map press enter to add it you will see with the timelapse selected the editor turned into the tilemap editor a tile map needs a tileset result that you will see in the inspector so we have one prepared for you in the assets folder that you can click and drag if you want to create it however you want to clear that click guitar set here create a new tileset and click on the resource to open the tileset editor that looks like that in this editor we have to load a texture an image that will chop into cells that we can then use to create levels on a grid so click the plus button go to assets and you want to load the tileset.png file you will see then in the center part of the editor you will have your texture opened then we want to create a new single tile and once you do that you have a snap icon that appears i'll just click and drag to start to create a region to then be able to set the snapping option the grid here so once it's on and you can see the snapping grid you can expand the snap options in the inspector on the right and we are going to set the step to 80 x 80 then with the select tool active click your original region like you click on the cell it will automatically snap the tile to it if you go back to the tile map and click and drag you can start to draw your level you will see that our texture is a bit larger than the grid cells we're going to change that in a moment but first let's click back on our tile set resource to finish editing it so you select the texture you select the cell like the single tile that you have here and we will add a collision to it this will make our character stop against the walls and the floor click the collision tab select the square create a new rectangle icon and this will automatically when you click inside of your tile create a square or a rectangle that fills the entire tile instantly so that way you can fold down that tile set here that editor go back to the tile map and when you click and drag you are creating walls that the character will collide with now we need to change the cell size to match that of our tile set in the inspector with the tile map selected expand the cell category and the size is 64 by 64. we want it to be 80 by 80 just like our texture and then can click and drag to create walls and ground that will stop the character the player i'll close the assets folder expand the source actor and now you can take your player here and drag and drop it anywhere inside the scene so i'll put it up in the sky i will click and drag the player so it's a child of level template and not of the tile map and then press f6 to play the game we'll see the character fall and it will stop on the floor so that's one nice thing that we have here now this is a nice start before we make our character move we add a bit more logic we're going to change the settings of our project so that we do have collision that works automatically right now by default but when we start to add the enemy and more logic in the game we will have some issues if we don't organize our physics layers just yet and also the game frame here is a bit small compared to the art you can see the character is very big on screen we want to change that so that it looks a bit nicer in the end to do so we're going to go to project project settings and in this window we are going to go down first to the physics layers so we are going to do that and then we'll do the screen size you want to go down to the bottom of the left roll up menu go to 2d physics and you can name your physics layers here on the right side for example layer one could be the player layer two the enemies layer three could be well in the next tutorial we'll have coins so you can call it coins and layer four could be we can't really say ground let's say the world so everything like the walls platforms ground everything like that would be under the world layer close the project settings for now i'm going to fold the output window and when you select the tile map in the collision category you have layers and masks the layers are where this style map is on on which tag it is so you have 20 layers and if you click the two dots on the left you will see a list of check boxes that have the layer names that you just created so our tile map we don't want it to be on the player layer so we click to uncheck that and we are going to set it to be on the world layer then the mask is the physics layers that this node the tile map will detect and that you can then use or process from the code the tile map itself does not need to detect anything so we are going to uncheck the mask here now using these layers and masks will not only help you avoid bugs it will also improve the performances of your games because when godot tries to detect for collisions between nodes it only checks between the layers and the masks that match between two nodes for example our player our character if we expand its collisions and the physics body to d it's on the player layer and it only detects what's on the player layer which is not very useful here instead we have to open or go back to the player scene to do that change the settings globally in our project where the player knows selected you want to change the mask it's going to mask or detect the world here which means the player is on the player layer and it collides with everything that is on the world layer so you save with control s go back to level template and you can press f6 to see that nothing changed our player still collides with the floor now if i were to change the collisions on my player make it mask another layer you will see that it goes through the floor it doesn't collide with it anymore so we want it to collide with the floor note that if i said we have to go back to the player to change the collision settings it's because this is the definition of our player this is when you add the player to any scene the default values that we will have and if you change an instance or a copy of the player like you have in the level template scene you will overwrite that value will make it different for that copy of the player only and not throughout the project now we are going to make our player react to the input pressing left and right to move horizontally and space to jump for example to do so we have to start by setting up input mappings so go to project project settings input map tab the input map allows you to map keys on the keyboard or on the gamepad to a label that can then reuse in your code to reference all these keys you have some defined by default by godot for the user interface and we are going to add some so click on the bar next to action and you want to type the name for your action let's start with move left click add and so let's do that first action you see it added at the bottom of the list on the right you have a plus icon that allows you to add input mappings click here we're going to add a key on the keyboard and then you want to press that key let's say let's start with wasd so a to move the character left you can add another key on the keyboard say a player wants to play with the arrows so left arrow and that should be it for now you could also add the gamepad so draw axis in this case and you could take axis zero left stick left the minus one and that way whether you press a left or press it on an xbox gamepad or on a dualshock playstation one you will get the same input move left in the code to react to these three inputs let's do the same for move right well i'm going to create this input action so the d key i'm going to add the right key and finally dry axis this time it's going to be axis zero plus left stick to the right side so add these and we are going to add an action to jump jump is going to be the w key the up arrow or on the not y-axis joy button here xbox a with that we have the actions we need to get started we can start coding the character's movement the player's movement to be exact click on the script next to the player node to open the script editor we're going to add that physics process function there again function physics process and we are going to write some code in there the way it works is this callback is a bit special this function as i told you it's defined by the engine it's specific to godot it doesn't exist in other game engines and it works that way when you have a class that extends another the actor gude will run this function's physics process but it will also run its parents physics process so it will run this code as well as everything that will write here automatically here we are going to first calculate the direction the player is trying to move in on every frame using our input to do that we have to use the input class in godot inside the physics process it's a globally available class that allows you to get on query for inputs on every frame in the game for example so when you type the name of the class that's accessible like that you can press dot to then access its members all of its properties or all of its methods that you can see with the parentheses note that pressing the dot and accessing some property is similar to the properties you have listed in the inspector in the editor if you hover any of these you will see the name underlined in this case gravity in lower case right when you do input dot if you control click on the input class you will open its documentation in the script editor and then you can see all the methods it has right under the methods section here and while going to use methods that will tell us on every frame if the player is pressing a key so let me close these docs here so what we're going to do here is call a method called get action strength on the input class and we can pass in one of the input actions we defined in the project settings you can see that godot autocompletes them for you so let's start with move right this function get action strength is going to return a floating point value a decimal value and if the key is pressed fully to the right it's going to return 1. if the key is not pressed it's going to return 0. this is handy because when it comes to directions we want moving to the right to be 1 and moving to the left to be minus one you will see that in a moment how how that works but you can control click on that method to jump to its documentation and you will see that it starts the line starts with float this is the return type of the function it will return a decimal value in that case and the documentation explains that a little better returns a value between 0 and 1 representing the intensity of the given action the point of this function here is that if you don't press the joystick all the way you will have a decimal value maybe if you pull the stick half of the way you're going to get a value of 0.5 for example to calculate the player's move direction the input direction we are going to make a calculation with the values returned by get action strength so let us add a new line above that while i'm going to stall that direction in the variable and also allow me to press ctrl shift f11 to expand the script area i'm going to create a variable called direction and it's going to be a vector2 the reason why i'm going for vector2 is again we can be moving horizontally so we have a horizontal direction and vertically we have a y direction two directions to take in account you can put your cursor in between the parentheses and press enter to add a new line to have the x and y directions aligned with one another here we are going to calculate the x direction like that input dot get action strength move right minus input dot get action strength and we are going to get the strength of move left here's what it does so i'm going to add a comma and on a new line set the y component of the vector to 0 for now moving to the right in the game should be a value of 1.0 or we are going to represent it that way and moving to the left is going to be a value of minus 1.0 like so all right so when we are making that calculation if we press the right key we are going to get a value of 1 allowing us to move to the right and we subtract the value returned for move left so that we get minus one here instead if we only press the move left action if you press both left and right at the same time you will get a value of zero just like if you neither press move right nor press move left we can use that direction to set the velocity of the character so we can say velocity the velocity we defined on the actor script now going back to player.gd you can say velocity is equal to speed times direction here and with that you can play the game you're going to see the character moves slowly and you can press left and right to move it left and right and we cannot jump yet here's why even though we set the direction to zero times the speed we should get a vertical speed of zero instead the character is still moving this is due to the actor script that's what i was explaining with physics process it's that we define some behavior in the player.gd script but godot is going to run physics process on the parent first so it's going to add gravity times delta to the velocity then it's going to move the character then we change the velocity and finally the character will only move left and right on the next frame later than what we're doing right now so one thing we can do at this point is remove that line from the actor's physics process and move the character on the player script and that way you will see it will not fall down why because we're setting the direction to zero one thing we can do we can set it to 1.0 by default we'll change that if the character jumps so that the character falls and stays on the ground and with that you have the ability to fall and the ability to move left and right i'm going to make a little change to the player's movement speed because this speed is fine for a monster for some ai that the character has to kill to make it easy to jump on the ai as we'll see later but for the player it's a bit slow so let's increase the x speed of the player again i have the player node selected to do so pressing f5 now the character moves much faster on the x and y axis we're going to add the jump logic to our character now in the place where we calculate the direction we want the value here to be -1 when we want to make the character jump but the rest of the time we want it to fall so we want the value to be 1.0 the reason we need -1 to go up is that the y-axis in the game in the game engine is pointing down like in most game engines so we are going to use something called a ternary operator it's something similar to doing if condition then do something and having an else block except that we can write it all in one line it works like that so we want the value to be minus one if the player just pressed the jump key otherwise we want the character to fall minus one if we just press the jump key else 1.0 it's going to make the character fall down and we want to do a little more than that because with this condition only we will be able to jump anytime midair so we want to add and is on floor is on floor is a function that you have on kinematic body 2d so if i control click on it you will see the kinematic body to the dox returns true if the body is on the floor and it only updates when we call move and slide this is why we want to have that movement slide here in our player script so we have control over when we move the character so the is on floor and is on while ceiling those kinds of functions just work okay so this gives us the jump direction now we're going to do a little something to make our code easier to maintain and to read in the future we're going to move that vector 2 here to a function to have a function that calculates the direction for us and i'll explain in a second why we do that so we're going to create a function called getdirection that is going to return a vector2 and we are going to return that value that we were assigning to our direction variable so select it all ctrl x to cut and in my get direction function i'm going to put the return keyword this is the value that the function is going to return and paste our calculation and in the direction variable we are going to get the direction we are going to call that function we are doing that to keep our code easy to read moving forward because for example if a teammate wants to understand how the player moves if you use functions like these you only need the physics process function and a few lines to understand the type of motion that the character does and then if you want to dive in the details if you want to make a change to the direction code it's in that get direction function that this doesn't seem like much as our player is simple but you will see by the end of the tutorial we'll have added quite a few lines of code and it will make our code easier to read than shoving everything in physics process let us work on the jump next because our character can move horizontally but it can not jump for that we are going to modify the way we calculate our velocity on every frame we're going to make it a bit more complex as we will add the ability to cancel the jump as you will see in a few moments but we're going to do the same as with the get direction function we are going to create a function to calculate the velocity and we can call it calculate move velocity so at the bottom of the script let's add calculate more velocity it's going to return a vector2 the type of our velocity and for now we can return speed times direction we have a few ways of handling this function as you can see we get an error because direction is not declared in the current scope the current scope means the function each block that can fold you can consider it a scope when you create a variable like direction inside of a function it is scoped or limited to that function if you create it outside the function let's do it like so variable direction is an empty vector2 like so then it will become available in all the functions in that file or in that class because this file represents a class the thing is you don't want to have too many variables outside of functions because having these values that people can modify you your teammates and the code is a big source of bugs it's hard to keep track of how these values get modified and putting a value here allows you to modify the variable from outside the player script from another script a game script to score script or whatever it's dangerous in that sense that is why whenever we can we will scope the variable create them in a specific function now for the move velocity we are going to pass these values as parameters of the function so we will need four well let's start with three we need a linear velocity this is the name that godot functions give to that velocity variable if you want in move and slide the first parameter velocity is called linear velocity in the documentation so we are going to use the same convention i'm going to change the formatting for my parameters here i'm going to align them vertically so after each parameter you want to put a comma to separate them and one going to add so the speed as a vector 2 well i'm going to pass every parameter explicitly i'm going to have the direction it's going to be a vector 2 as well let's order them like so and for now let's have just three this is a certain style of programming where we explicitly pass every parameter to the function to ensure that we know exactly which values the function is going to use to make its calculations and there again we do that to avoid creating bugs in our program so we're going to calculate the new velocity let's create a new velocity variable in the function and it's going to start from our linear velocity so this function is going to take the initial velocity make some calculations with the other parameters and return a new value a new value that we can then assign to our velocity or store or process however we want so let's do it like so we're going to take the original velocity we are going to set velocity on new velocity dot x we're going to set it to speed dot x times direction dot x and for the y component it's going to be a bit different so we're going to take the logic we had in the actor script and we are going to remove it from that physics process here i'm going to take that line where we're adding the gravity and we're going to put it in our calculate move velocity function so new velocity dot y we're going to add gravity times delta to it to make the character move down we don't have access to the delta value here we can either pass it to the function or we can use a function called get physics process let's see get physics process delta time i'm searching in the docs to see the function name that's i'm going to copy here you can use f4 to bring that search help feature and then you can look for delta time like that delta underscore time to find the get physics process delta time function so i'm going to copy it close the documentation and paste it with control v in my script and add the parentheses to call the function so this is going to return us the delta value that we had in physics process that way we don't have to add another parameter to the function so we add the gravity now we are going to add a condition if we jump so if we are jumping the y direction is going to be minus 1.0 so we can say if direction dot y is equal to minus one point o we are going to override that velocity we are going to make the character instantly jump so fill us in c dot y is going to be equal to speed dot y times direction dot y times that minus 1.0 so this is going to apply the player's speed allow me to go back to the player scene select it our y-speed here it's going to apply it going up and replace the velocity with that so it will make our character jump and for now it should be good enough so that we can go back to the physics process function and use our calculate move velocity here so velocity is equal to calculate move velocity and we are going to pass the velocity the first parameter of the function here followed by the direction so that will be the value of this variable up there and the speed again we are explicitly passing every parameter to the function to ensure that we combat a pure function in programming it's a function that only takes parameters in make some calculations and returns a new value it does not directly modify a property of our character which we also call mutating the values we are grouping all these mutations all these changes in the characters properties in this case the velocity in the physics process function so that it's very easy to keep track of where we're modifying the players or characters velocity okay we can play the game now and the character still does not jump now there's one line i forgot that we have to change we don't return speed times direction of course we want to return our new velocity from our calculate move velocity function okay so with that we can play the game and see that the character cannot jump even if we press the w key why is that happening this is a tricky issue here this is due to how the move and slide method works in gudu how the kinematic body 2d works this node is designed to be very flexible and allow you to create all kinds of games a top-down game like zelda as well as a side-scrolling game because of that i'm going to control click to go to the docs this function has quite a few optional parameters and one that's very important is the floor normal this is a vector that is perpendicular to the floor and pointing away from it we need that floor normal to be set for godot to tell us what is the flaw and what is not for the is on floor function that we are using in our get direction function to work so we have to pass in that second parameter the floor normal here and it's going to be a vector 2 pointing up so you can use vector2.up which is a constant defined on the vector2 class it's a vector2 with a value of 0 minus 1 like so we can use this vector2.up constant in every one of our characters when we use move and slide or we can define a new constant on the actor class it's up to you so you could say like that go to actor create a constant with the constant keyword this is like the other variables below this allows you to put a label on a given value but you are not able to modify it later this is a constant value and we can say floor normal is going to be equal to vector2.up the advantage of having that kind of label is that when we go back to our player here we can see that the second parameter in our move and slide function is our floor normal now i've made a typo here something that can happen i've written velocity instead of new velocity in my calculate move velocity function making it so the calculation would not work with that fixed the character can now jump like you would expect it doesn't jump very high the jump height and the impulse of the jump being controlled by the speed value it's y-axis so i can bump it up to 1400 for example and press up you can see that now the character jumps much higher we're going to add the option to interrupt the jump so make the jump a bit more like the one you see in mario where if you press more longer the character will jump higher to do so we are going to add a new variable in our physics process function on the player called is jump interrupted it's going to be a boolean as the name suggests so a value that can be either true or false this one's going to use an expression a bit like the one that we have in get direction we want to check that we just released the jump key so if input dot is action just released jump and that the player is actually jumping so velocity dot y is lower than zero if the velocity that y is negative the character is going up so it's currently jumping in the middle of the jump and we are going to pass that value to our calculate move velocity function so we can use it that is jump interrupted will be our full parameter now we have to go down to calculate move velocity add our is jump interrupted down there and it's going to be a brilliant value so that around the end of the function we can add that condition if the jump is interrupted we are going to set velocity new velocity dot y to zero and then we return that new velocity this is going to make it so if i keep the key down the character jumps to the full height but if i release it really quickly the character stops its you know phase going up and starts to fall instantly so based on how long you press the key you can now modulate the height of the jump a quick note on variable names right now in our calculate move velocity function we call our variable new velocity let's say you find it a bit long because we have the name of the function already we know that while calculating our move velocity and that's what we'll get out of the function we can rename that variable so you can double click it to select it press ctrl r to open the search and replace feature in the text editor and we're going to search for new velocity that is the first field the second field allows us to set a replacement string we can call it out the output of the function and we only use new velocity inside that function here so we can click replace all to replace all copies of the name because calling it new velocity led me to make the mistake of writing velocity instead another thing i want to introduce here is public and private variables we have some conventions as developers as to how we name the variables if we put a leading underscore in front of a variable we call it private this means that it is only meant to be used inside that script or that class in this case because we extend actor this would be in the actor and player classes public variables on the other hand indicate to our teammates that we can modify it from another script from another node in the game this is the case of our velocity right now because it doesn't have that leading underscore and a teammate could in another script just do something like velocity equals something else a new vector 2. um and we don't necessarily want that to happen so that's why we're going to rename it to put a leading underscore in front of it now the thing is we defined velocity in the actor script and while using it in the player script as well while having it in two different files we can search for a string like that for a name in the entire project and replace it in all our script files in the project by using ctrl shift f to find in files to find in a an entire folder we have an option like that or in the entire project so it's going to use the string that you highlight the bit of text so if you double click on velocity press ctrl shift f it's going to find velocity in the project then we can click the replace button to find and replace in the entire project and i have to go back out of distraction free mode i'll close the find and replace in script here and you will see that it finds several copies of velocity in the project and also finds it inside the calculate mobility function a place where we don't want to replace it so we have to restart our search with ctrl shift f and make sure that we only look for whole words we're only looking for velocity when it's a single word on its own and then when we click replace we are going to only get velocity as the variable name and as a separate parameter so we can see that it's finding instances of the string in two files actor.gd and player.gd in the replace field at the bottom we can type underscore velocity be sure to save your files before you do that and then you will click on replace all it's written that you can't undo that it will save the change instantly so we're going to do that in our case and see that now in both scripts actor.gd and player.jd we have underscore velocity and the game still works right because we replaced everything at once but you just want to be wary that when you are using that feature it's going to replace everything and save and the way to not lose work when doing so is to use a version control system like git this is a topic for another video another series but it is worth knowing that if you make a mistake if you use a version control system you can revert the change anyway for now we have our variable name let us work on our enemy next the enemy is going to be a bit similar to the player at its score so we're going to go to the source folder actors subfolder and select player.tscn and right click duplicate it we are going to call that enemy.tscn voila double click on that new scene to open it right now our enemy looks just like the player so we are going to select the first node call it enemy second nodes the player sprite what i'm going to call it enemy as well and in the file system we're going to search for our enemy you will see in the assets folder an enemy.png file so you can also expand the assets folder and with the enemy sprite note selected you can click and drag enemy.png onto the texture slot replacing the player with the enemy while then going to adjust the collision shape here for the monster make it may be a bit smaller let's say at the base maybe a bit larger as well this is the part of the monster that is going to collide with the walls it is going to block the player as well or hit and kill the player this should do now let's select the base enemy node because we duplicated our player scene the enemy still has the player script attached to it so i'm going to right click on the enemy and we are going to choose extend script i'm going to change in the inherit slot the script that the enemy is going to extend so click the folder icon and double click actor the template is going to be empty and the path by default should be enemy.gd in our actors folder click create to have your enemy script back to the enemy scene we have to change one last thing it's for the collisions remember these layers and masks if you select the enemy node the enemy is still set to be on the player layer instead you want to put it on the enemy layer and it's going to collide with the world so the mask property allows us to control that and with the player so with that we can get started coding our enemy save the scene click to open the enemy script i'll close the kinematic body to the docs and we're going to make it so the enemy is going to change direction when it touches a wall so to code the movement once again we're going to add that physics process function for the enemy we are going to make it move at a constant speed like the player and we are going to make it so if it hits a wall it's going to change direction so here's how we do it remember that we have our velocity property on the enemy just like with the player because they extend the actor's script we're going to change the x velocity of the enemy when it hits a wall so in kinematic body 2d we have just like the is on floor function and is on wall function that we can call and if the enemy is on wall we are going to multiply the x velocity by minus 1. you can use this shorthand to say multiply velocity.x by -1 by using the asterisk equal so that you don't have to repeat you know velocity that x equals velocity.x times minus 1. we are also going to move the enemy on every frame now the tricky part here is to decide if we move it before doing that check or after that you have to understand that these methods is on wall is on floor they only update after you move the enemy so we can move it first and then on the next frame it will change direction well in this case whether we move before after the check is not going to make a lot of difference but let's put it after for good measure so we can say velocity is equal to the result of a move and slide call to which we pass our velocity how we want the monster to work and our floor normal like so we're going to do one last thing we're going to ensure that the enemy always moves towards the player at the start of the game so our game is going to be so that the player is going to move to the right just like a mario game meaning that the enemy always have to move left at the start of the game that's what we want so i'll press f3 go back to the script editor and i'm going to add a new function it's another function defined on godot itself it's called ready the ready function is called by godot on every node in the scene in your game starting from the one deepest in your tree in the case of our enemy it would look at the enemy see that it has children so it will go to its children the enemy sprite and collision shape 2d and call the ready function there once these are ready it will call ready on the parent enemy node if we take our level template as an example the good engine will see level template has children the tilemap the player that will go down to the tile map call its ready function down to the player call the ready function on the child node of player then on player etc so it goes from top to bottom in the scene tree altar and from the deepest to the highest level node so this ready function allows us to set up our enemy in this case we can say in the ready function velocity dot x is equal to minus speed dot x in other words it's going to go to the left at the speed defined by the x component of the speed vector we're going to test our enemy in the level template so let's go back to the level template scene look for our enemy.tscn file and drag and drop it onto the game then we can play and see that the enemy moves left now it's not really falling so we want to add to our enemy script applying the gravity on every frame so we're going to do velocity dot y we're going to add gravity times delta the enemy script being much simpler than that of the player while not creating a function to calculate the move velocity because it would only be two lines of code now with the code that we have if we place the enemy close to the wall in our level template you will see that the enemy gets stuck on the wall the reason for that is this code gets called but the problem is that when we assign the result of move and slide to the velocity when the enemy hits the wall we reset the x velocity back to zero so we want to make sure that from move and slide we only use the y velocity here velocity.y equals so we call move and slide and we take the y component of the resulting vector and with that the enemy will now bounce when it hits a wall you'll see that it also does that when it touches the player because right now we don't kill the player when the enemy hits it we don't do it just yet we're going to do it soon but first we're going to do some optimization to the enemy one thing that will happen in your games is that say we place the enemy just outside the screen and i'm going to extend the level a little bit so that the enemy is outside the the screen at the start if i play you will see the enemy enters the screen soon enough in other words the ai is running it's moving even when it's away from the player this will be problematic if you have a big level and you have lots of enemies moving this will mess up your level because they will start to move every which way and maybe add in a bit or walk on spikes and die those kinds of things you don't control the interactions plus they will be calculating all the time using your game's performances so one of the best optimizations we can do in our games is to make it so the ai doesn't run when it's too far away from the player we have a node in godot built just for that it's called visibility enabler 2d so select the enemy node in the enemy scene the root node press control a and look for a visibility enabler 2d create that node and not the visibility not fire visibility enabler this has a small box as you can see by default this is going to pause the animation freeze the physics bodies those kinds of things if the node is outside the view one thing we can do is activate the physics process parent checkbox so that when the node is outside the view it stops physics process and you can add that with process as well so we can try that by playing the game the enemy has physics process enabled by default so it will enter the view now going back to the level template i'm going to move the tile map with the w key let's see if i manage to do that i'm going to move it to the left so minus 200 minus 400 okay i'm just going to make it so the enemy can get outside of the view so i'm going to put the enemy in view at the start of the game let it walk to the left and you'll see it should not come back to the right let's start the game the enemy goes out of the screen and it never comes back because as soon as it got out of the view our visibility enabler 2d stopped physics process on the enemy and that is something we can control via code because you saw that if on the other hand the enemy starts outside the screen it will be moving this visibility enabler is only going to trigger when the enemy gets outside the screen so we are going to go back to the script the enemy script and in our ready function we can call a method called set physics process and we need to pass a boolean value to it we need to pass false this will deactivate the enemy at the start of the game you will see that the enemy never enters the screen so now this code is not running until the enemy gets in the view we want to change the visibility rectangle the pink rectangle we have on the enemy which is the box that has to get in or outside the view for the features we have in the visibility enabler to work so we are going to resize that rectangle by changing the erect property on the node let's move it to 80 it's a little too big so i'm trying to see what the size of the enemy is because we can't resize it interactively minus 50 seems to do the trick for so you have the x and y position of the origin of the rectangle and then you have the width and height of the rectangle so i'm going to go 150 let's say a little more 60 okay to go down to the base of the enemy so when this pink rectangle enters the view the enemy will activate now it's time to add a camera so we can see our visibility enabler in effect we are going to go to the player scene so you can press ctrl shift o and start to type player to open it easily ctrl shift o is a shortcut to quick open scene press enter and we are going to select the player node control a and add a camera 2d press enter to add it to the player by default it's not going to do anything we have with the camera selected to go to the inspector and check the current checkbox to activate it this current checkbox is interesting the last camera to set this on is going to be the active camera we see the game through we only have one in our game so it's going to be that one that one attached to the player that we will see the game through but this gives us a nice camera that will follow the player node and you can see that as soon as we see the enemy we move to the enemy it's going to stop moving and as we get away from it we don't really see it but it stops moving we go away from the enemy it stops moving it's outside the view we go back to the enemy it moves again interesting right so this helps with performances in our game now we will improve the camera a bit later so that it doesn't center the character on screen for now you can select the camera press w or click the move tool icon in the toolbar to go to move mode and shift click to move the camera up on the y-axis so that the player is rather low on the screen for now this will help us play and test the game a little better let us add the ability to kill enemies by jumping on them doing something like having the player jump fall into the enemy and jump again from the enemy using the enemy's head as a base to do so we are going to have the logic split between the player and the enemy generally when you code if you want to code the death of the enemy the code that corresponds to that should be inside the enemy scene and the stomping code the attacks on the player should be inside the player scene we logically keep code related to a certain area of our game inside the corresponding scene in that area so i'm going to go to the enemy scene first to allow it to die when the player hits it to detect that we are going to add a new area a new rectangle here above the enemy so that when the player falls into it the enemy will detect that it got stomped we are going to create that now let's create a new area 2d node so select enemy press ctrl a to add a node and look for area 2d this area 2d will call it stomp detector it will detect the player stomping the enemy in the collision tab well i'm going to change the layer we don't want this to be on any layer the area will not be monitorable you can also uncheck the monitorable property here and we'll mask the player layer it will mask layer one so when the player enters the area we know that the enemy got stomped now we need a collision shape to detect something entering it in the area select storm detector control a and look for once again collision shape 2d for the shape add a new rectangle as usual these are fairly precise i like to use them because they are mostly bug free and some shapes have inconsistent behaviors now size the shape so it's a bit larger than the enemies collider we need to be generous with the player to make the game play nice to make it easy to kill enemies and while actually going to do something um right now our storm detector node is at the base of the enemy i'm going to select it press w to enter move mode and shift click to move the stomp area right above the enemy's collision shape you will see that we will use that from the code so that when your player enters the storm detector coming from below the enemy it will not kill it instantly that would be a bit strange and then we want to do the same move the collision shape back so that it aligns with the enemies collider we can change the color of our storm detector to do so select either the storm detector or the collision shape 2d go down to the canvas item category in the inspector visibility and you want to change the modulate property it's going to multiply the color by the color we select with the color picker so blues tend to work pretty well we can make our storm detector a dark blue we can select a purple or a green this multiplication of the base color of that base transparent blue will always darken the color and this is why some colors like the red for example give you a really muddy dark tone that's why you want to choose something that aligns with the base original blue blue or green will work well for that modulation this is useful if you couple it with the debug visible collision shape option in the debug menu for the project which makes it so when you play the game you will see the collision shapes like so all right now we need to add some code so that when the player enters the stone detector we react to that event godot has a feature called signals to do so when you select a given node like the storm detector and the node tab next to the inspector you can find a list of signals that are emitted when a certain event happens for example you can detect when a body entered the area a body like any kinematic body2d the enemy the player so while going to double click on that body entered signal and a window opens that allows us to connect that signal to a new function on a given node that has a script attached so we're going to select the enemy we want the enemy script to react here and godu will create a new method for us called underscore on name of the node name of the signal on stom detector body entered in this case click connect to create the function and open the enemy script the new function is added at the bottom of the script we're going to select it cut it with ctrl x and paste it right under the ready function this is uh how we do it at gdquest we put these we call them callbacks these functions that get called back when a certain event happens we place them right after the ready function because often you will define signals connections like these in the ready function and you will have the reaction that way right below your setup code now we want to replace the line that says pass a command tells us that we have to replace it with making the enemy die so when something enters the stomp area we are going to do two things first we are going to check if that body the player in that case is lower than the area so if body dot global position dot y is lower than get node we want to get our storm detector dot global position dot y so while comparing the position on the y-axis of the storm detector in the game world with the position of the player that will enter the area going back to the enemy script if we have that condition the character sorry it should be greater than the storm detector's global position if the player is below the storm detector we are going to return from the function return is a keyword that returns a value in that case void which means it doesn't return anything but it stops the function here so all the code that we write after that will not be run and if we don't return from the function we can call a method called q free that will delete the enemy in a sense and we want to do a little more than that one thing we can do is deactivate the collisions on the enemy because q3 is essentially like killing the enemy it's going to delete the note with that we can play the game and now you should be able to jump on the enemy and kill it that way note that there is a small delay between the q3 and the enemy dying we want to make sure that when the player enters the stomp area when it touches the enemy it will not be killed by it or collide with it so an extra thing we can do here is called get node get node is a function to get access to one of the nodes in our tree so we are going to get the collision shape 2d okay while getting that collision shape to the node and we are going to set that disabled property to true so that the enemy cannot be collided with anymore the dot disabled equals true and with that when you jump on the enemy you should not be able to collide with it we'll have to check if this works as expected later but in general in your games you will need some safety checks to ensure that you are not going to have the player die when it kills the enemy it depends on how you write the death code but let's now add the stomp on the player so open the player scene and in the player scene we need to add some tool also to detect the enemy in the final game we've used an area here as well an area called enemy detector select the player node control a let's add an area 2d and we'll call it enemy detector this one is going to specifically detect the enemy so we mask the second layer the enemies layer and we are going to not put it on any layer we can also make it non-monitorable this has the same effect now our enemy detector is going to have a shape a bit larger than our player select the enemy detector node add a new collision shape 2d and again that shape is going to be a rectangle shape 2d then we want to move the shape up center it with the player so you can use the w key to move and click and drag to move the shape up note that if you have snapping on you can toggle it with shift s you should have the node automatically snap to the collision shape 2d here so it will center itself it will align itself automatically with the other collision shape now i'm going to expand that enemy detector to make it a little bigger but not so much this is just so we are going to use that area to stomp the enemy so on the y-axis we want to make it you need to have a small margin under the character so that we can stomp the enemy and this area is also going to be the death area for our player in this demo so you want to make it a little larger than the player's collision shape now we are going to change its color as well so with the enemy detector selected i'm going to go to the visibility tab or category change the modulate color to let's say something blue as well this is still what works best all right with that we are going to connect our enemy detector with the player so the enemy detector detects everything on the enemy layer actually we have to go back to the enemy scene and make the storm detector be on the enemy layer and be monitorable we'll need that to detect when we stomped the enemy so let's do it like that we're going to save go back to the player scene and when we detect an area it will necessarily be the storm detector so we will make the character jump at this point and if the area detects a body it will necessarily be the enemy that touched the player so the player should die let's do it like that so enemy detector we're going to go to the note tab on area entered we're going to double click that and create an on enemy detector area entered on the player we create that function remember it opens the player script and creates the function at the bottom of the script so we are going to move it up and put it above our physics process here now when the area entered we want to stomp so we can do velocity equals we're going to add a new function called calculate storm velocity similar to how we calculate the move velocity down there let's write calculate move velocity but i'm going to replace move with stomp expand the script editor and we are going to pass two variables to that one is going to be our input velocity another one is going to be a new property b stomp impulse and the sump impulse is going to be a configurable variable that is specific to the player so in the player script outside of any function we are going to export a new variable called stomp impulse and we can set it to let's say 1000 pixels per second now we have to create our storm velocity function i'm going to add it at the bottom of my script here new function calculate storm velocity we are going to take two parameters linear velocity will be the first one and the second one will be storm or impulse let's say and it's going to be a floating point value like the move velocity calculate function we're going to return a vector2 now in the function we are going to create a new velocity or an out variable it's going to start at linear velocity it's going to be a copy of our start velocity and the out dot y is going to be equal to minus impulse here and we will return our output here so what this does is fairly simple actually it just replaces the y component of our linear velocity vector with minus simples it's like jumping except that our stomp impulse is a different value from our usual jump note that while doing all this setup as moving forward in the game you might have different types of enemies you might want an enemy with a bumper or something like that splitting that logic to a function makes it a bit easier to make the character bump at different heights you can also use that function to make complex calculations for how the jump works that is why we again split our code into functions it also helps to read that okay here we calculate the storm velocity we make the character jump and that stone pimples that we have on the player is configurable so when you click on the player in the editor you have now the stomp impulse variable that you can change to make the character jump higher when it storms an enemy we can try the game now and see that the player when you fall on enemy jumps thanks to that new function we're going to go to the enemy detector to add the ability for the player to die so select the enemy detector go to the note tab and when a body enters that area while going to make the player die so double click the body entered signal let us connect it to the player and grab that function created at the bottom of the script cut it move back to the top and add it right below our previous function i'll expand the script editor once again and we're going to cue the character free when the enemy entered the enemy detector area now if you play the game with f5 and the enemy touches the player it's going to kill the player here as you can see but if you jump on the enemy you stomp it now this is a let's say relatively easy way to code the system you will see that if the area is too small here or you move it down to be too close to the enemy's collider well the player will die and sometimes they will both die together the player and the enemy so you have to be wary of that that the area should be big enough so that the player doesn't touch the enemy and doesn't die when it falls into that stomp area this is why i made it fairly big and placed it above the enemy's collision box right here to wrap things up we are going to pimp up the game make our camera move smoothly in a slightly larger level so i'm going to select the tile map i'm going to reset the transform on it first i had upset it just for the demo and i'm going to add some walls to it so as before with the tile map selected ctrl shift click and drag to add bits of tiles here and there i'm going to add let's say bumps where we can place the enemies so that they patrol back and forth waiting for the player like that i want the level to be roughly two screens long and that should be good well i'm going to do two things yeah well i'm going to add some background to make our game look nicer not have that ugly gray that we have and we're also going to force the camera to stay within the limits of the level and i'm also going to add an extra tile at the bottom to make sure that it should be okay but that we don't see gray under the floor so to do that i'm going to head to the player scene and select the camera 2d the camera has parameters that allow us to limit how it moves it's going to stick to a certain position in the game world so with the camera selected you want to expand the limit category and we want to make sure that first it stops at zero on the left side of the game world so you can see that with that our camera is pushed to the right side of our y-axis and if you play the game you will see that the camera is going to stop on the left at the start of the tile map then at the top we want to do the same thing make it stop at zero this forces us in the level template to make our level under the x-axis if you were to place your level and your game above the origin of the game world you would have to make the bottom of the camera stop at zero instead but that's not what we want we want to keep it the way it is now going back to the player now it's going to follow the in x-axis or it's going to move along the x-axis that top limit and it's not going to go past the left limit the y-axis here and we can smooth the limit on the camera so that it doesn't abruptly stop on the borders of the screen in some cases now when we move the character the camera still moves along with it and we have a margin in the middle where when the character moves within a small box the camera is not going to move we can change that with the drag margin here the property that creates that box that box is a fraction of the total camera area 0 2 on every side we are going to make it so there's a bit of a margin on the vertical axis so the top and bottom properties but the camera always centers on the character on the left and right axes on the left and right side and to do that we have to reduce the drag margin to zero on the left and zero on the right then you will also want to make sure that drag margin h and v are enabled otherwise these drag margin properties will not do anything so when you do that as soon as you move the character the camera is going to center on it all the time finally we can smooth out that effect that movement so that the camera does not follow the character straight but it has a slight delay click the enable checkbox to enable smoothing i'm going to press f5 to play the game so that you can see that now the camera smoothly homes onto the player you can change that property i'm going to make the window stay always on top so that now i can change the property anytime and if you check the debug menu you have two options to synchronize changes that are on by default whenever you make a change in the editor like lowering the speed value for this moving and save you're going to see the camera move much slower behind the character and if you increase the value now the camera follows the player really quickly it has that slight smoothing but it's fairly subtle i'm going to select a value of seven let's say voila so that's a good thing to know you can keep a window above your editor like a gameplay window and change any value in the editor or i can go back to my level here and select the tile map add tiles where's the player it's around that area you can see that when i'm adding tiles in the editor they instantly appear in the game as well this is a really nice feature of godot that you can use to make good level design as you are working so now i'm going to create some more enemies here i'm going to select the enemy i'm going to move it in between these holes you can see that the enemy position updates instantly select the enemy in the scene tree press ctrl d to duplicate it and move the second enemy a bit farther out and now we have two enemies walking in our level we can jump on the enemy's head to stomp it or we can die miserably that's the thing i was talking about we want to make sure that the stomp area on the enemy is big enough so that we don't get that case where the player dies before killing the enemy so i'm going to make it a little bigger here and maybe go back to the player scene and make it so the enemy detector aligns with the x-axis with the base of the player's collision box and that should be enough to avoid that bug yeah seems to be working fine and with that you have a nice little level you can also make the camera stop at the end of the level the thing with that is that you have to configure the camera to do so for every level based on how big the level is let's see how to do that for our level template so we're going to go on the level template scene i'm going to zoom back and we want the camera to stop on the right edge of our tile map here on the last tile you can see we have rulers in the view that you can click and drag rulers from we're going to hover the left ruler and click and drag to place a ruler on the right side of your game level you can still use the mouse wheel to be more precise and align the ruler with the end of your tile the advantage is that you can see as you are dragging the ruler how many pixels it is compared to the origin on the x-axis you can also hover a an existing ruler on a given axis so for example to move an existing ruler you want to go to the ruler to the top of the view here and click and drag from there you can't drag it from the view you have to go in the roller area and click and drag and we can see that the level ends at 3600 pixels now we don't want to change the camera's limit in the player's scene because this will apply to every level where we place the player instead we would like to just change that value the end of the level in our level template here we can do that by right clicking on the player selecting editable children and you want to go down to the camera 2d expand the limit category and for right you will enter 3600 pixels once you've done that i'm going to move the player forward a bit so that we can see it as you move the player to the right side of the level you will see the camera stops at the rightmost of the level this limit feature is really nice because you can see how when you move the player around the game world the camera really clamps it stops at the limits we defined with that we have one thing left to do adding our background the background is a texture that you can find in the assets folder it's called background.png we're going to click and drag it into the game and we want to make it a texture rectangle now make sure that when you do that you are on the level template note so background is added as a child of it now the texture rectangle is a texture that can map to the screen it is a node designed to create user interface but it's sometimes useful to make textures that repeat or textures that take the entire screen area you will see its icon is green when you select it a new option appears in the toolbar called layout this is an option a tool you can use to quickly anchor and resize your texture based on the game window so click the layout menu and select the full rectangle option when you do that the background will take the entire game viewport click and drag the background to the top of the list so that it appears in the background and now when you play the game it's going to get stuck on the left side so it's not going to ban the entire game scene we can change that by creating a canvas layer it's like layers in a program like krita or so with level template selected press ctrl a to add a node and look for canvas layer add a canvas layer node i'm going to place it at the top right below level template and add background as a child of it now our canvas layer if you select the node has a layer index property this defines in which order these layers or the sprites draw in the game layer one is going to be above the default sprites that we placed in our scene tree so we want to use a negative number here you can put anything minus 100 to say it's really far in the background if you want this will make the layer draw behind everything and then can press f5 to see that now this canvas layer stays behind the character at all times so it's like a fixed sky texture if you want last thing i'm going to go to debug hide the collision shapes by checking visible collision shapes here toggling the option off so that we can see the game in its final form you
Info
Channel: GDQuest
Views: 701,307
Rating: 4.9132376 out of 5
Keywords: godot platformer 2d, make your first 2d game, godot 2d platformer tutorial, godot beginner, godot platformer, make a video game in godot, how to make a 2d game in godot 3.1, godot 2d tutorial for beginners, godot platformer enemies, make a game in godot, godot tutorial for beginners, godot platformer movement, make your first game, godot engine getting started, godot 3, godot 3.1, godot game development, godot mario tutorial, godot engine, godot tutorial 2d
Id: Mc13Z2gboEk
Channel Id: undefined
Length: 118min 25sec (7105 seconds)
Published: Wed Oct 02 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.