Godot Basics: Platformer

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys today i'll be showing you how to make this simple platformer in godot so let's get started first thing you're going to want to do is to install the kadoba engine if you don't have it installed already i'll have a link to it in the description below and after installing open it up and you'll probably be met with a screen like this we're going to want to create a new project and here you'll select where you want this project to be saved so for me i'll just select my godot folder and create a new project called demo platformer select current folder project name is also demo platformer and we'll create it and given this new project will be met with this empty screen with no assets or anything so i've provided a link in the description where you can find the assets that we'll be using for this project here i have it inside of this folder called platformer assets and what we're going to want to do in order to add this or add these to our game is to copy or i guess cut and then find wherever we created our project so for me it was in godot tutorials and demo platformer and just paste it here and then now if we go back to the editor we should find our assets here so the first thing we're going to want to do is to create our player object and our player object is going to be type kinematic body 2d so what i did right there was click this plus button and then in the search bar i'm going to type in kinematic body or can it and then you'll see here it comes up kinematic body 2d double click it to add it if you hover this yellow triangle it'll say that given being that this is a kinematic body 2d it has to have a collision so we'll add that to so search of collision and then select collision shape 2d and this collision also needs a shape so on this right hand side in the inspector in shape we'll select capsule because we want our player to be a capsule shape and then now just rename kinematic body 2d to player and then ctrl s to save now that we have a player and a collision we're going to want to add some graphics so that you can actually see your player in the game so to do that we add another node and the one we're going to be adding this time is sprite and for sprite sprite takes in a texture so in our sprites folder there should be a player.png just drag it over here into the textures and you'll see we have a little player you might notice it's a bit blurry that's because um by default when importing uh images and such into godot it'll be imported with a filter on which kind of like tries to soften any images you have but when working with pixel art we kind of want to preserve that jagged edge so in order to fix this we're going to want to click on player.png and right next to scene there's a tab called import and then if we scroll down a bit under flags there should be filter and click off and then re-import and then now you see a pixel perfect pixel art and we're going to want to repeat this for all of the images we've imported so coin tile one tile two and tile three so that when we use them in the future they won't be blurry like the player was uh now that we've done that um you saw i kind of just reshaped the collision to fit the player better you can do that by just dragging these orange circles on the collision and i guess a better way to do it might be to on this top bar over here these three dots click use pixel snap so that you're able to align the collision up with the edges of the player as you see right here and uh being that our player is kind of a ghost it's okay if uh some of the collision doesn't match up with the exact bottom of the sprite because it'll give kind of the effect that he's floating so after we've made after we've made these changes we're going to want to save and then now um we have a player we have collision and we have the sprite next we're going to want to kind of add the ability to control the player because now if we go up to the top right play this scene you'll see if you look really closely on the top left there's a kind of a white pixel that's our player and moving the arrow keys or pressing on the arrow keys does absolutely nothing so we're going to want to implement some movement and to do that we'll do it through a script so first thing we're going to want to do to add a script is to click on the player kinematic body 2d and then right here there's a button that's to attach a new script to the selected node so we're going to click it and it's fine being called player.gd by default and we're going to click create and here's our script this is uh really where the brains of the operation is going to lie where we define movement and other other things maybe like fireballs or something but um for this tutorial we're going to be focusing on uh movement and coin collection so uh let's think about what we want uh our player to be able to do we want it to be able to move and that's pretty much it for now because we'll just focus on one thing at a time so for movement we're going to want to define a variable called speed so this is going to be the speed that the player moves at and for now we can just set it to 100 and then we're also going to want to uh have something to store the velocity of the player uh as in like what direction they're moving yeah what direction they're moving uh up down left right and such and we assign this by default a vector 2. next what we're going to want to do is to you see over here um in the auto generated script there's a func process delta uh just to demonstrate you don't have to do this but if i inside of this process delta i print a you'll see when i click place scene it'll print a every single frame so basically what this process is doing is it's running whatever's inside of here every single tick it can so this is basically where we're going to put our movement data and stuff because we want that we want those things to be calculated every single frame but um for our purposes we won't actually be using the process function there's actually a separate function called a func pro physics process and this physics process is different from the normal process in that um this physics process tries to align every single call of this um or from what i understand it tries to align every call of this function to the frame rate of the game well this one uh tries to call it as fast as possible so as soon as the previous iteration finishes it tries to call it again this one aligns it with the frame rate of the game so that um any physics bugs you might encounter using process it'll be minimized when using physics process so before we actually do any input we're going to want to define what buttons we want to use to control the player and in order to do that we go to the top left project click on project inside project settings and you should see uh to the right of general input map and you can see that there's some default key bindings that godot provides in every default project but um for our purposes we're going to want to define our own so action up just type up and then click enter or the add button and in this new event click the plus symbol all the way to the right add a key and this key i'm just gonna press the up arrow so after pressing the up arrow click ok and then now this uh up arrow event is bound to this action called up and we're going to want to do this with all other directions so up down left and right now we have these key bindings we can go back uh we can go back to our script uh to actually get input there's many ways to do this but one way i like to do it is to use the input func input event function this is called um every time an event occurs so let's say moving a mouse or pressing a button every time something like that occurs this will be called so in order to actually use this we're going to need to go into the ready function and then set uh and then type in set process input and then inside of this we say true to to let the script know that we're going to be using the input process and although physics process is set to true by default i also like to put explicitly inside of the ready function that we're using it so that um kind of like a reminder to me that we're using it but anyways inside of our input function we're going to want to kind of parse the inputs of what the player is currently pressing down so in order to do that we're going to want to create additional variables up for the up direction uh down left and right we're gonna set these as booleans uh because it's a button press so it's gonna be true when the up button is pressed false when it's not pressed so initialize them to false and in this input event we're going to add a bunch of if statements so if event dot is action pressed and then autofill we can go down and find our up event if action is pressed up then we set up equal to true l if so alif is kind of like else if but um yeah uh when doing it in godot you need to type alif uh then l if event dot is action released so if the up arrow is released then we're going to want to set up to false and we're going to want to do the same thing for down left and right so i'll just copy and paste all this code and kind of adding spaces to make it look a bit neater we'll just change this to down and copy and paste it and save just a quick note this isn't the only way to do inputs this is just the way that i like doing them but um yeah with these inputs now set we can go into our physics process and kind of like do a test print so let's try up so if all works correctly when we um test play the scene pressing up will print or when we press up this false will become true and yep good so now for actually moving the player so let's think about what we want to happen when we press up down left and right so given that we're working on a platformer the down button doesn't actually do anything because um uh up is jump down if you think about it uh in the platformers you've played uh doesn't really serve a purpose because the player is always being pushed down by gravity but um in any case we've added it here so if you wanted to add like a sliding mechanic when you press down it's here available for you but um yeah so we're going to want to find out whether the player is moving left or right first so we're going to create a variable called htter which stands for horizontal direction and the value of this is going to be int left actually in yeah in left minus int right and what this means is um we're taking left which is a boolean and casting it to an integer so a boolean is one when it's true and zero when it's false so um thinking about it if left is one uh or if left is pressed then left in left will be one and then h stir will be one but that's only if right is not being pressed if right is also being pressed so that means left and right are being pressed simultaneously left will be one and right is also equal to one so then one minus one is equal to zero so our net horizontal direction will be zero so this kind of calculates uh based on what buttons you're pressing which direction you should be moving in and just for testing we're going to want to set velocity.x equal to h3 times our speed variable that we set up here and to actually get movement from the player we're going to want to call the function move and slide and in this movement slide we're just going to pass our velocity and save and try running this scene and if all worked correctly when you press left you should move left and if you press right you should move right and of course i messed up it should actually be right on this side and left on this side so yeah because um if you think about it right is moving in the positive direction and left is moving in the negative direction so uh when pressing left h2 should be negative one when pressing right it should be positive one so now when we run it pressing right should actually move you right and pressing left should actually move you left uh you should see your character move all the way in the top little corner of your scene that's good and all but um it's kind of pointless just having a little character moving on the top left without being able to uh even see what's happening so to solve that we can uh go to our player click plus and add a camera and this camera will kind of follow the player around if you see this purple border this is the size of the camera and if we play it right now nothing will happen because in order for the camera to actually function we have to set current to on so that the engine knows that this is the camera we want to follow and then now playing it uh you should see our character is now in the middle of the screen though quite small and pressing left and right although it seems to do nothing actually still moves the player but uh it seems to do nothing because the camera is moving along with the player but yeah so to make the player kind of bigger i guess in the context of the camera we can set the zoom 2.5.5 and now the player will be a bit larger i think we could even set it to 0.25 yeah and then now clicking play they should fill up a larger space on the screen and that's great um [Music] now you see we're moving left and right but we kind of want the player to indicate that we're either moving left or right because uh even when we're moving to the left the player is still facing towards the right and to do this we'll be working with sprite scale so if you come over here you can kind of like play around with sprite scale try setting x to negative 1 or setting it back to one that'll change the direction of the sprite and to take advantage of this fact we go to physics process and then if hter doesn't equal to zero we don't want to change the direction that the player is facing if the horizontal direction is zero so if it's not zero then we're gonna wanna access the sprite and access this scale property and then we're going to set the x scale equal to horizontal direction and saving it now and playing the scene we should see that the player turns along with the direction that they are moving in awesome so now we just have a player moving along a horizontal axis uh kind of pointless also because we can't really see them moving in relation to anything so on our screen it kind of looks like they're stationary so to solve this we'll go to the top left create a new scene and this scene the root note is just going to be a 2d scene so click this button and we're going to name it to world this is going to be the world where the player is in and where the actual level will be and save this scene save it as world dot uh t scene and then in order to actually move this player into the world we click this instance button and we can just click on player and he is now in the world and inside of this world we can uh just temporarily to actually see that the player is moving we add a sprite so um yeah nope sprite is all right uh so sprite first we're going to want to set a texture for it and then we drag it around so this is just the icon.png just here for testing purposes if we put it here and then we play the scene we see that the player we actually are able to see that the player is moving in relation to this new sprite that we put down okay so we have the player moving on a horizontal axis now we're going to want to add um jumping and stuff and also falling in order to do that um we're gonna go back to our player scene and open the script up again we're gonna want an additional variable and call this gravity uh for now we can set it to 3 or 10 yeah set it to 10 and then we're going to want also a max gravity so that gravity doesn't go to infinity and this can be set to 1000 all right so what we're going to want to do now is uh now that we have gravity and max gravity we're going to want to on every physics process apply this gravity to the player so in order to do that we just do velocity dot y plus equals gravity and then to cap the gravity so it doesn't go beyond um 1000 kind of like terminal velocity um we go over here and velocity actually i'll rename this to max fall terminal velocity so yeah it's their terminal velocity they can't fall faster than that speed so velocity.y equals the min between terminal velocity and the current velocity so if it goes beyond terminal velocity it's just bounded back to terminal velocity and now if we go back to our world and add the sprite again to see movement we see that our player is falling awesome uh yeah so given that there's no other collision objects in the scene our player just kind of falls into the void so we're going to want to add a temporary collision just so we can play around to do that we create a static body 2d and in the static body we add a collision shape 2d and the collision shape 2d we'll just set it to a rectangle shape and just drag the orange circle to create the floor and collisions aren't actually visible in games so for debug purposes we can go to the top left of the top left of the editor right next to project there's debug and then there's visible collision shapes and we can click check on that and then now when we play the scene you see we've fallen on to the static body and are now moving around on it uh pressing up doesn't do anything because we haven't implemented jumping yet but we're gonna do that now so one more thing to take note is that um i guess it'll be more easily visible if i duplicate the static body and kind of add a ledge so we'll chill on this static body for a while but then moving on to the next level you see how quickly the player fell from there to there that's because even when the player is on a static body they're kind of accumulating gravity onto themselves until they reach terminal velocity so in order to kind of counteract that we're going to want to make sure that gravity is only being applied when the player is not on the or is not colliding with the floor and to do that there is a function in godot called it is on floor so as long as this is not true so if the player is not on the floor we denote not with the exclamation mark then we increment velocity uh dot y um if you tried uh playing this scene right now you'd notice that you'd still fall with incredible speed that's because is on four actually only works if we add one thing to move and slide that is we have to let the engine know which direction is the up direction so that it knows um kind of what direction or what the floor is like the norm the floor normal i guess if you've taken physics but um yeah so our normal is quite simple up is um up is in the up direction i guess and in our case that is uh vector 2 0 negative 1. and now if we were to play the scene you'll notice that we fall less violently when moving from one ledge to the other all right now for actually jumping uh so jumping we're only we only want to be able to jump when the player is on the floor so we're gonna be using this uh function again but um we're also going to want it in these variables set a jump height variable so jump height and we can set it to let's say 300 300 300 to begin with so yeah if is on floor so if the player is on the floor if uh up uh remember this up is the variable we've set for detecting whether this um button is pressed so if up then we're gonna wanna just set our velocity set our velocity to the negative of jump height so make sure you have a negative before jump height because um in godot uh i guess moving upwards is actually moving in the negative direction and moving downwards is positive so yeah now we can test our game by going to world and then pressing up now you see our player is able to jump and i feel that the jump height is a bit too high so i'll reduce it from 300 to maybe 200 uh and yeah that's much better now instead of just jumping around on these uh featureless static collision or static bodies we're going to want we're going to want to create actual terrain with these tiles we've created so in order to use these tiles we're going to want to use what's known as a tile map so tilemap is a node in godot that kind of lets you use a tile set to paint a map and we haven't created tile set yet but we're going to do that right now so in order to create a tile set to use with this tile map i like to go to scene click new scene and then the root node is again a 2d scene and rename this to tile set and in tile set we're going to want to add a child of a sprite it's just a normal sprite and the sprite we can rename it to tile one and tile one we're going to add a texture and it's going to be this first tile and since we want our tiles to have collision inside of the tile sprite we're going to add a static body static body 2d and as we know static body 2ds need a collision so we add a collision shape 2d and this collision shape 2d we're just going to define its shape as a rectangle shape and then make sure pixel snapping is on so that we can fit it perfectly to the edge of the sprite awesome now that we have our tile we're going to want to keep the collisions uh in the same place so that when we drag it we don't accidentally move it around so to do that just click on static body 2d and click this lock icon on the top and collision shape 2d and this lock icon on the top now we can press ctrl d to duplicate this tile we've already made and once we do that we can drag it out and press ctrl d one more time for a third tile and each of these tiles we're just gonna change the sprite they have so that they have a varied appearance and now that we have three tiles we can convert this scene to a tile set by going to scene and then over here there's a convert to and then convert to inside here tile set and you can just name this tile set and save going back to world inside of our tile map on the right in the inspector under square this should be tile set it's empty right now but click the arrow next to it and load and we should be able to open up the tile set we've just made and now we can draw tiles wherever we want but you might notice that the tiles are really small when compared to the grid and that is because if we go back to tile map in the inspector we'll see under cell that the size is currently set to 64 by 64 while our sprites are only 16 by 16. so to fix this just change 64 to 16 on for both x and y and you'll see they line up perfectly and then we can just select different tiles for uh i guess more interesting appearance of the terrain and then now uh tess playing the world we see we're able to jump around on this tile map and uh now that the terrain actually has graphics we can go back to debug and then turn visible collision shapes off so that we have just our player jumping around on our tile map you might notice that our background is kind of gray if you want to change the color there's many ways to do that but i think the easiest for us right now is to go to project project settings and then in general if you type search on the left you should be able to just type in color and then in under rendering environment default clear color you just set it to black in our case unless you want a different background color but um yeah so now we have a black background with our tile map and player jumping around perfect so the last thing we're going to be implementing today is a coin that the player can pick up and to do that we're just going to want to create a new scene uh this one is not going to be a 2d scene so we're going to want to press the plus button and change it to area 2d and the area 2d like the static body and kinematic body needs a default collision shape or needs a collision shape childed to [Music] the uh node so we're going to just click plus and collision shape and in collision shape 2d since our coin is kind of looking like a circle we're going to want to set the collision to be a circle and inside of area to do we also want to add a sprite so that the player can actually see where the coins are and just drag the coin graphic into the textures of the sprite and then now we can kind of drag the collision of the collision shape 2d to match up with the size of our coin and we're going to rename this area 2d to coin and then click ctrl s for save and um yeah now we can go back to our world and click on this button again kind of chain and it instants a few coins into our scene um make sure you click on world before clicking on this chain button but uh yeah so now we have a coin in our scene we can click ctrl d to duplicate it a few times and spread them around our scene but when i click play you'll notice that they don't actually do anything when i run into them and that's because we haven't defined any behavior for them yet so to do that just like before with the player we're going to want to add a script to our coin and it's fine just being called coin 3d and click create and inside of our coin script we're gonna want to first click out of it and then click uh back on area 2d and then in the inspector you'll notice to the right there's a tab called node and inside when clicking node under signals you'll find a bunch of signals that this that the area 2d has so a signal is basically a function that's called whenever one of these events occurs and the event we want to keep track of is when a body enters our area 2d so under signals area 2d double click on body entered and connect to the script on the coin and just click connect and then now we have a function here called uh on coin body entered body um and we know that it's receiving uh or that it's connected to the signal because of this green arrow uh yeah that it's uh this function is called when the body entered signal is triggered so if we just do a test print here uh ascsd and kind of run run our world again go back to the world tab and click run we'll see that whenever we run into a coin uh asdsd is printed out into the console and that's good that means that our collisions are working and that the coin is detecting a body entering and when your projects get large it might be tedious to keep switching tabs and pressing this play scene button so to set a main scene that runs on default uh including when you export the game as an executable you can click on this play button and then no main scene has been defined select one and you can just click select and for our main scene we're just going to want to select world.tscn and that'll just define world as our main scene and now that we have collisions working between the player and the coin we're going gonna want to add uh something that lets the player collect the coin so to do that we're gonna add a function within the player uh script and that's just gonna be funk collect coin and it's not going to do anything yet because first we're going to want to create a variable and call it uh coins and by default it's going to be zero because the player starts off with zero coins and inside a collect coin we're just gonna want to increment coins by one and um yeah so every time this function is called coins just gets one added to it and for testing we can inside of the physics process we can just print coins and inside of coin we're not actually calling uh the collect coin yet so inside of this function we're just going to undo body dot collect coin and click run and you see every time we hit a coin this number increases but one thing that we want to be aware of is that on coin entered uh body this body could be anybody not just the player so let's say it could also be the static body that the floor is so if the coin were to come in contact with the floor then the coin would try to call the collect coin function on the floor and that would cause our program to crash because collect coin is not defined for the floor like it is defined for the player so what we're going to want to do to make sure that the coin only triggers this action on bodies that are able to collect the coin is to add a check that checks if body dot has method and then in here just the name of the function collect coin then we're going to want to do body body.collectcoin and then um as you notice before when we hit the coin the coin didn't actually disappear so we're going to want to do q free to to kind of destroy this coin so that it can't be collected more than once so no infinite money glitches and we can delete the rest of this because this is all we need for our coin class and now running in the world you can see that start off with zero coins when we hit one we get a coin but it disappears from the world and um when you actually export this game uh the console won't be available to the players so we're gonna want another way to kind of convey the amount of coins they have other than just console output so to do that we can delete our temporary test console output for coins and then inside a player we're going to want to add some kind of hud some kind of ui to let the player know that they have collected one two or three coins so to do that we're going to add a node called canvas layer and this canvas layer we're going to add a child to it and the child is going to be a label and uh it's gonna seem blank but if you go to inspector on the label you can just type in some random words so that you know where it is and um let's see how this fits in general on our game so far it's kind of tiny so we know we're going to want to have it a bit larger but before that we're going to want to set a custom font that kind of more fits our pixley aesthetic so to do that in our label under control there should be a tab called custom fonts click check on the font and in empty new dynamic font and click click on the dynamic font and inside of here there should be a tab called font and font data inside of the assets folder we downloaded at the beginning there should be a file called m3x6.ttf this is a font file and we just drag it into font data and now we have a pixel art kind of fun so with this font now um we can see it's kind of hugging the edge of the uh we can see it's kind of hugging the edge so we're going to want to drag it a bit outwards um just in general if you zoom out a bit you might be able to see this faint purple line and these purple lines along with this sort of turquoise line and this magenta line serve to kind of show how what your viewport is going to look like when the game actually runs with respect to ui elements so when this label was here before it was kind of hugging the edge of the screen so we're going to want to add a bit of space between the edge of the screen and our label and as we noted before the text was kind of small so also inside of this under label control custom fonts font there's a settings and inside of settings we can set size to 64. 64 might be a bit large let's find out uh nope it's perfect so yeah set it to 64 and instead of this sample text we have we can just type in points and then colon zero or i guess coins zero and then now with coin zero um running the game you'll notice that nothing happens because we haven't defined that yet and in order to do that we're just going to be kind of replacing the text that appears on the label so [Music] to do that we go to our collect coin function and right after we increment the coins we're gonna want to get the label so a dollar sign in canvas layer slash label and then after that we click dot text to get the text attribute from this node and then we set it to coins and then colon space and plus str to cast our coins to a string so coins plus str coins and then now when running the game uh anytime we collect a coin the counter should increment and yeah that's pretty much it for um our basic platformer thanks for watching and see ya
Info
Channel: weekend
Views: 221
Rating: undefined out of 5
Keywords:
Id: AHXfaNgW0KU
Channel Id: undefined
Length: 45min 12sec (2712 seconds)
Published: Mon Sep 20 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.