Learn to Make Games By Making Frogger | Michael Mcguire | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Learn to Make Games By Making Frogger

teacher avatar Michael Mcguire, Author | Programmer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Frogger Intro

      0:59

    • 2.

      Download no Setup

      3:06

    • 3.

      What we will make

      2:01

    • 4.

      Creating the Background

      9:10

    • 5.

      Creating the Player

      6:02

    • 6.

      Player Movement

      20:07

    • 7.

      Creating the Vehicles

      25:47

    • 8.

      Player Death and Respawn

      23:33

    • 9.

      Water Death

      7:44

    • 10.

      Water Platforms

      21:56

    • 11.

      The Win Space

      6:59

    • 12.

      Memory Leak Fix

      9:56

    • 13.

      Scoring System

      13:06

    • 14.

      Game HUD Score

      8:19

    • 15.

      Game HUD Lives

      15:25

    • 16.

      Timer and Bonus

      10:48

    • 17.

      Frogger Audio

      10:28

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

134

Students

--

Projects

About This Class

Embark on an exciting journey into the world of game development with our comprehensive Skillshare course, "Learn to Make Games By Making Frogger with Godot Engine." If you've ever dreamt of creating your own video games, this course is your gateway to turning those dreams into reality.

In this hands-on course, you'll dive deep into the fascinating realm of game development using the powerful and user-friendly Godot Engine. Whether you're a complete beginner or have some prior experience, our expert instructors will guide you step-by-step through the entire game development process, ensuring that you gain the knowledge and skills needed to create your very own version of the classic arcade game, Frogger.

Key Highlights:

  1. Introduction to Godot Engine: Get acquainted with the Godot Engine, a versatile open-source game engine, and learn how to set up your development environment.

  2. Game Design Fundamentals: Understand the core principles of game design, including gameplay mechanics, level design, and user interface.

  3. Programming with GDScript: Discover the fundamentals of GDScript, Godot's easy-to-learn scripting language, and use it to create game logic, handle player input, and manage game states.

  4. 2D Graphics and Animation: Learn how to design and animate 2D game characters and objects, including the iconic Frogger frog, as well as obstacles and environments.

  5. Sound and Music: Dive into the world of audio design, adding background music, sound effects, and feedback to enhance the overall gaming experience.

  6. Level Creation: Master level design techniques as you craft challenging and visually engaging levels for your Frogger game.


    By the end of this course, you'll not only have created your very own Frogger-inspired game but also gained valuable skills and insights that can be applied to a wide range of game development projects. Join us and bring your game development dreams to life with the Learn to Make Games By Making Frogger with Godot Engine course on Skillshare!

Meet Your Teacher

Teacher Profile Image

Michael Mcguire

Author | Programmer

