Player Input & Setup: Godot 4 Snake Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey folks this is Sean from bacon and games and in this code along series we're going to use the classic arcade game Snake to learn gdau since most games are built on the same fundamental building blocks we can use a simple game like snake to make it easy to demonstrate and recognize those blocks without the game itself getting in the way let's get started as you can see here I've got an empty gdau project set up and the very first thing I'm going to do is just create our gameplay scene going to re rename this to gameplay and then we're going to save it we want to save this in our gameplay folder by the way I've set up a couple of folders off camera that I know I'm going to need in just about every project we'll create a couple more together along the way the next thing we're going to do is attach a script to gameplay we're going to leave it named gameplay and this is going to be where the majority of our game logic lives we're going to give it a class name of gaml and save the first thing we're going to do is work on detecting user input which is quite simple to do from within our process function we can use the is action pressed and look for UI uncore up and for right now let's just print out up is pressed and save Let's test our game and this you'll see this pop up the first time you run any project it's asking which scene do I start with since we only have the one gameplay scene we're going to select current we can and we'll change this later so now that our project is launched you can see down here in our output window if I press the up button we're detecting that the up key is pressed so it work works so let's go back and repeat this for each of our directions and save now if we test it again you see it can detect left up right and down perfect although with these print statements we're not doing anything super valuable so let's add a variable up here called move undor dur for move Direction and we're going to store a vector 2 in it and by default we're going to set that to Vector 2. right which is the same as Vector 2 1 comma 0 we're going to default it to Vector 2. right because we need a direction for the player to start and most games will start you moving left to right so we're going to set this in here we're going to set this to Vector 2. up that's all we're going to do with user input for right now the next thing we're going to do is create something to actually move so we're going to create a new scene and we want it to inherit from area 2D we're going to base this node on area 2D because it's going to allow to detect a very simple collisions between the snake and the food that it eats and the snake and itself we need to resolve these angry yellow warnings an area 2D will'll expect a collision shaped 2D and a collision shaped 2D is going to expect a shape which we're going to use this circle actually let me switch back over to my 2D view so you can see if I delete this shape you can see when I've added my circle shape it appears at 0 0 the other thing we're going to need for the snake the the snake's head of course is a Sprite so that we can see it on screen so let's do that now and of course we don't have any Sprites in our project yet so let's right click on our gameplay folder let's create a new folder called Sprites we're going to tab over to our Sprites and with our Sprite folder selected let's drag them over into our project and just like that we've got Sprites in our game now we can use this devil's workshop logo as the head of our Sprite sorry the head of our snake and there we have it the art Assets in this video are generously provided by my buddy at the devil's workshop I'm going to leave a link to his itch page down below now you may notice that now that we have a Sprite I can no longer see my Collision shape well that's because the bottom of your scene tree is actually the top of the stack so you can think of it like this Sprite 2D is the closest to the monitor so if I drag this up to the top of my scene tree now I can see my Collision layer again and I'm going to save so in our gameplay folder oh actually before we save let's name this to head because this is going to be the head of our snake and now we can save and of course we are going to need a little bit of code on this this node so let's click the attach script create a new head script of class name head and again save now if we go back to our gameplay scene we can add that head by clicking this link button down here that's going to allow us to bring in another child scene here's the head scene that we just created click open it shows up in our scene tree now when we run our project very little happens but there's the head of our snake let's go back and drag that into the scene a little bit better so that we can see it doesn't really matter where right now actually since this is going to be a grid based game what we're going to do is go into our configuration snap configuration we're going to set this to 32x 32 then we're going to turn on our grid and now when I drag it around it's actually going to snap right onto the grid which is what we want because in snake your character actually moves in increments on the grid just like this so we'll just put him right here for now if I click play we've got our character here so far so good okay so now we've got our snake we've got our grid let's add some basic code to move this little guy around so let's click on our gameplay scene and I'm actually going to create a function called update snake because I know eventually we're going to be moving more than just the head around but for right now let's just get some basic stuff on the screen so that we can feel good about ourselves within this script we're going to want to reference the head so I'm going to click and drag over here and before I release I'm going to hold control and then let go and that's going to bring in actually you know what before I do that let's set this up to access as a unique name what that's going to do is in the event that we Nest this under something else and change the path to this node it's not going to break our on ready variable reference so which we're probably not going to do but frankly I think it's a good practice so we're now we're going to drag this over and this is actually going to be of type head and we're going to go as head just to make doubly sure that all of our code completion works now we don't actually have any code in our head right now really but let's for example let's just say we created a function called say hello that just printed hello if I come back into my gameplay script and type head dot now you can see I'm getting my say hello if I remove the as head a lot of times the code completion doesn't actually work yeah see no say hello so besides it just being a good idea to statically type as much as you can because it makes your code cleaner and easier to read it also so makes it a lot easier okay we don't need that so let's kill this say hello function back to gameplay we're going to move in 32 pixel increments because we want to stick to a grid before we do that we need to figure out on what interval we want to move this snake so I'm going to create a couple more variables one called time between moves which is going to be a float we'll set that to a th000 by default we're also going to need a variable called time since last move float which will set to zero that's going to represent how long it's been since the last time we moved we can also create a speed variable let see set this to let's say a th000 that's going to allow us to increase the speed of the snake as the game gets harder and harder so that'll do it for right now since the snake is going to be comprised of area 2DS that we move around and area 2DS are physics objects we're actually going to want to update them not in our process Loop but in the physics process Loop instead so what we're going to do is let's let's create a very simple mechanism in here for determining on what tick we're ready to move the snake and we can do that by doing time since last move plus equals Delta times our speed variable and then we can say if time since last move is greater than or equal to our time between moves we we want to update our snake and we want to reset our time since last move we can get rid of our pass and to show this in action we can print move the snake and if we run this you'll see on regular intervals we're getting that message if our speed went up let's make it say 10,000 to make it noticeably faster you can see we're going to be moving significantly faster so that's going to work for a mechanism to move the snake but now we have to actually do something with the update snake method so let's get well we can leave that in there for right now that's not going to hurt so if we want to move our snake on every tick we need to know the direction that it's going to move in and by how much so we have have the move Direction stored up here as these vectors and I'm actually going to type these out so you can see what these look like so Vector 2 do up is 0 comma -1 so that's 0 in the X one in the Y this is right is 1 comma 0 down is going to be 0 comma 1 because y goes positively in the down Direction and then this is going to be -1 comma Z so to move our snake we can actually multiply our move Direction by the size of our grid so in our update snake function we can do head. position equals head. position plus then we can take our move Direction and multiply it by 32 which is our grid size so you see if we play this now it should start out mov moving to the right very slowly and if I press up oh nothing happens why doesn't anything happen when I press up I'll tell you why because I'm pressing up on the w s and D Keys If I press up on the arrow keys now we're going up if I press left now we're going left let's fix that real quick so we can go into project project settings choose our input map turn on show built-in actions and find find our UI left right up and down right now these are default mapped to the arrow keys but we can add our W SD Keys very easily by clicking this plus button this is left so I'm going to press a and then okay and now you can see that the a key has also been added or mapped rather to UI left and we can repeat this process for right up and finally down so now if I play this I can move my character with the w s and D keys I can move it painfully slowly okay so a couple of things before we move on I want to do a little bit of refactoring first things first it's very possible that I might want to know something about our grid size somewhere else in the code I also might at some point let's say maybe our grid size becomes 16 or 64 I want to be able to change that in one place we're going to do that with an autoload file so I'm going to right click on my autol loads folder go to create new make a new script and we're going to call Global now I can expand open this up I don't need any of this we're going to create a constant called grid size it's going to be an INT 32 save that's all we're going to do with global for right now now that we've created our Global autoload file we need to make it accessible to the entire project by registering it as an autoload file we can do that by going to project project settings autoload and then click this folder navigate to our autol loads select Global it's going to pull the name in which is the name we want we can click add and bu default it's enabled so now instead of hard coding 32 what I can do is type Global do grid size which is going to be the same as 32 and that way if it changes down the line you only have to change it in one place the other thing I want to do and I I want to do this now because I know we're going to have both the head and then multiple bits of the tail that all need to be moved around the grid I want to create a base class that both the head and the the tail Parts can inherit from so that they both have the same methods to move them around and that they can be stored in an array that is statically typed so that we keep our code hinting intact it's probably not necessary for a project of this size but I like to do these things even in smaller projects because I think it's a good practice I think it makes my code more readable makes my life easier less typing so on and so forth so let's go back to our head and right now head is extending from area 2D which means by default it has all of the properties and methods of an area 2D but what if we wanted head instead to inherit from another class called say snake part that both the head and the tail could inherit from and that they would have shared functions for things like how to move them around on the grid how to keep track of where it was on the last tick because remember this snake is going to move in a chain and the first section of the tails is going to follow the head the second section of the tail is going to follow the first section of the tail so there's going to be some commonality between the heads and the Tails so let's make our lives a little bit easier let's create a new script that inherits from area 2D and we're going to call it let's just call it snake part I think that works and let's open up our snake part script let's give it a class name of snake part and we don't need any of this so snake part itself is inheriting from area 2D so that when the head and the tail pieces inherit from snake part it will still be an area 2D and have all those properties but it's also going to have the properties that we add the properties and methods of the snake Park class you only need two very simple things to make this class worthwhile the first thing is going to be a record of our last position which is going to be a vector 2 and then we're going to need a function that defines how we move it from where it is to where we want it to be so we're going to call this move two and it's going to take a vector 2D called new position and this is going to be really simple we're going to store the last position as its current position so that we have a record of where it was before we moved it and then we're going to set its position the new position and that's it it's very simple so we can actually close our snake bar class now and go back to the head and instead of extending from area 2D we're going to extend from snake part and you'll see that when I come in here if I type self. move to there's our new method that we're inheriting same as self as last position there it is now from here we can continue to add things to the Head class that are specific to the Head itself and we can add things to the tail class that are specific to that so that they become different and discret objects in and of themselves but they will always share anything that we put in the snake part so we don't actually need any of these in the head class so I'm going to delete them and then we're going to go back to our gameplay script and instead of doing this head. position equals head so on and so forth what we're going to do is we're going to say head. move to and then we're going to give it this new position so now if I click play oops nothing's happening why is nothing happening well that's because we've left out its position so what we need here is and actually we're going to make this a little bit cleaner so let's say variable new position Vector 2 equals head. position plus move Direction times Global Dot grid size and now instead of that we can put new position in here now if we play it and it looks the same but we're a little bit more flexible now looking at the time we're already a little bit longer than I wanted this video to be so I think this is going to be a good place to stop in the next session we'll set up boundaries to allow our snake to wrap from one side of the screen back to the other if you learned something today please like And subscribe to help me reach more wonderful makers like yourself and until next time be kind to yourself and be kind to others
Info
Channel: Bacon and Games
Views: 1,879
Rating: undefined out of 5
Keywords: godot, godot4, gdscript, godot 4 player input, godot snake game tutorial, 2d character controller godot 4, godot 4, build a game in godot, godot full game tutorial, how to make game in godot 4, make 2d game in godot, godot 4 simple game tutorial, getting started with godot 4, godot 4 settings, godot input map, godot player controller, how to code gdscript, free godot course, easy godot tutorial, detect collision godot, collision detection godot, how to make a video game in godot
Id: IgwQbmvtlK8
Channel Id: undefined
Length: 21min 7sec (1267 seconds)
Published: Tue Nov 14 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.