How to Make a Google Chrome T-Rex Style Sidescroller In Godot | Beginner Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I made my own version of the Chrome T-Rex game in gdo while I kept the gameplay very similar I changed up the graphics using some op Source images from h. there were three main game mechanics that I needed to work out a parallax scrolling background a physics for the dinosaur to be able to jump over the obstacles and an obstacle spawner with Collision detection so first onto the Parallax background this works by splitting the background image into multiple layers and then placing the layers over each other each layer moves at a different speed with the furthest away layer moving slowly and the nearest layer moving fastest to give this 3D background effect for this I use gul's parallax background and Parallax layer nodes in gdo I begin with a new scene and I create my first node this is going to be a parallax background node I rename it to BG and then I can start adding the different layers the first layer is just a solid green image and for that I can use a Sprite 2D node I drag over this first layer into the texture and the only thing I change here is to untick this Center property this puts the green image right in the middle of the screen this one doesn't need to scroll but the other ones do so I'm going to create additional child notes here and these will be Parallax layers each layer then has its own Sprite 2D node this notice what contains the image for that layer I drag over plx2 into this texture property and again just untick the centered value to give the impression of an infinitely scrolling image we go back into the Parallax layer node and under motion we add mirroring now I need to know how wide this image is first of all so if I go back to the text JN I selected it will tell me that it's 1152 pixels wide I can put that into this mirroring X property and now you can see that has created a second image to the right now as this one Scrolls the second one is going to take its place and just give us the impression of continuously moving backgrounds the backgrounds that are furthest away like this one have to move slower than the other ones and that's where this motion scale comes in make sure the X and Y aren't linked by UNT taking this little chain here and set this value to something less than one I will use 0.6 I can then duplicate these two nodes by selecting this option or highlighting them both and press controll and D I do this four times and then I go through each of my Sprites and I replace the texture with a new one so I upate this one the fourth one and then lastly the fifth one and with that you can see that we've now filled out the entire background however all of The Parallax layers currently move at the same scale because I duplicated them this first one which is the furthest one away is at 0.6 I'm going to go through the m and increase them by 0.1 for each of them so as we get closer they move slightly faster and then the last one will be 0.9 and that's it for this scene so I can go up here and make sure that I save it inside my scenes folder next I set up the dinosaur scene and add in the jumping physics the dinosaur will be a character body 2D node because that node is specific to user controlled bodies I will use this spreadsheet for animating it which will be done by the animated spread node then a couple of collision shapes are added one for when a dinosaur is running and one for when it Ducks down and lastly I'll play a jumping sound effect using the audio stream player node so set up you seene in the same way and this is how your not tree should look at the end just bear in mind that I've renamed some of the nodes here now I can begin configuring these nodes and clear these warning signs the first one I'm going to begin with is the animated Sprite and that will give the player an actual image to use the animated Sprite node has an animation property here which contains our Sprite frames I need to go in and first create a new set of sprite frames and when I click on it again it brings up this animation panel down here this is where I can configure the different animations that I want to use so let's take a look at the spreadsheet the spreadsheet I'm using has all the images in a long line and these are the animations that it contains there's the idle animation running jumping taking damage and lastly the ducking animation I'm not going to use all of these images so for jumping I only use one still frame I don't use the take damage or the hurt animation and for the ducking down animation I skip out that first image now I can begin setting up the animations in gome I'll start with the idle animation so I rename this one to idle and then I click on this icon here which says add frames from Sprite sheet my Sprite sheet is in inside the assets folder and then IMG and it's called more.png when I click this you'll see that it's already split into four rows and four columns because that's what is defined up here by default I actually have 24 frames and they're all in one line now you can see each of the frames is split up into its own tile the idle animation if I just zoom in over here is the first four titles so if I select these first four or frames rather if I select these first four I and add them into my animation now I can zoom in here and I can actually see the image has appeared it's very small right now though so I'm going to scale the whole thing up I'm going to do that at the main parent node so if I go into the dyo node here and I look for my transform I can change the scale to eight times now the image is much bigger but you'll notice it's a little bit blurry if we go back into our animated Sprite there's an option here under texture to change the filter from inherit to nearest and that will sharpen the image back up again I can test this animation out I have some controls down here and if I click play it's going to start running through the animation I can change the speed of it because that's a little bit slow for me I can change that to 10 frames and now it's going to run twice as fast this icon here allows me to add more animations now see if you can set up the rest of the animations yourself the steps will be the same as for the idle animation you just need to select the appropriate frames from the Sprite sheet once you finished you should have four of these animations set up remember to change all of them to 10 frames per second so that they run at the same speed the last thing to do with the animations is to pick one of them that will start to play When the Game begins and that's going to be the idle one so I select idle and I click this little autoplay button and now I can configure my two Collision shapes so the first Collision shape is going to be for the running State I change the animation over to run and I go into this Collision shape on the right I select a rectangular shape and I just adjust the size size you can turn on Snap up here to make it a little bit easier so I just capture the left side and up to the stomach I don't really include the head and then I go all the way to the feet and all the way to the head and I can then repeat for the other Collision shape but before I create this one I need to change my image over to the duck image now I go back in here and I create a new Collision shape which is another rectangle I need to start it at the same point as the last one so it doesn't go to the new feet it goes to the previous feet then I pull the side in just like before pull the head in just like before but for the height I just bring it down to where the new head position is going to be during the game I can toggle these two Collision shapes on and off so that when the player Ducks down it can get underneath some of the obstacles the last thing for setting up this scene is our sound effect so I go in here and I just need to drag over my sound which is jump over into my stream now this sound effect I'm not going to play right now it's very loud so so I had to reduce the volume and I set it to minus 25 I didn't want it to become an annoying sound every time you jump so it's just kind of in the background and that's it for the dinosaur scene for now so you can save this one just like the other one inside our scenes folder now I need to create the ground that the dinosaur is going to run and jump on top of I've created a new scene and set up the node tree already so you can configure yours in the same way the parent is going to be a static body 2D and we don't have to change anything here on the Sprite we just need to add in the image of the ground that is underneath background and it's ground.png we drag it over here then untick centered and just adjust the transform to move the ground down to the bottom of our game window the position for that is 552 the game window is a little bit difficult to make out so I'm going to turn off these grid lines and now you can see this purple outline is our game window the ground is twice as wide I'm not using The Parallax layer for the ground instead I'm doing The Parallax scrolling myself using code and that that means I need an image that's twice as wide as my game window the last thing to do is create a collision shape this is going to be another rectangle and we just drag it down to fit the entire size of our ground image and for this I can turn on the snapping again just to make it a little bit easier to adjust it so that takes care of one side and then I just extend it over to the other and that's the ground done so I'm going to rename the parent node to ground and then I save this scene together with the other ones in that scenes folder and now we can start pulling those things together I create a new scene and I create a new node inside of it this one is going to be our main scene with a main node so I rename that one to match I'll hide the grid again just to make it a bit more visible and now I can start pulling through those other scenes that we've created if I use this link up here I can instantiate the scenes I'll bring through our Parallax background there it is there then I'll bring through the ground and lastly I can bring in through the Dinos dinosaur we can move the dinosaur to position it closer to where we want the game to start the last node that I need to add is a camera 2D node this node will follow the player as we scroll across this map but you can see that it's not positioned in the same place so I go into the transform property and I adjust this to be half of the screen width and half of the screen height now the camera is positioned perfectly over the game window I can now save this scene and I can actually test it out at this point if I press F5 and I select the current scene it will run the game for us and now you can see we've got our idle animation running we've got the background and we've got the ground the order of these nodes is important if I was to move the dinosaur down a little bit and then move it behind the ground you'll see that the feet disappear now this is going to be a problem later on because I'm going to add obstacles in code so the obstacles will always be at the bottom of this not tree I want the dinosaur to always appear in front of everything so first first of all I'm going to move him back to the position that he was at I'll just undo these steps and then I go into the dinosaur scene which should be inside my scenes folder and on the parent node there's a property which is called ordering I'll change the Z index to one this will mean that it's always drawn on top of everything now let's add in some code to give the player controls we'll go into the dino node and up here I'll click to add a new script the script is mostly blank but it extends the character body 2D node which is what this one originally was called to add jumping into the game we need two forces one that pushes the player up and one that pulls the player back down and that's going to be our jump speed and the gravity at each iteration of the game Loop we want to apply these forces to our dinosaur and that's going to be done inside a physics process function we increase the dinosaur's vertical velocity velocity y by the gravity jumping is going to be done by pressing the space bar and we can check for that as an input when the space bar is pressed we apply the jump speed onto our velocity value and at the same time we play the jump sound to move the dinosaur and to handle the Collision we call gdos move and slide function this jump sound is going to become annoying so for now I'm just going to comment this out and if I test this game and I press space bar you can see the dinosaur jumps and falls back down there is one issue though which is that if I hold the space bar then it just keeps jumping so what I need to be able to do here is only jump when the player is on the ground and gor has a buil-in check for that I'm going to put it right at the start here and it's going to check is on floor if it is then I want to be able to jump but otherwise I'll just fall back down if I run it again and I press space bar it only jumps once so if I hold the space bar it just keeps jumping every time it lands back down on the ground but you might have noticed that the animation never changed and that's because we never told it to so at this point I'm going to add an L statement so if the player is not on the ground then I want to change change it to the jumping animation the other action apart from jump is going to be duck and that's going to happen when the player presses the down key so we can check for this at the same time if that happens then we simply run the duck animation and lastly if none of these keys are pressed then we want to play The Run animation if I run this game now we start off with the Run animation of course the player isn't actually moving anywhere but you can see that it changes from running to jumping and then if I press down it now changes to a ducking animation so all three are working correctly now another thing I want to do in the code is to be able to toggle these running and ducking Collision shapes on and off depending on what the player is doing and we can actually visualize these if we go into debug and visible Collision shapes if I run the game now you can see the Collision shapes here so you can just about make up the difference between the two here so you've got the running one that's a bit taller than the ducking one what I will do is Begin by saying that the running Collision shape is not disabled and I'm assuming that we are running but then if I press the down key and we change to a ducking State then we disable the running collision and if I run this now you can actually see that so the color here is going to change when I press the down key it changes to this kind of orangey color and that's just to signify that that Collision shape is no longer active when I let go of the down key it activates again now we can begin creating the obstacles each one is going to be an area 2D node as the parent and then inside that is going to be a Sprite 2D node this first one is going to be a stump so I'm going to change the name of the node accordingly then we go into our Sprite and I'll drag over from the obstacles folder the stump image it's a little bit small so I'm going to change the scale to four times and then to get rid of that blurriness again we go into texture and change it to nearest instead of inherit I still have this warning label up here which says that there's no Collision shape I'm not going to man manually create one though because the shape of this is a little bit awkward what we can actually do is go up this Sprite up here and create a collision polygon sibling this will try to work out the size of the image and create a polygon for this Collision shape I can modify it a little bit though because you can see it's kind of mixed some areas and also it doesn't need to be super accurate so I can just get it to capture the outer limits of this image and that'll be close enough now I can just save this scene with the other ones and that's the stump completed there's two other obstacles there's the barrel and The Rock and they will need scenes created just in the same way so try it out and see if you can create those ones yourself when you're done you should have the stump the barrel and The Rock scenes The Rock image is a little bit bigger than the others so for the scale I actually used three instead of four and for the barrel polygon well you didn't really need a polygon because it's a square so I actually just used a rectangular Collision shape here there is one more option icle and that's the bird and it's a little bit different to the others it's an animated Sprite for one but also the shape of it is a little bit different based on what I've covered so far in this video you should be able to put this together yourself so I have a go at it and then I'm going to go through what I've actually configured now this note here is area 2D just like the other obstacles and I haven't really changed anything there then I created an animate Sprite node added a flying animation and using the tile set I picked out the first four frames I changed the frame frame rate to 10 frames per second and I set this one to autoplay on load the image was also a little bit small so I scaled it up to four and then texture was a bit blurry so I changed the filter to nearest that was it for the animated Sprite and then I had to create the Collision shapes I wasn't able to automatically generate a polygon because this isn't an individual Sprite node so I created these two Collision shapes the first one is a rectangle like we've already done previously but the second one I haven't used yet and it's a capsule shape it allows you to create create an oval shape instead we can leave the obstacles and move on to the next part back over on the main scene I can now add in the script for motion I go up onto the main node and click this button to add a new script I'll begin by defining a couple of variables right at the top here these are going to be constants and they will be the start position for the dinosaur as well as the 2D camera node after that I Define a couple of speed variables this is how fast the dinosaur is going to move across the screen I'll Define the start speed as a constant and then a variable for the changing speed as the game gets more and more difficult I also Define a maximum speed so that the dinosaur can't go too fast now I can begin creating my functions down here I will create the new game function one of the things this function will do is reset everything back to its starting coordinates so here we take our dinosaur node and we set the position back to the start position variable from here I do the same for the dinosaur speed the camera position and the grand position I need to make sure that I call this function as soon as the game is run so that goes inside the ready function I execute the game just to make sure that everything is positioned like it should be the actual game logic happens inside this process function here the first thing I'm going to do is take that start Speed and assign it into my current speed variable I can then use that speed variable to move the position of the dinosaur and the camera by increasing their x coordinate I'm effectively moving both of them to the right all the time if I run this now we can see the effect happening so the dinosaur runs across the screen our background is working exactly as it should it's an infinite scrolling Parallax but you will have noticed that the ground eventually went off the screen and the dinosaur fell down we need to make sure that we also move the ground along with everything else so for that I need an additional variable I'll go back up here and I'll Define a variable called screen size then inside our ready function as soon as this node is loaded we calculate the screen size from our game window I can now use this to see how far we've scrolled back in my process function I will add a comment to say update the ground position this will check if the camera's Exposition minus the ground Exposition is greater than 1 and 1/2 times our screen size it basically means that the camera has moved on too far and now the ground is about to go off the side of the screen if that is the case then all we do is just shift the ground Along by the width of the screen if I execute the game again we can see that the ground just continues to scroll but what's effectively happening is that when the right edge of the ground gets to the right edge of the screen that's when we trigger that if statement and we reposition the ground back over on the left as the dinosaur runs across the screen I want them to earn points so the score increases the longer you can run I need a variable to be able to track this and that's going to be a score variable inside the new game function before we reset the nodes I want to reset the variables the only variable that I'm using for now that these reset setting is the score variable and we set this to zero then back inside my process function once I've moved the dinosaur and the camera I can now update my score so I will take the speed variable and I will add it to the score to see this working we can just print this out for now if I run the game again we can see down here the score is very quickly increasing as the player runs across the screen this isn't a very good way of showing the player score though I would like it to appear on the game instead so somewhere on the top left I'd like to show the score for that we're going to need a new scene I'll switch back over to the 2D View and set up a canvas layer node this node is used for heads up displays as it's always shown on top of everything else so I'll rename that to HUD and I'll set up my text text can be done using labels so I will add that as a child node I'm going to have a few labels so I'm going to rename them accordingly this first one is going to be the score label I need to add some temporary text into it so it will say score then I adjust the alignment to Center I can also go down into theme overrides look for fonts and I can change out the font so down here in my assets I've actually got a font that I would like to use then I can set the font size to something a little bit bigger than this and now we've got the score coming up a handy way of positioning things on the screen is to use these anchor presets so you can put something in the top right in the middle in my case top left was okay so I will stick with that one there are a couple of other labels that I want to add to this heads up display Now using this same approach try setting up your own labels for the high score as well as text in the middle of the screen that says press space to play when you're done your not should look like this and your game window should have these labels in it all three of them are exactly the same the only difference is the text they contain as well as the positioning for which I use these anchor presets now we can save this scene inside our folder and go back into our main script back inside the main script just after we update our score I'm going to call a function called showcore we will need to Define this function so I will go down the bottom here and create a new function which will update the score text but before I can do that I need to link that scene into my main scene so I go up here again to instantiate and I pick up my heads up display now I can access that heads up display so I'll drag it down but what I actually need is the score label inside it so I need to go down one more level and to do that I use the get no function this looks for the score label node inside our heads up display scene I access its text property and I will set it to display our score because the score is an integer it has to be converted into a string first and if I run the game we can see the score up here in the top left increasing I think it goes up a little bit too quickly though so I would like to add a modifier to this to divide the whole thing by 10 I go all the way back up to where I'm defining my variables and just underneath the score variable I add a new one called score mod modifier I can now use that variable when I'm displaying my score so instead of just showing the score variable I say its score divided by that modifier of 10 running it again we can see the score goes up at a much more reasonable rate another thing that I would like to fix is that the dinosaur shouldn't start running immediately I would like to wait for the first player input before the game really begins and for that I will create another variable at the top here which will be called game running I can use that variable inside of my process function to check if the game is running and if it is then I'm going to execute all of this code so I indent all of it inside but if the game is not currently running then I have an L statement because this means that we've just launched the game and we're waiting for the player to press the space bar so I'm going to look for that as an input once we get that input I set that variable over to true if I execute the game now you can see we start off we have got this running animation playing we'll fix that in a second but the dinosaur isn't running and the score isn't being updated once I press the space bar everything begins properly this text though should disappear as soon as we press space so let's add a line to take care of that I already showed how to access a node of a child so when we went into the score label we went down two levels now I'm looking for the start label and that's going to be done in the same way I use the get node look for start label and then I just hide it but if I hide something then I need to make sure that I also show it whenever we have a new game started right at the bottom after I reset my nodes I'm going to reset my HS up display as well let's run that again and this time as soon as I press space that disappears and it feels more like the game is beginning properly but before the game does begin the score isn't displaying anything even though we set the variable to zero right at the start of the game and that's because we aren't calling that update function so now if I run the show score function it will update that no node to show the actual variable before we move on to the next bit let's just fix this issue with the animation the dinosaur starts off with a running animation if we go into our dinosaur scene we can modify this Behavior the dinosaur has an idle animation but it doesn't have an idle State here and that's because the game running variable that we use in the main script doesn't appear in here there is a way for us to pass it through though so just inside this if statement I'm going to add another line which looks for the game running variable from from the parent this allows us to get any variable from our parent node and I'm saying that if this variable is not true then I want to be in an idle state but if the variable is true then I want to execute this section of code just like I was doing before make sure that this jump animation though and this L statement doesn't get indented when you do that this part is separate and that's in line with this first if statement that checks if the player is on the ground or not this section here that we passed for now well that's going to be our Idol State because the game hasn't started so we can copy over one of these lines and replace the animation name with idle if I run the script now the dinosaur starts off in an idle State as soon as I start the game he switches over to the Running Animation and that's the dinosaur scene finished so we can close that one down as well as the heads up display and go back into our main script now I would like a way of increasing the game speed the further you go to do that I will update the speed variable inside of our process function currently I'm just setting the speed to our starting speed but I'm going to add onto that our score divided by a very large value because the score increases very quickly so I'm going to set a value of 5,000 but I don't want to add arbitrary numbers into the code so instead I'm going to Define this as a variable and that will be the speed modifier that variable hasn't been defined yet so we scroll back up and look for we've defined our speed variables and add this one to it this will allow the game to increase in speed as we progress so I can print out the speed variable down here and I run the game then as soon as the game begins we can see that we start with a speed of 10 and that was our starting value but when we get to score round about 500 that increases by one the game is going to continue getting faster and faster and eventually it will get to a point where it's just too fast to play I will need a way of limiting the speed and that's where that Max Speed variable from before comes in and this section of code here will limit our speed to the maximum speed allowed now I can finally begin generating the obstacles so far with the other nodes I've been able to instantiate them and Link them into this scene here but for the obstacles I won't be able to do that instead they're going to be generated in the code so I need to preload them inside of the script right at the top here I'm going to preload each of the scenes I assign them to variables so for example the stump scene has its own variable and then I find the location inside this folder structure here so that scene is inside this scenes folder and it is down here then I simply repeat the process for my other three obstacles which includes the bird and then I group them together inside of an array to make it easier to work out which one is which notice that I don't add the bird into this array because the bird is generated slightly differently and it behaves a little bit differently to the others as well I then need an array to track the obstacles that I've already created and then finally I will Define another array which has the heights at which the bird will spawn so just to add a bit of variety the bird can spawn either high up in the game or just above the player enough that he has to duck to avoid colliding with it with those preloaded and set up there's one more game variable that I need to add at the bottom here and that is going to be last OBS and this will just tracked the last obstacle that's being created now I can begin creating the obstacles this will be done in a separate function and that function will be called generate obstacles I'll call it from inside of my process function just after I adjust the score so right at the top here before I move the dinosaur and everything else I'm going to call this new function generate OBS so then we'll go down here and create this new function the three stationary obstacles will behave slightly differently to the bird so the ground obstacles will have their own logic first I chose not to use a timer to create these instead I have to first of all create an obstacle as soon as the game begins that's going to be done by checking if that obstacles list is empty so if there's nothing in it then I can create something I then have to pick the scene that I want to use if I go back up here I've got all of these three scenes minus the bird stored inside of obstacle types so to add a bit of variety I'm going to randomly pick one of these and generate that one so that's what I'm going to do inside this function next I'll pick an obstacle and I'll assign it into this obstacle type variable I'll then create a new variable which will be the actual obstacle instance itself then I can instantiate the obstacle type and I will say save it into my obstacle variable once that's created I save it inside the last obstacle variable so that I can track the last one that I made once all of that is done I add that node as a child of my main scene and I also include it inside the obstacles array but if I execute this now we don't see any of the obstacles and that's because they aren't being positioned anywhere visible so we need to Define their X and Y coordinates and this is where it gets a little bit tricky because I need to be able to position the obstacles right on top of the ground and to do that I need to know how tall the ground is as well as how tall the obstacle image itself is so there's some information that I'm going to have to pull from these nodes for a start now that I've created an obstacle instance I can access all of its properties this instance could be any one of these scenes so for example if we open up the stump scene again we've got properties inside it we have our area 2D a Sprite and a collision polygon I can access all of that information inside of my main screen script the first thing that I want to get is the height of the obstacle and I can do that by going into the Sprite 2D node getting the texture and asking for its height but the images are scaled and they're not all scaled in the same way so I also need to get the obstacle scale and that gives us the information about the obstacle image but what about the ground I need to know how high up or how tall that ground image is I'll go back up here and just after I get my screen size I'll add another variable for ground height our ground is a note here and this also has a 2d Sprite inside it so just in the same way if I go into my ready function just after I get my screen size I can get the ground height so I access the ground node then I go into its child node of sprite 2D look at his texture and get the height of that texture now that I have all of that information I can finally position my obstacle at the correct place just after I work out the height and the scale I'm going to work out the X coordinate this will take the width of the screen plus the score because the game is constantly moving to the left and it will add a little buffer just to make sure that the obstacle appears on the right of the screen and then moves onto the screen otherwise it will just pop onto the screen and it will look kind of weird we've got the x coordinate and now we can do the y-coordinate which is a little bit more to it again we take the screen height this time we take away the ground height so that gives us just a space available above the ground and then we need to work with the obstacle height and its scale to work out how high up it needs to be on top of our ground then I just add five pixels just to offset it a little bit now that I have these variables just after I create my obstacle I can assign this position based on obstacle X and obstacle y if I test it out again and I start running you can see straight away I got this Barrel appearing so it was the first obstacle created and it appears just off the screen so as soon as I start running you can see it slide into view so that works but the code is getting a little bit messy so to tidy it up I'm going to create a separate function down here called add obstacle then I can take these last three lines from here and I can move them into this function instead I just adjust my indentation and then I need to tweak this section here because I'm no longer working with OBS X and Y I just have X and Y P in as arguments now I can call that function in here once I've created my obstacle if we test this out again I should have the same result as before but now the code is a little bit more reusable but how do we create more of them so right now we only have one appearing and then once it goes off the screen that's pretty much it right now they're only being generated if the obstacles array is empty but as soon as we create one obstacle we add it to that array so this never runs again I need a second variable here or a second condition which is going to be an or statement and this is where that last obstacle comes in so instead of using a timer to generate these obstacles I look at where the current obstacle is so if I create an obstacle and it gets to maybe just past the middle of the screen then I want to get another one created at the back of it so that's what's Happening Here I look at the position of the last one and if that's less than the score plus a random number between 300 and 500 then we want to create a new one so why have I added this random range here well without this each obstacle would appear at fixed intervals so just to randomize the spacing between them a little bit I've added this random range if I run it now we should be able to get obstacles so as soon as that one goes to about here a new one appears right in behind it I'd like to add a bit more variety to it though so that rather than generating one individual item each time sometimes they will appear as little clusters so for that I need to create another variable up here which will be the max obstacles and I'm going to set that to three then I'll add a for Loop and this for Loop is going to be based on this Max obstacle variable so it will range in between 1 and three then I indent all of this code inside the for Loop but if I run it now nothing will change because each of the obstacles is still positioned in the same place so even if I create three rocks or three barrels they all align in the same position so I need to space them out inside this obstacle X variable I will do that by adding a 100 space multiplier based on how many of them I'm making now if I run it again you can see we've created two rocks and two rocks three barrels and it just adds a little bit more Randomness and variety to the game this isn't something that I want to start from the beginning though I actually want the number of obstacles to begin as one as the game starts and then increase as it gets more difficult so I'm going to add an extra variable right at the top to control this or rather two variables one is going to be the current difficulty and the second will be the maximum difficulty this way the difficulty can increase as the game progresses I need to Define my starting value for difficulty is zero and then I need a way of adjusting it so as we progress to the game and the score increases we want that difficulty to go up so I'll add a function right at the bottom here this will be called adjust difficulty it's going to take the current score and divide it by the speed modifier that we defined earlier this however could allow the difficulty to increase too much so I want to limit it using that Max difficulty variable I still need to call this function though and that will be done inside of my process function so right at the top here I'll add a comment to say speed up and adjust difficulty once I have adjusted the speed I will call that function to also adjust difficulty I can now use this inside of my generate obstacle function right now I'm setting the maximum obstacles to an arbitrary value of three but instead I can set it to difficulty + 1 that way it's going to range between 1 and three and as we progress through the game we'll generate more and more of these obstacles in little clusters we can run the game to test this out so at the very beginning we should only have one obstacle appearing at a time and this will continue until the difficulty increases at score 500 from this point on it could be between one and two obstacles so you can see that we had two two then one and then a couple of twos if I keep going now difficulties increased again and now there's a real variety between one and three obstacle bunches what we haven't done though is add in the bird so right now all we have is the three static ones that on the ground but we want to add in the bird as well I'm going to add a random chance to generate a bird so we still run this code as normal and we create our obstacles but there's also going to be a random opportunity to spawn a bird the bird is something that should come in a bit later on in the game so it's only going to happen when difficulty has reached the max difficulty then I will choose a random number and I'll divide it by two to see what the remainder is this basically will give me either a zero or one so there's going to be a 50 50 chance of generating a bird the code for this is similar to what we've already done for the stationary obstacles we first of all instantiate it as an obstacle variable then I Define an x coordinate for it based on the screen width the current score and then add a 100 pixel buffer so that the bird comes in from the right hand side I then Define the y coordinate and that one comes from that bird Heights array so I pick a random value and that will mean it either comes in low or it comes in higher once I have those variables I can call that add OBS function that I created earlier to create this new bird obstacle I won't be able to test this right away because it will only come in when I move to Max difficulty so for now I'm going to get rid of that check and I will just say is difficulty equal to zero and I will comment that out just to see that we're actually generating these birds correctly so at this point there should be a 50/50 chance of generating a bird right now I haven't had one but there you go so we've now appeared with an obstacle and a bird directly above it you will have noticed though that the bird doesn't move it just kind of sits there in its static position we actually need to add a little bit of code to the bird scene so the other obstacles are okay I'm going to close them down but the bird does need to add a script so I go back into this parent node click this button to add a script and it's going to be just one line we go inside the process function and then we adjust the bird's position based on the speed variable in the parent node which is our main game node so essentially I'm going to move the bird left using this minus across the screen but not at the full speed because then it's just going to be way too fast cuz the player is moving to the right and the bird is going to move to the left at the same speed so instead I have the bird speed that way it does have some movement but it's just not as fast as the player so if I test this out again now you can see the birds are coming in and because we have that movement on them it just looks a little bit more natural they're not just stuck flapping their wings in the same position so now the obstacles are working pretty well there is one thing that isn't immediately obvious though and that's that once the obstacles go off the screen on the left hand side they don't disappear they're still there in the game and that bird is still flying to the left so we need to clean that up because as the game progresses we're just going to have a whole bunch of items in memory that have long gone off the side of the screen we go back inside of our process function and just at the bottom here once we've updated the gra position I'll add a little section here to remove the obstacles that have gone off the screen this is where that array from earlier comes in useful the obstacles array I iterate through that one and I pick out each individual obstacle I then look at the obstacle x coordinate and if it's less than the camera's position so it means that if it's gone off the side of the screen then I need to delete it I don't have a easy function to do that so I'm going to create my own and that's going to be called remove obstacle I pass in the obstacle into that function function and it will clean it up for me so now we need to Define this helper function well I already have a add obstacle function up here so I'm just going to create this one right underneath it remove obstacles this needs to do two things first it has to remove the obstacle instance or the node from our main node scene and that's done by calling Q free on the actual node but I also need to remove it from that array so I take my obstacles array and I erase that obstacle from it that tidies up our obstacle generation pretty well but one big thing is that I can still run through all of these we don't actually have any Collision detection to understand how this Collision check will work we have to look at one of these obstacle scenes if I open up the stump we have the stump node set up as an area 2D node and that has a bunch of individual signals one of the signals that we're interested in is body entered so this signal will emit whenever a body in our case our character body moves into the area that we've defined with a Collision polygon so if our character body which is a dinosaur moves in here then it's going to trigger that signal it won't only be looking for this dinosaur though there are other objects on the screen and in the game that will trigger this method so we will need to filter all of those out but the important thing to note is that this is the function or the signal that we're looking for the challenge that we're going to have is that we don't have that node inside this tree so how do we access that signal well that's going to be done by connecting to it from the main script inside our add obstacles function where we first generate them once we've created it I'm going to connect into that signal this line basically says look at that node find the body enter signal and connect to it but inside these brackets I need to add a function and that's going to be the function that triggers whenever this signal is emitted this function doesn't exist yet so I'm going to create a new function and I will call it hitor OBS for obstacle and now I need to Define it so we'll just do it down here we Define this hit obstacles function but importantly inside it we have to add in the body that we've checked for collision with I got stuck on this for quite a while because I didn't put anything into those brackets when I was making this game so I have to give credit to the guys over on the Discord channel for helping me figure this one out so we pass in the body then I can check the name property of that body and compare it against the dinosaur well my dinosaur node is called Dino so that's what I'm checking for but if you were making a different kind of game with a different player you would need to make sure that this here match is whatever your character is called so if that is the case then it's a dinosaur that has come in contact so for now I can just print collision and if I run this code and say I run into this obstacle you can see it's detected straight away so every time we come in contact with something whether it's the bird or one of the static obstacles we're picking up the Collision what we need this to do is to trigger some kind of game over function so we'll Define that just now I'll call a game over function from here and then I'll will go down and create it below so we'll say function game over and the first thing I'll do is pause the whole game and I will also set the game running variable to false now if the dinosaur runs into any obstacles the whole thing freezes up so that's partially there but I have no way of restarting the game for that I need a game over scene I've created the scene here and it's quite similar to what we've already done I have my canvas layer for the game over node and then I've added a button Noe as a child which we haven't used yet for the text I've put in restart then to position it and to size it accordingly I've gone into a layout and transform and set the width and height to 250 and 55 I didn't position it like this I just use the center preset and lastly I just changed the font the font size and created texture styles for the different conditions of the mouse to create one of these you just click on one of the empty spaces new style box flat click it again and then you can change the color to whatever you like I don't need this one so I'm just going to clear that out of here and I will only use normal over and pressed there's no script with this so you can just save this scene and we can close it down now we can instantiate it inside of our main scene so we'll click on that link and pull in the game over it comes up straight away with the restart button being shown here but we will hide that inside of our script to hide it we go into our new game function right at the top and just after this line we hide the game over scene I'll also update this comment to reflect that so we hide it at the start but we need to make sure that we show it when we have a game over condition so if I run it now and we run through and hid an obstacle it now pops up we can hover over it but clicking doesn't do anything we aren't actually connected to this node so in the same way as the obstacles had a body entered signal this button also has its own signals so if I open this back up and we go into the button and switch over to node there's the button press signal that's the one we're interested in so I need to make sure that I connect to that as soon as we start the game inside of this ready function so before we have the new game game function will Connect into that button node and we trigger the new game function from it so now this new game function will be triggered at different times first it will be when we run the game but then anytime we have a game over condition and we press that button we will also trigger the new game function allowing us to reset everything so let's try this again run into an obstacle click restart still nothing happens and that's because we've paused everything so right now the entire game is paused but we don't want that to apply to our game over scen so we go into this process Tab and change the mode into when paused now the game over scene only works when the game is paused so if I run along come in contact and I click it now we have this partial reset not everything seems to have worked though and that's because we haven't unpaused the game so right at the top here before I set the difficulty I'm going to unpause the game Run It Again run into an obstacle and hit restart and now everything is back to where it was at the beginning I can start playing again but you may have noticed it's the same obstacles restart again and there's that bird that I just ran past restart and there it is again so what that's telling us is that while we're restarting the game we're not restarting the obstacles they're still there from before we need to make sure that as part of this new game function we reset all of our obstacles as well we'll do that by iterating through that obstacles array cleaning up each of the nodes by calling Q3 on them and then once we're finished with that we clear the entire array so let's try this again and I'll run along hit that barrel and there's a bird coming over as well if I restart that may have just been luck that I got another bird there and maybe again okay it seemed like something went wrong but it was just bad coincidence that the bird seem to be appearing each time but now we can see that it's coming in slightly differently in each iteration and we're nearly done there's just a couple of things to tidy up the first one is we temporarily commented out this section here when we generate the birds so we're going to get rid of this and put it back to how it should be so the birds are only generated once we reach the max difficulty but the other thing I want to do is add in this high score so right now nothing actually happens when we die and restart the high score is always just nothing I firstly need to create a new variable for this so I'll do it right at the top here and then I can generate a new function we'll go right down here and just after we have a function for showing the score just to keep them together we'll also check for the high score well first of all we take the current score and we say if it's greater than the high score then we can update the high score to match but we also need to update that label which is inside our heads up display node so just like we did with show score up here I need to now access the high score label and update it to show the new high score now I just need to call this function from somewhere and the only time I want to check for the high score is when the game is finished so basically we look at the score at that time and we compare it to the current high score so add it right at the bottom here and if I test the game out again I currently have no score but now as soon as I've died the high score is gone to 101 if I can get a little bit faster and further than this time the high score updates to 182 now and that's it we now have a fully working Dino Run game so I hope you found this useful and if you did please leave a like and I'll see you in the next video
Info
Channel: Coding With Russ
Views: 34,622
Rating: undefined out of 5
Keywords: godot, godot tutorial, godot beginner tutorial, godot project, godot beginner project, godot starter project, gd script, godot buttons, godot signal, code, game dev, learn to code, godot 4.0, godot 4, godot 4.0 tutorial, godot engine, t rex, google chrome, parallax, parallax background
Id: nKBhz6oJYsc
Channel Id: undefined
Length: 49min 17sec (2957 seconds)
Published: Tue Oct 24 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.