Teacher
Level: Beginner

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Frogger Intro: All right everyone, in this section, this is actually a module from a larger course, and here we're going to go ahead and create Frogger in order to help you learn how you can make games using the Gatto engine by recreating a classic game from, I believe it was the '80s. It's been a long time. But you can see with this we're going to get player movement. Music We've got some wind zones, collision detection. We're going to be able to use tile maps. Understand how tile maps work. We have visual representing time. We have sponsors going on. We have collisions going on. We have some physics happening we got keeping track of lives and score, as well as some background multipliers. We've got a lot of things going on in this simple little classic game here. So I hope you enjoy as we move forward. And you should hopefully at least have a basic knowledge of programming, if not of G D script going in that will help you with keeping up and not getting lost as much. 2. Download no Setup: Welcome future developers. If we're going to be developing things using the Gatto engine, either video games or desk Cop software, first thing we're going to need is well, the Gatto engine. So let's take a look at how we can go ahead and get this downloaded. Now, the first thing or the first way I should say that we can get this is to download Gatto from the official website here, simply go to goto engine.org. All like we see here. Right here on the screen. And once here, you'll see the download section up at the top of our screen. As well as two download buttons in the center. We have the LTS, which is three point and the latest, which is 4.1. We will be using the latest version, which is 4.1. There's nothing wrong with the three point x version. It's still being developed on, and it is the long term support. However, if you were to use it that version while following along, there may be some functions or some things that we write that might have different names or potentially not even exist in the old version. So just keep that in mind, and because of that, I would recommend that you do use the 4.1 version as we go through. All right. So this is the stable version and 4.1 came out. So you can either hit the download latest button or the download tab at the top. Both of them will bring you to this screen here. All right. So go ahead and to download this. All we're going to need since we are going to use the GD script programming language. All we need is the standard version here with the blue button. And the difference between this one and the.net version is the.net version also supports C Sharp. And if you were to use that, then you'd have to scroll down and also pick up the.net that is required in order to use it, as well as preferably external programs to Rachel Codin it's just a whole lot of extra things that we don't need when going through this course. So if you want to get it from the website, you can go ahead and just hit that Goto engine button there for 4.1 on the standard version. Now, there is a second way that you could get this. And that would be from Steam. You can come over to Steam and go ahead and download it from there if you would like, and that is going to give us the standard version. By default, Steam version does not have the dot p version available. So you don't have to worry about any confusion with that if you go ahead and get it from Steam. 3. What we will make: All right, this week we're going to kick things up. An option, instead of going off of just some texts like we did last week. This week we're going to be creating or recreating an old two D game from the '80s called Frogger. Now this is going to give us a chance to work with a two D player controller collisions. Maybe we'll get into some particles we can work with responds as you see. If you've never played Frog before or you've never heard of it. You see here we're going to be working with UI for our heads up display. We have points that we're going to need to keep track of my mouse there for a second. But not only that, but we're also going to see, is it going to show it here we have a certain amount of prog per player. Obviously we don't have coins in, but this is essentially the game Here we have two little safe zones. In this little purple area, we have a road in the middle that has five lanes of traffic alternating back and forth. If the frog gets hit by one of these cars, they die and the player loses a life. They make it up to the top. They can hop on the turtles and logs to make it across into the safe zone. If they land in the water, that's a fail as well. Which I guess now that you think about it doesn't make too much in the way of sense since it's a frog. But there you go. That's the idea of what we're going to be creating, and that's what frog is, if you've never played it or heard of it. 4. Creating the Background: All right, so let's go ahead and get a jump. Start on creating Frogger. The first thing you're going to do is make sure you download the assets and just go ahead and move that sprites folder into your project. Again, I just created an empty folder specifically for Frogger, but I would recommend that you create a new project for this. That way you can export it without having any issues in the future. All right, so the first thing we're going to need to do, especially since our sprites are so small, is we're going to need to shrink them. Or not shrink them, but shrink our screen down to more of the arcade cabinet size. To do that, we're going to head on up to project and go into our project settings. All right, so it should start just like this with the advanced settings turned off. And you'll see on the left hand side just going to go down to the display section and go into window. And we're going to set the width to 336 and the height to 240. All right, this is an arcade cabinet screen size. The screen resolution for this, and it's going to be perfect for our small sprites. All right, once you go ahead and set that, you can go ahead and just close and you'll see our little blue box has gotten much smaller than what it used to be. The first thing we're going to do here is we're going to create the background. So we're going to create all the road, the water, the purple median that they call it, the scoring area that we have to get our front to. We're going to get all of that stuff set up. That way we can jump right into getting our game play and all that that set up and running in the next following videos. All right, so we're going to need a two D scene here. Let's click on two D, and this will give us a node two D for our root node. If you want to go ahead and rename that, you can. You can name it Maine if you want. Game Manager, Doesn't really matter. If you really want, you can just leave it as the default name. Going to leave me as default for now. In order to create this in our little background, I'm going to create a new tie map. I'm going to hit the plus button and we're going to go and select Tile Map from the drop down, see in our curtain node. Select tile map. Go ahead and double click that and select that. Now I have mind set up here. I'm going to go ahead and just delete all of these. 1 second. All right, so you should look like this when you have tile map selected. If you don't have a select, go ahead and select it. What we're going to do is head on over to the right hand side. We're going to go to the tile set here. It stays empty at the moment, but what we're going to do is click on it and go to new tile set. And then click on that tile set, and that'll bring us here. Now what we need here is we're going to need the little goal area, the water, the road, and the median. If we go into our sprite and scroll down, we will see home, median, road, and water. If you just hold control, you can select all of these at one time like this and just go ahead and drag them into our tiles box here. All right. Before we can actually use them here. As you can see, we can't click on anything. What we want to do, I'm just going to scroll in there with my scroll wheel, or you can plus a minus. The first thing that we need to do is make sure we're on the set up tab here, select our water, and we can click on it. And now we have this orange box around it. That means we have a tile that we can now use. I'm going to do the same thing for road, median home, Brow straight across. Now home is a little bigger. I'm thinking it might be one bigger than that. Let's see, what do we got? 2062 big. How's that? I think that'll do. Perfectly fun. All right. They ever go? I've got a 16 by 24 here for this tile. All right, so now if we click on tile map at the bottom. Our screen down here. We should now be able to click on and start drawing our sprites. Click on my median, Click on my purple tile here. Just drag one row across the bottom. Go to my road, we got five layers of traffic. We need five rows of our black beer 4.5 If we refer back to our image, we then have another layer of purple, five layers of water, 12345. Then we have a layer of water that fills underneath of our home. Let's do one more layer there. Let's grab our home. Just go ahead and click on one spray, and drag your mouse across so you can select all three. Let's place it. Oh, look at that. We seem to have this issue. Well, what's going on? We are replacing our water tiles here. We don't want to do that. We need to actually draw this on a, another layer. And I'm just going to go ahead and finish filling that up with our water. All the way up to the top of the last two lines. I'm going click on our home section here. And we don't want to replace these, we want to build on top of it. You'll notice here on the right hand side of our tile maps, we have something that says layer zero. And if we have a drop down, there's nothing else there. What we want to do is go to our inspector of our tile map, open the layer section, hit add new elements. Now we actually have a second layer back in the tile maps with our home row selected. We can go to the dropdown layer and hit layer one. Now we can actually draw directly on top of it without affecting our final. We've got seven across with this. Just to make sure self our rose, 1235, looks good to me. If we click back on our No TD, nothing is great out. Here's what we're working with. If you remember, when we're looking at the Alpro set up, what it looks like, we actually have our score. That information is set up right at the top here in this empty blue area, this empty water space, we have our logs, turtles that jump across that help us jump across here. Inside of these little blank areas in home is where we can score points by getting our frogs. Purple is safe and our black road is where our cars are going to spawn. All right, we now have our background all set up just like that. Pretty easy to get going. The new tile map is real nice to quickly get up and going with this. We didn't used to have layers. Now that we do that makes setting things up like this much easier. All right, that's our background, Let's go ahead and jump into the next portion. 5. Creating the Player: All right, let's go ahead and create our player. But before we do, I'm going to go ahead and save this. It's going to control S. Go into my frog or holder and save my scene real quick. All right, so for our player, our player is actually going to have its own scene that we bring in. So we're going to click on the plus right up top here or add new seam. We're going to go to other since this is a player that we need to have control over. This is going to be a character body two D. This used to be called a kinematic body. In other engines you may hear people refer to it as such, but here it is now called a character body two D. Now this character body, we have this yellow triangle here that gives a little warning. It just tells us that our node doesn't have any shapes. It can't collide with anything. It's got no collision for now, that's fine. Use that to floating there. What we're going to do is we're actually going to go go and add a, another node in here. And what we want to add is a sprite. Two D. We want to add an animated sprite. We want our sprite to be animated. We do have two frames for this. Let's go ahead and do an animated sprite. Two D on the right hand side in the inspector. Let's open up the animation section versus sprite frames. Let's click on it and do new sprite frames. Then let's open those sprite frames up just by clicking on it. All right, let's have our default animation, which I'm going to go ahead and rename that to just be idle. Then we're going to add a new animation with this little icon down here. I'm going to rename that to Jump A Idle. Selected. I'm going to bring in Proger idle and G, jump. We're going to bring in Proger Id, then our jumping icon Proger, and now we should be able to go between the two whenever we want to play these enemies. All right, if we play there, we're jumping, we're doing our little bouncy bounce. You might notice that the sprite is a little blurry up here in our renderer. But down here we can see it's supposed to be nice and risk. Well, to fix that, we can go ahead and we can just select all of our sprites here at one time. From our file system go to the left hand side to the import isn't going to be an import moved this let me just go ahead and let you know where that part is. All right, so if you head on into your project settings, where I go head on into your project settings and locate the rendering and texture section here in advanced settings on or do we need it on this? No, we don't need it on that. We want a default texture filter here, change it from linear to nearest. Go ahead and close that, and you'll see your sprites go much sharp. If you're going to do pixel art like this, this is the default you want to set you in your project settings. And now we have a nice sharp Roggio. That's all we really need. We don't need to worry about the collision or detection or anything like that for now. We'll worry about that when we get to that portion. So I'm just going to go ahead and ha, to save this. And I'm just going to call this player. Now if I go into my main scene with my node two D selected. I can click on not this plus for a new node, but the chain beside it. That'll let us instance in a scene that already exists for us. That's going to be our players scene. Now we can go ahead and grab it and we can bring this little guy in. We can play, we can do whatever we want to do with this little guy. So let's see what's our transform. We know this is in values of 16172, wouldn't it would be 176 if we're on values of 16. And I'm just going to move my little froggy up. Here we go. Be a little more centered with that. Now I have my little frog in my main scene with my background and he's ready to go. All right, that'll do it for this one. We have our player set up as much as we need at the moment that we'll jump into the next one where we will address doing some player movements. 6. Player Movement: All right, let's go ahead and we're going to create the movement for our little froggy to be able to move up, down, left, end, right. To start off, we're going to need some inputs. Now if you want to use the arrow keys, then I down, I left, and I right already exists, but I want to use WASD. So I'm going to go up into my project and go to my Project Settings, and I'm going to go into the input mapper at the top, add a new action. And I'm just going to type in add left and right. Now for each of these actions here, I'm just going to go to the right hand side and hit the plus button up. I'm going to hit the plus. I'm just going to press on my keyboard. I'll show you what that looks like, what you'll be seeing from there. Let's see, this is this window here. I'll bring that up above. Here you go. I just hit the key and we have that. We hit okay, we go to down. Hit the plus, press S key again. A left and D for right now we have up down, left and right for our controls. We can close out of there. Our player is going to need a script. And I'll take a note here on my animated sprite on jump, I didn't get rid of the first sprite, so I'll just have this one with his legs spread and put a script on side of our character body two D on our players scene, we just have an empty one like so. Now what I'm going to do is I'm going to create a function called movement. So this is just so we can keep everything clean and organized and keep all of our movement in one location. We're going to do to take input here, we're going to use the if statement in the same if statement we've been using a lot. If then we want to access the input object or the input class input, then we want to check action. We want to go with release. Just released or just pressed. Either one will work for this game, specifically. If we go is action pressed, then that is while the button is held down. Just pressed and just release means, well, just press is when as soon as the button gets activated when you press it down. And release means the block of code is going to execute when you lift your finger up. I'm going to go with just press, let's try that. I'm going to use the button and this is a string that should have popped up. You automatically, this was a colon. So we can go inside to it and create the code block. All we're going to do is we're going to do two things. We need to move our little rock, we need to move it up the screen. And we're going to go up by one block and everything is split into 16 16 block or 16 tile size. So we're going to move our froggy up 16 blocks. In this case, we're going to get our position. If it makes a little more sense to you, you can say self position because you're moving your self that this script is attached to right now. That's going to give us an x and a y ordinance that has two numbers associated to it. If we click on our character body and look inside the inspector under transform, you see we have an X and a Y and these correspond to the location that they are on the screen. If we click onto our main scene and go to our character body, you'll see it's position is 169.2 33 in my case, this is where we're starting from. And we're going to be adding or subtracting from this for either the X or the Y to get our movements since we want to go up. When we press up, we're going to be affecting the number, We're going to say position. We're on ourself, we want to get the position property and then we want to get the number of it to go up the screen, we actually have to subtract. So we're going to say minus equals that. We could say this is equal to our position y number, is equal to position y minus some number, which our number in this case is going to be 16. If we were to just leave it like that and run our scene. Well, how unfortunate our little froggy doesn't move. Why doesn't it move? Hopefully you cued on or grasp that before I hit the flight button. We're never calling our movement anywhere, so we're never actually checking for any of this stuff. For that, we're going to just stick it inside of the process function here. Movement and now it's being called. Oops. At least it would, if we could spell it correctly. There we go. If we try running that now and hit the up button, which for me is W, you can see we're going ahead and we're moving our 16 blocks at a time. We win. We got one little froggy up there. Now of course, the problem is we're still moving, but we can't go backwards. We have no animation or anything. Let's get our animation working there. How do we play our animation? Well, if we look at our player scene, we can see from our script we can, we can follow this one line easily, just one level to the animated sprite two D. Let's get that node. The way I've shown that before was using this dollar sign. It would be the easiest. As soon as you start typing animated sprite, it's going to pop up. Remember that's only animated sprite two D because that is the name of it. If I were to name this banana and very por spelling of banana, then that's what I'd have to type in here in order to access it. I'm just going to reset that name back to Deft. All we're going to do is we're going to call on it. Play, Play. You'll see the animations that we created pop up. We're going to use jump. We try that now just with that one edition of our line, whoops, we have to actually play this scene and not our player, you can see we go into our jump, but we're stuck in our jump. Now, that's a little disappointing. How can we fix it? How can we go back to normal? Well, we can set it so that when our animation completes, then we return back to our idle form. In order to do that, we're going to have to access the animated sprite of our player. Go to the right hand side to the node tab and we're going to connect a signal that this animation finished. If we just double click that, we'll get a pop up to connect a signal here. We're just going to select the character body two that our script is on and hit the connect button. It's going to hold all to use my arrow keys to bring it up whenever our animation finishes playing this block of code is going to execute. Now what we want to happen here is we want to return back to our idle state where our frog is just sitting there. The same thing. We're going to get our animated sprite two D, we're going to call play. That's going to be idle if we try that. Now what do we again if we play the right scene, how we attempt that. Now we see we now have this little jump that's appear as we pulling across the water. That's awesome. Now the thing is our idol is going to be playing constantly at this point. Our idol plays and then it finishes. And because it finishes, it's going to play, no, that's not really going to be an issue. That could be something to keep in mind going forward to solve this issue. We can actually fix this with an if pick. And as you can see my little output there, I was checking things and I'll show you how to do that. I'll clean that up. All we have to do is we can check animated sprites. Want the dollar sign there? If animated sprite two D Animation. No, what was it called? Well, if we go into our animated sprite, and by the way, you can access this, if you just hold control and you click on the animated sprite two D here in our code, then it'll open up the documentation page for Here's what we're looking for here. Get animation. We want to get animation. As you see that wasn't popping up. Sometimes it's useful to check out the documentation anyway we want to do if animated sprite two get animation. If we were to take a look at that, the current animation of the sprite frames resource at the value is changed. Frame counter, frame progress or reset. But what we want to do is we want to get what this animation is. That's basically return to us what animation is playing or currently selected. So we're going to use the double equals because we want to compare whatever gets returned to us and we want to write jump. Then when we play our idle, we're just going to tap that in one, so it could be inside of our lock. Now we're basically going to check when our animation finishes. If the current one is jump, then we're going to play idle. If we run that, there we go. We have our little boing. It looks exactly the same, but we're not going to be constantly playing the idle animation over and over and over when the idle animation plays. Remember it plays once and then it's done. It's not looping. If yours, for example, is looping for whatever reason, the go ahead slick your animated spray. And if it's looping, you can see our mouse here. That's because this is turned on. So you just go ahead and click it turned off, so it's white like that. If it's blue, then it's on. If it's white, it's off. Now when our animation finishes, after we jump, we're going to check if our current animation is jump. If so, then we'll play idle when idle finishes. This if statement will not be true because when we get animation, it's going to be idle, not jump. Since that is no longer true, we're not going to do anything else. We're not going to keep replaying idle over and over this time. It's a small difference, one of those things that are on the back end that the player is never going to notice. Like I said, in a small game like this, it's not going to make that big of a difference, if any that is noticeable. But it's something worth knowing going forward. But when you do want to make bigger and bigger games. All right, so let's go ahead and we can now get our button. If we just copy and paste this, we can get L if instead of an if we want our down pressed instead of up, we want to plus 16 instead of -16 Because if minus is going up, then plus is going to take us down. So now we can go up and we can go down. Now our little froggy doesn't turn around at all, which is a little disappointing. But we can easily fix that by adding one more line in here. We can do that by talking about its rotation before we jump, we can get self rotation. If we take a look at our player, we go back to our player scene, click on our character body inside the inspector. If we come down, we see we have rotation here. Rotation is in radians rather than degrees. What we can do is we can say rotation equals. We can use this function that's built in called deg two red. That might have changed here. It looks like it has. It looks like it's been renamed here, deg two d, It's got the underscores in it now. Then let's take one argument in the form of degrees. If we say 180, that's going to be a full turnaround. We turn right, that's going to be 90 degrees. If you turn left, we're going to be -90 Either way, we have to get to positive 180 or negative 180. I'm just going to go with 180 degrees here. This function is going to convert this 180 degrees into radians so that it can be assigned to our rotation here. Now, one full rotation in radians is 3.14 and this is where pi is from. This would be the same here, 180. As if we were to just copy this. Say rotation equals pi divided by four, then that'll give us one rotation. Pi divided by two, that'll give us half our rotation here in radians. If I were to show you that with pi divided by two, there we split down the other way, maybe it is a little more than two. Now, I don't normally use radians myself. We can see divided by four. We get this little awkward angle. It can be a little awkward when dealing with radians at times, which is one reason why I prefer to use degrees to radian just because it's something I can work through a little quicker. As you see, there we go. We flip the face down. Only now we're not facing back up. So now we have to fix that inside of our code. We'll just do the same thing when we press up, we set our rotation to zero if we were to play it. Now, here we go. Now we can jump up and we can jump down. Now what if we want to jump left and right? Well, we can get those with two more LCs here. I'm just going to space these out to be a little more legible. Here we go. Starting on our second here, we're going to say if action is left, instead of modifying the y value, we're actually going to modify the x of our position. Because x is left and right, if we're going left, we have to -16 here, degrees to red. Well, we could set this to 270 just to stay on the positive side here. Which means our last L here. When we press right, we're going to modify the X position instead of the Y, we're going to plus 16. If we're moving right, we're going to be rotated at 90 degrees. We go ahead and try that now. Should see. Now we can jump around in all four directions we can get around. If your frog is placed in the correct location, you should be able to land in all of these little home goals here. No problem without going over. Here you go. Now we go to keep our position. Well on the screen would be nice. We can worry about all that stuff later on. For now, we just have our movement going around and this vehicle is getting low long. I just wanted to keep movement in its own little section. Here, there we go. We can run around as our own little frogging Boeing. Boeing. But all right, there you have it. We can now go ahead and move on to the next section of our code. I think next we're going to, I think we're going to create our vehicles and have them start going across the road here. 7. Creating the Vehicles: All right, today we're going to go ahead and create the vehicles to go across. Now we have a couple of different ones. Let's see how many we have here. Inside of our sprites, we have five different cars. There we go. And some of them go left, some of them go right. And they're already facing in the direction that they want. That's great. All we have to do is create them and have them move across our screen. All right, let's go ahead and create a new scene with our plus button here at the top. For our tabs, we're going to go to other node and just like our player, we're going to use the character body two D here. We're going to give it a sprite. In this case, since we have no animations for it, we're just going to use a regular sprite two D, we can go ahead and assign a one of first sprites to it. Now in this case I went ahead and selected the little truck, but of course you can pick whichever one you want. Specifically, I'm using one that's moving left. At the moment, that's worth noting. I'm going to change this name from character body two D to be truck. I'll save that as my truck scene. I'm going to need a little more now. We're not going to use a collision shape, although we are going to have some type of collision be able to happen here. Because obviously our frog has to get squished in some way if it gets hit. To prepare for that, I'm going to create an area two D that's just going to pretty much allow me to have a predefined area that I can check to get that area with area two D selected. That's now where I can bring in the collision shape. Now the collision shape has this little triangle on it, giving us a warning collision shape selected. We move to the right to our shape section and we create a new one. That's just going to be a new rectangle shape. Now we don't use complicated shapes such as using the polygons. Instead, use polygon with shape with some of these basic shapes here. Because the temple your shape is the better it's going to be in terms of performance. However, the more complicated a collision is, the more accurate it's going to be. It's a balance that you, yourself would have to work out. But in this case, luckily for us, we can just use these rectangles and that respond, especially since for recreating an older game like this. All right, now that we have our collision shape like this, and again, if you didn't catch that, just make sure your rectangle is covering everything. Every part of the truck here. Now our truck is actually going to need a script on it. I'm going to add one to it, and instead of calling it the truck script, I'm going to call it the vehicle script. Now the reason why we're going to call it the vehicle script is because we're going to be able to use this script on all of our vehicles. Now to do this we're going to a variable. For us what this is going to do, this export keyword is going to allow us to change inside of the inspector. Let's go with the at sign export and we'll create a variable and we'll call this direction, it's going to be an integer. By default, we can just send it to zero or we can send it to one. Doesn't really matter in this case. If you save that and select your truck again, you should see direction inside of your inspector on the right hand side. Now in our case, we're going to need to be negative one because we're going to move means we're going in the negative direction. I just went ahead and set that to negative one. Now in the process function, we're going to have our character is correct, but our truck move. Then in order to move, we need to have something called moving slide or moving collide. Either one will work in order to have movement. In my case skin moving slide. Moving code is just fine as well. Pretty much just defines what happens when two Physics bodies collide with each other right there. Either smack up against each other and stay there, or they can slide along each other. In our case, it doesn't really matter since we're just going to be using the area to determine if our frog has been hit by the truck. Now we have moving slide. We can't just play it now, because we still have to control this movement. I'm going to have a, another variable here called speed, which will also be an integer. I think. I'm going to set this. We'll try eight now. We'll see how quick that moves. That might be a little too quick. I'll actually try it with two. Now that I think about it, All we're going to do is we're going to change the velocity and we want to change the x number. Just like position, we have both an x and a y When it comes to velocity. Velocity is going to control our object moving consistently. Let's go to velocity as of four, interesting, maybe capital V because I know there is a built in one. Pretty sure here, it's low, right there. I must have just put a typo in there. But there we go. So we can just do velocity x this time. We're going to say equals. We're not going to say minus or plus, because this is going to be dependent on our direction, say speed times direction. We're going to move along the x axis, so we're going to be moving left and right at the rate of speed, which is two right now times direction. Right now we're at minus one. So it's going to be two times minus one and that's going to give us a negative two and should have us move left. We went in the inspector and we change it to a positive one. Then that should be two times one. Bring in a positive two and have us move in the right direction. I'm just going to set mine back to minus one. I'll go back to my main scene and just bring a truck in to take a look at it. I'll just set it right here. Play the scene and see if it moves. We can see it's moving, but it's moving way too slow. We're going to have to tweak that. Let's go back to eight. Maybe eight was good. Try that. Eight is not good, but it is much better. Let's see, do we want to be moving at 16 pixels? 16 looks good, although that looks like it might be pretty easy. Maybe we want to increase that. Keep in mind we can always come back to this, and since we're using the speed on all of our vehicles, we could easily adjust this and tweak it once we actually have all five lanes being used up for vehicles. Let's see, with 32, 32 is looking nicer here, I think 32 is where I'm going to leave it and tweak it later on. Maybe you want to go to 48 or I don't think we're going to be able to get to something like 64, but you never know. I suppose I'm just going to use 32 as my base. All right, so we have a truck moving in one direction. Now we can create our other vehicles as well. Let's see, we have two more that move left and two that move to the right. Let's see what do we have here. And we're going to go to the left. So we're just going to pretty much repeat this process and use the vehicle script on all of them. All right, I've gone ahead and as you can see I've made my other four car scenes here. All I did was come in, adjust the collision shape if I needed to replace the sprite with another one of our cars. And then if necessary, taste the direction for minus one to positive one, that controls all of our cars. And I went ahead and I placed them approximately to where they would be here, just so I can test and take a look. As you can see as we run it, our cars go ahead and drive and they go across the screen in the appropriate direction and they never collide each other. Awesome. Now all we need is more cars that span. We don't want to place these consists, except we have to place them manually. Then we have to just have this huge list of cars that we have no idea how long it's going to be for them to spawn. Or how long it's going to take for the player to either run out of lives or complete the level. What we're going to do is create spawners for these cars. All right, these spawners are basically just on a set time spawn the vehicle. We could have five different spawners if we want to, one for each lane. Let's see, I think that's what I want to do. I think I'm going to have five different sponsors that way they can all have their own times and if you wanted you could just have set as spawn limit, one time limit for all vehicles. That's perfectly fine as well. I'm going to go ahead and create one and this is just going to be a basic no two D. I'm just going to call this Sp. Do we want to call sponsor one here? Yes, go sponsor one and this is going to control my top spawns up here and I think I'm going to use this as its base location as well, so I'm just going to get a good spot. And since this is the truck, I'll bring it back to there and that'll show me that the truck spawns on this position. It'll be right there on my spawn. I'm going to create a new script. This is just going to be a spawn script. Once again, we're going to use this on pretty well every, all of our spans that we create here. What do we need to do? Well, we need to wait a set amount of time. It's going to delete this common out of there. As well as the one down here on line nine. All right, so we need to wait a set amount of time. That time should be random then based on that spawn in our case we're going to be loading the truck. I'm going to go ahead and do variable here for my truck. That's going to be a pre load here. Mr. means we're just going to load the scene beforehand. That way we can use it, we can instance it in at any point. So I'm just going to grab my truck from my file system and drag it in. That way we have the correct location here to the scene. With this, I'm just going to show you what the one vehicle here, because then we just have to come in and we can tweak this. Show you how we can export. Well, that way we can actually use this script on everything instead of making multiple scripts just because of one variable difference. I'll show you that. But first let's get this up and running. What we're going to do, we're not going to use this process at all. We're actually going to create a function called spawn vehicle In here, we're where we need a random number. Let's go ahead and call time late time. Just call it wait time. We'll set a float and we'll set this equal to, let's see, a random integer and not mistaken. We could just do something like this and that would work. I don't think we have to use Rand range, although I could be incorrect on that. All right, there we go. Since I want to double check that, just to be safe, I'm going to hold control. Click on Randy and that's going to open me up to this page. And yes, I did this correctly by using percent 20. In this case, a GC is going to give us an titubetween 0.19% 100 will give us 0-99 And if we do percent 100 plus one, that would give us a number 1-100 In my case, if I do three, then we're going to have a wait time of 012. I'm going to add one to that. Now we have to wait at least 1 second, and between truck spawns it's going to be 12-3 We can see how this looks. We could always adjust this later. Now our wait time we have that, now we have to actually wait this amount of time. We'll say wait, we have to get the tree in order to do this. The await keyword here means we're just going to wait for this. In our case, it's going to be a timer, but this could also be waiting for a signal to be sent out. But right now we're going to say a get tree create Tim. This is going to be our wait time here. Our random wait time that we have time, we're away for that time out signal that gets sent out when our Tim ends. Which will be based off a random number, a random amount of seconds. All right, so once that's done, we can create an instance of our truck, of our, we'll say VT for vehicle VI for vehicle instance equals, in this case we're going to say truck but should change it to vehicle Truck instantiate and then we'll add it to our spawners self, a child to add it into the scene. And I All right, let's see how this works now. It's not going to because we didn't call it. Let's go into our ready function here and our spawn vehicle function that we created. Let's try it now. There we go. So we had another truck spawned in, and we're not going to have anymore because we're only spawning at once. What we can do from there is after we add child, right after we add the truck into our scene, we just have it recursively call itself. It's going to cause an infinite loop. It's going to keep, it's going to spawn a vehicle and do nothing and then spawn a vehicle. When it's done with that spawn another vehicle, it's done spawn a vehicle and it's always going to be a random number every time that we have to wait in between spawns. If we just take a look at it now, we can see they're fairly consistent in its spacing. And then that was a much larger spacing. We got a really close spacing on that one. It looks like percent three plus one might be the shortest that we want to go, but there you go. It's up to you. That's a lot of close ones together. It's up to you if you want to tweak that a bit, play with it at all. And up to you how you want to have them spaced out there. Now, the reason we don't have to set its position is because we're adding it as a child to my spotter. And the spotter is right here, since the truck here is at 00 in its position. The truck here is at 00 in its position here. And we can see that if we go to transport 00, it's going to be exactly the same as it's parent, which in this case is going to be sponsor one. Where my sponsor one here is that it's going to spawn in that location, just off screen enough. Now, how can we change this script to run to be able to use it for any of our vehicles? What we need to do to make this work for all of our sponsors, that we can have as little work as possible here. Well, first off, I'm going to change my variable name from truck vehicle because now we're going to use it for more than one vehicle, not just the truck. That means we're going to have to change it down here in our spawn from truck instant to vehicle instantiate. We want to have this variable exposed inside of our inspector so we can tweak it on a per node basis. Here we're going to do the at signed with export. Now what are we going to export here? Well, we could just leave it as such. And this will just work if we look inside the inspector. But if you want to get specific, this is called a pack seen, that's how you would export this. Then we could even just delete the pre load here, we just have a sign, our vehicle and declared as a pack seen. Now if we click on our spawn and our scene here, we can just open the vehicle and say New pace or we can load. Obviously we would want to load. But to save some time, we can just go into our file system, grab our truck, drag it in, and drop it in there. If we run this, we'll see our trucks spawn just as they should, just like they did before. All right, perfect. If we were to grab, say, let's see, Car one is also going to the left, let's grab car. Replace that scene in there, and take a look at it. There we have it. We got it working here with a different vehicle. All we have to do is change this one out. That's a lot of cars in a row. There again, I can come down to you tweaking things, but there you have it. I'm going to go ahead and replace this one with truck again and stop that from running. Now, I can go ahead and I can make more spans. I do, we do history and mismatch. That's interesting. I'm not doing anything with history. I'll just use control D there. And this one is sponsored two. So I'll just come on down, make sure that lines up that this is going to be car three. I'm going to look for my car three, scene and drag it in. Go ahead and take a look at that. There we go. We have our trucks and our car spawning in at our different intervals. Fantastic. We can do the same thing for our bottom here. I'll duplicate that one more time. And I'm just duplicating that with control D with spawner selected. And I'm just going to pull that down here for this vehicle. This one is just, I'll pull car in here, we take a look, we see all of our cars going to the left are all spawning in correctly. Fantastic. Now we just got to get the two over on the right. The same thing. I'm just going to duplicate my spawn here and just drag it over to the left hand side. And then I adjust it here. Our position that should be good. And that is car my car Fc would duplicate it one more time and mass it up here for my car two scene. All right, now should be able to come in here and delete all of these temporary cars and trucks. If we run it should be working perfectly fine, spawning all of our vehicles in there. We have it now. We can run around with our little, yeah, our say, little froggy here. There we have it now. We just need a way to hop across this water so we can get in there of a way for our little froggy to get squished. I think we'll handle the squishing. Next time we'll get player death in here. 8. Player Death and Respawn: All right, so how are we going to get our little froggy to get if he gets hit by a car? Well, the first thing I did is I added a collision shape two D to cover the size of my froggy. We're going to use that in order to determine if you got hit by a car in combination with the area two D that is on our vehicles. Inside my animated sprite, I created a new animation called Death, and I brought in the frog dead Sprite. Now that we have that we also need on our vehicle, we're going to have to add in a signal connection here. And the one that we're going to want is body entered. We could come through here and connect them one by one on all of our vehicles or we could save a little time and connect it through through the code. I think that's what I'm going to do here, just that way we saved a little bit of time. Now let's take a look at how we would connect this signal through the code instead of the interface. The easiest way for us to set this up is as you see in the following, inside the ready block here, that error is just because we haven't created that function yet. We see we grab our area two D because that's what's sending the signal, the signal name which is body entered, you can see that on the right. And we're going to connect that signal with the connect function. Then we create what's called a callable and pass in a name. And this name is going to be the name of our function that we want to call on. Player hit, Frog hit. You can go with that is what I'm going to call mine. Now all we have to do is just come on down and create a new function for Funko. This function also passes in a piece of data. If we take a look at the body entered signal here on the right hand side, we see it passes in the body and that is a node two D, it's going to be a two D node of some type. We have to put that argument in node two D. And just like that that should now connect the signal for all of our vehicles. And to test this out, we can go ahead and print body. And we'll see this something I've also done is I changed my player. I've renamed my player from character body TD to be player. Then I've had to go into my main scene here and replace it so that the name was updated. Now if we go ahead and run this, we should have a body get printed out every time we get hit by a vehicle. So let's test lane one. Yeah. Lane two, Yeah, Lane three, Correct. Lane four. Our last lane, the truck. Here we go. All of our vehicles are detecting when we get hit and we can see we have a lot of vehicles there with this time, that might be a good amount. Or maybe you want to increase the minimum spawn between them. Again, completely up to you and how you want to go about it, go about yours. But with that, all of our vehicles have now been connected and set up to squish our little frog. The reason why I told you I read my character Body TD. For the player to play, I'm using a capital Is because we're going to use this name on our vehicle script. We're going to say if and then passing a spring here, player. So we want to see if this string is inside of another string. And the string we want to check is body name. Now remember body is whatever object we just collided with, Whatever body just entered our vehicles area. The name property of it is going to give us whatever this name is here, which in our case is player. See if our name is player instead of body name. We could just do a double equals if we wanted to be an exact name, it's completely up to you. In this case, it shouldn't affect anything. We end our statement with our colon. Drop down to the next line. Now we can execute our piece of code. What do we want to do when our player gets it? Well, we're going to call the death function on our player. Now, this function doesn't exist yet, so we're going to have to go create that. But body death if you want to have an extra case. Security here. You can say if body has method can pass in the string of death, then we can tap body death in one more. We can go like this and this will avoid an error. If we were to go ahead and run this, you see we're not going to have any errors here. Because we're basically saying, okay, we're saying if we collided with the player here, player, if that body has this function, then call it. Right now it does not have that function. If you wanted to put that extra layer of security in there by using has method, you can certainly do that. I'm going to go into my player now and create this function bunk death. We're not passing any arguments in with it. What's going to happen when our player dies. But we need to play our death animation so we can get our sprite corrected. Let's go ahead and do that. Animated sprite two, play death. Let's take a look at that now. What happens when we get hit by a vehicle? A poor little frog crossing the street? Okay, so we see you die and then we one or sprite is the wrong way. It's not facing up the way it should. Let's correct that. After that, we're just going to set its rotation. And we've already done this. When we press up, let's add that into our death function. Here we take a look that should now be acting right flat. We're in position awesome. Now what you can't see is we're constantly being collided with because our collision shape keeps hitting these cars. And not only that, we can also keep moving, so we can't bring the being and we're alive again, we have an unkillable frog. All right, one prof matter time. Let's stop our collision from happening. And we can see this, and I'll show you that if we come into our player hit and I'm just going to go ahead and print out squished frog. You can see that even though we're dead, we're still getting squished, squished frog. And we're going to keep getting squished even though we're already dead. We don't want this to happen because this might just keep subtracting lives from us, depending on how far apart the spawns are. Let's go ahead and fix that on our player. To do that, we're going to get ahold of our collision shape that we created, the collision shape two D that we added onto our player. And we're going to use something called called deferred on it. What this essentially going to do if we take a look, is calls the method on the object during idle time always returns null, not the methods result. There you go. Our keyword here is calls it during idle time. So it's going to call this whenever we pass in, when it gets the next chance that it gets, basically instead of trying to call it now when it might not be able to stamp functions, it is going to tell you to do that before we call that. You don't have to delete them. I'm just going to show you here the error. If we come in here and I go disabled equals true, we're going to see we're going to run into an error here. It doesn't prevent our game from running. Let's see, we got squished twice. Our disable isn't working for 12. If we go into our debugger and look at errors, that's going to tell us that we can't change the state while flushing queries use call deferred. So it's specifically telling us to use that, that's why we're using call deferred here. Call deferred in here is going to be a string of what we want to do. In this case, it's going to be set disabled. That disabled takes a second argument and this is going to be what we said to, in our case, it's going to be set to true. Now if we look at this, that error is going to be gone and we're only going to get squished to one time. There you go. It's not going to pop up anymore inside of our code if you're worried about call deferred. When we get hit by a close range of vehicles such as when it's like three back to back, we can take a look here. It's already been disabled before the next vehicle even touches us. All right, so now we can actually die here. What we have to look at is how do we get ourselves back. Right. Now we're just an unkillable frog because we can't collide with anything. So we have to fix that with our death. We have to have a respawn of some sort. We need to make sure that we can only move if we are alive. Deal a little more than intended there. All right? We need to keep track of whether or not our frog has been a live or is alive. We can do this with a simple function that just checks if alive or if dead. Based on that variable, we can either move or we can't. For this, we're going to use a set of states, which is going to be an enum, as you can see here from the example here. We can use these enums to hold specific pieces of data. I suppose you could say, It's basically like a list of options that we can select from. It makes it easier when it comes to checking things. You can see this when it comes to basic form of a state machine which is used for characters. For example, if you played Grand Theft Auto Five for example. You have different controls when you're on foot compared to when you're in a vehicle. That's because you're on foot. Controls would be one state. Swimming would be another state. In a car would be one state, in an aircraft would be another state, et cetera. We're going to use this to know when we are alive and when our froggy has been squished. In order to create this, instead of using the Var keyword, we use enum. The name of the enum, which says is going to work like a state machine, I'm just going to call it state. And then instead of using equals or colon, we just jump straight into the curly braces. Traditionally, from what I've always seen, these are always going to be in capital, So I'm going to have a live the drop to the next line, dead. These are our two states, alive and dead alive will be the default state here. We're going to create a new variable called current state. We're just going to declare this as being a state, one of our states here. All right, now with our movement, all we have to do is check if current state is equal to two equals state alive. And then tab our movement in. Now we can only move when we're alive. Now when we die, we have to tell it that our current state is now being set to equal dead. If we run this now, we should not be able to move. Once we die and get squished, there you go. We got all squished in and we can't move. Now all that's left is for us to go ahead and create the respawn. Let's create a Respawn functions once we have lives in here. This is where we're going to check if the player has lives left. We're going to call this. All right, let's go with how do we respond? We're going to need to set our collision back to working. So we're going to need to call deferred in our collision shape. And instead of setting it to disabled, we need to set it to false so that it is no longer disabled. We need to change our position, self position and we need to reset this to where our starting position is going to be at the moment. That is 169.2 33. I'm just going to copy this value real quick inside of my main scene. I'm going to add a. See what did they rename it? Here. Here we go. It was renamed to mark two D, and just give me 1 second. I'll get that up for you. There you go. So we're going to use a marker two D. I'm going to set its transform for now. I'm just going to paste the value in, going to set it to the same position that our frog is starting at. I'm going to call this player spawn location. Now when we respond we can to self dot position equals our. Player that's not going to fill out for us. I'll just have to type it in, player spawn location position. This should happen pretty instantly. So let's go ahead and go up to our process here we're going to form another check, LF current state is equal to state dead. We can call respawn. This should spawn right back in the beginning where we started. If you get killed, we seem to have what is. Oh that's fair. Players spawn location, We can't get access to that because we actually have to go up the tree to remember who our player, and the player does not have direct access to this players location. Here we need to go up, follow this line and go up one and then that takes us to this node two D. And then no two D then has access to a players spawn. We have to go up on the way we can do this is a few ways we can go ahead and do get parent get node. This get node is just a long form of writing that dollar sign. Then inside would be a string or the path directly to Playerspalocation. Alternatively, to keep this a little short, we can just do get node. We can pass in things. We can say use one dot which is equal to writing self. Or we can do two dots which is equal to that get parent we just deleted. And you can see that as a much we can say do this with get parent player spawn location. All right, that should fix that. Now when we get squished, you see we get right back to the beginning on. We can't move yet still because we do have to set our current state. Remember we can't move current state equals state alive. And not only that, we have to set our animation back to being our idols. We'll get our animated sprite to play our idol sprite. Set it back to normal when we run it. Now we can't really tell when we get respond to. What I'm going to do first of all is I'm going to use calder and set that down after everything else because I notice we're getting squished twice. So we'll see if just moving that line, we'll fix that. It does not. Okay, not a problem. We'll just have to have a small timer, for example, afterwards. Which is fine. All right, so let's see, what did we need? Our dead symbol isn't working all too well because we died. We're instantly respawn. We can't tell anything that's going on. What we're going to do is inside of this respawn, wait, we do what we did before using get tree and create that timer. We'll set it to 1 second. That feels like a long time. And the time out signal 1 second may feel like a long time here in an old game like this split. And then we respond. Awesome, Now we're getting squished multiple times there, which is a little unfortunate. I'm just going to come down here and create another small timer for 0.5 And I'm going to see what I can get away with or how small I can shrink this through testing 0.5 we can get away with it. I'm going to try 0.2 I can get away with 0.2 We may even be able to get away with 0.1 having that really short delay here. There we go. Now we have that 1 second that our death image is going to be on the screen of our poor little squished bronchi. And then the resp happens. Awesome. Now, if you wanted, you could set this number into a variable up here to respond Tim, or respond time. And that'll be your time in between your responses. Now for me I think I'm just going to leave it at one. That's not a problem. I don't think I'm ever going to want to tweak that. Now, if you notice here, when I was going if I sit right here, I might get squished by the car underneath no fine, but I did get squished there when I turned to the side. I might want to tweak my Y position a little more. I might want to tweak my Y position a little more there. But that's going to come down to just playing around with the position and that just a little more, but no problems. But that'll do it for this. We now have our player death and respawn system happening. We don't have any lives going on right now, but we'll get to those lives when we get to our section. But with that take care, there was a lot of information that we went over. I hope you're ready for moving on to the next section of the game. That is. 9. Water Death: All right, so let's make it so that when we jump into the water, we die and have to respond. Well, to do this, we could do this a few different ways, but the easiest way then, I'm going to say for us to go about this, since we are using a tile map, is to take advantage of that and use the tile map to tell us what tile we are standing on. If we are standing on the water, then we'll die. If not, we'll be fine to do this. Let's head on into our layer script. Close on the other as we'll go into our player script, what we're going to need is a new variable to hold our tile map here. Now we don't have to set this at the top, but we don't have to constantly set it in our function. We're going to make either all let's just get this and we're going to use the keyword on ready. All that means is the variable that we're going to make would be the same as if we set it here in the ready. If we said for example number equals ten, it would be the same thing as if we created number and then set it to ten down here inside of the ready block. That's all on ready means this is useful for when we want to get ahold of specific nodes that are inside of our scene. In our example, we want to get ahold of that tile map. Here we're going to do var tile map and we're going to set that equal to yet parent node. Of course it is currently just called tile map. Now remember what I said I think it was in the last video. Instead of using get parent here, we could shorten this down in our get No, just to do and have the same equivalent of get parent. But then I'm going to do that just to keep things again a little shorter. All right, so now we have our tile map. Now what we want to do is we want to check what tile we are standing on. I'm going to go ahead and create a new function here. I'm going to call this check cell ID. That's going to give us a void turn. What this is going to do for us is we will basically use it to first get the position of the cell that we're standing on. So we're going to say bar map Pause, which will be set to our tile map. Local to map. And then this will take a position, and that position is just going to be the position of our player. Now local to map is just going to give us back a position which will be the position of the cell that we are standing on. The cells would be each of these orange squares. Since we're standing on here immediately when the game starts, it would tell us this cell here, the location of this cell. Then the next variable we're going to create is going to basically go in there and say, okay, that's made with this tile. Now what is that ID? And it's going to give us back one to get that ID, we'll create a variable here. This is just going to be tile map. Tile map, Yeah, sell source ID. That's just going to take two arguments. The first one is going to be the layer it's on which is layer zero. The second one is going to be the position which we already got from our map, a variable here. Now this ID should now be whatever we are standing on. If we come in and we print this ID, we just run check, sell ID. Inside of our process, we see one immediately get printed out for the median to get printed out for the road, and three for the water. Those we run this, we can take a look down in the output, we see one get printed out for our median, two for our road. If I can make it to the water here, we're going to have one for the median again. And then three when we hit the water. There we go. Now we know that this is working perfectly even if we come all the way up here because we're checked for layer zero, we're going to three is going to be our water. Well we know that. Now what we're going to do is we can now I D is equal to three and this is where we would kill our player. Then come in, call our death function here. Now when we touch the water, we should die. There we go. Now we can die when our player touches the water. And wait for the respawn. Now this is a, could be a little taxing when we're checking it constantly like this. No matter what the next best location would be to call in here only when we're alive. But even better is we can call it whenever we actually move. So I'm just going to add this to the bottom of all of my movements here. Now when I move in any direction is the only time we're going to check. Instead of spamming it so far. Good, jump up, dead. Wait for response. Now we move again. All right, so now we're able to drown our frog in the water. And we're able to let our froggy get squished by a car. All right, so we have all of our deaths check. Now all that's left for us to do is to get our platforms working and then get our little wind points at the end by jumping into the right locations. And then set up our heads up display with our score. Then I think will be about done. I don't think we're missing anything after that. Could be wrong. But there you have it. We can now round our froggy with the water and you now know how to get the ID of whatever tile your player is standing on. All right, to do it for this one. I'll see you guys in the next video. 10. Water Platforms: All right, let's go ahead and get ourselves our platform set up. Once we have our platform set up, the only thing we can do or the only thing we'll have left for these platforms is basically just swap out the sprites and to make these longer and shorter through for my platform here. I'm just going with sprites set up here that we have. Using the log for this example, the end middle and the other end, end middle and start. That means I'm using three sprites here with my main scene. The root of my scene here being a character body that I've renamed platform. I could rename it to log if I wanted. That has an area two D with a collision shape that covers up my log. Here I have connected both the body entered and body exited signal. Once you have both of those signals connected, the script on your platform should look like this. And we are ready to add information or add everything onto it. With the way that we're going to do this, we're also going to be adding things into our script as well. The majority of this work will actually be on our players script. For the time being, let's go to our players script and add a couple variables that we're going to use. First one it's going to be platform, and that's going to be a lean. And that's just going to tell or let our water know whether or not we're safe because we're on a platform or if we're not on a platform. So called the death notification. We're going to get our current platform or platform and that's a character body two D that we pass in. Then we'll eventually set to it. For now just send it to know to need a platform direction which is an integer fault we're going to set to zero even though it shouldn't matter. Again, we're going to use platform, current platform, and platform direction as our three new variables on our player script. We're going to go ahead and move down to our check cell ID. We're going to add to our statement, so we're going to say ID equals three platform is equal to false. That way we say if we're in the water and we're not on a platform, then we'll kill the player. We have our conditions set there. Let's see for our player. We're also going to check, while we are alive, if our current platform is not equal to null, which it's only equal to it. For now it'll be an object assigned to it. Once our player stands on our log, say current platform is not equal to null, then we can just go ahead and our position plus equals 0. So we're going to do a little mass. We need to open and close our parentheses here because we're going to use the order of operations when it comes to our math. We're going to say platform direction times 16. We're going to use this as either plus one or negative one, just like we did with our vehicles. And multiply by 16. We're either going to be moving 16 to the left or 16 to the right. And we're going to be doing this over time, so we're going to multiply that by delta. This way we're not frame based were more time based. So the only thing left for us to do is to set our platform direction. And we can do that via a function we want to go, Yeah, let's go a set direction. And that'll take a argument of an integer returns nothing. All this is going to do is he's going to set our platform direction equal to. All right, so now we can head over to our platform script. We don't need this ready block, we can delete that inside of our process. We want our log, in my case, to keep moving. I'm going to go ahead and do position plus equals 16 times delta. That's going to constantly move it to the right when we enter, when our player enters the area. So we're going to set platform here to true. And we're going to set our current platform to our log here. My platform here. I'm going to say body platform and set that to true. Now we're on the platform. Body Legos curve. Platform. Yes. Current platform equals L. When body exited, we're going to do the opposite. So we're going to set instead of true, we'll set it to false instead of sell. Set it to no. All right, so what we're doing so far is when our front jumps on the log which is currently moving to the right at all times. While it's doing that restart that our log is currently moving the right by 16 over time and not based on brains. Now when our player enters the area of our platform here that they can stand on, we're going to set the platform variable on our player to true that way when we check the cell ID to see if we're standing on water platform will be true and our player will not be killed. Then we're setting the curve platform variable of our player for the current platform equal to self, the character body here. That's moving, representing our platform. Based on that, we'll be able to move our character here. Current platform is not equal to null. If we're on a current platform, then we're going to move our frog in the same direction, at the same speed. The last thing that we have left is to actually call this function that we created, Set direction. Body, set direction, that takes an integer, which then we'll move into the right, We'll use positive one. Now if we go ahead and add the platform to our scene and run it, as you see, there's our log and if we jump onto it, oh, we ended up dying. There might need to update this flat. One moment there, new one, back in. Move on down there. Give Dad another shot. Okay, I'm dying. So my signals might need to be reconnected. I'll disconnect that And reconnected and I'll do the same with my exit. Disconnect and reconnect my body exit and we'll see if that was the issue. Okay. Hey, I believe I see what I missed here and we're getting this information a little too quick. So before we have our F statement inside of our check cell ID, I'm going to use a wait and do what we did before with get tree create timer. And we're just going to have a small pose there of 0.1 and get that time out signal. That should fix that for us. Here we go. Now we can jump onto our little log and we're good. We can jump back and forth on it and be okay and we're moving and as soon as we jump off, we're fine to run back to the other side if we want it still. If we jump in the water, we went ahead and died. All right, how can we make this script a little more, I guess. A modular in a way, in a way that's going to be more friendly so that we can constantly change whether we have two sprites, three sprites, one sprite, how big our collision shape is and have all of that regardless. As well as I guess set our direction so we can have some moving right and some moving right or some moving left. Well, we're going to go ahead and export a direction of an integer that to zero. By default, we got the word bar in there. There we go. So now I want to go to my platform. I can change this to one instead of zero. We can take direction and pass that in here when we call set direction plus equals. And we could do the same thing here where we have direction times 16. We can go ahead and check and make sure that everything's still working. We haven't broken anything. Our lock is still moving. We can jump on it and Okay, so we haven't broken anything yet. That's great. Let's see, What else do we need? Well, I suppose that would be it. And we can just go ahead and set or create all of our different platforms now using the same script then when we just create a sonderjust like we did with our trucks. All right, I'll be right back. Why create a couple of these? All right, so I've gone ahead and I've made long turtles as well and just threw a few here in the scene. And as you see, go ahead on this log, jump to the next turtles, Next one, jump to the right, up on my turtle, jump on the log, and I'm ready to jump into what would be our wind space. All right, our platforms are certainly working just fine. Now is great. I do want to know I did add weight for 0.1 on body entered before changing the platform on our platform script. I do want to take note of that now. All we need now is our sponsors. All right, so let's go ahead and create those. We're going to effectively make those just like our truck ones here. We're going to go ahead and get ourselves or add on a No two D, we call it platform sponsor. We'll go ahead and start lining these up. So I have one there, I have one there, I have one, looks like there. Okay. That look even does that. It's actually a bit of a weird spot. Yes, go there. And then we need a couple for the other side, for our hurdles, take it over and one for hour hurdle. All right. So those look like some good spawn points. These ones a little close back. Those ones up a bit. We're going to have something similar to our truck spawn. I'm going to go ahead and just copy our truck. Let's see, are those going to be the same different name, the vehicle? Pretty much. We could probably get away with just using our truck script on here. Our platforms would be named vehicle, but I think I want to do a different ones because I don't like the wait time. I don't think that would be good for the platforms. I'm just going to use that as my base. I'm going to click on my platform Spon add a new script in here. I'll go ahead and just paste in the vehicle script. I'll call these platforms. We will change to platform. Do instantiate for platform instance self at child I wait time, see this is where the issue is going to come in. Let's see, we'll go 1-2 and we'll add three to that. We'll see how that works. Then we'll change this from spawn vehicle to spawn platform. This one here is going to be our log scene platform scene. The next one again, it's going to see, go ahead and just drag my script up and attach them to all of my platforms. And two is my log scene, three is the log platform. And then 45 will be my. All right, so if we now get rid of these platforms, move my player to be underneath the bottom so the C can sit on top. Let's see if these working. Yeah, get all the way across, there's my turtles. It looks like we need to change those wait times. That's going to make it extremely easy for our player to just make it across. This is why we wanted to use a different script from our truck because we're going to need completely different wait times for the platforms. All right, so let's try plus ten. This will give us a variation of 11.12 seconds. Oh, why did I get between these cars? 11.12 seconds might be too small of a gap in this case. At this point we're just to see what fits best here, maybe we'll try 5.6 I'll jump all the way across and we'll see what this spread is like. But at this point, you're just pretty much tweaking your numbers to see what looks good for your platforms and what looks good for your trucks. Just want to make sure these aren't going to be completely consistent the entire time and it does not look like they are, which is great. Alternatively, if you wanted to hardcode the a little more or make them difference, specifically come up here and do wait time up here. And we'll make it a float not a flat. Alternatively, you could do it up here and delete this line completely. If you wanted to have a specific amount, you wanted to have control over the exact amount of time that you waited per responder. You can do it that way, but I'm going to continue with this bit of randomizing here. You know what, I'm going to go ten there. I think that'll do it for this. Because now we've got our responders, we have our platforms. Everything seems to be up and running. We could make it across. I guess next we can do our victory, our little victory up there when we jump into the correct zone. Let's see, do I like these numbers? And we jumped into the water, we died. Awesome. I think I like these numbers for now, at least. All right, that's it. We're done with our platform swing and riding them. Next we'll cover the area where we jump into our wind zone and spawn in our little home frog there. All right, I'll see you guys in the next one. 11. The Win Space: All right, for the wind zone, you can see that I've got a new scene here. And that's just an area two D with a collision shape and right two D that just has my home frog here as a texture. It is turned off or visible is disabled by default. You can do that by clicking the little eyeball here. Wind space has a script as well as a body entered signal connected to it for the script simply, all we're going to do is we have body wine set to true. Wind zone is a new variable that has been added to the player body. Current state is set to body state. When we have a new state added here, we now have a live dead. And when then all we do is we get our sprite two D, get the visible property, set it to true on our player to avoid any issues and to fix a little bug. I pulled right here, LF current state is equal to state dead. I put our weight, our 1 second of weight here and pulled it out of the respawn function it used to be here at the top. I just pulled it out and moved it up there into our state. That should be all we have to do now. We can go into our back to our main scene and import our wind zone, our wind space. Just bit it on in there. Into each of our little slots. You may have to do some testing to make sure that your frog is not prematurely touching it in order to trigger the wind. Here I have mine covering all my areas. If you want to check collision zones and all these, these debug areas, we just head up to the debug menu at the top. And you'll have the option to show visible collision shapes if you do that when you run it, you'll see we can see all of our little collision boxes here for everything. There we go. If you're accidentally triggering it or you might be, go ahead and enable that. Take a look yourself. You'll see once we make our way up, we should have another log. There it is. We can trigger our wind Notice we did not get dead printed out to our console down there. When our state is our current state, state win, we respond and then set wind zone back to falls. Now we're also using wind zone. Down in our cell ID, we added another condition here. If ID is equal to three and platform is false, if we're on the water, we're not on the platform and our wind zone is not true. Or you can say wind zone is equal to false, that would be another way of writing it. Then we can call death. If we're not in the wind zone, we're not in the platform and we're on the water. Then we kill our froggy. Otherwise, our wind state should be triggered and we can just do a respond without killing our player. All right. The wind space is a very simple, very easy to do there. Now, whether you leave the frog here enabled, the entire time is up to you. If you wanted, you could come in and add a timer node. You could come in here and add a timer and then set this to, I don't know, we'll say 5 seconds. Then we can come in, or rather we can connect their time out signal to our wind space on time out, we'll set our sprite two D visible to false. Right after we turn it to true, we can start the time. We can get the timer start. If we were to do this way, which is up to you, this is where a bit of design is going to come in. How authentic do you want and how custom do you want to make your game, et cetera. So my locks And that starts spawning on, so I can hop on here. We wait to go across. If we use the Tim er here frog, our little home frog is going to show up for the wind. Then after a few seconds, and it's going to disappear. So you see it up there, and there it goes, it disappear. If you wanted to disappear like that, that's how you would do it. We can just just add that timer into your wind space. Set it in the inspector to how long you want it to be. Start the timer after you set the sprite to being visible when the timer times out, set it to falls. All right, that'll do it for our wind space. And we just have to take a look at our heads up display or hud or gooey, and look at creating a score system. All right, that's it, and I'll see you in the next one. We're almost done with creating ourselves a Frogger clone. 12. Memory Leak Fix: All right, we're not going to add any features. We're actually going to fix what would be a crucial prop, especially in a bigger game. Now what we have is a memory leak in our game. We have this from two points technically were around ten. But let's take a look, if we go ahead and play this game, and I'm just going to pull this out here, I'm going to have to slide the silver guys. You can see everything spawning off screen and they come, just look at those cars go, and the platforms up top will do the same. They're going to keep going and they're going to go forever. They are never going to stop. This is what is called a memory leak. All, I'll leave it right there just so we can see that easier. But if I pause this and click on the remote tab here at the top of our scene tree, which is only available when the program is running. We hit remote, take a look at all these cars just in one spawner that still exists even though we probably don't need the majority of them. The same with all the other spawners. Our platform, our platform spawners aren't too bad because they have a much slower spawn rate than the cars. But they're going to go on forever and they're never going to disappear. They're never going to get freed up from the memory. Eventually you will have this tiny game that could take up 128 gigs of Ram just to keep playing it. It would take a long time, but eventually it would all add up. Let's fix this crucial, I guess we call it a bug. It is very simple for us to do. We just got to put one if statement inside both of these scripts. Now the numbers that you pick here will of course depend on your project. But from what I've tested out and based off of our window view, a set of numbers that I'm going to use here. What we're going to do is right now I'm inside of my platform script and inside of the process here, I'm just going to check if global position, now the difference here between and global position is if we go into our platform here, for example, this is going to be our local position, right? So just the position property. But when we're in our main scene, above everything else, this is going to be in charge of our local position that we see on screen, regardless of who the parent is. For example, if we take a look at our space here, we can see that its position in our main screen here is at 24.45 This is going to be more of a global space, whereas if we go into here, we can see our wind space, our local position here is at 00. These are two different numbers. Hopefully, that makes sense to you as to why we're using global position here. Of course, we want the X property because that's going to control our left and right. If our X is greater 436, that's about 100 pixels off screen to the right, based off where our sponsors are. This is still gives enough room to go past that. If our global position x is greater than 4,436 or global position x is less than negative 100, we're going about 100 pixels offscreen in left and right direction. If either of those are true, all we're going to do is self free. All right, so now we should see character our platforms, disabling each other or deleting each other out of our memory. This is only one potential solution for something like this. Another solution if, depending on your game, for example, if you're doing something like a bullet hell, you're going to want to go with something called object pooling. And we can talk about object pooling in future video. All right, so I'm going to go down to my spot here, my vehicles. Let's see, which one are we looking for here On our vehicle script. There we go. So not on our spot on a vehicle script. And same thing assigned to the process is going to paste in the same code. If global underscore position do greater than 436 or global underscore position x, it's less than negative 100 self. Now if I go ahead and run this, and we're in the right scene, our main scene here. I'm going to go ahead and pause this real quick. Build our remote tree, we can take a look at our regular spawners here where the cars are going to be. Here's my game window to pull that out. If I go ahead and let this play. All right, We have some cars net spawning in here. We can see this here. I'm just going to extend the window off to the right. I have a mistake there. I seem to have grabbed Gato instead. There you go. You can see they're in the remote as well as visually there. Once you go far enough, they're actually completely deleting themselves. Now our objects are all being managed and we can only potentially have so many or so many in our scene at any given time. You can see the platforms at the top doing the same, the same things happening off to the left hand side of screening. What we can't see right now. There we go with that simple one, technically two lines of code. We have our memory, our memory, just leaving my mind right now, memory leak. It's funny since we're talking about memory, but there you go. With that, we have fixed our memory leak issue. I'm going to show you an issue here. Not really an issue, but just to show you one more example, here we go to the platform. If we used position instead of the global position, you're going to see an example here. If we take a look, you're going to see, especially with the turtles, you're going to see the turtles spawn right about this area here. All right? Watch them. They're coming in when we're using that local position, there you go. You see they're disappearing way too soon. They barely get on screen and they disappear. They get about here, and they're gone. This is why we have to use the global position. So I just wanted to demonstrate that a little more visually for you. There, not redraw Q free, just like I said, completely destroys the object and takes it out of memory. All right, so there you go. There's how we can fix that memory. All right, next we'll be moving on to the score and hud, adding player lives and all that in there. 13. Scoring System: All right, in today's video, we're going to go ahead and add the point system. As you can see here, these are the rules that we go by. Ten points for each step, 50 points for every prog that gets in, and 1,000 points for every time we get five procs in. That's what we need to keep in mind when we do this. I'm going to start with creating a global, also known as a singleton or an auto load script. For that, I'm just going to right click in my file system and create new script. And I'm going to call this, I'm just going to keep it simple and go global. To activate this, we go up into our project settings. Let's see, do we have that captured right now? We do. We go, it might be a little big. There we go. And we go into the autolite, our global script. It'll get the name global by default, you could change it, but I don't see why we need to add. And there we go. Now we can use this script anywhere in our code right now, I think that's where we're going to hold our score. That's where we're going to hold our score. If we close that, we can now open our global script by double clicking it to give you an example. Here we can come down here, we can create another function here called print score. I have a variable up here called score. It's an integer which say you got 50. The whole point of this function is just to print the school with it being a global. I could go into my players script here. I could just write that name that we had for that I left, which was called global for the capital. Then we could use the function we just created, print score. Then when we run this, we'll see that score printed out here in our output. A global script contains variables and functions that we can alter and use within our game, in any script at any point. Let's just go ahead and we can remove all of that stuff and set score to zero by default. We're going to go ahead and have a function called update score. All we're going to do here, we're going to be printing out our score. Do we displayed on screen in this video? Now we'll save the displaying on screen for when we start covering the Hud. Here we're just going to go ahead and print the score. When this happens, update score will take the new amount to add the we do score plus equals new amount we can do. Well, let's first make sure that this stuff works. Every time we hop we get ten points. All we're going to have to add this into our movement and all of our pieces. So we'll go global update, update score, because we didn't save it yet. Update score, and pass in ten points. And we'll go ahead and copy this down into all of our movements and go ahead and jump in game. And as we move, we should see ten points constantly get added. There we go, 1030, 4050, 6070, 8090, 10110, et cetera. So this is working all of our buttons. Fantastic. We can just get our points up like that. The points here are awesome. I just went ahead and get rid of the other printings. Are there false Just to clear that up, make it a little easier for you. As we go ahead and run in there and we run around, you can see in our output our number goes up every time we move. There we go. It's working fantastic. Now, we also have to keep track of how many frogs we get in total. Frogs. Doesn't sound like the amount that we want. We call it a combo frogs. I don't know. Let's call it the multi frog. Multi frog, it's an int, starts at zero every time you add to the multi frog. All right, we do multi frog plus equals one. I remember with every combo of five, we get 1,000 points. Here's where we go. Multi frog less than five. Then I'll just tap this line in here. Then we'll just do score plus equals new amount. We do score plus equals 1,000 we'll get 1,000 If we get five in, that's only going to be if we get into a scoring area. We can't actually increase our multirot, go to our wind space and go into our body entered. This is where we are going to increase that number. We're going to be global multi frog plus equals one. And we're just going to stick it right on in there, inside of our wind space. Then we're also going to call our update global update score. And we're going to pass in 50 because we got a frog in, since we're increasing our multi frog before updating our score. So we're updating our multi frog y one. Then we'll check basically if that is our fifth frog or if that is not our fifth frog, then we'll do this. We'll just add in that 50. Otherwise we'll add 1,000 And then we actually need to set multi frog back down to zero because that has to be reset. Let's see if this works. All right, we're all the way up here. Let's go ahead and get in the zone. We're up on the log now, we wait for these turtles to come by little turtles on the turtle frog in the turtles. So we're going to have 290. We jump on here. Now we go into zone we should jump up to 340. We went up to 350 on that one because we also moved at the same time, we got to remember that we got our ten points. Do this frog or work that way. It's actually been a long time since the plate, so I'm not 100% sure on that. If that's the case, then to solve this issue, of course we can just add 40 and then it'll count that plus ten from our jump in there. If we were to go ahead and jump in that, now it would look like a plus 50 to which like I said, I'm not sure if it counts that actual jump or in the actual game. Maybe it's something we can take a look at. Maybe you can just leave that up to personal choice on whether or not you want to allow that to effectively count Froggy died. Said I seem to have a Brad Frog, here we go. Seem to have gotten to a little bug by jumping at a weird spot. Now my little frock is fine. This puts us at 05:50 so this next job will put us at 600. There you go. It's up to you if you want to do 40 or 50 here. Which basically comes down to whether or not you want to count that as your main, count that ten as your main thing. And I just remember we should probably get five frogs in there to actually test this. Might go ahead and just fast forward on the video here in this part just so we can get five in. All right, I've gone through it and I did my loop multiple times, five drugs, and went ahead, we got up to 4,800 points. Awesome. Seem to be working perfectly fine. Our score system works. We got our plus 40 or 50, depending on how you sent with whether or not you're going to count the extra step as part of your 50 or if you want to do a 50 additional. On top of that, we have our ten points per step. Here we have our plus 1,000 every time we get five multi frogs. Every time we rescue five of these frogs, all we got our score set up. I guess next we can just take a look at how to display this and start getting our heads up display. Hugo all set up. 14. Game HUD Score: All right, let's go ahead and start creating the game hood for our game today. We're going to go ahead and just get the score up here on our screen. For this, I just went to my No TD and I added in a canvas layer. If I come in here, canvas layer is what we're looking for, not canvas grew canvas layer is basically going to be everything that's on top of our game no matter where it is in our scene. So this is, as you would imagine, where all of your hot elements go. If you're playing say, Dark Soles, this is where your four quadrants are in the bottom left. For example, if you're playing Sky Rim, your three health stamina and Mana bars, W'll be across the bottom and so on. For us just to do the score here on my Canvas layer which I renamed to Guy I Stanford Graphical User Interface. I went ahead and I added on two labels, Two just regular labels here. And I named it Score label, just has the word score in it and score text which just has five zeros. Now the text of both of them were too big for this project. On both of them, I went into the inspector down to theme overrides bond size. My score tech is on size ten and the score label is on size 12. Now you might notice that I do have an extra black bar down at the bottom. I went up into project settings and in display window, I went ahead and updated my viewport height, 240-256 There you go. You can see it there. So I added an extra 16 pixels so I could add the black across the bottom because that's where our health bar is going to end up being down at, or our Lives bar in the next video. All right, once we have our two labels here on our canvas layer for the score, you can't find out where to change the text for that, it's just select your label and inside the inspector at the top you'll see the section there for text, Type in score for one and put in five zeros for the other one. This will give us a good idea on the amount of space we're going to need. All right, now to make this work, all we have to do is add one line to our global script here, outside of our and our L S block. Outside of both of these. Regardless of how much points we add, we need to get our score text label. Set the text to actually display our school since we are coming from our global script. If I go ahead and run this for a moment and then just posit, switch over to remote global is here. It doesn't have access to anything. We have to actually go up the tree once to get to root and then come down to our two D, then down to our gooey. Then from there we can grab our score text since we have to go up and then down we can go ahead and just get node. And remember, this takes a string as an argument. And as you can see, we could just write the whole path just Roth, two D in this case. But even then, since we only go up to one level, it's still faster if we just do two dots just to go up one and then we come down to our node two D. From there we access our Y there, we get our score text, if you're wondering. We're just following that white line down from our global here where we're writing this code. We have our two dots, which is the same as writing get parents. So we go up one to the root. Then we're just following down on every stop with this white line. We see this white line comes down and then it goes in points. No two D, that's where we've written there. We follow the line down again, stops and points in at the Y. We write that for the next stop. Then we come down and it finally points into our score text. And we end it there. Whenever you're in delts, go ahead, click on the node you're looking for. Just follow that white line to get your path on the score text. Right, This label type object, we're going to get access the text property of it. Let me just get the game off your screen there. I just looked over and saw that it was covered. Again, we use two dots. Same as get parent. That takes us up to, up to the root node and we just follow this white lines, it comes down points at node two. D comes down points, then it comes down to points at score text. And we're just following that path here all the way down. We want the text property of it and we're going to set that. We're going to set it to our score. However, if we just do this, all those zeros are going to disappear. As you see, we can't really do much to the score in this aspect, what we're going to do is we're going to actually turn it into a string with STR and then two parentheses We can write our score inside of that. That score is now going to be treated like a string instead of an integer. Now we can do pad, and we can pad it with zeros. We pass in the number five. We're going to have five digits like we see here, 12345. So we're going to have these 50 slots. Our score is going to change, but even though if it just says ten, we're still going to have all five of these slots available to us visually. It's going to look just like it would on an arcade. And in a typical scoring system. If we go ahead and play this now we can see our score there at the top. If we pop around, we should see our score increasing as it should. That's a lot of cars up there. There we go. Let's follow this long. Here we go. Let's go get ourselves some points. Ride the log, ride the turtles, ride the log. And we can ride the turtles, ride the log and jump home free. All right, so our score system seems to be working perfectly fine. It's displaying accurately. It's fantastic. All right, the last thing for us to do at this moment is, well, in this video, nothing. But in the next video, we're going to go ahead and set up our lives that when we die we lose a life. And that's going to be reflected visually on screen by showing how many lives we actually have left. 15. Game HUD Lives: All right, let's go ahead and add in our lives now. Our lives are going to have six lives at the most here. And we're going to go into our gooey canvas layer. We're going to add a new node, I know that's not visible. Just 2 seconds. There you go. We're going to search the word texture. We are looking for the texture progress bar. All right. I'm going to rename mine to the Lives bar. I'm going to move over to the Textures section in the inspector for the progress. I'm going to move over the health bar and into that slot. Set the maxed value again in the inspector to six. I'm going to set my current value to six. Now you should see them. I'm going to grab this little orange handle and pull it up just so it only takes up space we need. I'm going to bring it straight down to the bottom into that empty black space. Those are going to work as our lives. You'll see as we tweak the values 6-5 it's evenly split up, so we can easily determine how many lives we have left. The six, of course, is going to be our default and we're going to need to tweak that every time we actually die in my global here. Again, maybe game manager would make more sense for a name, but for now it's going to leave it with that. We're going to go to lives by default six. I'm going to create another function, Update Lives, Nothing. And we're going to fall saved path. Instead of a score text, we're going to get lives far and we're going to access the value property here that we can see in the inspector. We're going to say plus equal amount. Amount is going to be a parameter that we pass in which is going to be an end when we lose a life, we're going to add negative one to it, which will make it go down to five. This also give us the ability to add lives in future by just putting in a positive one to gain a life. But also updating that we actually have to update our lives as well. The same thing plus equals amount. Now we can go to our player, we can look for our death. There it is on death. We also need to go access our global script. Update lives and pass in negative one. That should do it. Very simple, small thing to do Now when we die on screen, we should lose a life and we should see our life bar down there, drop down to five. I need to pull this up because you guys can't see the bottom there. There you go. Let's see if we drop down to five. There we go, We split. I ran into the back of that car. I was looking at it, and you only gain points when you move forward on Frogger. We lose a life when we go in the water as well. We can go ahead and update that if you wish. If you want it to be a little more accurate. We're only going to update score when we press left and right will not get us any points. The only pressing forward will, which makes sense because that is a lot of points you could rack off real quick. Where's my logs? There they are now we ride the turtles. Doom on the turtle. I was going to go for the log, but I felt like I was going to miss it, so I stayed jump on the log here, and then we'll jump onto those turtles and we'll make it home free On this log, we are. All right, awesome. There we go again. We can lose the lift. Cool. Our live system works. It updates visually on screen. We have the ability to add in lives in the future. All right, I guess that'll do it for this section. Unless we want to add live when we get school, we want to do that. All right. If you want to be able to gain extra lives when you reach a set amount of points, here's what we're going to do. We're going to create a variable called multiplier inside of our update score. We're going to perform a new check here. We're going to say score divided by score divided by, we can say 10,000 if you want, times our multiplier is greater than or equal to one, then this is where we're going to add onto our lives. So we would need to do lives, normally we would say plus equals one. But since we want to cap it at six, what we're actually going to do is say lives equal. And we're going to use that function called clamp. Now, clamp allows you to have three arguments here. The first argument is what you would add instead of plus equals one. Our first argument here is going to be one. Then the next argument is going to be the minimum and maximum that this value can be the minimum, It could be zero. Our lives will never go below zero. Here, the maximum number that we can have is six, so it'll never be a higher number than six. That's how clamping works here. We can call update lives with one, right, so we're going to have a plus one to add on to that what we can actually just move our clamp right down here inside of our update lives and replace one with a mount. Then we could probably get away with not having anything in there, Not setting it up. Let's just clamping it down there, Update lives on e. Then we're going to want to increase our multiplier plus equals one. And the reason why we want to do this because if we don't, we're going to constantly gain a life because our score is always going to be divisible. Once we gain one life, every time we move, we're going to keep gaining it. We want to change this. If we get a life at every 10,000 points, then we'll get at 10,000 10,000 times one is still going to be 10,000 then the next time is going to be 10,000 times two, we'll need 20,000 points in order to get a new life. And then it'll be 30,040 et cetera. If we were to go run this now with just that, we can see if we run in, we go and lose a life, maybe even lose two. Now we've got to make our way up, pass through all this traffic. We got to make our way to this log. Then we can ride the turtles log again, transfer to the turtles, wait for the log to get up here, and then if our score was high enough, we should get 10,000 which I didn't change it now that I think about it. So that's a little disappointing, but we can check that real quick just by go into our wind space and we'll say, hey, we gain 20,000 Now if we were to check it to gain points on every 10,020 shouldn't do anything. It should just give us the one life, which is fine because you should never get 20,001 dog. Anyway, the most you should get at one time will be 1,000 What you see as we go, boom, we're almost there. We should see our lives at the bottom increase, plus one. There we go. So our lives have increased. All right, so our lives is now working. I'm going to go ahead and reset this back down to 40 points. We want to make sure we can game over. That's going to be. I guess inside of our global here update lives, we're going to go ahead and see this. Let us go negative one by chance. No, it will not. That's perfect. We don't have to worry about that. We could say if lives, actually we wouldn't have to already because we're setting it up here. We checked beforehand. So we say if lives, it's less than zero actually would already be zero. Let's say we have zero lives left, then we die, right? We're passing another negative one. We're saying if our lives are already zero, then we're going to have, we'd say, game over, but we're just going to reload the scene into a brand new game. If our lives aren't already zero, then we're going to come down here and we're going to subtract our life. For this we just use get three reload currency and that'll be the same as if we had just started the scene. This if we write in our lives are not getting reset, probably because they don't reset on Global. Let's find out. Let's go into our ready and let's take a look at how we debug this, say print lives and we'll see if that resets. We're getting squished broad. We're never actually getting our ready back and it's constantly reset itself. All right, so instead of in the ready, let's print it down here. Trying to figure out why we're constantly dot here. It resets after two, how are we going 6-0 All right. I'm not sure why, but the clamp seems to be what was causing that break, which is because there's no real reason from what I could tell that it should have been jumping from six lives to break down to zero. But that's fine. I just changed it back to lives plus equals amount now if we run the game and see if we can run through or back to losing lives one at a time. Once we get down three lives to one, here we go into the water. We're out of lives when we get hit. Next, it's going to be a game over and our game is going to reset. There we go, we got a reset of our game. We quickly run across, we can go back to losing lives again, but there you go. We have that reset. We now lose lives and display on the screen appropriately. When our lives are too low, we completely reset the game and start over again, as well as gain lives every time we get 10,000 coins. 16. Timer and Bonus: All right, let's get our Tim Er going now onto our guy. I just added another label down here with the word time with a override, font size set to 12. I then have a texture progress bar, just like we did with our lives here. I changed the fill mode to be right to left instead of left to right. I'm going to rename it here, Tim bar. My max value 30, my current value 30. Everything else is left the same. I turned nine patch stretch on so I can stretch this bar out to be whatever shape, length width that I want. And I'm just using the timer and that I have here, I just drag it in as the progress bar from the progress texture. There you go. I just stretch it out, place it down there for something that looks good. I also have a timer that I added down here with a script on my guy and the time out signal here connected to it. This is what we're looking at here. What we need to do every time, this time or times by default the timer is set to 1 second, which is fine. That's what we want. What we want to do if we want to get our time or bar and we need to subtract one from the value, we can just go ahead and grab it with our dollar sign. Here you get it, since this is coming from our guy value minus equals one. Now if we were to go ahead and take a look at that and run that, we should now see our timer ticking down. Beautiful. That's exactly what we want. Now we've got to check. We need to check if our, our timer bar value, it has hit zero. If so, unfortunately, our little frog has to die. That's just how it is when our timer runs out. Let's go ahead and get our F node. Remember we're on here, so we're going to have to go up one for our node, two D, then come back down player. And we're just going to call our death function on it. Oops. And that should be two equals, because it's a comparison if we're to run it. Now when our timer runs out, our little froggy should just go splat and we lose a life on our hide. Just give it a minute there for the timer to run out. Now having this timer here on 30 seconds, I see that my platforms up top need to be a little faster or at least a bit of a smaller delay. I think speed might be the better option rather than changing the delay. But there we go. A little froggy has died. And it keeps dying, that's not great. We need to actually reset that. Now, once it hits zero and our froggy dies, let's reset our timer bar. Let's get the timer bar and set its value back to 30. We can have a brand new bar filled out. Now, this isn't the only time when it needs to be reset, it needs to be reset when we reach the goal as well, we're going to go ahead and get node go up one, get our gooey, and then get our timer bar and set the value back to 30. Now before I test this, I'm going to go into my platform here. I'm going to change this to 32 and double that speed. That means I have to go to my player and adjust that. Well there is when we are here, 32 now should at least move quicker and hopefully I can get on without missing. There's the turtles. We need some logs. Thank you. Log. I don't know if I'm going to make it. I'm not going to make it. I'm going to lose my frog. Goodbye for a hug. I hardly knew ye see, this is going to be a little difficult. Does our time or not reset when we splatter? It does not, so we need to set that as well on our player. Where is it that we die? There's our death right there. And we respond. Oka, Yeah, let's stick it in depth here again. We're going to go up and then come back down to our timer bar and set the value back to 30. That way when we die that resets. I guess I am going to change que respawn, the spawner value platform spawn. I'll remove the plus six. See how that looks now since we have completely new numbers. Okay, that's looking fine. We might be able to actually make this now. There we go. We made it in our timer reset. And when we die, our timer. So reset as well. Fantastic. I can see I still need a bit of a boost in there. My minimum, I'll do 3 seconds just because I saw quite a bit of overlap when I ran through there. But we saw the timer is working perfectly fine now. Now you do, or at least you're supposed to get a bonus as far as the points go, based off of how much time is left when you do score. We'll go ahead and implement that as well. I just got to go reactivate myself with what the multiplier is. I know it's something times the amount of time that's left. So give me 1 second there. All right. It's ten times the remaining time that's left. Let's see when we get to our wind space, before we reset that, we need to update the score here again. We're going to add 40, but then we're also going to add whatever is left here. We're going to say, actually let's put this in its own variable here. We call it pie bonus. Ten bonus. Pie bonus. Of course, I want to send it to this value times ten before we reset. Now on our second update score here we do time bonus. All right, so now we should have our time bonus in there. So the faster we can get over there, the bigger bonus we're going to get up to a maximum plus 300 points. Hypothetically, I mean, you're not going to get there at 300 or 30 seconds left because it starts at 30. I might not get there at all. Might be close. I got it. But you can see I got 190 points on that one. All right, there we go. We got the timer in there, as well as the deaths when the timer runs out, and the score bonus when we still have time or left and we make it to the end. All right, so that's it. I think that might be it. Or frog. I don't think I'm forgetting anything here. If that's the end of frog, congratulations you made it to the end, that's amazing. I hope you guys learned a lot. We went over a lot of things throughout this project. Variables are working with lots of different scripts, but we completely recreated this game from the '80s. And what's great about these old games, they're fairly simple in concept, but especially if you're new to programming, there's a lot that you can learn from these games. All right. Take care. Have yourselves a good one and I'll see you in the next week. What? I'm going into a week now. Oh boy, Week four is going to be fun. We got a lot of things to talk about in there. 17. Frogger Audio: All, we're going to go ahead and add in the audio first. So this is going to count our hopping when we move the background music and our death sounds. All right for our background music. We can just go into our main scene here. Select our root node, which is our node two D, Go ahead and hit the plus or add a new node. And what we're going to add is this audio stream player here. Then we're going to go into our sounds folder, grab the music three, drag it in there, make sure you turn auto play on. That way we don't have to waste a script and waste writing code to play it. It'll just start all by itself. Now, warning, this might be a little loud when starting. If you want to adjust the audio for just the music here, you can go ahead and change the volume. D, B here, the lower you put it, the quieter is going to be zero is the default for all of them. However, if you want to lower the music for all of your audio at once, you can click a little audio tab at the bottom, down there. And here is all of your audio bus. We have the master here, which if you've changed audio settings and games before you notice, we have the master slider. That's what this is here. We can change the volume of this to whatever we would like. If you do want to add a different audio bus, you can customize your sound effects from music separately. We can just hit the add bus here. We'll just rename this to music Now with our audio stream player selected, you'll notice in the bus section here on the inspector. We now have a music piece here from the dropdown. This music will come through this piece of audio first and then it'll get out, put it to the master as you would expect a. Right. So it's up to you what you want to do. I'm going to go ahead and lower my music to maybe 0.6. Not sure. I'm going to make sure that you guys are actually able to hear this. Hopefully, this doesn't hurt anybody's ears. I'm going to hit play and find out. All right. So that seems like it's quieter than I am, so I'm going to assume that that is okay. But if you want, you can always lower it a little more. I think I'm going to go with minus ten here. Now the rest of our sound is actually going to be on our player. Because our player has, the player has the jumping our player. The other sound effect need, our other death. The plunk, the squish, and the hot. We're going to go over to our players. Same. We're going to add an audio stream player for them as well. We're not going to touch anything else inspector, unless you want to add an audio bus for sound effects and then change the bus there specifically. That's up to you and again a personal preference. But once you have an audio stream player added to your players scene, we can go into your players script. What we're going to need to do is set the audio stream by loading in the audio file and then actually play it. What I'm going to do is I'm going to go to our death function first, and this is going to have an ID passed into it. D is obviously going to be an integer because we're going to get a two or three. So I'm going to call an int and I'm going to set it equal to two by default. The reason why I'm using two is if we go back to our tile map and take a look at it, our road is ID two. By default it should be our road. It should be a squish. What I'm going to do here is we're going to get our audio stream player, Audio stream player stream throughout that stream property. You're on our player, right, that stream here. And we're going to set it equal to, and we're going to call load open and closed parentheses. And inside of here it's going to be the path to our file two is going to be our default, that's going to be our squish. So I'm going to get squash, squash. Wave out of our Sounds folder and drag it in there. That way I don't have to write it out. Now what we'll do is on the next line, we'll say if ID is equal to 33, remember being our water. If we're dying and it's on the water, then we're going to do the same thing we did on the previous line and set our stream. And load in a new file this time set of squash. We're going to load in plunk. Then outside of that if statement, all we're going to do is play our stream. So we're going to say audio stream player play, just like that. Now if we go ahead and get ourselves squished on the road, we should have one sound effect. And if we go jump in the water, we should have another. Okay, for now, I'm going to go ahead and just turn the autoplay off on the music so we can listen. If we jump in the water, hit by car. Okay, We have the same audio playing on both. Well, that's a little interesting. Why is that? Well, apparently we're not passing in any ID for three. It's never going to be three. The reason for that, remember we got to go down and check, sell ID. We are actually checking if our frog is drowning, that's what we have to pass in to our death. Now, it did not error because we told it that if we don't pass anything into it, used to by default, but since we want specifically an ID of three, whenever we're in the water, we have to make sure to pass it in down here in our check cell ID function. Now if we were to do it, we should have our plunk in the water and squished on the road. There we go. We know if that's working perfectly fine. Now the only thing left for us is to do our hopping. For that, that's just going to be up in our movement where we can go check our audio stream and set that audio stream player stream equals load. And risk going to grab our sound effect and drag it in there. On the next line we can just play our audio audio stream player play. We can copy that into every button press here. If it's down we can do that. Boom it's left. And if it's right now, if we play it, we should be able to jump around. Let's go into our main scene and try that down can show pushed down as well as ground water, down, down, down, down, down, down. Awesome. Now all we have to do is turn the music back on on our main scene audio stream player, Autoplay, turned back on just like that. We have the Frogger game complete with our audio and gameplay. I got hit by the back of the car there. But there you go. We have added sound to it, and now our game feels a lot more complete. There's nothing else we can really do here. You can feel free to add more onto it. You can try adding pick ups. You can find new sounds and replace them. Maybe if you want to create your own sprites and use those to change it up a bit, makes a little more custom for you. Or if you want to just keep it as your own little arcade remake, that's awesome too. But that'll do it for this one. Take care and have yourselves a good one pack yourselves on the back. We've completed Frogger. Next week I think we'll start talking about some of the differences and similarities between two D and three D and start getting into that.