The Godot Bootcamp | Michael Mcguire | Skillshare

Playback Speed


1.0x


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

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.

      Course Introduction

      7:47

    • 2.

      Download and Setup

      8:55

    • 3.

      03 Printing to Output added images

      14:53

    • 4.

      04 Variables

      10:22

    • 5.

      05 Strings

      12:25

    • 6.

      06 Integers and Floats

      10:42

    • 7.

      07 Constants and Comments

      7:29

    • 8.

      08 Lists

      10:22

    • 9.

      09 Adding and Removing

      10:28

    • 10.

      10 Pushing and Sorting

      6:58

    • 11.

      11 for Loop

      10:18

    • 12.

      12 Range

      5:40

    • 13.

      13 equality

      13:50

    • 14.

      14 if elif else

      11:02

    • 15.

      15 Dictionaries

      16:54

    • 16.

      Getting Inputs

      17:17

    • 17.

      17 while loops

      8:03

    • 18.

      18 Functions and Arguments

      7:59

    • 19.

      19 Function Alias

      8:14

    • 20.

      20 Classes

      12:46

    • 21.

      What we will make(filled space)

      2:01

    • 22.

      Creating the Story Book

      8:05

    • 23.

      Create the Interface

      12:35

    • 24.

      Select Story and Prompting the Player

      24:53

    • 25.

      Ending and Play Again

      16:07

    • 26.

      What we will make(filled space)

      2:01

    • 27.

      Tilemap vs New TilemapLayer

      5:30

    • 28.

      Creating the Background

      9:10

    • 29.

      Creating the Player

      6:02

    • 30.

      Player Movement

      20:07

    • 31.

      Creating the Vehicles

      25:47

    • 32.

      Player Death and Respawn

      23:33

    • 33.

      Water Death

      7:44

    • 34.

      Water Platforms

      21:56

    • 35.

      The Win Space

      6:59

    • 36.

      Memory Leak Fix

      9:56

    • 37.

      Scoring System

      13:06

    • 38.

      Game HUD Score

      8:19

    • 39.

      Game HUD Lives

      15:25

    • 40.

      Timer and Bonus

      10:48

    • 41.

      Frogger Audio

      10:28

    • 42.

      Transitioning from working in 2D to 3D

      6:03

    • 43.

      Understanding the Differences of 2D and 3D

      4:12

    • 44.

      Similarities Between 2D and 3D

      6:37

    • 45.

      Materials

      14:48

    • 46.

      Lighting

      17:15

    • 47.

      3D Assets

      4:33

    • 48.

      Gridmaps

      15:53

    • 49.

      Creating the Player

      7:10

    • 50.

      Player Movement

      8:05

    • 51.

      Creating Vehicle

      20:27

    • 52.

      Player Death and Respawn

      11:41

    • 53.

      Water Death

      7:04

    • 54.

      Water Platforms

      25:46

    • 55.

      Memory Leak FIx

      4:51

    • 56.

      Win Space

      9:36

    • 57.

      Score GUI and Timer

      19:37

    • 58.

      What is an API

      4:04

    • 59.

      How to Use an API

      5:07

    • 60.

      Script Setup

      6:44

    • 61.

      Making API Calls

      15:10

    • 62.

      RapidAPI Python to GDScript

      19:14

    • 63.

      What are WebSockets(filled space)

      4:53

    • 64.

      Establishing A Connection

      14:20

    • 65.

      Sending Data with WebSockets

      7:46

    • 66.

      How is Desktop Development Different

      4:32

    • 67.

      Anchors

      5:36

    • 68.

      Search Layout

      10:52

    • 69.

      Results Layout

      8:02

    • 70.

      Making A Search

      26:20

    • 71.

      Thumbnails, Titles, Genres

      22:42

    • 72.

      AnimePage

      27:52

    • 73.

      Fonts

      8:42

    • 74.

      Custom Themes

      14:53

    • 75.

      Multiple Windows

      5:13

    • 76.

      Menu Bars

      18:08

    • 77.

      Whast are Particles

      3:29

    • 78.

      Creating a 2D fire

      15:50

    • 79.

      Creating a 3D fire

      14:15

    • 80.

      How to Code any Mechanic

      3:53

    • 81.

      Gravity and Jumping

      10:58

    • 82.

      Saving and Loading Files

      27:52

    • 83.

      Triggers and Pedals

      6:35

    • 84.

      Controller Vibration

      3:26

  • --
  • 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.

450

Students

--

Projects

About This Class

Welcome to the Godot Bootcamp, where you'll embark on an immersive journey to master game development and create powerful GUI-based desktop software using the versatile Godot game engine. Whether you're a beginner or an experienced developer, this comprehensive course is designed to equip you with the skills and knowledge needed to excel in the world of interactive software creation.

Godot is a highly regarded game engine known for its flexibility and robust features. In this bootcamp, you'll dive deep into Godot's capabilities, exploring both 2D and 3D game development techniques. From designing captivating gameplay mechanics to implementing stunning visual effects, you'll learn the ins and outs of game development using Godot.

But that's not all - this bootcamp goes beyond game development. We'll also venture into the realm of GUI-based desktop software. You'll discover how to craft user-friendly interfaces, create interactive applications, and leverage APIs and web sockets for real-time networking.

What sets this bootcamp apart is its practical and project-based approach. Throughout the course, you'll engage in quizzes, hands-on projects, and collaborative group work, allowing you to apply your newfound knowledge and develop a portfolio of impressive projects.

By the end of this bootcamp, you'll have mastered the GDScript programming language and gained proficiency in utilizing Godot's extensive toolset. Whether you aspire to create indie games, pursue a career in game development, or build intuitive desktop applications, the Godot Bootcamp will empower you to turn your ideas into reality.

What you'll learn:

  • The Godot game engine and leverage its features for game development

  • Dive into GDScript, Godot's intuitive scripting language, to build game mechanics and interactions

  • Create captivating 2D games through sprite manipulation, animations, and collision detection

  • Explore the realm of 3D game development, including scene creation, lighting, and character controllers

  • Develop powerful GUI-based desktop software with intuitive interfaces and interactive elements

  • Utilize APIs and web sockets to implement real-time networking features

  • Gain hands-on experience through quizzes, and projects

  • Access a wealth of resources, tutorials, and a supportive community of fellow learners


Whether you're a passionate gamer, aspiring developer, or tech enthusiast, the Godot Bootcamp will provide you with the knowledge and skills needed to excel in the dynamic field of game development and GUI-based software creation.

Enroll now and embark on an exhilarating journey to become a proficient Godot developer!


* frogger assets are attached to project page
** Any version after Godot 4.0 should be fine

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. Course Introduction: Hello, and welcome to the Got to boot camp. I'm Mike Maguire, and I'll be your instructor throughout this course. In our first video here, we're going to go over everything that we're going to cover throughout this course, which is mainly going to be around game development within the GoTo game engine. However, we are also going to tackle a bit of software development where you'll be creating your own desktop applications, as well as branching into things like APIs and websites and have everything communicate across with each other. And all of these things can always be loop back and used within games itself, so we can still consider everything part of game development at the end of the day. Let's take a look at the overview of the Goto game engine. Well, Goto is a powerful and versatile game engine that offers a wide range of features and tools that are very useful for game development. Now, one example of this is something like cloth physics, for example. Let's say you wanted to make a cape on a character. In Goto, you could have that set up in about a minute, whereas in other engines, it would take a lot longer just to get the cloth physics and that working. So that's one benefit that we would have if we were to be creating a three D game that involves things like cloaks, capes and anything else that needs cloth physics. It is an open source engine, which means it is great to use and has a large community of developers contributing to its growth. Now, I emphasize the free portion because some people say that unity is free, and at least at the current time, it's not free. There is a personal version that you're allowed to use up until a certain point once you have a certain amount of revenue or if you want certain features, you would then have to pay. So I wouldn't consider Unity free completely, and other engines that people consider, such as unreal. They do take a portion of your royalty, so though you're not paying upfront, you are paying in the long run. And then we have other engines like GameMaker that are I believe they're on a subscription basis now. So GOTO is completely free from beginning to end. You never have to pay for anything. GOTO also supports both two D and three D game development. Which, of course, makes it suitable for a wide range of projects. It's not going to limit you in what you can do or make things extremely difficult, for example, again, with GameMaker, it's a TD engine. And if you want to do three D, it would be a huge pain in the butt to force it to do that because that's not what it's for. GoTo is meant for both TD and three D, so you're not going to have any pain when it comes to doing that. You just have to worry about how to create your games, I suppose. Alright. Now let's look at the benefits of using Gato. Well, let's explore some of the key advantages of using Goto for your game development projects. GoTo has a user friendly interface that makes it easy to both navigate and work with even for beginners. I offers a visual editor that allows you to create game scenes and manipulate objects and set up your game logic without having to write a whole lot of code. And that's where GD Script will come in where it is very beginner friendly and fairly easy to pick up. Goto's node based system simplifies the creation and the organization of all of your game objects, making it highly intuitive and efficient. Let's look at the Gatto communities and resources. Gatos community is vibrant and supportive with developers from all over the world, sharing their knowledge and experiences. There are various online forums, websites and social media groups where you can connect with other Gato users, ask questions, and find inspiration. One of these main ones is on the Gato website itself. There's a forum specifically for people to ask questions and get help with anything that they're stuck on, whether it's a beginner question or something more advanced. Additionally, Gato has extensive documentation and tutorials that are available pretty much anywhere at this point, making it easy to find answers to questions that you're looking for and to help you with learning new techniques. Now, what are you going to learn in this course, exactly? In this course we'll cover a wide range of topics to help you become proficient in using the Goto engine to create applications. You'll learn the GD Script programming language, which is essential for building gameplay mechanics and interactions, and will be our main scripting language. Now, the reason we're going to go with GD Script over something like C Sharp is GD Script has a better support at the current time, although C Sharp is getting pretty good in their support as well. But GDScript also has a tighter grasp, I guess you could say, to the engines API itself, as well as being much easier for beginners to pick up and get running with. We'll explore both two D and three D game development, including sprite manipulation. Of course, we'll go over novations, collision detection, working with particles and a lot more. You also gain experience in creating a Goey or graphical user interface based desktop software using Goto and learn to utilize APIs and incorporate using web sockets for real time networking. Alright. Congratulations on completing the introduction to the Goto game engine in the next video, we'll delve into GD script, the scripting language that we'll be using in Goto and get hands on with a bit of code. Now, remember, the Gatto community is always there to support you, and I'm here to guide you every step of the way. Let's dive into the exciting world of game development together. 2. Download and Setup: Welcome future developers. If we're going to be developing things using the Goto engine, either video games or desktop software, first thing we're going to need is, well, the Goto 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 Gato from the official website here. Simply go to Goto engine.org, 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 X 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. Alright, so this is the stable version 4.1 just 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 to go ahead and to download this, all we're going to need, since we're 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 write your code in. And 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.net version available. But you don't have to worry about any confusion with that if you go ahead and get it from Steam. Alright, so if you get it from Steam, you can go ahead and just hit the Play button. Or if you get it from the website, you're going to get a zip file, and all you have to do is just extract it and you can just go ahead and start running the application. Alright. When you go ahead and run it, you'll be met with a screen like you see here. And all we're going to do, of course, you're not going to have all these projects and things in your side. But all we're going to do is we're just going to hit the new project button here. And that should give you a new window that pops up just like you see here. And all you have to do is decide where by going into Browse, decide where you want to place the project here as we go throughout the course and go ahead and give it a name. For this, I'm just going to go ahead and call this boots bootcamp. For this purpose, I'm going to go back, and then I'll call it Goto boot camp, and I'm just going to hit Create folder because it has to be in an empty folder here. And there you go. We see we got a nice little green check here indicating everything is fine. We then have three render modes, forward plus, mobile and compatibility. Compatibility is used as OpenGL. As you can see, from the points here, each version has their own pros and cons. But for the most part, you're going to be working with Board plus. Unless, of course, you're doing something you're going to be creating a mobile version or something, then of course, you should use the mobile option here. And if you're working on a version to be deployed on the web of your tool or old hardware, then you would use compatibility. So I'm just going to go ahead and leave foward plus here selected, and we can just hit Create and Edit, and that'll go ahead and create the project and open it up. So that will just take one moment there. All right. You'll then be greeted with the following screen here, and we are now inside the engine and ready to get ourselves to work here. Now, to give you a brief rundown, down on the bottom left, we have the bile system, which is where all of our biles, scripts, game assets, et cetera, are all going to be stored. Continuing on the left hand side here, we have the scene tab. This is where we would visually build out, well, the visuals of our projects. Here's an import tab. So if you need to reimport an object for whatever reason, you can do it from there. Going over to the right hand side, we have the inspector, which will be very important. We'll be in there quite a bit throughout this course. We have the node section, which will allow us to connect some built in signals, and we have a history that we can go back through. All right above that, we have a couple buttons. We have a play button here, and that is to run the project. That is going to run through the default the default scene as if it was being opened through running the executable after the game was exported. The majority of the time, you're going to see me hitting this one here, as run current scene, and that's going to run the current scene that I have selected rather than running the entire project. So, for example, in the middle, you have this tab that says empty. If I built if I built something here, hitting that run current scene, it's going to run what is running in this tab regardless of what my other settings are set to. In the middle, you're going to see this where we have our two D or three D, or scripts, and the Asset library, where you'll be able to come in and you might find tools or new additions to the engine, things like that that might help you in the future, or make your life a little easier. Depending on what it is that you're doing, so keep that in mind, the Asset library could be very helpful, very useful. And, of course, you could always use it to just look at code and try and learn from it. Alright? We have the engine downloaded. We have it running. I'd say we have it installed, but it's not really installed, right? We just kind of unzipped it and opened it up. And we have a new project created, and we're ready to jump into learning about this language of GD Script. 3. 03 Printing to Output added images: All right. So now that we have our project created to give you a quick look at the interface here. On the left hand side, by default, we have the scene hierarchy. So this is our scenes and how the current scene or level, as you might look at it, if you're doing game development looks, and below that, we have our file system, and this is our folder structure and all the files that we have in our project. So this is where we're going to see our saved scenes, our scripts, any textures or other resources that we have in our project is all going to be shown up down here. On the far right, we have the inspector, and this is where we're going to see the properties of each item within our scene. Along the bottom, we have our shader editor. We have our animation timeline, our audio bus to do some mixing. We have our debugger to fix any errors that we need to, and we have our output console that we can take a look at, and we'll be quite useful throughout this course. And of course, right smack dab in the center, we have our big view port. And by default, you can see we're putting the three D area. And at the top, we're just going to move over to two D because that's all we need for this. If we just zoom out, you'll notice this blue box. That is essentially the size of our window. Now, if you want to go ahead and change this, you can just head on up into project settings. And that does not get picked up, it looks like. Let's see if I can toggle in that. There we go. So all we're going to do in here if you want to change the size of your window there, we're just going to come on down and see display and window and viewport width and height. There's what you can change there. And you see this doesn't have a whole lot of settings here, but if we too advanced, we'll get a lot more options that you can take a look at, such as a high refresh rate, and it looks like the high DPI is on here. I know there is high DPI, energy saving mode. So there's quite a few options here that you can take a look at. But for now, we don't really need the advanced settings. I just wanted to point that out for you the width and height here. I'm going to go ahead and I'll just change mine to 12 80 by 720 just to get a nice round and standard number, and being windowed perfectly fine. We don't need to start minimize, we don't need to start maximize. And by the beginning here, it's not even going to be worth really paying attention to. For the first good part of this. But there we go. I'm going to set a 12 80 by 720. And if you set at that, you might notice the blue rectangle change. You might not. And that's only because it's just a really small, minute change there. But yes, anything within that blue rectangle is going to show up on your screen. So to get us started, I'm just going to go ahead and in the scene on the left, I'm going to select user interface, and that's just going to give us a control node by default. If we wanted to, we could click other node, and we can see all the different things that we can add and just selecting control here. We can see all user interface nodes inherent from control. It controls anchors, offset, adapt, position, size relative to its parent. But in general, we can see control is used for a user interface. And that's what we'll notice here, anything related to user interface is going to be colored green. All right, so we'll go ahead and select that and hit Create or hit the user interface button there. Either way, you'll come to this same screen or the same result. And with that, we have a scene that we can add our script to so we can actually start on the code a scene that we can play so we can see our code run, and a scene that we need to save.Quite frankly, so I'm going to go ahead and save it. Control dot C TSCM that's fine. Just go ahead and save it there. And I'll add my first script. Now I'm going to call this printing because that's what we're going to go over here to begin with. Print. Language is on GD script, enhanced control, templates on no default. We could just go with empty because we're just going to delete everything in it anyway, so let's go ahead and go with that object empty and create. Alright, so all we see here at the top is extends control. And that's just saying that this is coming from our control class, and whatever is extending is the type of node that the script has to be attached to. So since it's attached to a control node, it has to extend control. So just moving on down a little bit there. We're going to create a we're going to go ahead and type in Bunk Underscore. Ready? I put a cool in at the end of that. Hit Enter, and just type in the word pass. Now we can remove the error that's appearing there. But this, what we just typed in here is just a piece of code that was removed because we did an empty script. And I can go ahead and show you that here as well. So if you do it the other way, I'll go ahead and delete that script, take it off of the control. And if I add a script to it, again, you can just hit the slide Control and hit the script button here up top, or right click on Control, and you should be able to add it. And I'm noticing that this is not appearing there. That's fine. You can you know what's good because you're able to well, you're seeing it on your side. But if we were to select a node colon default, the template when attached in our script, hopefully, I remember and I'll put a picture up here on screen in case of you guys are a little confused. You hit Create, you'll be presented with this screen here, and all we essentially did when we created an empty one is we deleted all this, and we just typed in this section again. That's all we did. Now, the reason why we're going to use this underscore ready here is because anything inside of this block here, which at the moment, is just the word pass, is going to run as soon as the control here enters the scene, which is already part of the scene to begin with. So it's going to run as soon as we hit our play button. And what you're going to learn here is we're going to learn about the different ways that we can actually print out to AR Console. And why might you want to do this? Well, you can use this to give yourself some information. You can use this to help you try and debug some small errors. And importantly, things that you print out here can actually go to your logs. So your logs, of course, if you've ever had problems with a game or a piece of software in the past and post on a form, you might notice that people ask you to post your log. Well, this is what they're asking for. So let's go ahead and jump into this. And the most default way or plain ways we type in the word print, open and close a pair of parentheses, and in between those parentheses, we can use a pair of double quotes or single quotes. Does not matter, but whatever it starts with, it has to end with. So if we have single quotes here, you cannot type the word don't as you see there, because we're having an issue where the T is not included, and basically, it's stopping here at this apostrophe, the single quote, and then it's continuing after the So in this case, if we're going to have something like that in there, we would need to do double quotes for the start and the beginning, notype that properly. So you can use either one, but depending on what you're writing, it might limit you. So the first thing we're going to type in here is Hello world. Now, this is a staple when learning any programming language that we print out to the console Hello World. So it's kind of like a rite of passage. It's something everyone does when experiencing a language for the first time. All right. So you can come up here and you can either hit this play button here at the top. With the little clapper, and that's going to play the current scene. Or you can hit this play button here at the top. I says Run Project. And if you hit the one that says Run Project, it'll be prompted with a screen to select your main scene, which in this case, we going to use the one that we already have, so you can just go ahead and hit the select current option, and it'll run. You'll notice a window pop up. Hopefully without any issues. And you'll see down in the console down here that we have printed out Hello world. So we've already learned how to print out to the console. So at a bare minimum, you now have your first application. It's not a very exciting application, but it's something that you created that works. Now, throughout this course, if we do print, this is more than likely the method I'm going to go with, but there are a few other things that is worth noting here. And one of those is print with two Ts. And what that's basically going to do is that's going to put a tab between objects. So if we like this and separate our objects with a comma and we go ahead and play this, you'll see in the output, this is now space by tab in between our words. If we have two different objects like this, we can do prints that at the end, one T and an S, and that's just going to put a space in between each object, just like we had initially, where we had hello world as one piece. Now, we also have printer with twoRs and this is actually, I call it printer, but it's more of a print error. And you'll notice when we run this that this actually pops up in our console as red with a little red dot there. So this is something that we can use if we want to show an error in the console. There's something that we can see. And since it's red and the rest of our text is white, it's something we can jump to immediately. And that just leaves us with one last option here, and that is print raw. Now, if we do this, you're not going to see anything here in the console output. But what this does is this is actually going to print out to the console window that's running behind the scenes and should still go out to our logs. That should cover it for printing, being able to do all these printing methods here. So again, we got print like we see here. We've got print two Ts. Boom. S there. And to note, you don't have to have a space after the comma, but just looks nicer. It's kind of something standard that people end up doing. But I'm going we got prints with an S. And there we go. Go ahead and type bed in. What else do we have? We have printer, which is printing your own errors. And we had print raw. So there's all the different ways that we can print out to the console, of course, minus print raw, which would only be useful for us if we're going to our log. But there we go. There's all the different ways that we can print, and that'll do it for this lesson here. And the next one, we're going to go ahead and we'll jump into some variables and or mathematics. 4. 04 Variables: Alright. And this lesson, we're going to go ahead and start talking about variables. And if we have time, we'll jump into mathematics. So variables. What are they? Well, they're something that we can use to represent any piece of data. So like we had before where we had a piece of data that was set and sign a pair of quotes, we can set that to a variable, which would be very useful, for example, if we had a really long sentence and we could just type in one word or one letter, and that could mean the exact same thing. So a variable is a label that you can use to store a piece of data such as what we've printed before with Hello world. So let's go ahead and add that into a script. So let's create a little control. I'm going to add a script here. And I'm going to go ahead and just call this. Let's go ahead and we'll call it variables. And hit Create. And the only one we're gonna need here is gonna be our ready function, of course. And Yeah. Alright, so we'll go ahead and let's just put type pass back in there. And our variables are going to go right here at the top. So to create a variable, all we have to do is type VAR VAR for variable. Put a space in there, and we can type whenever we want here. And this is going to be the name of our variable. So what we're going to put in there is let's let's call it a greeting, right? And at the minimum, that's all we have to do. We can assign it later if we wanted to. Well, we're actually going to assign it right here at the top. So we're just going to say equals. So we'll say greeting equals, and we can put our pair of quotes, and you can say hello new W now, we have ourselves a little sentence here, but we can put that in wherever we put the word greeting. So if we go ahead and we print out our variable greeting, and if we go ahead and run this, You'll see down here in our outbook we're going to get the greeting that we typed up there at the top. Now, you can type in whenever you want here. You can make it as long as you want. And all of this will be represented by this singular word. And if we wanted to go further, we could just make it a singular letter like G and do this again. And as you can see that one letter represents all of that. Now, for the purposes of a variable, especially ones that are top here, using one letter like this is terrible naming because someone comes in, they look at this You can see there's a variable called G, but it doesn't tell you what it is. And a variable should tell you exactly what it is, and as little context as possible. So we'll leave it as greeting because that's what's going on here. We have a greeting that is happening, right? I just Controls to save. So now we have our first program running, and now we're using variables. Now, piece every variable is going to have some type of data that is connected to it. This is normally called the value. Now, it doesn't matter what type of data this is. I can always be labeled as a value. So in our case, greeting is the variable name, and Hello New World is our value. Now, one of the benefits that we have for this is it's a little more work. But let's say we come in here and we wanted to use that sentence or that greeting over and over and over and over again, throughout our code. Can you imagine having to come in here and edit all of these things if you want to make one change to your greeting, then come in here and edit all of these one by one. Well, with the variable, we can just do that right here at the top. So instead of hello, new world, we'll say hello and welcome to the World program. And because we're using a variable here, we just changed that phrase in all of these lines of code at one time. Now, like I say, if we were to go through that one by one, that would extremely suck. As I was mentioning earlier, we could set this earlier or we can set this later, and we can actually overwrite this as well. So we say greeting, which is our variable name, and we'll say equals, I'll say this is my new value. So we'll see that the top grating is going to be what is set here at the top. But then after that, we're going to change what that variable means. We're changing the value of it, and then we're going to print out our new value. If we go ahead and play that, there you go. You can see that there. So we can change it at the top, which ideally you should when you can, or you can change it lower down inside of your script at a later point. You can change it or sign it to something completely different. All right. So that gives us our quick overview here on variables. So what I'm going to leave you on here is that there are a few names, a few rules that you should try and follow when it comes to naming your variables. Now, these rules typically is a variable name. Variable can be named using letters and numbers and underscores, which cannot use any spaces in the variable name. The language will just not allow you to either that to do that, and you cannot start your variables name with a number. That's something to keep in mind there. Avoid you should also avoid using any keywords or function names that already exist within the language, or you will receive an error. And you'll learn as you go through what's a keyword, what's not. And a keyword would be something like VAR there or variable. Now, you might wonder when something like that might come into a situation. But what if you had the wanted a variable called pass to represent password, what you saw when creating the script that pass is actually already a thing, so we can't do that. And last, a variable name should be short but descriptive at the same time of the piece of data that it contains. So as an example, having a variable called name length would be a lot more appropriate and acceptable versus something such as length of my name. Now, they both convey that same information, but one of them is a lot shorter, it's more concise and overall will be seen as a better variable name. Okay now, something worth noting as well when it comes to our variable errors is notice how this is all lowercase. If we had any of this at any point as a capital, as you see, we're going to get an error from up there, and we just see at the bottom identifier grading with a capital G is not declared in the current scope. So what that means is this, it looks like we're trying to use a variable, but this variable does not exist. So capitalization is hugely going to be something worth paying attention to, especially encoding. Alright, so that'll finish up here for taking a quick look at variables. And in the next one, we'll start looking at some of these different types of datas. Namely, we'll start looking at strings. 5. 05 Strings: Alright. Today, we're going to take a look at at strings. Strings is a type of data. So let's go ahead and jump in. All I've done here is I've created a new script, of course, for strings to pertain specifically to this lesson. Now, as programmers, we're both defined and gather some data to store, as you saw previously with our variables, and it helps if we can classify the different types of data. Now, the type that we've been using has been called a string. And a string is anything that falls in between a pair of quotation marks, be that the double quotes or the single quotes that we mentioned earlier. So our hello or rather our greeting variable that we were using was holding a piece of data, and that data can be classified as a string for its type. All right. So when assigning a variable, it is best practice to also assign the type of variable that it is. And if we go ahead and take a look, so if we come back and we have our ba greeting, we set that equal to hello new world like we had before. We can actually set this in two different ways. So we can put a colon after our variable name and type in the type of data we're looking for, which can be a string. And you can see this is one way that we can classify it as a string. Now, alternatively, we can use the Walrus operator, which is a colon right beside the equal sign. We have colon equals. And what's that's going to do is that's going to take our grading and we're going to assign it equal to this piece of data. And then whatever type of data this is is also what we're going to classify it as. So we're going to both classify it to this piece of data to the type of this data and set it equal to this data. So there are two different ways that you can do and it is highly recommended that you do so. Of course, in this language, you don't have to, but especially on much larger projects, this is going to help a bit in performance, being able to classify all the stuff beforehand. Alright, so what we can do here is every class, in this case, string there as you saw when I typed that out, and it changed to this more of a green color. Everything here has a different case. So I'm going to go ahead and create a new variable, and I'm going to call it name with a capital N because all lower case is already taken. So I'm going to say name equals, I want to just go ahead and put my name in there. And remember, we still want to classify it. So I'm going to use the Walrus operator here. So I'm going to say colon equals. Now, everything has a set of methods on it. So if I go ahead and type in my name here or variable, and I do a period, you can see all these different things pop up, these are all things that are related to a string. And the one that we're going to look at specifically right now is called capitalize. If we come in and we just do name dot capitalize, we can see that completed. Now it's blue. We have an open and closed parentheses in there, and our error here has gone away from where we waited there. Now, if we wrap that a print statement and play that we'll notice inside of our output, everything has capitals after every space. So even if I make this as all lowercase, as you see here and we rerun that, you can see it still comes in with. Now, capitalize is something that you should do for things like names and titles, as you would expect. Now, with the name capitalize, you might be a little swayed to think that it's going to make everything a capital, but it does not. And this is where Python kind of does that better because they call it title, which I feel is more appropriate. In this case. But either way, you notice that's how capitalize works. And likewise, we can make it all capitals and we can make it all lower case. So all we have to do here is instead of calling capitalize, you can say we can do two underscore upper. And if we run that, we're going to have all capitals. We're missing one parentheses there, which is what our error was telling us down there at the bottom. Now if we take a look so we see everything is now in caps. And if we did this the other way, so if we have all caps, and we did to underscore lower with our open and closed parentheses, now everything is going to be in lowercase. So we can make things capitalize. For things like titles and names. We could make things into all upper case, and we can make things into all lower case. Now, with strings, we can also add these together, and we can use something called we can use what's seen as a placeholder. So for example, we come back in here. It's going to hit Control Z or Control Z back that up till we have all lowercases here. And let's say, for example, we want to print out a greeting. We want to say Hello. Welcome to programming, and we want to put in the name here. But we also want to put in. We want the name to be dynamic. So we might not know what the name is by the time we get or we should know what it is by the time we get to this point. But we might not know what it is at the start. Now, this could be because our user hasn't input hasn't told us what it is. Or it's just something that we haven't that we may change later on. But all we're going to do is we're going to do percent sign and lowercase S. Now, this is a placeholder for a string, and all we have to do is outside of the quotes, but inside of our parentheses still, we do a percent and we could type in our variable name here, which is just name with N. And if we run that, we can see that's going to insert where that percent S is with whatever the value of our variable name or the value of our variable. Now, this changes up slightly. If you want to use multiple variables, so we'll go ahead and say create another one. And we'll say let's call it job and we'll set that to feature, and we'll say, Hello, welcome to programming percent S. You are a percents. Now, you might think that we could just do another one like that, or you may think we just do another percent job in there. But really, what we do is we have our percent sign here, and we use square brackets. Now inside of here, this is where we can put all of our variable names here, separated by a comma in the order that we want them to appear. So if we run that, we can see everything gets filled in, and you want to make sure that you fill that incorrectly because again, the order that you fill it in here is the order that is going to be filled in in the sentence. And obviously, this doesn't make sense. Welcome to program teacher. It doesn't sound right. So just kind of keep that in mind. Also noting, if you have multiple things here, such as if we go like this, right? If we have too many variables listed, it's perfectly fine. We're not going to run into any issues. The only time we're going to run into an issue is if you don't have enough. That's when our error is going to, I suppose they don't have any errors in here anymore. What you see? I know, there it is just not showing up as an error. Which I expected. But here in the console, rather, it says not enough arguments to format string or for format string. So it's telling us that we don't have enough arguments here that really should have appeared more as an error. But you can see it does pop up. Just put those back in the right order. So if you are filling in information, just make sure you have enough information and you're filling it in in the right order. Now, I'll say alternatively, you could fill this in in another way. However, it takes up more room, looks more cluttered, tartar to read. And by that, we're talking about doing basically this addition. All right, so like this, boom, again, so we can do something like that. And you see, you can do it this way, but it looked a little more problematic or not as nice looking, but you can certainly do it this way. And I'm missing a space between there and here. And you'll see if we print that out, that's going to give us the same result. So that is two different ways that you can use your variables inside of your strings. All right. So that'll do it for strings. We're going to go ahead and move on to looking at some other variable types next. 6. 06 Integers and Floats: Alright. Today, we're going to take a look at numbers, as you can probably see by my script name. There? Now, numbers in programming can be broken down into two different categories. Now, numbers in programming or rather they're used in programming for all different kinds of things such as keeping score, different kinds of game mechanics, algorithms, visualizing different data, some of the things that you looked at that are art or shaders that may have all come from just math. Now, these numbers are either going to be called an integer or a float. Now, a float may also be called a real number. So if you ever hear someone talk about real numbers, they're probably talking about floats. Let's go ahead and start with integers. Integers are a whole number. Now, their class, if you wanted to create a variable, let's say binuM if you wanted to create a variable for this, an integer, it's just shortened down to INT. That's it. And a float is going to be classified just as that as float in all lowercase. All right. So if you want to create a variable, those are the two ways that we do that, and I'm just going to create another one here just to have them here at the top. So you can always take a look at it. Now, when we're printing things out, we can print out numbers. So if we type in five here, go and print that out, we can see five comes up in our console. Now, what may be a little different is we can actually perform math in here. So if we say five, that's ten, and maybe we want to put a space in there, make it a little more readable. Take a look. That's going to print out our total here of 15. So we can actually perform a subset of math within thes. And we can do that with addition. We can do it with multiplication. We can do it with subtraction. And of course, we can do it with division, as you can see there. And you see division in this case, has given us a debugger, and that's because integer division goes into a decimal part. The decimal heart will be discarded. So this doesn't go unevenly. This actually returns to us a float. And since we're dividing two integers, we actually did not get that out to us. So we got zero, but we did not get anything after it. And that's what that error is telling us there in the debugger. And we'll get to that when we touch on floats here in a moment. But what we can also do is we actually support exponents and square roots. So example here, we can do P, which gives us a number to the power, something else or an exponent. So if we say two, we put a Tama. As you see there, we have our base number followed by our exponent. If we say two to the power let's go with five. All right? We're going to going by the rules of exponents, we're going to have two times two times two times two times two. So that would give us two times two, which is four times two, which is eight, times two, which is 16, times two is 32. So if we run this, we should get 32 as a result. There we go. So we see that we do exponents out. Likewise, we can also get the square root of something with SQRT, and the same situation here. Similar situation. We pass in one number. In this case, we'll do with 32. And we pass it in. We'll see what times itself will give us 30 or yeah, what times itself would give us 32. What is the square root of it? And we see that gives us a float here. 5.6 5685, 42, 4942, three, eight. That is a long number, but if you multiply that number by itself or with itself, you will get 32. As you see, we gave it an integer and we got back a flow. And with square root, that is certainly possible with exponents that's not going to happen unless, of course, we use a float to begin with. And as you can see, square root is expecting a float for the first argument. So that is why this is essentially being converted into a float, which would be the same as doing 32.0. In this case. Now, you can use any combination of math that you want in here, so you can use any combination of using all those together. Let's say, for example, we have five plus in parentheses three to the power of 7/3, and then subtract nine. Now whether we're using bed Miss, bod Miss PEMDS, however uber taught the order of operation, we're going to be looking at our brackets or parentheses. They are parentheses. I don't know why some places call the brackets, but parentheses. So in that case, we're going to be looking inside of here first. Then we're going to look at the exponents. So the first thing we're going to do is our math here. So three to the power of seven. And then we have to do what's inside the parentheses. So then we need to divide it by three, right? Because next up is our multiplication and division. In this case, we just have division, so we're going to divide that by three. That leaves us now with five plus our result here, and then subtract nine and addition the subtraction could be done same time, just going left to right. And if you do all of that math, you'll get an output of 725. All right. So it doesn't matter. The order that we do this in well, the order that we type it in. The order is going to be done in the correct way, and we can mix and match all different Basically, you can do any mathematical formulas in here. All right, so now when we look at floats, I said that we had five minus ten. So if we come back here to this situation, we had five minus ten, and we do that and we got a little debugger, sorry, not minus divide. And we got a little debugger saying, Hey, this is the float and everything app to zero is being left off. Well, what if we want that? Well, we have to convert one of these into a float. So we either have to do we have a solid number like this. We can do 0.0 on one of them. And you see now we can actually get our decimal number. Or what we can do is we can do dot, and they still have this? No, they do not. Does not appears. So what we can do is we can just type in the word lot and surround one of our numbers inside a parentheses. That's going to convert our ten into a float. So we can do it that way as well. If we don't necessarily know what the number is that's being input into it, if that makes sense. So if you have a user typing numbers in, you don't necessarily know if that's going to be an integer or float that the user types in. So we can just convert it at the time, right? So that's how we would fix that issue there. We simply just convert one of them into a flow. Now, in code, any number that has a decimal point is called a flow. And we use this term in most if not all, the programming languages like I mentioned earlier, they can be called a real number. And all languages must be carefully designed to properly manage these decimal numbers. As a user, of course, just using the language, you don't have to worry about how the language is handling it. Just know that it is being handled. And as long as the language is handling it well, that's all you need to worry about. Now, any of the mathematical expressions that we looked at already, we can also do that with floats. They're not exclusive to integers. And as you saw right there with our 5/10, and we converted one into a float, you can use integers and floats together at the same time. 7. 07 Constants and Comments: Alright. Now, before we move on further, I do want to talk about a special variable called constants, and I want to talk about comments. Now, these are small topics, so I'm just going to do them both here in the one video, and should only take a couple of minutes. A constant differs from a variable. Now, you remember when I said that we could change what a variable is or we can change its value at any point. Well, a constant is a special variable, and this special variable cannot change its value once it is set. So once that value is set, it can never be changed, and it just is what it is. So if you do try and change it later, we should run into an error that appears in our code. And we can go ahead and take a look at that. And all we have to do to create something called a constant instead of a typical variable is we do CONST instead of VAR. And as you see, we got some pop ups showing up down there at the bottom. Don't worry about it. But constant we can call. And again, if we call it MOM, and see, we still have an error here because it's expecting me to set the constant to something. So if I set that to say five, pool in equals five, see, now the error goes away, the constant has been set. Now, the issue here are not really an issue, but if we come down here, we try to set my num to a different number, let's see if the error is, it is. There it is. So you see you cannot assign a new value to a constant. Is what's showing up down there. And we see this at line seven character five. One, two, three, four, five, so at the end of our variable name because we're trying to set it at the end of the name, which makes sense. That's how you set things here. So we're going to come up with this error. So you only want to use things with consent that are not meant to be changed. Such as if you're creating a game or an application that has an online connection between users, you're probably going to set this to a max amount of users or a max amount of players for each of your servers. So you only want to use constants for things that'll never be changed. Pipe pass back in there again, clean those issues up. Now, a comment. A comment can be both good and bad. So they're not exclusively one way or the other. It just depends on when you should and shouldn't use them. Now, comments are like minor notes that you can leave to yourself to explain what is going on within the piece of code, why you did something in a specific way or whatever else you need. Now, a comment is actually on the screen right now, and you've been seeing it this entire time. Comments can be useful for any future developers that have to look at piece of code that somebody else has done, or maybe you worked on it at one point, then someone else is coming to look at. And a comment, as I said, it is already on screen, and has this you may know it as a hashtag symbol, or if you're a little older, you may know it as a pound symbol. And we set up right above where we have our underscore ready. We have this hashtag and it says called when the node enters the scene tree for the first time. Now, that, since it is prefixed with that hashtag symbol, this is a comment in this language. Now, in some languages, you may have to do the double slash, like so to create a comment. But in GD script, we just have our little hashtag symbol there. Now, you can also use this to comment out a line of code. And the reason we can do this is because anything with a comment it's been commented will be skipped when the code runs. So if we have print and we print out, mind num here, if we go ahead and try this, it's going to get printed out as expected. But we can also put this little hash tag here, and it is commented out. Now it's just complaining because we don't have anything after our ready function here, so I'll just go ahead and put the pass back in there. And you see now it does not get printed because it gets skipped Now, what if we have a lot of code? Maybe we're trying things. It's not working out. I want to try a couple of different methods, but we don't necessarily want to get rid of the attempt that we already tried. Well, we can actually comment large sections of code with a shortcut key. And to do this, all we have to do is we're going to highlight all the chunks you want. Say we want that, we want to keep the ending in the beginning. All we have to do is highlight these pieces and press Control K. Now, if you want to back, this might be Command K, I know they like to use command instead of control, I believe, for a lot of their shortcuts. In general, Control K doesn't work. Try Command K. But that's all we have to do, and that's commenting out that entire section. Now, likewise, if we highlight all those and we hit Control K again, we can uncomment all those at one time. And Alright, so there's comments and how they work. Later on, we'll talk about a clean code more towards or closer towards the end of this course, where we'll go over a little more about when you should use comments, when you shouldn't. What are good comments, what are bad comments. But for now, that's what comments are, and those are what constants are. I just wanted to let you know about those. And we'll move on. We'll see you in the next one. 8. 08 Lists: All right. Let's go ahead and take a look at a list. Another name for these are also array ARRAY, but most commonly referred to, at least from my experiences as a list. So what is a list? A list is a collected group of items that get put in a particular order, and you can make a list that contains any type or any combination of different datas. So we can have integers and floats and strings all combined together into one list. Now, your list does not need to be related. The elements don't need to be related to each other. However, it would make sense if they were. Think about if we had different kinds of pizzas, right? And each one of those different pizza types had a list of toppings. And then they had a some other random element on there. They had who made it or who makes that specific type. It's not really related, so you probably there's probably a better way to handle that kind of situation. But lists are indicated by their square brackets, just like when we were using our variables inside of our strings with those placeholders, a list is surrounded by square brackets. And those square brackets, each item is separated by a comma. So let's go ahead and take a look at a list of groceries. Let's go groceries. We have our square brackets, and let's go tomatoes. Or, you know what, let's just go singular. We'll go tomato, pickles. Drop and buns. Alright, so if we were to print this out, If we were to print out these groceries, you'll see that we're going to have square brackets down there in our output. You probably don't want the square brackets. You probably don't want, that kind of an output. You might be looking for an individual item. Well, let's take a look at how we can access individual items from this list. To access an element or an item within the list, we just need to tell GD Script the index position of the item that we're looking for. So if we go ahead and print this out, so if we do groceries, we put a pair of square brackets after that, and we can now put in a number. And these numbers will actually start at zero. So even though we count one, two, three, four, a computer is going to start at zero. So tomato is going to be zero, pickles one, ketchup two, and buns three. So if we do groceries zero, and print that out, we see we're going to get tomato in there. If we do row shoots one, we're going to get pickles. Now, if we go out of order, for example, if we go four because we count one, two, three, four items, we're like, Okay, we want item number four, we're going to have an error because four would actually be the fifth item. So what we really want is three to get that last item there, or buns if you're getting the wrong item, just make sure you're going for the index value and not the item number. I've seen quite a few people get confused by that or get confused on that mix up. Now, since in this case, these are strings, we can use things that we've learned before. So we can use like two upper, for example, and get an upper case. Oops. Here we go. As you can see there. We can also to lower, capitalize and all that. Let's see once we put this.in here, we are getting a good list fantastic. But you can see all the normal stuff that we have in there with all strings. So we can do our upper or lower capitalize. Now, what if you want to keep everything to a set type? So setting this to a list like this would be the equivalent of going like this and setting it to an array, which is fine. An array can all different kinds of items. But if you want to narrow it down even further or maybe just want to squeeze out that slight more performance, what we can do when we're declaring it as an array, we actually type it out like this. We give it the square brackets, and on the inside, we declare what type can be in here. So in this case, all of mine are strings. So I'm going to use string for the inside. And what this means here, the square brackets element tight, and then square brackets again, theta tight right beside our declaration of an array tells our script or code that only a string can be in here. So if we put a number, an integer, we're going to get error. So this is how we can narrow down our list to a specific type and squeeze out just that very slight more performance, that little extra. But again, unless you work on something that's more of a big project, probably won't notice. And thus, just calling it a normal array or using the Walrus will be fine. Now, something that I didn't mention before is when we're looking at strings, we can actually get the length. So if we get light, like so, we'll actually get the length of that character or that item. So in this case, we go for index three, which is buns. We want the length, and that's going to give us four because we have four characters, B, U, and S. Now, what's different is a string. You can access the index of a string as well. So if we were to come in here and ask for Index one, of that string, we're going to get the letter U because each character has its own index within the string. So B is zero, U is one, N is two, and the S is three. So we're accessing the third element. We're going into our groceries, getting the third index value, and we're getting the third index value of that item. Hopefully, that makes sense, and it's not too confusing. But if you want just the front or the back of a list automatically, we can actually get the index of negative one, and that will always give us the last item in the list, which in this case, buns. But alternatively, we can also on our list of groceries, you can just kind of dot front. You get the first item, which would be tomato. Ooh. We need one more parentheses there. We can call dot front for tomato, and we can call dot Bat. We get the last item in the list. So if you don't want to use an index, you could just call dot front or Dot Back if you want to get the first item or last item. Now, since in this case, they're all strings in that, remember, we can still use them inside of a sentence. So we'll be like, honey, we still need to get some, and we'll use our percents, and therefore our playder and now we can just go ahead and insert what we need here. So we can go ahead and we can replace the first placeholder with groceries, and we'll call that index. Let's go with index two, and then we can call Let's go with capitalize. Now if we print that out, I'm missing one parentheses on the end there. Go. So now we can see our statement here. We have our item being inserted in and it's being capitalized. So we have a capital K to start out, which would work nice if we had a list of brands, for example. And of course, you can do this and fill in multiple items as well. All right, so that'll do it for introduction into lists here. We'll continue on with some more features in the next video. 9. 09 Adding and Removing: Alright, we're going to continue using our same script for this one, since we're still talking about lists, and we're just going to go ahead and talk about how we can add we're going to go ahead and talk about how we can add items to our list. So to do that, we're looking at it, and most lists can be most lists that we create are dynamic, right? Which means they can be modified. We're using variable. We're not make it at a constant. Obviously, a constant cannot be modified. And the majority of the ones that we're going to create are going to be to zivar which will be dynamic, which means we can add and remove items to and from that list. Now, you might use a list to keep track of what quests a player has in a game, for example. Thus, you need to be able to add new ones, remove ones once they've been completed. In terms of data, we may use a list for registered users. Now the simplest way for us to add to a list would be to call the method append. So if we go to groceries, we can call a pen so dot append, and then whatever we type inside of here will be added to our list. So if we go ahead and add in, let's go let's go with some Pringles, right? We type that in. Let's go ahead and print our groceries before and after. And we can see the difference before and after it's been added to the list. And you see a pen is going to add an item to the list, and it's going to add it onto the end of the list. So it's going to end or add it to the back of the list. Now, using a pen allows us to easily and quickly add items to a dynamic list, which is fantastic. And that means we can also start with an empty list. So if we come in here, I'm just going to comment that one out, so we can go with the same thing here. And we're just going to make this an empty list. Now, if we start with this Z we can start with something empty and we can add into it. That'll also work. It's just as easy. And creating a list like this is common, so we don't always know the data we need to add until the program is running. Sometimes we have a set list of options, and other times maybe we're going to add to a list in the future. So it's always good to know how we can add into it. Now, what if we want to insert into a list? We don't want to add it to the end, but we want to insert into it. Well, instead of adding an item into a list, we may need to insert an item into a list. And to insert an item into a list, it takes two parameters. And that just means two things that we pass in. So when we did a pen and we put one item in here, this would be a parameter. And when we insert an item, it's going to take two of these parameters. So going back to our old list here again, Just back that up. There we go. And the position of the first is first position and second the value. So we're going to go ahead and call insert on here, and we can see. The first thing we put in is the position. So let's say we want to put it in position two, in index two. So right now, index two is ketchup. So we want to put something in between pickles and ketchup. So we're going to have pickles, our new item, and then ketchup. So after we put our index, put a coma, and we put in our new variable or sorry, our new item, which I'm going to go Pringles again. And if we print that, we can see pringles was put in between pickles and ketchup. I was inserted as index number two. So not only can we add to the end, but we can insert an item at a specific point inside of our list. Now, when a new item gets inserted into a list in our case position, one of our items gets put in between, well, in our case, two and three, and we have a brand new item. Fantastic. Now, the fact that we can add to list and insert into a list is great. But what if we need to remove an item out of your list? Well, we can easily do that. All we have to do is call dot remove And in this case, with the new system here, it pertains to remove at. And we just go ahead and pass in the index, right? So if we pass in two now, we pass in two. This is going to remove ketchup, so we're just going to have tomato, pickles, and buns. That's what we should have when we run this now. So there you go. We've remove the item at index two. So removing items is fairly simple, as you can see there. Now, there are going to be cases where you want to you may want to get an item and remove the item at the same time. And we could do this in multiple lines of code, but we don't have to because we can actually pop this out. And I say pop because that is the name of these two methods we're going to learn here, and that is pop front and pop back. So if we do Pop, underscore, front, and you see when we print groceries here again, the first item is going to be missing. But this actually not only removes it, similar to the remove, remove that that we just did. But this also returns that front item. So if we were to store this in a variable and call this item, this is actually going to return that, and that first item in our list, which will be our tomato that gets removed, it's going to be assigned to item. So if we print item afterwards, we're going to get that tomato. And it's the same concept. If we pop from the back, we're going to get the last item, which will be buns. So items will be equal to buns. All right, so it's going to go ahead and yell at us there. So what you would want us to do is because it can't imply what the type is, we would have to declare it manually like this. So there are some situations where you won't be able to get with that automatic inferred declaration. And you'll have to do it yourself. This is one of those few cases where you would need to if you choose to go that route, which you probably should. Again, just something to get used to. That way, you can always get the maximum performance that you can. That way, if you reduce the amount of optimizing that you'd have to later. And the last thing we're going to take a look at in this video is we're going to take a look at how we can erase an item, even though we don't know or where that item is in our list. If I just we're going to go back to printing out our groceries again, and we don't need that variable anymore. What we're going to do is we can call dot eras. And for this, we can actually just type in the value. So we can come in and we can say Keto. Now, remember this is case sensitive when it comes to springs. So a lowercase K is not going to be the same as an uppercase. Though to us, it looks the same, or we would consider it the same. In code, there are two completely different things. So if we call erase and just pass in the actual value, we can go in and we can see that is going to be erase no matter where it is in our line. Now, you may think, what if we have multiple values that are the same, and we call erase? Well, it's only going to delete or erase the first instance that it comes across, so it's going to through it's going to say, is this matching what we're looking for? No. Is this, no. Is this Yep and delete. And it's going to stop there. So if you wanted to erase multiple, you would have to keep going through at this current time. We will learn a better way if you wanted to erase all instances of a specific value. But for now, it's only going to remove one item. All right, that'll do it for today's lesson or this lesson. We have just a little bit more to learn about lists before we can move on. So one more lesson coming in. 10. 10 Pushing and Sorting: Right now on our final lesson on lists, we're going to be looking at the push methods and how we can organize our list and getting the length of our list. The push method, there are two of them. They allow us to alter the contents of the list. There's push front and push back. Both take one argument and that is a value. Now, when using push front, our value gets added to the beginning of the list, just as if you were to use insert at index zero. Likewise, when we use push back, our value gets added to the end of the list, much like when we use append. So if we were to take a look at this, we can then take our groceries and we can use push front, and we'll add in our Pringles. And if we take a look at that now, we'll have pringles pushed to the front of our list. And likewise, we could use push back to get it sent to the back of our list. Now, personally, I usually just end up using a pend when I want at the back of the list. But we do have the alternative pushback to put it in the back end, of course, push front instead of insert in deck zero. The push methods are that simple. It's not a new concept. It's just two more methods that you can think of as an alternative way to do this. Now, when it comes to organizing our list, you can see that in most cases, our lists are created in an unpredictable order as our program runs and as we add things to it. And you can't always control that order, especially if you're having the user input a bunch of items. And because of this, the problem becomes unavoidable, really. But we are in luck. Inside of GD Script, we are allowed to sort our list using a simple method just called SRT. Now, SRT will begin sorting out our list in an alphabetic order, and this counts for numbers as well. It's going to go in order for our numbers. Now, it's worth knowing that numbers get included here in other languages, having numbers such as a list that contains one, three, and 025 or 025 would get sorted in the order of 1025 and three, whereas in GD script here 025 and 25 are read as the exact same number, allowing our sort to be a little more accurate than there may be in other languages. All right, so let's take a look if we run sort, and then we print it again. Afterwards, we can take a look at it and we can see the normal look, and then we have a sorted look that comes into play here. Now, this also runs in with our numbers. So what happens if we have numbers like this running, and we try to sort. Well, you see, we're going to run into the error here. Because it's not really compatible for the sorting we resolved. So what we would need in this case is we could have two separate two separate lists here. We'll call this one numbs. We'll do our one, 95, three, 287. And if we were to sort this one, we can see all of our numbers will get sorted out just as we would expect in order. So one, two, three, 87, 95. So we can sort a list of numbers and we can sort a list of strings, but we cannot sort a list that has numbers and strings. So we need a list that's one or the other. If we have a list that contains both then we kind of got a problem going on. We just have to accept the fact that we're not able to sort it, and maybe we should go back and rethink how we're organizing our lists that we need. Now, what we have as well here is we can take a look at the length of a list. Now, length when we get the length, this is actually going to give us return a number to us. And when it comes to a list, it's actually called size. So if we print out the size here, we see we're going to get a number. In this case is telling us five. Now remember, we have index zero, one, two, three, four, but the amount of items we have are one, two, three, four, five. And since this gets returned back to us, we can actually store this into a variable, and we'll call it List. We should probably call it list size. But here we go. And then, of course, it's just like any other variable, and we can go ahead and just call it in. If you need to get the size of a list for any reason whatsoever, and there are quite a few reasons that you'll come across to your journey that you'll need to know the size of the list while your list can dynamically change, Alright, so that covers everything that we're going over here with list. So we're now done with list, and we're going to move on. We're still going to use our lists, but we're going to cover a completely different topic now or in the next lesson. Alright. Take care. And if you need to go back, review this. The list section here had a lot of things to go over. 11. 11 for Loop: Now that we know how to create our list, edit them, add to them, remove from them, and get specific items out of our list. Now we can take a look at another feature set, another basic coding term, we're going to be talking about what's called a four loop. Now, there are oftentimes where you may need to perform the same action on every item within your list. For example, if we wanted to list out all of our items, we would need to come in and print all of these things out, right? So let's go ahead. Come in, groceries, and we're going to need index zero, and we'll just copy this down. One, two, three, and we can remove that editor. They'll say index one, index two, and index three. So normally we would have to go through and do something like that if we wanted to list them all out. Now, this is tiring. It's needless or needlessly takes up a lot of space. By the time we've gone through them all, and honestly, looking at the code, it's not a very attractive code, looking at the same thing happening over and over and over and over. But when you want to perform the same action on every item inside of a list, we use what is called a for loop. So looking at our groceries list up there, we can see that it's full of items, and if we add anything to it, we're going to have to add another print statement, another one, another one. Anytime we remove it, we're going to have to pull or delete lines out of there. It's a hassle, it's annoying to maintain. But we're able to automate this process within this four loop. So if we want to print things out just like we're looking at here, all we have to do I just comment that out real quick. As we say, or, and you notice that's going to change color. We have a keyword here. And the next item here is you can use pretty well any variable that you want to use here. This is a completely new one. If you want to do something to help you keep things clear, you can use item, but a popular popular shorthand is just using I and I stands for item. Now, we talked about variables and how your name should it should speak to the person, you should know exactly what it is just while looking at it. And it's become common practice to use I to stand for item that once you get into coding, you're going to recognize what that is. And also, if a variable is only going to be used in one spot, such as in this one loop, it's okay to have your variable be shortened like this. But going on, so we have four, we have a variable to represent our items to four I or four item, we say N, groceries. And what this is saying is every time we go through and do whatever block of code we write down here, I is going to be equal to tomato, and then I is going to be equal to pickles, then I will be ketchup, and then I will be buns. So at the end of our for loop, we can put a colon, head enter, go down to the next line. Now, you notice how we are now indented two levels now. This is our first time having to indent a new level, so make sure that your indentation is correct. When coding in some languages, they use the curly braces, but in languages like Python and GD script, we use the indentation method. And I've seen quite a few people come up with errors or tell me something isn't working when their problem ends up being that they're not indented enough or they're still indented and then come backwards then come out. So do keep an eye on that. And let's go. So for item in groceries. All we want to do is we want to print our groceries, right? We just want to print that item. And that's it. That's all we have to do print, pass in I for item. That's all we have to do, and we're going to get the same result as you see here, now, the difference is is we can go ahead and we can add as many items as we want to this list. So we can come in and go like this. Again, you see how many items we have starts getting ridiculous. And this happens when we start adding or appending more items into our list. And you see, I don't have to change my code at all, and they all get printed out. No problem. Same as if we were to delete them all. And go down to two all of a sudden. We only have those two print out, we don't have any issues. Was back with this print setup, we're going to have issues because at this point, when we had all of these items in there, we would have had to come in and create a bunch more print statements or whatever it is that we want to do to each entry. And now that we're down to two, we would have to come in and modify our code and remove the bottom two lines here. So whenever you want to run the same code on multiple items inside of a list, we're going to use a four loop for that. All right. So hopefully that's clear. Inside of our four loop, our first item here is a variable, commonly referred to as I, but you can make it whatever you want. Stands for items. So for each item in groceries, we're going to print that item. So I is going to be equal to tomato. And then once we print it out, I is going to move on and become pickles, and then we'll print it out, and then it moves on to the next item and so on. Just back this up here. There we go. Now, what if we want to do something after this four loop has completed? Well, we're going to hit Enter to go down to the next line. And you see how we're still indented two lines. Well, what we can do is we can hold Shift and hit tab to, I guess, outdent, right? We go back one level, or you could just hit the back to base key once and that we'll also take you back one. And now you can see that the carat here is lined up with the four loop. That means we're outside of it. So we can go ahead and print now and say, four loop completed, and we'll see that's only going to happen after everything else has been printed. So if you want to do something outside of the four loop, just make sure you pull your indentation back a level. Now, to help you avoid errors, make sure that everything as I was saying, as I said earlier, make sure your spelling is correct for things. Capital G for groceries and a lowercase G for groceries. Though to us, they're the same thing. They's both groceries. They are, as far as code is considered, two very different items or two different variables in this case, and same with our I there. So we say four I to lowercase I, we can't print to capital I. It's not going to know what that is. And we're going to have errors from there. And then, of course, our indentation levels that we just went over. All right? So that completes that on as far as a basic four loop goes and principles of it. Now, you can do the same thing if we had set of numbers here. If we were to come in here, you can come in. Just put a bunch of numbers. Oh, this minum. So now, when we do for I and minum, I is going to represent the numbers three and then 675 and then 23 67. So since we now have numbers, we can also do math with that, so we can say I plus 100. Keep things simple. And there we go. We can now see printed out 103, 775, 123, and 167. And then our print statement afterwards telling us the four loop has been completed. So if you don't have a string and you have something like that, you could perform some math. You have numbers. Of course, with strings, if you really want, you could insert them into a placeholder, if that's what you wanted to do repeatedly. All right. So that gives a quick look over what a four loop is and how we can use it. 12. 12 Range: Something that we can use a four loop with. Typically, when we want to do something maybe a set amount of times, but we don't need a list. We don't want to go through a set number of lists or a set list of items we just want to do something a set amount of times. Well, this is where things like range come into play. Now we can use range to get all numbers between a set of values if we wanted to. And this would require a couple of arguments pressed in. If we take a look at range, we can see this, well, in this case, just has three dots at the moment. But the first argument is going to be the lower number. So if I say ten, then that takes a second argument, which would be the higher number, so let's say 20. So this would give us a range 10-20 so let's go ahead and print this out in the form of a let's say 44, let's say, N for number four N in range. And let's print N and see what we get. Well, if we look at it, we see we got ten, 11, 12, 13, 14, 15, 16, 17, 18 and 19. So you don't get the last number that's printed out here because once we get there, if you can imagine it, if N would be equal to 20 and 20 is not 10-20. It is 20. So it does not get printed, and the four loop ends. Now, likewise, we can come in here and we could put a range of what if we put a range of just 20? We print that out? What do we get? Well, we got the same thing. We only go up to 19, but we're starting from zero. So if I wanted to do something 20 times, I could put in the number 20, and it would happen. It's just since we're starting off with our index at zero, starting counting from zero and not counting from one. So using this, we're able to go through a set range of numbers either from zero up to a number or all numbers between a set range. Now, you can do this for if you want to repeat a specific action. You could do this if you want to do or loop through it based off how big your list is, right? Because we know how to get the length of that now by calling size. Anything that can give you back a number, we can plug it in here. That's really all range is for is to give us all the numbers within a set ring and then the four loop has us going through. So one thing that we can do with this is, for example, let's take a look, and we could print out or rather, let's go ahead and create a variable. We can create a whole new list here. So we'll call this square, and set this equal to an empty list. And what we could do is we could then do square pen so we can add to our list. And what we're going to add would be an exponential value. So we want to add all the squared numbers. So numbers 0-20 all squared up. So we would put that in a Posh do exponents. So I'll say N for whatever number we have here. With the power of two. And we want to print the inside? No, we'll print on the outside. We'll go ahead and print square. All right. So we have an empty list to start off. We're going to go through every number 0-20, and we're going to square. So we're going to say zero squared. Whatever that equals is what we're going to add into this list. Is going to say one squared, that equals will go in, two squared will go in, three squared, and so on. So if we take a look at our list now, you can see we got zero, one, four, nine, 16, 25, et cetera, all the way up to 361. So range is a way that we could add some numbers into a list or create a list based off of something that already exists. So preexisting value. All right. So that's about all we can really do with that. So there's four loops and how we can use them list with a list. And there's four loops and how we use them with range to repeat a set of instructions or a piece of code for a set amount of times. 13. 13 equality: Oh the core of every check. So very important part here to coding is going to be the if statement. And these are the kind of things that we would run through in everyday life where we check if this happens, then we do this. Otherwise, we do this, right? So for example, just using your computer there. If you're in editor, if you press K, we put K on the screen. Right? If we hit backspace, we delete the previous character. That's the general idea of how an if statement works. Now, an if statement is always checking to see if something is true, right? So if we press K, which we did, we pressed it, which means that is now true. Then it's response was to put K on the screen. So in order to get these checks, we have to use if statements with what is called an equality check. Now, an equality check is basically check if two items are the same. And we can check if two items are the same, easy. We come in, and we do a print. We can say five equals five, right? We can do that, and if we print it out, we're going to get the word true. Now keep in mind when we do an equality check, this is going to be a two equals, double equals sign here. So if five is equal to five, so if five and five are the same, we're going to get through. Now, if we check for five equal to six, we're going to get false because five and six are not the same. They're two different things. And this counts with printing as well. This comes back to our statements earlier. So if we have tomato with a capital and we check if that's equivalent to tomato with a lowercase and we print that out, you see we're going to get false because even though to us, it's the same word because one has a capital T and one is a lowercase code sees it as two separate things. So they would both have to be capitalized to be true. So that's all the equality check is. It's checking if this is true or if these two things are the same, then we can do something. So let's go ahead and jump in, right? We can say if, and then you can type in. So if we do our tomatoes again, tomato. Double equals tomato. And then we end this with a colon and we enter to go on to the next line. So now we're indented one block. So whatever we put in here is going to happen if these two are true, right? If this condition is true, we do this. What we're going to do is we're just going to print a string. These two are true. So if we were to print that, we go ahead and start it and we notice it doesn't print because as we went over, T and lowercase T make a difference, so they are not true. But if we add apt T in there, then this indented block is going to run. As you see, these two are true are now printed out. Now, aside from the equality check, we can also do an inequality check. And in the case of this year, where we have an uppercase and a lowercase, remember, we can use two lower. So in this case, if we want to see if these two are the same, we can say if capital tomato is equal to lowercase tomato dot capitalize or true, which they would be because it capitalizes the first letter, then these two will come back as true. Now, alternatively, what this alternative though we can do is we can use the inequality. And with that, we do we can do exclamation point equals. And that means not equal. So the exclamation point means not. So if tomato, not equal tomato, which means we're checking if these two things are different, then it's true, and we go in and we go into our piece of code here, or indented block. Now, alternatively, what we could do is we can actually type at the beginning the word, not. So, if not, tomato equal tomato. And that would give us the same thing as saying, I tomato not equals tomato. So you can either write the word or use the exclamation point before the equals, if you want to check that. There are plenty of times where we're going to check if two things are not equal to each other in order to achieve different things. Now, we looked at this a little bit with numbers. But what we can do is we can actually advance to if you remember back in math, where we had greater than and less than that we had to check and use. We can use that here in code as well. So we can say, for example, if we went back to our five equal to six and we'll print out equal? Does five equal to six? No, of course not. But we can ask if five is less than or equal to six. And then we can get our block pill, which obviously says equal, which is true, which chans out there to make it a little more accurate, right? So if five is less than six, less than or equal to. Notice that. So it could be six compared to six, and it would still come back true. Whereas if we just had the less than sign, it would come back false because six isn't less than six, six is six. So we can use less than, less than or equal to, greater than, reader than or equal to, equal to, and not equal to. I know that's a lot of equality signs and symbols for you to remember, but hopefully you can keep those kind of checks in the back of your head. And we can use the s for if we were to say, say someone goes to the store and they want to purchase alcohol. Let's say it's 19 for the age there to purchase alcohol. And obviously, you're going to have to show your ID, prove your age, right? And if we were to code this scenario, the cashier is going to look at the ID, and they're going to perform an equality check. They're going to see if the person in front of them if they are 19 or older, greater than or equal to 19, then we come back as true, and we would perform the sale. If they came back as under, right? So if that check came back as false, then obviously, you wouldn't sell it to them. And that's the kind of route that I know some of these players have gone with video games as well. So if a game is rated M for mature, that's, I believe, a 17 rating. And then we're going to check to see if the person is 17 or older, greater than or equal to 17, sell the game, if not, refuse sale. So those are two examples of how this kind of if check and equality checks kind of translate to, like, real life in these real world situations. So now that we've covered one, we can also cover two conditions at the same time. So we can say I six is less than six, and something else to say, and five is greater than two, so we know one of these is true, right? We know six is not less than six, but we know five is definitely greater than two. So if we were to print this out, we'll see, it doesn't come back true, nothing happens. We don't get to this block. And the reason for that is because both of these statements need to be true because we're using and. So this piece needs to be true, and this piece needs to be true. So if we were to change this down to five, should we say if five is less than six and five is greater than two, it comes back true. So you can have multiple conditions, and it doesn't have to stop at two, right? You can come in and you can add a third condition, a fourth condition, a fifth condition. You probably shouldn't once we have that many conditions going on, but the point is is that you could. You can have as many conditions as you wanted. Now, what we can also do is we don't have to check if one of these how change Baca six, less than six, we don't have to check if both of these are true. We can use the or operator. And this will check basically if this is true or this is true. Condition one is true or condition two is true, then we advance inside of our code block. So we only need one instance to be true when we use O. We need all the instances to be true when we use and. Now, what's important is if you don't want to write out the words and as well as or, we can actually use two vertical pipes to represent or or we can use two ampersands to represent the word and So whichever route you go with that, again, it's going to be personal preference, whether you use the ampersands or the pipes or the aprisands and pipes or just writing out the word. It's not going to change anything. And as far as I'm aware, it does not affect performance in any way. It's just two options of doing the same thing. So ultimately these come back as either true or false. So ultimately, this is what we are dealing with right? So we're basically checking if true. So if this is true, then of course, we print it out, right? That's ultimately what we're doing. But when we're doing the inequality checks, we're checking if something is false, right? So we're saying if these are not if they're not equal, then that is true, and we move into our blog. All right. Hopefully, that made sense there. There was a lot of things to kind of juggle around in there. If you're a little confused, go back, watch it again. But that'll do it for our equality checks, inequality checks. A Boolean is just the result here, either being true or false. And let's see, that covers we also went over multiple conditions either through and or through using or. And we've compared numbers. We got greater than less than equal to not equal to. We went over a lot here. So I'll do it for this section and we'll move on to well, continuing our I statements here. 14. 14 if elif else: All right. So we touched on the if statements briefly because we needed to in order to use the qualities, equality checks and inequality checks and all of that. So let's dive in a little more on the I statement. Now, with I statements, you'll notice in the conditional section that we were going through, we start our code with I, of course, because we want to check if something is true. So the if statement says, I this is true, continue and go into my block of code. So now, this is a conditional that tells you if something is true or false, essentially, and pretty well always follows or is always followed by the I keyword. I think I worded that a little weirdly. Our check always comes after the I keyword. So just like when checking for multiple conditions to be true, we can use that in our if statements, like we checked with strings earlier. But one of the key differences is It's a block of if statements can get a little complicated when we have a bunch of checks that get used, as you saw when we could put and, and we could just keep adding more and more conditionals and we could use Os to keep going. Pretty much we have an unlimited amount of conditions that we could check. And we can use condition, any conditional with I statement. So if we look at the simple if statement like we did before, we said, If tomato equals tomato, then we would say it's true, right? As long as they were both spelled exactly the same with capitalizations and all that. But what if we want to have a catch all, right? So what if we want let's see. Let's create a variable called NUM. We'll set it equal to six. We'll say inside if I ready, we'll say if num is greater than or equal to six. Right. Colon and we'll say, go ahead and print in there. Ha, it's greater. And if we go ahead and print that out, we'll see, Okay, that's he comes back. It is greater than or equal to six. However, if we say if it's greater or equal than to seven, nothing is going to. But in some cases, you may want something to happen as a result. And this is where the else block comes in. I'm just going to lower that. So else, followed by a colon, that's all we have to put there. We're saying if all those checks above are false, none of those are true, then the else block will take care of it. So we can come in here and we could go ahead and print this, I have a space in there, say, this is not greater. And we can go ahead and have our checks. So now we're really going to get this is not greater or we'll get the response. This is greater. So regardless of whether it's true or false, we're going to have some sort of response, some kind of action and you might go ahead and think, Okay, well, you can just go ahead, von down, do another if, another if, and another if, and you can keep making all these different checks. But the problem is, is if all of these are true, for example, if we change this to four, this one to three, this one, two, Actually, if we change these, we want to go the other way. If we say if these are seven, eight and nine, so if these are greater than six, since these are if checks, all of these are going to run as you see here, they ran for num, seven, eight, nine. They all came back true, so they were all triggered. However, what if we only need one of these? What if we just want the first one to be true to trigger it. And then if that triggers, none of the other conditions are checked. Well, this is where another keyword comes into play here, and this is the else if. So it's kind of a combination of the I and the else put together, and we just call it LF. So if we come in here and we say if for these. I'm saying, if this is true, then we do this. If not, then we check se, if this is true, do this, else, if this is true, else, if this is true, and if all of those fail, we'll be left with just the else statement. So if we were to run this now, you can see the first one becomes true up here, and then we never get to these. And we can tell that if we come in here and we just put a bunch of exclamation points in so we can differentiate it. We can see the first one gets detected as true, and then we skip all the other ones because we don't need to check them. So we're not checking if all of these things are true individually. So there may be certain situations where you want to use multiples, multiple if checks on their own. But a lot of times you're probably going to have more of an I else if or an if else. Kind of chain going on like we see here. Now, this can really get things to be a little complicated at times when we go into this. So if we take a look at an example here, there we go. Alright, so we have all of our checks in place here. So I just select a random number for age to 15. So we're going to check if age is less than 13. All right, we're going to take on the assumption of maybe movie theater prices, right? So come in there, we'll say, I age 13, it's going to be this price, if it's 13-64, so it's greater than 13, less than 64, it's this price, and if it's over than 64, we do this price. And then we have an here saying that he is not valid, which is just in case catch all. We should never have a situation like this. Let's go. So we have 15. We can go through ourselves. We'll say, it's not less than 13. So skip that. We go to our second check. Age is greater than 13 and less than 64. Yep, 15 is. So we should get back the price is 14 50. If you play that, we can see that's exactly what we get. So there is an example of doing an if, else if and else kind of chain going on there. So again, the example there would be something like maybe a movie theater with different ticket prices based off of the age of the person who needs a ticket. Now, we can use these if statements as well, and merges kind of with our four statements or 44 loops, and we can chat things such as we'll let's say we have our groceries. Right? Cereal. Ketchup. Milk. However, we may have a check for out of stock items. Which maybe you're developing an application that keeps track of what items are out of stock and in stock. When an item is out of stock, they'll appear here. So we'll say, this store is out of stock of milk, right? So we'll say we have no milk, but we want to check. So we want to go through our grocery list. So we want to say for I, right? For item in groceries, just like we did previously in the four Luke section. And we want to see if that item is in our out of stock. So putting this whole thing together so that we have for item in groceries. We want to check if I in out of stock. So using in here is going to check if the item is in there. So if cereal is in this list, we're going to do this next block of code. And if it's not, we're going to continue on. So we're going to say we're going to print and we're bringing everything together here. We'll say percent S is out of stock. And then we'll just pass in the percent I to pass our item into our string. Putting this whole thing together, we see the only thing that triggers it is milk because milk is indeed inside of our out of stock list. So you can see how quickly we're starting to string things together. We're printing out to our console, we're inserting variables into our strings. We're using I checks to see if something is true, and we're running a four loop to go through everything inside of our groceries. Go through everything inside of our list. Alright, so that should cover everything here to go with the if checks and if, else, if, else, as well as hopefully some examples to make things a little clearer and to see how all of this comes together. 15. 15 Dictionaries: A all right. Everyone, today we're going to take a look at dictionaries. Now, we're obviously not talking about the kind you pick up, this kind of word and a definition associated to it, but you could use a dictionary to make a dictionary. And a dictionary is pretty good relations to what a dictionary is encoding. The reason for this is because they work in the function of having a key value pair. So in relation to a normal dictionary, we would have the word as the key, and then the definition would be the value. So dictionaries are a set of data that can hold data types of any kind that we have discussed up until this point, including other dictionaries in of itself. A dictionary can keep a set of related information all at one place, such as game or program settings or information on enemy characters. A dictionary can easily be identified since all the data, all of their data will be encased within a set of curly braces versus a list which uses the square brackets. So let's go ahead and take a look at how these dictionaries get formatted. All right. So going here up here at the top, we're going to make a new variable. I'm going to call it M dictionary. And of course, we're going to set this and equal to a pair of curly braces. Now, the way this works is we can go ahead and enter to make it nicer to look at. And we do a key value pair. So for example, we'll say key one, and then we do a colon and then the value. So we'll go this my value and if you want to insert another one, we put a comma, and we can enter drop down to the next line, and we can do key two. There we go. This is my new value. And, so on all the way down the list. Now, the name of our dictionary can be anything you'd like, just like a normal variable. But once we get inside our curly braces, you can see we have a string, and this first string here is our key. You can obviously name this whatever you wish, but similar to variables, it should be clear on what the data it's related to. So it should have some kind of indicator of what the value is relating. Example, this could be inside of maybe a weather dictionary. A key might be temp or temperature, and then the value would be the actual number. All right. So an example of this if you're doing settings, could be having an audio dictionary and a graphics dictionary. Now, your key, as you can see there is followed up with a colon and then your data. Your data here is what we're referring to as the value, and it gets treated similar to a list with an index of zero, if that makes sense, being your first value. Now, we could go ahead and call this with different situations or a couple of different ways that we can actually call it. You can even, I guess, we can have different data types in there. We could have a list in there as one of our values. So if we want index zero here, we'll give it will give us our name, returning with Jim and Index one, returning yes. We're turning as our health. So if we had it in sorry, a dictionary inside of a dictionary, which we can go ahead and do here, right? So we'll say this is name, and this would be report back as him and the next one we'll have health, and we'll say 100. So in a situation like this, This where indexes that are coming from. Now, of course, we don't have to use indexes. We could just fully write out names when it comes to dictionaries, which is always nice. Just remember each key must be separated with its own comma, so let's go ahead and come on down here to our reading take a look at how we can access a dictionary. All right? So when we access our dictionary, we'll go ahead and print it, of course. And what we're going to be looking at is we're going to be printing out my dictionary, of course, and we could just print out like that. But of course, if we want to narrow it down, let's take a look. So it gets printed out is we get Key one and then we get key two, and then those go inside of another curly brace for the other set. So we can either get Key one or key two here. Now, if we want to get key one, we can just do curly brackets right next to it, similar to an array. Only we can go ahead and type in Key one. And as you see here, we're going to get the result, Key one down there. And the same thing. If we do k two, we're going to get the new dictionary that Kit is holding. Now, what happens if we go ahead and use zero for our dictionary here? Try to access that. We're going to run into into this situation because we are out of bounds of this dictionary. So there are different situations for something like this. For example, what we could do is go my dictionary, right? Again, and we can do dot keys and something like this. This is just going to get all of our keys and return it as an array, so this is going to be a list of all our keys. And then we can do our square brackets and put a zero in there. So we could do something like this, and this would work, although it's a long certainly much longer than it needs to be. And I know with three, occasionally, this would work as well. You could just dot Key one. Yeah, there you go. So you can just do dot and put in the key value here. So we can do two, and the K two goes into another list of its own, sorry, another dictionary of its own. So we could then go and do another dot. So we can do my dictionary.k2 dot, I'll say Health. And as you see, our result is 100. So there's a couple of different ways that we can actually access the contents of our dictionary, be it going to log method by getting a list of our keys and putting in an index, just passing in the key that we want as a string or using a dot method like this, similar to a function call or a method call. Now, when we have dictionaries inside of dictionaries, you've seen essentially what we'll be doing here with dotqt dot HeL. Only you can access that through our square brackets. So we can do key two. And then right beside it, we will just do another set of square brackets. That's also we can just write it out like that, which has a pair or two pairs of square brackets each key going down. So that's how we can access our dictionaries and side of dictionaries. It can be a little confusing, so hopefully that was clear enough, at least if not the explanation with the actual demonstration with seeing it in use here. Now, dictionaries can hold, all other types of data. So they could have list in them. They could have numbers, you know, integers, floats, strings, dictionaries and side of dictionaries. So we have this whole wild set, and of course, accessing those is really going to come down to the methods that we've shown you there, and based upon what type of data it is, obviously if the value is going to be an array, then you're going to access the values in there like an array. Now, what if we want to add into our dictionary, right? So we have my dictionary there. Let's go ahead and create a new one. We'll call this Colors, have the sequel to an empty dictionary. Give me errors for down there because we didn't fill that in. Now, what do we do for passing in some piece of data here if we want to add a new entry into our dictionary? Well, we can just go to our colors and we'll go ahead and pass in a key as if we were trying to access it. So we'll call this let's go with cool or cold colors, and then we just set that equal to the value that we want. So we'll go with a blue. If we print our colors now, we should see blue being the value, being a string value here of the key cool. So we should see that here inside of our colors dictionary. And there we go. We can see that right there. So it's as simple as that, you add onto it, and this should work for an array as well. So if we just have a list here and print that out, as you see, it works just as you would imagine it works the same, even if we're doing different type of data set here. So there you go. Easy enough for us to do. We simply call it and then set and this works the same way if you want to reset or change this as well. So if you want to change the key inside of it, if you come down here and change this books. So first, it's going to be these numbers, and then we're going to change it to red and print it out again. As you see, you can add keys to it and overwrite keys using the same format. Now, what gets a little complicated is when you want to add a dictionary into the dictionary. Do we just pull that out? And let's see if this now works, typing this in. So we'll say e one. All right, we'll say value here. And let's see if this works. Alright, cool. So we can do dictionaries this way just as easily. Awesome. So I don't have to go over any type of work arounds for that. Perfect. All right, so there you go. There's how we can add to our dictionary and overwrite the keys. Now, we can take a look at looping through our dictionaries. So obviously, dictionaries are going to be a little different here. So we're going to use My dictionary again, and we're actually going to run a four loop so we can go through it. So what we want to do is we want to do four and typically, we're going to use four key in my dictionary. So at this point, we're going to get key one and key two. This is what we're going to loop through. And if we just print that out, print P. You can see we're going to get key one and two printed out to us. Now, if we want to go even further in inside of this, we can go for value, let's say, in Key, we can print out value and we can see what we get there going two layers deeper. Oh, here we go. My mistake. My dictionary and surround the same curly braces. There we go. That's what we want to do, and we'll print the value that way. And there we go. So we see Key one, name, health and key two. Now in this situation, since we do have a string here, it did print out all the characters individually, which is what you're seeing here with it being vertical. And characters do include spaces. That's all we have that there. As you see we went through for key and dictionary so we got key one. And then what we do in here, we then loop through the value, and we're printing off all these letters individually, and then we print the key name. So that's why we have this and then key one. And then we move into key two, and we print out the next one. So name and health, and then we print on key two. So you can see how we loop through these dictionaries and you could go further in or you can loop through a specific set of dictionaries. So you can see how we go looping through these dictionaries. All right. So that's about everything you need to know in order to use and access elements of your dictionary. So that'll do it for here. Next, we'll take a look at getting input from the user, and we'll be jumping into some more looping. 16. Getting Inputs: Alright, so it's been brought to my attention that apparently inputs is missing from the language portion. So we're going to go ahead and I'll show to do that real quick. I'm just going to do a user interface. I'm just going to click Control for my new scene. I'm going to go ahead and rename this. I'm going to call it. Let's go input test. I'll go ahead and save it with Controls, input test dot TSN. That's fine. And I'll add a script to it. Great. And I'll just close all these other sections that we do not need for this, right? So, in my case, I'm extending a control, but in your case, might be extending a character body two D when it comes to creating players for games or really anything, it doesn't matter too much what it's extending because you can add in or take input from pretty well any node type. Right. Now, what I'm going to Yeah, we'll just use print for acknowledging it. So there's a few ways that we can get input. And one of the main ways that you'll see a lot of people do is going to be inside of a funk underscore process, or it's going to be under funk Physics process. These are two different points in the frame. The physics process is where you should put anything that is physics related. So something like moving your player. Since you're probably going to have to deal with things like collisions and other physics based things, you should probably do it in physics process at the frame. And process up here is probably where a lot of other things within your projects are going to go, but you usually want to try and keep this as clear as possible. Now, another situation that you might see used is going to be another function called input. And unhandled input, and our last one is unhandled key input. Now, there are some small changes as to how these are handled and see if I just hold my mouse over here, depending on the version of Gudo you have, you may or may not see this. If you don't see the pop ups and your version, you should be able to just hold control and click on the function and you'll get the same information. You read about some of these differences here with unhandled key input, unhandled input, and so on. But these bottom three here are specifically for input. And then up here is where you're going to have more continuous things like holding down forward to move, for example. All right? So I'm going to get rid of the unhandled ones. We're not going to need it for this. I just wanted to point those out to you show those are an option to use here. I'm going to get rid of the Do I want to get rid of that? No. I'll keep that from my example. And I'll get rid of physics process just because I'm not going to be moving any characters or doing anything physics based. And I'll show you here. The easiest way for us to do some input is going to be if input, and this input class holds all the inputs that are available either built in or ones that you add to the input map. So we're going to say I input dot. We can say I and you can see here, I anything pressed is similar to how you would get to a main menu and would say press any button. So if you press any button, this is going to trigger. Other than a main menu, I'm not sure where you might incorporate this, but if you do need it, is anything pressed is there for you? And we'll go ahead and test it. So we say, I input is anything pressed and tabbed into that, we'll say print something if we can spell, spelling is hard sometimes, something pressed, and I'm going to go ahead and hit Run current scene. You see, as we sit here, just take a second to run. There it goes. If I hit any button on my keyboard, I'm going to hit J, something press and it actually triggers five times with it being just where it is right in the process. If I hit L, there we go. We can see that numbers increasing. If I get rid of the stack, you can see Every time I press buttons here, you can see our number down here in the corner. Filling out, right? So even just clicking into it, because that's input, that's something. Left click, right click, any of these buttons on the keyboard, right? Always work. All these things trigger because anything can trigger. It's anything pressed. Now, what other options do we have? We have is, and we have action just pressed, action just released, action pressed. And then we have some joy. So these joy buttons, of course, is going to be your controllers, right? So it's going to ask you for a device, and then it's going to ask you for a joy button. Now, I don't have a controller plug in, but this is you can do something specific for controllers, which is not what we're going to be doing here, but it is something to point out for us, just like we have key label, keypress, the physical key, mouse button. So you can see, you have a whole slew of things that you can here. So let's go with the easy one, the simple one. Let's say, sorry, just take a drink. Okay. So if input is action just pressed. Now, you're obviously not going to have a whole lot of these. You're probably going to see a lot of these UI buttons down here. Some of these UI except, I believe that is the enter key by default. And you see we're passing in a string of an action. Yeah, so we'll go ahead and put that in. And now you'll see when I run it now keep in mind this is action pressed. So if I press the button down, I'm holding it, it's only being pressed one time, right? It's only showing up one time. No problem. And I let go, nothing happens. Now we can have another system set up, so we can say I input dot is action, we can say release. We'll go with the same button here. I accept, and we'll go ahead and print and we'll say something release. We have pressed and just released, and we're using the enter key for both of those. So if I press this button down, it says something pressed. If I keep it held down, nothing happens. And as soon as I lift up off of the key, something released. So depending on what you're doing, you may want something to happen on press, or you may want something to happen on release. Now, alternatively, there is another option that you saw on there. It's going to be if input is action press, so not just press, but press. And I'll say I accept. Great. So we can see the difference here. Print. This is what's going to trigger when something is held down. So something held. So you're going to see, I'm going to press it. We're going to see our something pressed. I'm going to keep it held down for a moment, so we're going to see a spam in this output console of something held down, something held. And then when I release, we'll see something released. Right? I did that just for a moment there. I pulled this up. We can see something pressed, and then something held for all this time. And then something released when I lifted off of the button. They see you got a three different situations that you can use here. And depending on the kind of system that you're doing, what kind of inputs you're doing, you can use any of these for your purpose. Now, I I did mention that we also had key say is key Press. And then this is going to take a key code. So in our case, with what we were doing now will be key Enter, right. And we'll just go ahead and print Enter, press. And we run that, we hold it down and we can see we get that. So we don't get just pressed and just released when it comes to keys. So do keep that in mind. Now, if you want to set up your own actions here, I'll just back this up. More. There we go. Like I accept like we have here. We're going to be doing this in the gaming portion. But you just go on up to project settings, go to Input Map, and then you can add a new action, make sure you're in the right box here. I'll say new we'll go ahead and call this test action. Hit the add button. Now if I scroll down to it down here at the bottom, I can hit this plus icon, and I can put whatever button I want. So let's say I put the K button, right? I hit Okay. And I can come in here and I can say, I action just pressed, test action. Now I run that. Now, if I hit the K button, we got that something pressed being triggered. So adding new inputs to your project is as simple as that. And there are a few other things that you could get into. So are going to have or they're going to have more specifics such as action word things like action strength. So action strength is where we're going to get actual numbers. So input, get action strength. And if we were to take a look at it, we see if we're going to get a blows. We're going to get a number back 0-1. And this is how much or how hard a button is being held down. So on a keyboard, it's basically zero or one, right? It's either press or it isn't. However, if you deal with controllers, this is where you can create things such as holding a button halfway down to aim and pressing it all the way down to shoot. For example, there were quite a few old games that have that kind of system with that. Metal gear solid had where you would press I think it was the square button in the old games. You would press to aim, and you would press it all the way or release to do the shot. And get action strength is how we would actually get that. Alright, so there's a lot of options you can do in order for getting input, but I've shown you all the main ones for dealing with that. And I still have input here set up, and that's because event input event is anything. So that could be a mouse click, could be a keyboard one. It could be just moving the mouse on the screen because mouse motion is an input event, right? So if I just went ahead and print event, here. And you take a look. See, as I just move this, you can see mouse motion comes with a lot of things. The position relative, you got pen and pressure and tilts, or if you want to do tablet support. You got that. You got the velocity, which is how fast the mouse is moving. Alright. Let me see the button index. So left click is going to be Index one, right click is Index two. So if you're going to be using something like input, you're going to have to narrow it down. So for example, we would do something like VR let's say I event is input event. So we can say key if you wanted it to be a keyboard, JoyPad buttons. If you wanted it to be a button, event action, mouse, mouse button, mouse motion, screen drag, screen touch. These are things that you would use to create a touch screen button, for example. Input event, shortcut. So you got all these things in here, but let's just say input event. Let's go. Input event key. And then we can say ar EV equals event as input event key. And let's go ahead and print EV, see what we get from here. We see nothing is happening here. And as soon as I hit a button on the keyboard, we can see now we're getting buttons, right? We're getting key coodes. We're getting the mods, whether it's physical, the location, whether it's pressed, and of course, echo, which of course, echo is going to be true if the button is held down. So we have these input event keys now. All right. So now we can go ahead and we can say I EV press, right? So if the button is being pressed, and we can use the word here or you can use two ampersands and just enhanced. So we're checking to make sure both conditions trouve and EVP code equals P ED, in my case. And I can go ahead and print out something like D, E, press. Now if I had any other button on the keyboard, nothing is going to happen, but as soon as I press the Dkey, we get that acknowledged. Now, if you really want it, you could just come in here and inside of your input, just say I input action press, Film. You can do all that in here. But when we're getting event, you may as well use it, and these are the kind of situations that you can do now, if you want to use the event as well, as well as the action here. All right. We can say if event is input event key, if we want, and event is action press, and now we can go ahead and pick something we had test action. I don't really remember what test action was. I'm not going to idea about that. But I'll say action Press. I don't remember what that was. I think it was the KK. I hope I'm right. And I hit it, and we see Action Press. Alright. So there we go. So we have that working for us. All right, so I hope that gives you a pretty good idea of how we can get input from the player. There are some other small ways. For example, if we had a text box on screen, we could grab the text property out of that. And I believe if I remember right, we're going to be seeing that in our first project. All right, hopefully that clears up any confusion that there may be, and hopefully you can understand some of the ways that we can get input from the player. 17. 17 while loops: All right let's take a look at while loops. Now, we've used a four loop before in the past, and now we have a second type of loop. And a four loop, as you remember, we'll loop through a set of items that is within something else, whether that's within a range of numbers or within a list. A Wile loop is something that's going to loop forever as long as a certain condition is true. So Let's go ahead and take a look at how we can use a Wile loop. In this case, we're going to use it to count up. All right, so let's go ahead and create I'm going to save myNum, set that equal to zero by default. And we're going to say Wile binuM is less than or equal to five. We're just going to print out myNum. And at this point, if we go ahead and try this, our loop is going to get stuck, and the whole program is going to crash. We're going to be stuck on the splash screen. And as you can see in the output console down there, it's just going to spam zero because that's all it knows how to do. And in fact, this isn't even going to close, so I have to hit the stop button in the top. So with a wile loop, it is dangerous to get yourself stuck in it. You have to have a way to exit at all times. If there is no exit coded in, you will crash. Now, there are many ways to do an exit, and in this case, we're checking if M NUM is less than or equal to five, so the easiest way to fix that would be to create that statement to become false. Now, we can do that by simply just setting M NUM is now equal to six, which will break it. We're not going to count up, but it will break. It will break out of the loop. But what we would rather want since we're using a wild loop, we can assume we want to count up so we're just going to call myNum, say plus equals one. Now, that is the exact same thing as saying M NUM is equal to myNum plus one. It's just a shorter way of writing it by doing plus equals one. So now if we run it, we're going to see it count out of zero, one, two, three, four, five, and then once we get to six, that is no longer going to fall within our condition. So that's going to make our condition return back as false, and we will break out of that loop. So that is one way and fairly solid way to break through it. However, it's not the only way to break through. As you saw, when we had just a print num, we caused the crash. But what we can do is we can actually use a keyword here called brake. And that will break the loop, no matter what, no matter if the condition is true or false, it's just going to break out of that loop, as you see there. Even though zero is definitely less than a five, because we use this keyword, we are able to break out of that loop, regardless of if the condition was true or false. Now, we can use while loops with things like dictionaries and list and a list. So we'll go ahead and take a look. So we'll say Wile new users. And all that means is while as long as there are users inside of this list and it's not empty, it'll be returned as true. And once the list is empty, it'll return as false. So what we're going to do inside of this loop as we can say our current user is equal to our new users dot POP and we can pop front. And we'll just go ahead and print out there. Verifying user, and we can do our percent S and just pass in our current user. All right. So now if we go ahead and run that, we can see we're going to go through. And once everything is exited or once you've popped all of the names out, this is now false and we break out of that loop. And you can see down in the output, we print out this statement for every user that we popped out. Now, if you want to remove things out of a loop, we can certainly do that in a very easy way as well. And, of course, this doesn't just count for removing things, but we'll take a look at our animals there, and we can see we have lizard in there three times. So what we can do for another statement check here is we can say, if lizard, There we go. Or wild lizard in animals. So as long as lizard is one of the keys inside of animals there, this is going to continue to run. If you remember what I said earlier or previously when we were looking at lists, I said, If you had multiple items in your list that you wanted to get rid of that were say duplicates, you would have to call remove or erase on them constantly over and over and over until they were all gone. Well, now that we know about Woloops, we can simply just do a check to see if lizard is inside of animals. And while there is a lizard in animals, we're going to go ahead and remove it. So simple, we're just gonna call Animals Dot. Remove it, not remove it. What you call erase Lezard. You see here, we're going to go ahead and print animals afterwards. Every time we remove it and we take a look. And we see we have two lizards now. We started with three. Then we add one lizard, and then we have no lizards. So you can see this is an easy way you want to run through a loop and say, remove all of the duplicates out. All right, so that'll cover it for what wile loops are and how we can use them in a few different scenarios. 18. 18 Functions and Arguments: Let's go ahead and jump into functions. Now, functions, we've already seen and used two of them. We've used process and ready throughout the course thus far. But you can completely create your own functions. And as an example, we can have one that it would be something like the following that you see here. So we could have one called greeting that welcomes you to whatever it is that we're doing, right? Books if we can spell that correctly. Now, you'll notice something in common with all of these. Now, just looking out all these, you'll see some similarities, and you'll see that these have been the basic structure that we've been using this entire time, and these make up the basic structure of any function you'll ever write. On the first line, we start with the keyword Bunk FNC, which tells GDScript that we want to define or create a function. And this is followed up by another word or series of words, but we cannot have any spaces in it. Which then is preceded by a pair of parentheses, and this creates a function. Of course, we have to end it with a colon and then go into the next line and tab in one. Now, starting on this second line is the piece of code that we want to write or run inside of our function, and of course, we'll only run inside of our function. So if we were to run this right now, nothing would happen. But what we can do is we can go up into our ready so that when this script is loaded in, we can actually call greeting the function that we just created. And that means that function is going to trigger whenever ready gets triggered. So though we don't have to write everything inside of the ready function, we can organize everything into separate individual functions and call them. This will help keep our code cleaner and nicer to look. And your function name should follow the same patterns, I suppose you should say as your variables. So for example, I went over how your variables should be preferably shorter, well defined and tell you exactly what piece of data it's holding. Well, a function should do exactly that, as well. A function should hold or tell you exactly what's going on inside the function just by reading the name. And not only that, but a function should only do one thing and one thing only. That function shouldn't be doing four different things within it. Now, we've gone over or use some of these functions that have taken arguments or parameters. Some of these such as remove that and erase where we have to add in another piece of information. Well, we can do that with our functions as well. So let's say we want to create a program that welcomes someone. We've done this before. We've done our percents. We put in that. But instead of creating a variable at the top, we're going to create one right inside of our functions parentheses. Now, we could just leave it like this and it'll take any data type, but we can also go ahead and declare what type of data that has to be. We can even go a step further and we could tell it or declare it, as well as give it a default parameter. Now, when something has a default parameter, that means it is optional. We don't have to put in an argument in when we call the function up here and ready. We don't have to type anything in here, and if we type nothing in, the default parameter is what will be assigned to it. However, if we type anything in here, it's going to overwrite it. So let's go ahead and give it a default of Bob. And we can go ahead and add percent user in. By, we know what to fill in. And you'll see if we just call greeting and don't put anything in, we get Welcome Bob. But if we go ahead and we type something in here like, let's go with Jim. And we type that in. You see, we get welcome Jim Jim then comes in and overwrites the predefined default of Bob. Now, what happens if we try to put something in that is an irrelevant type? So let's put it zero. What we take a look at, EC, we immediately get an error, and it tells us that should be a string, not an int. And that's the benefit that you're going to get from declaring what type of variable it should be. If we did not have that and we just, Hey, user is equal to Bob, now we could overwrite it. And we say, welcome zero, which doesn't make sense, when you're needing specific pieces of data into your function, you're probably going to need it to be a specific type as well. So just like variables, it's going to be a good idea for you to fill in exactly what type of info or declare your arguments type. Even if you don't want to set a default, now, it's also worth noting that we can have multiple arguments in here, and this is where positions start to matter. So we've done this before where we had inducer or name and job. So if we do a comma here to separate it, and we could put job in there, and we just put a string. And again, we can go ahead and We can call these in any order when it comes to filling them in in our print just as if they were normal variables, and you're probably noticing this error here. Now, functionally, there's nothing wrong with the code here. But what it's telling you is something that you got to keep in mind, and that's anything with a default parameter has to be placed at the end, because all optional parameters must be at the end of your list of arguments. It's just the way it is in GD script. So you have to put all the mandatory ones upfront, and then the optional ones at the end. So you see all we did was just switch job and user around, and now we don't have any errors, even though functionally, it's the same. All right, so that'll do it for our quick introduction here into functions and arguments, also known as parameters here for us to fill in as well as showing you our defaults or how to assign defaults and the order all these things have to be in. 19. 19 Function Alias: Alright, so let's put everything together that we're up to at this point. So let's go ahead and I'm going to open up the input that we did before just by double clicking on the script out of my file system. And I'm going to go ahead and grab everything I had here in ready. And we could stick it in ready. But what we're going to do instead is we're going to set this all into a brand new function that we're going to create. And I'm going to call mine Process text. Process text. On in down there, and there we go. And we can just now say pass inside of our ready. All right, so now we have our function inside of process text. And what I'm going to do actually my apologies. We're not going to do that there. That is going to be inside of our ready. Text process is actually going to be done at a separate stage, and that's going to take an argument that we can call new text, and we'll assign it with a default parameter of nothing. All right. Now, I'm just going to highlight these, hold Alt and use the up arrow key to move it up. Alright, so in process text, what we're going to do is we want to take this text like it's put in, and we can check it, similar to what we did here in the process here. So I'm just going to go ahead and copy what we had in the input, move it here into our process text. Grab these and pull it back by holding Shift and hitting tab. Now, what we're going to do is we can keep this as quick, but I'm going to change it to Q. So if my text equals Q, and we don't need to get the text field at all, because we're going to use our new text property. So now we're going to pass in a piece of text into our process text function. And we're going to check if new text is Q, then we're going to call the Quit just like we did in our input, and we're going to create a variable called My Name if there isn't. And we're going to assign that to whatever the new text is that we pass into this argument or pass into this function as an argument. And then we can fill it in again, just like we did with our input. Not doing anything fancy here. Let's go to we need to get our input. So let's go into our process, and we'll do our if statement, so we'll say I input is actin and we're going to go with just release. And we'll go with the Enter. Now, if you put now, if you don't have any action here, you could use UI except, I believe, is a default one for it's either space or Enter or the enter key. But if you didn't create one before in the input section, just head on up to project and project settings, go into the input map tab at the top, add in a new action called Mind Enter. And then beside that action after you add it, you'll see a plus button. You can hit that and you're able to select whatever key or button you want it to be. So all we're going to do here when we release the entropy is just going to call our process text, and we can actually pass in this text field that we had. So let's go ahead and grab that text field and grab the text property of. Now you'll see once we come up here, we can go ahead and type in whatever we want. And it fills in just as we did previously inside of the input section. So all this works the same and fundamentally, it is the same. But as you can see, when we're writing this out, this is all we need now. We have I key is pressed, run this function. It's a lot shorter, it's a lot cleaner and nicer to look at. And most of all, we're able to use this function anywhere that we need it, so we don't have to write the same piece of code over and over and over. Now, if you have a long piece of code, or sorry, not a long piece of code, a long function name that you just can't think of a better name for, what we can actually do is you can actually create an alias for that name. Now, an alias is kind of like a stand in, right? So we can take this short name, and it's going to represent this function. So it's going to represent this long name, kind of like a variable does. We have one short name and it represents this large piece of data. So this is going to be one variable name that's going to represent an entire function. Alright, so let's go ahead and up here at the top of our script, we can go ahead and create a variable. I'm going to call this alias. And what you're going to set this equal to is we can just set this to the name of our function. All right, process just like that, and it'll work. So if we come down here and hit Enter, we can go ahead and do alias dot, Paul, and then inside of these parentheses is what we want to pass in. So this would be our text field and our text property of it. You'll see if we go ahead and run that. Boom, everything works just exactly like it was before. It's just a little bit shorter and we're using an alias. Now, alternatively, if you have maybe you want to create an alias for a function that lives inside of a different script on a different note completely, the alternative to it's going to be similar to that. So I'm going to create an alias too, and these are called callable. And a callable is psycho function, right? So the only difference is when we create it as a callable, we actually have to add two arguments in there. So the first one being where the function is. So in this case, it is on the same script as the sales. So we can say self. However, if this was on, say, our text field, then we would do our dollar text field,cel. But since this is on the same script, we can type in self, and then it takes a second argument, which, as you see, is a method or function name in the form of a string. So we would go ahead and type it in like that. And now you can see that we can do the exact same thing we did for alias to.com and pass in our art. There you go. So those are just two ways that we can create an alias for a function. 20. 20 Classes: What is the class and how can we create one? So we've already used classes already. We just haven't referred to them as classes. We've called them object. And the line edit here, this is a class, and all the classes that exist are in the form of nodes here. So you can browse through, and you can take a look at all the different classes. And there are even some classes that are not in that list, such as JSON, which we'll get to when it comes to when we go over how to save and load different file types. But this is what we do, right? You call a class and you call new to create a new instance of whatever that class is. Now, in the case of a line edit, we have something graphical, but in the case of something like JSON, where we don't have anything graphical, but we do have things that we can use. And we'll see this in our next section, we will go over regular expressions as well. So let's go ahead and give ourselves an idea of how this stuff works. Let's go ahead and we're going to create our own class. I'm just going to right click in my file system this time and select New Script. We're going to inherit from in this case, yeah, we can inherit from node. That's fine. And I'm going to call it my PET class and hit free. And now I'm going to find it and double click it so we can open it up. And I'm going to delete everything in it except for our extends at the top. Now, to create a new class, we actually don't need any of that stuff that we had before. What we're going to do is type in class underscore name with a space, and we can put whatever we want the name of this class to be. So keeping with the name of the script, I'm going to call it PET and this is going to be our PET class. Now, you're going to add a second argument here in the form of a string, and this would be a path to an image inside of your project. An icon, and that icon will actually show up here, similar to how control has a little circle here, green circle. Your function will replace that icon. All right. So inside of Pet, what we're going to do is we're going to we can create some variables here, right? So savar name, right. And that'll be equal to an empty string. We'll have our age of our PET. And then it'll just be set to zero by default, and we can have the type, which will be set to a string. Now, since this is going to be its own class, it would be nice if we had ways of changing some of this stuff. So we can go ahead and we can create a function called name. Go. And I'll set this to new names so we can avoid conflict. That and we'll make this function called change name. We go. So now we have that and we can do the same for our age and everything else. So we can come in and we can create our funk just like a normal script or just like we normally do on a script with a change age. We'll pass in a new age and we'll simply just set We got these two Blackbird. Yeah. So we want to set age equal to new age. And we can do the same thing with PET, with t that would you change type which wouldn't really make sense unless you have some kind of really weird animal that can change what kind of creature it is, I guess something like a ditto in Pokemon. So let's go ahead and with a type equal to the new type. And we can determine what these are. I'll say string, and string that way, we have no issues and passing things in. And now that we have this, I'm going to go ahead in close out function class. We want to add a new script onto a control here. Class test. All right. Now, what we're going to do is inside of our pretty function. We can now go ahead and create a new variable called PET and we can set this to PET dot new. And now we've got access to all of our functions, so we can say PET, do a dot. And now you can see, we've got the age name, type change age, change name, change type, and then all the standard things that we would have on a typical node that we're extending. So if we wanted to, we can now print out this is my pet percent S. He is a percent S and is percent S O. And now we can easily just fill this in. What we have here. So PET first stuff is names. I'll say Etname fed by pet dot Type and pet dot H. Now, this is getting a little long. You notice these light lines here in the editor, and then a much harder line here. Try not to go past those lines when possible. And what we can do is just hit Enter it's not going to see it there. Is it on the oro? So what we can do is something like this and keep everything organized in a one line. We can keep everything clear like this, and when we written or when we boot this up, we'll create a new pet, but we're not going to add it into the tree because we don't need to, in this case, because we just want to access the properties of it, right? And we can create. This is my PET. We have this sentence and fill in based off of the information that we have there, which the information that we have there, the defaults are all empty except for the zero. So the sentence still looks a little weird. But what we can do is before doing that print is we can call Pet dot change Let's use Name, for example, and we can pass in a name. So we'll say Billy. And now you can see that fills in here inside of our output console. And we can do the same thing with age and the type. However, if we're going to make something like that mandatory, then that's going to be a little annoying to require other user to do consistently. So what we actually do there is we can call an int function, and this is something that's built into all classes. So funk underscore INIT, open and close our parentheses. And this is where we can have a set list of parameters that we have to put in. And these are all things that will be set out of a default as soon as our class has been created. So we'll go ahead and pass in I'll say new name. And then we'll do new age and new, right? And then all we're going to do is we're going to say name is equal to new name. We're going to say age is equal, equal to new age, and type is equal to new type. Now, when we go back to our testing script, you'll see that we have an error. At least we should have an error that pops up. Here we go. And that's because now we have to have arguments. So inside of new inside of the new call here, this is all the parameters that we must fill out for our int function. So we need a name, an age, and a type. And again, we can call these by types your string and and string you see when we come in here now, we're going to have we need to fill this out, so let's go ahead so we can put a name in there. Let's say bats. Our second argument is our age that we can put in two. And then we needed a type. Let's say dog All right. Let's go ahead. We can run that. And now we see all that gets built in. This is my pet bax. He has a dog and is 2-years-old. Now, all that gets filled in. We condense that down because we don't need to do we don't need to write out three different functions to change this from our pet. And instead, we just put it all inside of our in it or our initialized function that comes rebuild into all classes. Right. I hope that gives you an idea of what classes are and how we can create them and how we can really use them inside of our code. A class can be accessed for any script or rather you can create a new instance of that class from any script. And you might create a class just to have some utilities so you can save time. I just bring it in a utility and calling some specific functions that you may need all over, or you might use it to create an object, like, in this case, a pet class or if you're creating a game, maybe an enemy class, and then that enemy would have its own health and its own attack and its own set of information. 21. What we will make(filled space): Alright, this week, we're going to kick things up a notch and instead of going off of just some text, 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 some spawners. And as you see, if you've never played Frogger before or you've never heard of it, you see here, we're going to be working with UI for heads up display. We have points that we're going to need to keep track of. Find my mouse there for a second. But not only that, but we're also going to have see is it going to show it here? Okay, so we have a certain amount of frogs per player. Obviously, we don't have to put coins in. But this is essentially the game here. So 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. And 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, kind of 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 Frogger is if you've never played it or heard of it. 22. Creating the Story Book: Alright, welcome, everyone. And today, we're going to start creating our very first game. What we're going to create today is actually the storybook for our MadisGame. And this storybook is going to hold all of our stories as well as the prompts that we're going to ask the player for. Now, if you want, you can go ahead and create this in a totally new project. I'm just going to go ahead and delete our little examples here that we were using. When you were learning the language here, just going to select them and delete them. That way, I can start with a clean slate. And since I'm just going to keep all of our projects in inside of this one project here, I'm just going to go ahead and create a new folder and call it MDLIbs. Again, I would recommend that you create a new project altogether. That way you are able to export everything individually. Alright, so we went ahead and we have this. We have our MadipsFolder, for your project. And I'm just going to go ahead and click on my folder. If you're starting a new project, you can just right click in an empty space. And I'm going to create a new script. I'm to go ahead and create a script here, and I'm just going to call this storybook class and hit Preate. All right. So now I can go ahead and mine did not fall on my folder because I clicked on the outside, so I'm just going to right click and move it to where I would like. And I've got it inside of my folder here, right? I'm going to open that up. We can extend No, that's fine. We're not going to need any of these because this class is just going to hold some information for us. So I'm going to go ahead and put in a class name storybook, and we're going to need extends for this? No, I don't think we are. So I'll go ahead and move all of that so we have a complete fresh start here. Alright, so this where we're going to create our stories, and our stories are going to be held inside a variable that is up type dictionary. All right, so I'm going to create a variable called Stories. And that's going to be a dictionary. And because it's a dictionary, I'm going to go ahead Enter to open this up. Remember dictionary is denoted by the curly braces that surround our information here. And for these, I can just say story one and a colon, that'll be our key. And now we need a value for that. And that value will also be a dictionary because we're going to need two pieces of information here inside of the story. We're going to need the actual story. A and that is going to be just an empty string for now. And then it's also going to have one for our props. And that's just going to be an array. So we're going to have square brackets here. And this is the template that we're going to use for all of our stories. So we're going to have story one, story two, story three, story four, et cetera. And all we're going to do is we're going to go ahead and build this in. So for example, for the story, we will say, let's see what do we want to put here? Alright, so I went ahead and created my little story here. So one day the percent S. Now, percent S is just a placeholder for any string. And we can replace this later on with whatever the user puts in. So this percent S, in this case, is going to act like our blank in our story. So one day the blank went to the blank to receive a Quest. This quest was to go to Blank to retrieve blank, right? So we have this little story here, and and there we go. If you want to split the story into multiple lines, we can easily just do this. So by doing this by having our slash here at the end, and then on the next line, we have a plus. It is going to add this string to this string, and now we can have it all together in one place. But not only that, it's a lot easier to see when it's all inline or in site like this. Now, I went ahead and printed this out with an int just for testing purpose just to make sure we're no issues going on, no weird bugs. There we go. We're all set. Now, for our prompts, these are going to be strings inside of this array inside of this list. And as we go through, one day, the blank. So this blank makes sense if it's a noun, so we can go ahead and just type in noun. And what's next? Went to the blank, so this is going to be a place. Our next one to receive a quest. This quest was to go to the was to go to, and this will be another place to retrieve something. That would just be another noun. All right? So that's essentially how we're going to work with our prompts. So we go through. We have noun then a place, then another place, and then a noun, and that fills up all of our options here. That will give us enough things to fill in our blanks. And all we have to do now for more stories is just put a comma here at the end, drop to a new line, paste in a duplicate of what we just had, change story one to story two. And now we can go ahead and create another story with some more prompts, and we can just go ahead and repeatedly do this. In order to have ourselves a nice full storybook to use. Alright, so we have a second little story here. One morning, D Baker went to I went to Blank U in shop. To his surprise, however, there was a blank stopping blank. Now, I went ahead with verb noun and Pronow, but now thinking about it, Pronoun probably doesn't make sense, because we already said this was a he, right? His shop, his surprise. So I'm just going to change this back to just being a noun, so stop being Blaine. And you can just go ahead and continuously do this and create as many fun little stories as you can and really fill up your storybook. And once you have your storybook completely created and ready, then we can move on to the next section of this and start creating the interface for our user to interact with. And then we'll actually get into creating the code and making it all function. 23. Create the Interface: Alright, so let's go ahead and start creating the interface that we're going to need in order for our player to actually play the game. So right now, we have just an empty scene here, and we're going to need a new one. So let's see what do we want? Well, we're going to need the player to be able to type in some text, right for the prompts that are provided. We're obviously going to need to display text on the screen for the user in order to know what prompts they need, as well as reading the story at the end. And we can go ahead and put a button in there as well. That way, if the user doesn't want to hit Enter, they can click on the button and still submit their text. So those are three things that we're going to need as a minimum here. So let's go ahead. We can create I'm going to go ahead and click on User Interface here on the create root node section on the left hand side, and that's going to give us a control node to start us. All right. And I'm going to go ahead and rename this to Maine as this is going to be the main source here for our game. I'm going to hit this little plus button right above it with Main selected, and this is going to prompt me to create a new node. Now here you're just doing all of the different objects that we could create. And remember, we can do this in code as well. We're just doing, for example, we're going to go into Control. And you know I'm just going to go ahead and search. I'm looking for this. So the equivalent to selecting that and it being added in here would be the same as if we had a script on our main here, and we just said line edit dot new, and then we added it to the scene. That's the exact same thing as what we just did here, only we're doing things visually, only because this is going to be quicker at the end of the day. And if we have the tools to speed up production, we may as well take advantage of them. I'm going to go ahead and just grab the little oranges little orange handle here, I stretch it out. And I'm going to go ahead and while that is selected, I'm going to go to the top of my screen. Click. There we go. This little icon beside the anchor, and you'll get a pop up for anchor presets. And I'm just going to select the one that's in the center of my screen. There we go. That way, I know that my text field will always be right in the middle. Alright. So now this object has a bunch of properties or you can also call they're variables, right, that are on these that we can access. And one of these is placeholder text. And we can see that if we take a look on the right hand side of the inspector. We can see the placeholder text here. Now, we can go ahead and type in here, and this will give our user an idea of what they're supposed to type in. Just like how you go to a website and it might say email in the email field and password in that field. So we're going to say submit prompt, dot, dot, dot. That way our user knows that this is where they submit their prompt. And I'm going to go ahead and rename my line edit to user you want to call it User prompt? No, let's call it prompt you want to go prompt text, prompt field. Prompt submission. There we go, because we submit our font here or not fonti prompt, sorry. So I'm going to go with that and just call prompt submission. Now, I did mention I wanted a button, so I'll select Main again. I want that to be the owner. I'm going to type in button at the top. And now I have a button, and I'll set the text of this button to just say, Okay. And I'm going to do the same thing with button selected, I'm going to select the button at the very top next to the anchor and select center. That way, it can be centered. And I'm just going to grab ahold of it with left click, and then I'm going to hold Shift afterwards and slide it to the right if I can get ahold of it here. Here we go. Just like that. There we go. Now, I think some stories might get a little long. So I'm going to go ahead and grab both of these, both my prompt and my o button. And for that, I just went ahead and you can shift click or Control Click. Either way, we'll work for here. I'm going to grab it on my UI and then hold Shift so we can keep it in a straight line, and I'm just going to move it down a bit just so we have a little more space at the top in case our stories get a little long. Okay. So these anchors show where our object is going to be in relation to this point on the screen? So this anchor is in the dead center of our screen. So regardless of how big the window is, this text field, this line edit, and this Okay button is going to be down that far, approximately from the center at all times. So that's almost going to automatically update its position based on the anchors and window size. Which is great for us, it's because we never know how big a screen is going to be Let's see. Going from here, what else do we need? Well, we're going to need to display some text. Let's see. We could use a label to prompt or to show our information. We could also use a Rich Text, which I think we're going to use a thad. So we're going to go ahead and add another one into our scene, and this is going to be a rich text label. And I'm just going to pull this orange box out, this handle. And I think I'm going to set the anchors to the center that way everything will be relative here. Click hold Shift and bring it up. And I think that'll do for a lot of our information, how big is this text? Yeah, I think that'll be fine. All right, let's see. Rich Text label, I'm going to go ahead and rename that to my display text. Alright. So I think that's all we're going to need. I'm going to go ahead and hit Controls and save my scene. Here it is inside of my folder. And now if we were to run that, we would have no issues. We can see everything's worked out perfectly fine here. Everything looks good. We can type inside of our books. And I'm going to go ahead and look for the window, so I can show you that here. Now it's going to be important for you to see the window. There you go. You can see we can type in it, and delete things out of it. Awesome. We can hit the OK button. Fantastic. Now, this background is a little bland. It's a little boring. So what I'm going to do is I'm going to head on over to Google and just go ahead and search for Blackboard. There you go. Search for blackboard, chalkboard, whatever you want to look for so. And I'm going to go ahead and just pick an image at random and save it. So now I just got to find where my folders are. Here. Save, come back over to Gato. And there you go. We can see it saved right here. Inside of my folder. So I'm going to add one more object to my main here in my scene. And this is going to be a texture rect that I'll just rename background. And I'm just going to drag the Blackboard image here that I created or sorry, didn't create that I found on Google. And with background selected, the texture rect, I'm going to drag it over to the texture slot on the right hand side, inside the inspector and drop it in. And if you need to, you're going to change the expand size here and the stretch if you need to in order to change the size and tweak this. For example, if we set this to keep aspect, it's not going to move, but if we change our expand mode to ignore size, for example, here we go. We can see we can go with that. And if we just change keep aspect to scale, here we go. Now we can stretch it out to fit our needs. Now, what's important is you see this blue outline here. Everything inside of that box is what we are going to be able to see inside of our window. So I'm just going to make it just a little bigger than our window just to make sure it's completely covered. And our anchors in the top left corner. Now, for a background, that is not going to work. So I'm going to go ahead and adjust my anchors, and I'm going to select the one that is full wrecked. And that's going to put one pin in each corner. That's going to ensure that no matter what size our window is, this background is always going to fill it up. All right. So now we have one issue. Our background is on top of everything. We can't see our button or anything that we did before. Well, this is just because of layers, essentially. If you've worked in something like Photoshop, you'll be familiar with layers here. All we have to do is just grab our background, and we actually have to brak it out. Because what's at the top is going to be behind everything else at the bottom. I know it's kind of the other way around in Photoshop. At the bottom is usually what's behind everything. Go in here, just kind of flip, something you have to remember. But there we go. With that, we have our visuals all set up here and we're ready to start jumping into some of the code in order to make our buttons and everything else work and get our game started. 24. Select Story and Prompting the Player: Alright, we're going to go ahead and jump into doing some of our code now. We're going to put our script on our main node here. So I'm just going to add a script. I'm just going to leave mine called Min and hit Create. Alright, so let's see. What do we need to do? Well, we need to keep track of what our current story is. So let's go ahead and create a variable for that. Current story. That's going to be it. Is it going to be an array in our case? We're going to select a story, and that's going to give us No, that's going to give us a dictionary back. But we can actually hold this back and make it a dictionary. There we go. We're going to need to keep track of our players words, right? The words that they have submitted. So we're going to say players words, and that one will be an array that we can add to. Now, we're going to use a keyword here called on ready. And in 4.1 here, we actually have to use this at symbol in order to use these keywords. Put this at symbol and then use on ready. Then we can go ahead and create our variable like normal. And this is going to be our player text. Which is going to be equal to our prompt submission that we want to get ahold of. So in order to get this node, there's actually a couple ways to do it. The easiest one is to just use this dollar sign, which just simply means get node. And from here, we have an easy access to our prompt submission. As you see, we only have to go down one level here. And if we begin to start typing, we'll see the auto complete pop up for us and we hit that, there we go. Whenever we want to access this object, we can just type in player text. Now, we're going to do this as well for our display text and our button. So I'm going to say display text is equal to what I just called it display text. Awesome. And we'll have one more for our button. Do we need the button? No, we don't actually. We're not going to need one for that. No worth using this default button here. Okay. So let's go ahead and remove process out of there. So what we're going to need, let's see. We need to select a story, right? So we have to assign our current story, and to keep things organized, we're going to create a function to hold our set current story. It's a funk set current story. It's like so. And since this is a separate function, I'm going to go two lines in between. And how do we set how are we going to set this current story here? Well, we're going to return nothing at the end of this because we're just going to assign it directly to our variable. So in order to get this, we're going to need to get a random number or select a random story. So I'm going to create a variable called Stories, and this is going to be an array, which is just going to be equal to our storybook class dot STRESOh. And look, we cannot access that. So let's head back to our storybook class, and to avoid having to create a new object for this, since all we need is to access the stories that are in it, we're going to use that static keyword that we mentioned in Week one. Right now we come back to our main script, and we can do storybook dot STRS I cannot assign a value of type dictionary to variable, so we want to get our stories. And on this dictionary, we're going to use we're going to call dot keys, open and closed parentheses. And what this is going to do this keys call here that we can call on a dictionary, it's going to return an array or a list of story one, story two, story three, story four, et cetera. So that's going to have all of our little story names here. All right. Now, from here, we have to select a random one. So the question is, which one do we want? Well, we're going to create a variable called selected story here. And, of course, this is just going to be a string because all of our stories are strings. So it makes sense. And let's access our stories here, right, stories of Ray. And in 4.1, we can just select pick random. That's all we have to do, and it's going to randomly select a story to give back to us. And that's all we have to do for that. Now all we have to do is just go ahead and set our current story. So we can say current story. Let's see. We just set it to that. Then that should give us a dictionary full. Both of those, that should be fine. So we'll just say current story equals selected story. Strength cannot be assigned to a variable type. Oh, that's right. Got to write that differently. Storybook dot Storys and then I'm going to use these square brackets here because we want to access the story that's inside of it. And the one we want to access is selected story, right? So again, we're going to go over this. We're creating a variable called stories, and that is an array or a list. And that is being assigned to all of the different stories, right, the keys of our dictionary. Of all of our stories inside of our storybook. So now stories holds all of our little story titles. And then selected story is a string that is being set to a random story out of there, out of our list. And then we're setting the current story that we already created up top, which is the dictionary. We're setting that equal to the story that is inside of our storybook, the story that we selected. All right. And we can see this work easily if we just go up to our ready block here, and we need to actually call, set current story because obviously you're going to do that at the beginning of the game. And then I'm just going to go ahead and print out our current story. This way, we can just see if it's working because it's already empty by default. So if I print it out before, we set our current story, we should be able to see that, and I'm just going to play this scene. Here we go, so we can see it's empty at the top. And then after we set our serve, we have the one morning the Baker went to blank to open up his shop to his surprise, however. So it looks like we got the first story. Let's run that again. And here we go. We have a completely different story here now. The blank sky was beautiful shade of blank as the blank blank threw the blank. And we can see we have our prompts all here as well. This is fantastic. We're all showing up here. Everything is working great. We now have a story to work with. We have them randomly selected. Now we got to worry about how do we prompt player, right? Well, we don't need these print statements anymore because we know it's working fine. So our story has been set. How can we prompt our player? Well, simple. We're going to come on down, create a new function. We're going to call it prompt player. And what we're going to do is let's see. Let's go right into our display text. And we want to access the text property of that so we can set that. And to remove any potential confusion, we're going to say, let's use plus equals here, and see how this looks for our situation. And I'm going to say, May, I have the thing we're going to add to it, it's going to be our current story proms. And the prompt that we're going to ask for how we know which one we want is going to be based off of our player words that we created up top here, right? Our players words. And we're going to base that off of the size because remember, when we're working with a list, we start counting at zero, one, two, three, right? So if our player size is zero, that means we have no submissions yet. So we're going to get the first item in this list. If we have one item in player submitted one word, then we're going to get the second item, and so on. All right, so we can prompt the player this way. And I know that's getting a little long on that side, but let's see. At the moment, that's all we need in order to prompt the player. All right. So what we're going to do from here after we selected the current story, back up in already, we can go ahead and call prompt player from there. And that should be all we need. So let's go ahead and try it out. Oh, seems I have run into an issue here, and what is that? Let's take a look. Oh, yes, I see the error here. Tell me prompts is not a thing because I used a capital P inside of my storybook. So if I just make that a capital P, that should solve my issue. And there we go. So it's asking us, may I have a verb? And then I can go ahead and type in here. You can hit Okay, hit Enter. Nothing's going to change here at the moment. But you notice how I had to click in that box when we started. So if I just restart that, and now I have to come down here, I have to click in it myself. Well, why don't we just automate that? Let's go ahead and get the player text. And we're going to call something called Grab focus. So now when we run this, there we go, it's already there, and we can just start typing immediately. So we don't have to waste any time. All right. So in order to continue prompting the player, we have to take a look at our words being submitted, right? We actually have to submit these words. So for this, we're going to have to connect some signals for us to know when things are happening. So I'm going to go ahead and click on my prompt submission in my scene. Then I'm going to move over to the right and click on the tab that says node. And here we can see all the default signals that have been in here. And the one we're looking for is text submitted under the line edit section. And basically, whenever we hit the enter key, it's going to submit whatever piece of text the user has typed in. So I'm just going to go ahead and double click on that. All right, so you should see a screen like this, and all of this is great out because we do not have any scripts on those, and this one is blue because that's what we're trying to connect the signal from. So we're just going to select our main because that has our script on it, and we're going to hit Connect. If you want to rename the function here, you can, I'm not going to. I'm just going to leave it with the default name here, and I'm just going to hit the Connect button. And you'll see it added right here at the bottom up our script. I'm just going to hold Alt and use the up arrow key to shift it up a few spaces. There we go, get that out of the way. Go. That's out of the way. But there we go. So we see on this function name, which is going to trigger from that signal, it's going to execute this block of code. Now we can see we got new text, which is a string that gets passed into us. So that new text is whatever has been typed inside of this line. All right. So when a piece of text is submitted, what we need to do is we can add this to our player words. And since we're going to need to do this potentially multiple times throughout or at least in multiple locations, let's just go ahead and create a function for it. Funk, add let's see what did I call it? Add to player words so we can keep things clean. Here we go. And all we're going to do inside of this function is we're going to append our words, right? Players words. Append. Now, append. This call here just allows us to add things into our array, add items to our list. So whatever we type in here will be added into and all we're going to be adding is playertext dot text. Now, we could make this possible do cleaner, but it might cause some potential issues later. Who knows? So we're just going to do it this way for now. And what'll be nice is if that display text, if we clear that out off of our screen, so we make it an empty an empty string, I guess you could say. We're going to say display text dot. And we're going to call clear, and that's just going to empty it out. And what that's going to do is that's going to remove the prompt that is on our screen, asking us for a verb or a noun or whatever. And to visually show our player that our text has been submitted, we can go ahead and do that to our player text as well. Let's take a look at how that's looking now. We got to call back to here before we forget. So on our text submitted, we're going to call add to player words. All right. So if we go ahead and run this and take a look at it now, you say, May I have a verb and we'll say running. And I hit Enter. And you see our text down here was emptied and our board at the top here was also emptied. So that's great. It looks like our text was submitted and we're ready to update with a new prompt. Fantastic. All right. So in order to continue our prompting, we're going to partially set up what we're going to need for setting up the ending and restarting the game. So we're just going to leave that portion of that out and come back to this function in the future. So right now, we're just going to use this to check the or call it check player words Lang. So I don't want you to get confused with that name. It'll make more sense when we add in when we're checking if the game is over. So I'm going to go funk, check player words Lang. Alright. So what we're going to do is the way we can word this Let's see. We can say if we're going to use an if statement here. So I'm going to say if player words got size. And remember, that's just going to get us the amount of items that are inside our player words here. So the amount of words that we've submitted already. And we're going to say that is equal to our current story, the prompts, prom pots No. There we go, dot prompts. Dot size because remember our prompts is a list. And of course, we have an error here until we put our colon in there at the end of our line. So we're going to say if the player has submitted the same amount of words as we have prompts, then we can do something. But we don't want to do that, right? Because we want to say, if not, like that. Because we want to say, Oh, if the player hasn't submitted enough words yet, then we need to prompt the player again, and that's exactly what we're going to do. We're going to call prompt player. All right. And when it comes to the next video, we'll come back and we'll rewrite this function. But for now, this should work for us. Let's go ahead and take a look. So, may I have an adjective? Sure. Let's go with pretty. You hit Enter and thing is updated. But we're not actually checking our player length anywhere, so you see why that's a problem. So let's see where do we do that? We do that when we add to our player's words. So after we add the word and actually submit this word for us, then we'll check the link and see if we can keep playing and if so, prompt the user for the next one. Let's see. May I have a verb? Yes, let's go with RN or Run. There we go. May I have a noun, dog. May I have adjective? Pretty. May I have adverb. Yes, swiftly. May I have a noun? Hope we got a lot of things here. Red. May I have a verb ending in ING? Robbing. And there we go, our thing has ended. We're out of prompts. We don't have our story yet, but we do have all of our prompts happening there. Now, we can see that our display text actually did not clear out, which is interesting. So instead of calling clear inside of our add to player words, let's just get the text property and set it to an empty string. And let's see how that works here. I have a verb, run. There we go. So now we have it updating this way. I'm not sure why clear isn't working. Maybe there's a bug in there right now. I don't know. But we can just clear it manually by setting it to an empty screen. And if you want to keep that going as one on each line, if you want to keep that going, one on each line, all we have to do is just add a plus equals and do this back end. Or is it a forward? I think it's the forward here, and this is going to be a new line. So if we take a look at it this way, so it can have a b run, and that's actually not going to go in that way. I always mix these two up as to which direction it's supposed to go in. Adjective. Pretty. There we go. Now we can have a new ent on each line to ask you. So if you'd rather have it like that, that's how you can make that little tweak. Have a noun. Yes, dog ending with ED I'm drawing a blank here right now. I don't know why, but you get the idea. So we can have a new line that way where you can completely clear it out completely up to you on how you want your presented. Alright. And I think that's enough for today because I think all we need now is to basically end our game, whether that's completely ending it, telling our story, seeing if the player wants to play again, and all of that fun stuff. So one quick note here before we take off. Instead of prompting the player here at the top, what we can do now is we can actually just do check player words length inside of our ready, and that should set us up the same visually. Yeah, there we go. Alright. So there you have it. We have a lot of our game setup here. It's simple in terms of video games, and it's giving you a chance to really use the things that we've gone over in week one, regardless of which version if you did both of them. So we're working with variables, different data types, certainly working with functions to keep everything nice and clean. We're using object oriented programming here with our storybook we're prompting up our players. You're learning some new things. If you didn't go through the alternate version, you've learned about append. You've learned about Grab focus, regardless of which one you've gone through there, you've learned about pick random and keys. So you've learned quite a bit of things in addition to whatever we've learned in the first week, whichever version you've gone through, maybe you went through both. But I'm going to stop rambling on here, and I'll see you in the next one where we will wrap this game up so that we can have a full playable thing. 25. Ending and Play Again: All right, everyone, let's go ahead and wrap this up. We're going to end our game. We need to check if our story is done. We need to actually tell our story, and we're going to use our Okay button to have two uses here. So it's going to work to both play again with a new story, as well as submit our text. So let's start out with that with our button here. So I'm just going to go ahead and select my button, and I'm going to connect the signal press and again, I'm going to go ahead and just connect that up to my main, and I'm going to leave it with the default name here. And just to keep things a little clear, I think I want to move this up just a little bit and put my two spaces in between there. That way you can just have my two signals here next to each other. Alright, so right now, when our button gets pressed, we can go ahead and just use add to player words, and that'll function the same as if we hit Enter on our keyboard. That should work perfectly fine, exactly the same. So verb, Ron, we hit Okay, we go now, Dog, okay. All right, so everything's being submitted, everything's working fine. Excellent. So we have to know when our story is done. That way that way we know whether it's time to tell our story and end our game, or do you keep playing and keep asking the player for another prompt. Well, in order to do this, we're going to go ahead and create a new function, and we'll call it I story done. And the whole purpose of this function is to just tell us whether or not we have any more prompts left to guess. So we're going to return a value here. And what we're going to return is whether it's true or false. That's going to be player words, size equals our current story prompts, right? Remember, we want to use double equals here because we're doing a comparison. And that's all we're going to do. We're just going to return that, and that's either going to be true or false. Alright, so now in our check players words length here, instead of writing it like this, we can actually reformat this. And we can say, if I story done. And for now, we're just typing the word pass because that's when we're going to end the game, and we'll add an else block in here. Here we go. So we'll say if the story is done, then we'll end our game when we write that part of our code. Otherwise, prompt the user again. So let's see what happens if we do this now. We come in adjective, ready, we hit the pay button. Fantastic. Our text still grabs the prompt. Everything's still working. Awesome. We have not broken anything yet. That's great. Alright, so how do we end our game? Well, if the story is done, we have to end the game. So we're going to create a new function called end game, and notice how we're creating a function for everything here so that we can keep everything organized. And we say, Okay, well, we're having an issue when the game ends, we know to come down here and look at the end game function. Or maybe our story is not being shown at the end, and we're going to have to go to the function that we'll create here in a second called Tell Story. So this will help us with narrow down any bugs that we may get in our project. In the future by being organized and prepared now. All right, so how do we end our game? Well, what I'm going to do is I'm going to take our display. You want to go with our display text? No. We want to grab my prompt submissions, right? So we want to get the player text. And what we're going to do here is we're actually going to use quarter. And what that should do is go back to our scene here on two D, is that should grab this line and just completely delete it off of the screen. So that way it no longer exists. That's basically what it does. Completely deletes it, removes it out of memory. So it frees up that memory, and that's important to do, not necessarily in this game, but in other games. Say you keep creating these new objects, but they never get deleted. You're essentially going to start getting to a point where you create memory leaks. So you got to remember to cue free anything that you no longer need. And at this point, we no longer need our player text. All right. So what we're going to do here next is I'm actually going to change the text on our button. So I'm going to grab our button, that dollar sign, remember that short get node, right? So we want to get node in the node we want to get is our button. And the reason why we're just writing the word button is because that's what it's called here inside of our scene. So if I renamed that to something else, I would need to make sure this matches. So on this button, we want to get the text property of it, and I'm going to set that to say play again. And while we're at it, we should make sure that it says Okay when it comes to prompting our player. All right. So I'm just going to put that inside of our prompt player function and just set the text to say, Okay. Alright now, the last thing we have to do inside of our endgame is call tell story. And that's going to give us an error until we create that, so let's go ahead and at least create that name, tell story, and that is now a new function. In order to tell our story to the screen, all we have to do is completely empty out the text. So display text dot text equals an empty string. And I'm just going to put this in here in Side of Tell story just in case you're going with the new line approach when prompting your player here. So just in case you're doing that, I'm going to clear out the text here as well. And all we do now is we set our display text and the text property of that that we can see. And we set that equal to our current story. And we want the story property. I'm going to make sure I spell that right inside of my storybook, story with a capitals. And we have to fill in all of those placeholders. So the way we do that is just do a sent sign, and we add whatever we want. So, for example, we can go with banana, and that's going to fill in our first blank with banana. Now, we have multiple items. So because of that, we would have to do it in the form of a list like this and do a coma and do our next one, right, tomato and do the next one and so on. But we've already done that. We already have our list or array of all of our strings. This is our player words that we created, and that we've been adding all of our text submissions to. So we can just come up here and say players words. Alright. So now we go to check player words Link, and we say I story done, and we're going to call Endgame. All right. Now, do we need to call this anywhere else? No, but we are going to need to do our restart button here in a moment, let's go ahead and just make sure this works. All right. So can have an adjective. Yes, pretty a noun, rock, a verb ending in ED, educated. An adverb, swiftly, a plural noun flowers. And there we go. We can see our line at it has been deleted. Our button now says play again instead of Okay. And we have our prompt at the top. The pretty sky was a beautiful shade of rock as the educated swiftly through the flowers. Now, I have two Ss there. Was that my mistake, possibly. Was that something that I had in my story? It's possible, as well. And no, it does not look like that was in the story, so that was completely on me. I must have hit S twice. But there you go. There's our story, and our play again button doesn't work here. And the reason for that is we're trying to add our player words. It brought us to this function for our error. And if we were to look at it, parameter, new text is never used, that's perfectly fine. But the issue that it's giving us is telling us that player text doesn't exist, right? We can't go to our player words. Can't do any of this stuff. Well, that's fine. Our issue is actually here with our button press. Because based on whether our game is done or not, we'll determine whether or not you want to restart the game or prompt the user again, correct? So I'm just filling these in. Just don't mind me here. If you are following along with using the arrows because you want to, I story done, is going to return a pool because we are returning something, and this will give us a true or false. Everything else, we're just returning a void on. So I'm just quickly going through there and filling those in. And I think that's all of them. Got them all, right? Alright, so when our button gets pressed, all we have to do is check if our story is done. So if I story done, and we want to restart the game. Else, now tap that in. We're going to call add to player words. So how do we restart the game? Well, to completely restart it, in this case, all we have to do is get tree, and that's going to get this entire tree of ours. And all we have to do is call reload current scene, and it'll be the same thing as if we had just hit Run current scene here at the top. If we had just hit that button for the first time. So when reload current scene goes off, we should be in this situation again. So adjective, so I'm just going to run through this so we can see that we have something completely new educated adverb Make sure that I only put one in there this time, plural flowers. There we go. Okay. That's cool. And we play again. May I have a verb. Ran noun. Cookie. Another noun, Brownie. One morning the Baker went to ran up should said Run. Up his shot to his surprise, however, there was a cookie stopping, oh, I said Brownie instead of Brownie. I put an R in the end. My fingers have betrayed me in spelling today. But now we can play again, and we can have another story starting. So we can now just keep playing this for as long as we want. And this game fully works for us. And if you ever want to add a story, we can just go into our storybook and you can just continue adding more stories and prompts, and it'll just keep working. We don't have to adjust our code at all for any reason. We just add another entry, story five, story six, story seven, and we can just keep on going with as many stories as we want to put in. Now, if you're curious about this error here that's in yellow that you saw earlier, it's just telling us that new text is not being used for M signal, and that's fine. We don't have to worry about this. It's only a yellow error, which is just letting us know. And we could turn this off. There's a few things that we could do, but the easiest thing is to just put an underscore here at the beginning. That's all. Now if we go ahead and run this, that error is no longer going to show up. So this underscore at the beginning of your parameter just says, ignore if not used, basically. But there we go, we are now telling our story, and we have an end to our game. We're either telling the story or prompting the user to keep playing, and we have or prompting the user for more blanks to fill in. And we have a play again button in case we want to keep going. Alright, so that'll do it for mad libs. This is a fairly short game that we've gone through. This is probably maybe about an hour that we spent to go through this, and you've started putting together functions, these returns. If Else statements we've used a few times, we're using booleans. We're using dictionaries, arrays, classes. We're using a lot of things here even though it's such a simple game, I would say. Well, with that, you've completed it. Congratulations. Give yourself a pat on the back. And I'm excited to see things that you create in the future, and I'm excited for us to move on to the next project. 26. What we will make(filled space): Alright, this week, we're going to kick things up a notch and instead of going off of just some text, 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 some spawners. And as you see, if you've never played Frogger before or you've never heard of it, you see here, we're going to be working with UI for heads up display. We have points that we're going to need to keep track of. Find my mouse there for a second. But not only that, but we're also going to have see is it going to show it here? Okay, so we have a certain amount of frogs per player. Obviously, we don't have to put coins in. But this is essentially the game here. So 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. And 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, kind of 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 Frogger is if you've never played it or heard of it. 27. Tilemap vs New TilemapLayer: Alright. It's me again here. And I just wanted to interject here before we jump into Frogger, you'll notice that if you're using a new version, Tao Map has this yellow triangle here, and that's giving us a notification here that this node is going to be deprecated, which means it is going to be removed from the engine. So depending on when you're watching this, and the tile map node may no longer exist. And if I have to take a guess, it'll be removed at 5.0 of Gato. That's just my guess. I have no idea when it'll actually be removed. But I'm going to show you the alternative that was added in just in case you want to start using the alternative. Now, instead of the Tilemap, well, if you're watching in the future, you know what to use instead to clear up any confusion. Now, with the tile map, we have our tile set all set up here, right? And we have all of our nodes, sorry, not nodes, our textures, our road, water, the median, and our home. And you see we go ahead and paint on here, right? We can come in and just paint onto the screen. And we have multiple layers here in a drop down on the right hand side, which is still here at the bottom. Now, this is what's different. These layers are going to be their own nodes now instead of having everything inside of one tile map. So all we would do instead of this tile map is we would then add in a tile map layer right? Go to our inspector, tile set, open that tile set up, make sure we it tile set down here at the bottom. And we can go ahead and add in our median. We can add our road, and we can add our water. Then anything else would be exactly the same, which I don't think we touched anything as far as collision or anything here. So you shouldn't have to do anything else there. And then just like the tile map, you can come in and you can paint with so you can go ahead and just make sure you come in, select your node, select the tile you want to use. And of course, you can come in and just start painting, just like you do with the tile map, right? So we can come in. We can go, boom, boom, put it in, grab our purple. Change my tile, grab our purples, come across, fill in the road pieces. Right. So you can come and snow pint in like normal. Now, what we have in a separate layer is this home section. So what we would do is we would go to we would actually come up and add a second tile map layer now. Grab another tile set, select the tile set down at the bottom, and we would bring in that home tile. And there it is. Now, I left mine is kind of a default here, default in size, so I probably want to come in and change the tile size here specifically for this one. But that being said, right? I can just come in, paint, tile map, select all of these, and I can come in and I can just paint it in, right? I just stamp it in just like it did before. So using a tile map layer and a Tilemap isn't too different. You just got to remember each layer is going to be its own node down instead of just selecting it from a drop down. And when it comes to the actual code, if I come in and we take a look, we take a look here. Normally, we get our tile map. We call Get Cell source ID. We pass in the layer number and then the map position in this case, so we can get the idea of what we're standing on. Now, this function exists in both the tilemap and tilemap layer. I'll select Tilemap here and you can see right here, Gell source ID. I'll go ahead and use the magnifier for you here. Let me see it. Get cell source ID. The first one is the layer, and then the coordinates, and then we have an optional flag there. Do we have that. But if you want to use the Tilemap layer, tile map layer has the exact same thing, the exact same functions here. The only difference is we don't pass in a layer. We just pass in the coordinates. So if my tile map here my tile was a tile map layer, in this case, it would be layer zero that we're using. So I would get this one that has my median row water on it, and all I would pass in is just the map position, and that's it. So you just got to remember to all layers are going to be individual tile map layer nodes in the future. And any function that asks you for a tile map layer, you just don't put anything in. Just skip that argument. Alright, so hopefully that clarifies up any confusion that you may have depending on when you're watching this. And that's the main difference here that we're working with. Alright, take care. Have yourself is a good one, and I hope you enjoy Frog. 28. Creating the Background: All right, so let's go ahead and get a jump start on creating Frogger. And 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. Alright. So the first thing we're going to need to do is, especially since our spreads 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. And to do that, we're just going to head on up to project and go into our project settings. All right. And so I should start just like this with the advanced settings turned off. And you'll see on the left hand side, we're 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. Alright. 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. Alright, so 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, and the scoring area that we have to get our frog to. So 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 set up and running. And the next following videos. Alright, so we're going to need a two D scene here. So let's click on two D, and this will give us a node two D for our root node. And if you want to go ahead and rename that, you can. You can name it Main if you want. Game manager. Doesn't really matter. If you really want, you can just leave it as the default name. I go to leave mine as default for now. And in order to create this in our little background, I'm going to create a new Tilemap. So I'm going to hit the Plus button. And we're going to go ahead and select tile map from the drop down. S in our create node. Is like Tilemap. Just go ahead and double click that and select that. Now, I have mine 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 Tilemap selected. If you don't have it selected, go ahead and select it. And what we're going to do is head on over to the right hand side. And we're going to go to the tile set here. It stays empty at the moment. 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. So if we go into our sprites 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 All right. So 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 setup 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. And I'm going to do the same thing for road, median, and my home bro straight across. Now, home is a little bigger. So I'm thinking it might be one ty, No bigger than that. Let's see. What do we got? Oh, 26 too big. How's that? I think that'll do perfectly fine. All right. Did they ever go? I've got a 16 by 24 here for this tile. Alright. So now if we click on Tile Map at the bottom of our screen down here, we should now be able to click on and start drawing our sprites. So click on my median, click on my purple tile here, and just drag one row across the bottom, go to my road, and we got five layers of traffic. So we need five rows of our black here, three, four, and five. And if we refer back to our image, we then have another layer of purple, five layers of water. One, two, three, four, five, and then we have a layer of water that goes underneath of our home. So let's do one more layer there. Let's grab our home and just go ahead and click on one sprite and drag your mouse across so you can select all three. And let's place it. Oh, look at that. We seem to have this issue. Well, what's going on? Well, we are replacing our water tiles here. We don't want to do that. So we need to actually draw this on another layer, and I'm just going to go ahead and been filling that up with our water all the way up to the top in the last two lines. So I'm going to click on our home section here, and we don't want to replace these. We want to build it on top. So 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. So what we want to do is go into our inspector of our tile map, open the layer section, hit Add new element, and now we actually have a second layer. So back in the tile maps with our home row selected, we can go to the drop down layer and hit layer one. And now we can actually draw directly on top of it without affecting our final There you go. We got seven across with this. And just to make sure solve our rows one, two, three, five, right? Looks good to me. If we click back on our no TD, so nothing is great out. There's what we're working with. And if you remember when we're looking at the Alfoger setup, what it looks like? We actually have our score, and 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. But right, we now have our background all set up. And 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, and now that we do, that makes setting things up like this much easier. Alright. That's our background. Let's go ahead and jump into the next portion. 29. Creating the Player: Alright, let's go ahead and create our player, but before we do, I'm going to go ahead and save this. I'm just gonna hit Control as go into my froger folder and save my scene real quick. Alright. 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 tab right up top here or add new SEM. We're going to go to O. And 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, and in other engines, you may hear people refer to it as such. But here, it is now called a character body two D. Alright. Now, this character body, we have this yellow triangle here that gives us a little warning, and it just tells us that our node doesn't have any shapes. I can't collide with anything. It's got no collision. And for now, that's fine. Can to floating there. And what we're gonna do is we're actually going to go and add another node in here. And what we want to add is a sprite two D. We want to add an animated sprite. Well, we want our sprike to be animated. We do have two frames for this. So let's go ahead and do an animated sprite two D. And on the right hand side in the inspector, let's open up the animation section where it says Sprite frames. Let's click on it and do new sprite frames. And then let's open those sprite frames up just by clicking on it. Alright. So we 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 plus icon down here. And I'm going to rename that to jump. All right. So with Idol selected, I'm going to bring in Boger Idol PNG. And with jump, we can bring in Boger Idol and then our jumping icon, Boger Leak. And now we should be able to go between the two. Whenever we want to play these enemies, All right. Areo, see you see if we play there. We're jumping. We're doing our little bouncy bounce. And 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 crisp. 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. Actually, this isn't going to be an import. You've moved this. So let me just go ahead and let you know where that part is. All right. So if you head on into your project settings, Whoo. Where did I go? Head on into your project settings and locate the rendering and texture section here for advanced settings on. Or do we need it on this? No, we don't need it on for that. We want a default texture filter here. Change it from linear to nearest and go ahead and close that, and you'll see your sprites go much sharp. So if you're going to do pixel art like this, this is the default you want to do in your project settings. And now we have a nice sharp broki Alright. And for now, 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 hand Control S 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 No This plus for a new node, but the chain beside it. And that'll let us instance in a scene that already exists. And for us, that's going to be our player scene. And now we can go ahead and grab it and we can bring this little guy in. And we can place. And we can do whatever we want to do with this little guy. Let's see. Let's transform. So we know this is in values of 16. So 172 wouldn't do. It would be 176 if we're on values of 16. I'm just going to move my little froggy up here. Here we go. Be a little more centered with that. And 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. And with that we'll jump into the next one where we will address doing some player movements. 30. 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? So to start off, we're going to need some inputs. Now, if you want to use the arrow keys, then I up, UI down, UI left, and UI right already exist. But I want to use WASD. 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 up, add down 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. And for up, I'm going to hit the plus. I'm just going to press W on my keyboard. And I'll show you what that looks like. What you'll be seeing from there, let's see. Is this window here? And I'll just bring that up above. There you go. So I just hit the W key, and we have that we hit Okay. We go to down, hit the plus, press the key. And again, A for left, and D for right. Alright, so now we have up down, left and right for our controls, and 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 I put a script on side of our character body t2d on our players scene. And 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. Like so. And this is just so we can keep everything clean and organized and keep all of our movement in one location. All we're going to do to take input here is we're going to use the if statement. The same if statement we've been using a lot. So we go if, and then we want to access the input object or the input class. So input. And then dot because we want to check is action. And we want to go with released this game. Or just released or just pressed. Either one will work for this game specifically. If we go with pressed, is action pressed, then that is while the button is held down. Just pressed and release means will just press as soon as the button gets activated, when you press it down and released means the block of code is going to execute when you lift your finger up. I'm going to go with J press. Let's try that. And I'm going to use the button, and this is a string that should have popped up you automatically. And this with a colon, so we can go inside to it and create the code block. And all we're going to do is we're going to do two things. We need to move our little froggy. 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. So we're going to get our position. And if it makes a little more sense to you, you can say self dot position because you're moving yourself that this script is attached to. And right now that's going to give us an X and a Y coordinates. That has two numbers associated to it. So 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. So if we click onto our main scene and go to our character body, you'll see, its position is 169 and 233, in my case. So this is where we're starting from, and we're going to be adding or subtracting from this from either the X or the Y to get our movements. So since we want to go up when we press up, we're going to be affecting the Y number. So we're going to say position dot Y. All right, we're on ourself, we want to get the position property, and then we want to get the Y number of it. And to go up the screen, we actually have to subtract. So we're going to say minus equals. That we can say this is equal to position Y number is equal to position Y minus sum number, which are sum number, in this case, it's going to be 16. So if we were to just leave it like that and run our racein Well, how unfortunate Our little froggy doesn't move. Why doesn't it move? Hopefully you cue on or grasp that before I hit the play button. We're never calling our movement anywhere, so we're never actually checking for any of this stuff. And for that, we're going to just stick it inside of the process function here. Movement. And now it's being called. Whoops, at least it would if we could spell it correctly. There we go. And if we try running that now, 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. A dada 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. So let's get our animation working. So how do we play our animation? Well, if we look at our player scene, we can see from our script, we can go down we can follow this one line easily, just one level to the animated Sprite two D. So let's get that node. And the way I've shown that before was using this dollar sign, it would be the easiest way. And as soon as you start typing animated Sprite, it's going to pop up. And remember, that's only animated Sprite two D because that is the name of it. So if I were to name this banana and very poor spelling of banana, then that's what I would have to type in here in order to access. I'm just going to reset that name back to default. And all we're going to do is we're going to call on it play. So dot play. And you'll see the animations that we created pop up. So we're going to use jump. And if we try that now just with that one addition of our line whips, you have to actually play this scene and not our player. There you go. You can see we go into our jump, but we're kind of stuck in our jump now. So that's a little disappointing. So 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. So 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 says animation finished. So if we just double click that, we'll get a pop up to connect a signal here, and we're just going to select the character body TD 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. Yep. So whenever our animation finishes playing, this block of code is going to execute now. And what we want to happen here is we want to return back to our idle state where our frog is just sitting there. So the same thing, we're gonna get our animated Sprite two D. We're gonna call play, and that's gonna be idle. If we try that now, what do we Again, if play the right scene, how we attempt that now we see we now have this, like little jump that's appearing as we ping 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. So though that's not really going to be an issue with this game, that could be something to keep in mind going forward. So to solve this issue, we can actually fix this with an IT 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. All we have to do is we can check if Animated Sprite whoops. You want the dollar sign there. If animated Sprite two d dot. Yet Animation. No, it's not what was it called? Well, if we go into our Animated Sprite, and by the way, you can access it and we just hold Control and you click on the Animated Sprite two D here in our code. Then I'll open up the documentation page for. And here's what we're looking for here. Get animation. So we want to get animation. As you see that wasn't popping up. So sometimes it's useful to check out the documentation anyway. We want to do I animated sprite tod dot get animation. And if we were to take a look at that, the current animation, the Sprite frames resource, the value is changed, frame counter, frame progress or reset. But what we want to do is to get we want to get what this animation is. So that's going to 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. And then when we play our idol, we're just going to tab that in one so it could be inside of our I lock. And now we're basically going to check our current 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 Bing and it looks exactly the same, but we're not going to be constantly playing the idle animation over and over and over. It's when the idle animation plays, remember, it plays once, and then it's done. It's not looping. And if yours, for example, is looping for whatever reason, then go ahead, select your animated sprite, 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 to turn off. So it's white like that. If it's blue, then it's on, if it's white, it's off. So now when our animation finishes, after we jump, we're going to check if our current animation is jump, and if so, then we'll play idle. And when idle finishes, this if statement will not be true because when we get animation, it's going to be idle, not jump. So 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. So it's a small difference, one of those things that are on the back end that the player is never going to notice. And 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 down button. So if we just copy and paste this, we can get if instead of an I. We want our down pressed instead of up, and 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, and we can do that by talking about its rotation. So before we jump, we can get self dot rotation. And if we take a look at our players, so we go back to our player scene like on a character body inside the inspector. If we come down, we see we have rotation here. And rotation is in radians rather than degrees. So what we can do is we can say rotation equals, and we can use this function that's built in called Dg two RAD, and that might have changed here. And it looks like it has. Looks like it's been renamed here, so deg two RD. It's got the underscores in it now. And then we'll take one argument in the form of degrees. So if we say 180, that's going to be a full turnaround, right? Because if we turn right, that's going to be 90 degrees. If we turn left, we're going to be -90. So either way, we have to get to positive 180 or negative 180. So I'm just going to go with 180 degrees here. And this function is going to convert this 180 degrees into radiance so that it can be assigned to our rotation here. Now, one full rotation in radians is 3.14, and this is where i is from. So this would be the same here, 180 as if we were to just copy this rotation equals Pi divided by four. Then that'll give us one rotation. So if we want to do Pi divided by two, that'll give us half our rotation here in radians. So if I were to show you that with Pi divided by two, Oh, we split down the other ways. So maybe it is a little more than two. Now, I don't normally use radians myself. We, we can see divided by four, we kind of get this little awkward angle. So you see, it can be a little awkward when dealing with radians at times. So what I which is one reason why I prefer to use degrees to radian, just because it's something I can work through a little quicker. And 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. And we'll just do the same thing when we press up. We set our rotation to zero. And if we were to play it now. There we go. Now we can jump up and we can jump down. And now, what if we want to jump left and right? Well, we can get those with two more LCFs here. And I'm just going to space these out to be a little more legible here. There we go. So starting on our second SIF here, we're going to say I action is left. And instead of modifying the Y value, we're actually going to modify the X of our position because X is left and right. And if we're going left, we have to -16 here. And degrees to rad. Well, we could set this to 270, just to stay on the positive side here, which means our last Elsev here when we press right we're going to modify the position instead of the Y, we're going to plus 16. And if we're moving right, we're going to be rotating at 90 degrees. So if we go ahead and try that now, should see now we can jump around in all four directions. And we can get around. And 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. There you go. And now we kind of got to keep our position. And well, on the screen would be nice. But we can worry about all that stuff later on for now. We just have our movement going around, and this video is getting a little long, so I just wanted to keep movement in its own little section here. There we go. We can run around as our own little froggy going, boing, boing, booing. But right, and there you have it. We can now go ahead and move on to the next section of our code. And 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. 31. Creating the Vehicles: Alright. 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. So, that's great. All we have to do is create them and have them move across our screen. Alright, so 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. And 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, and we can go ahead and assign one of our 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, so that's worth noting. And I'm going to change this name from character body to D to be Truck and I'll save that as my truck scene. And 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 it. So to prepare for that, I'm going to create an area two D. And that's just going to pretty much allow me to have a redefined area that I can check. And 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. So collision shape selected. We move to the right to our shape section, and we create a new one. And this is just going to be a new rectangle shape. Now, we don't use complicated shapes such as using the polygon hooks. And instead use polygon or sorry, will you use shape with some of these basic shapes here? Because the templer 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. So it's kind of 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 will find, especially since we're recreating an older game like this. All right. So now that we have our collision shape like this, again, if you didn't catch that, just make sure your rectangle is covering everything, every part of the truck here. And 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, Bruni export a variable for us. And what this is going to do is this export keyword is going to allow us to change this inside of the inspector. So 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, and by default, we can just set it to zero or sorry, we can set it to one. Doesn't really matter in this case. And 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 it to be negative one because we're going to move left, which means we're going in the negative direction. So I just went ahead and set that to negative one. And now in the process function, we're going to need to have our character or well, character is correct, but our truck move. And then order to move, we need to have something called move and slide or move and collide. Either one will work in order to have movement here. In my case, I'm just going to use move and slide. Moving collide is just fine as well. It pretty much just defines what happens when two physics bodies collide with each other, right? They 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. So now we have moving slide. We can't just play it now because we still have to control this movement. So I'm going to have another variable here called speed, which will also be an integer. And I think I'm going to set this. We'll try eight for now, and we'll see how quick that moves. That might be a little too quick. So you know what? I'll actually try it with two now that I think about it. And all we're going to do is we're going to change the velocity, and we want to change the X number. So just like position, we have both an X and a Y when it comes to velocity, and velocity is going to control our object moving consistently. So let's go to velocity, and as of four, Interesting. Maybe it's a capital V because I know there is a built in one. Pretty sure here. Oh, no, it's low right there. I must have just put a typo in there. But there we go, so we can just do velocity dot X. And 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. So we'll say speed times direction. So 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. So 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. But if we went in the inspector and we changed 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. So I'm just gonna set mine back to minus one. And 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 this scene and see if it moves. We can see it's moving, but it's moving way too slow. So we're going to have to tweak that speed. So let's go back to eight. Maybe eight was good. Let's try that. Eight is not good, but it is much better. So let's see. Do we want to be moving at 16 pixels? 16 looks good, although that looks like it might be pretty easy, so maybe we want to increase that. And 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. So 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, like, 48, or I don't think we're going to be able to get to something like 64, but you never know, I suppose. So I'm just going to use 32 as my base. Alright, so we have a truck moving in one direction. And 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 at 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, so 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 collesson shape if I needed to, replace the sprite with another one of our cars. And then, if necessary, age the direction from minus one to positive. And 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. And 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 with each other. Awesome. Now, all we need is more cars that spawn, and we don't want to place these consists because if we have to place them manually, then we have to just have this huge list of cars and we have no idea how long it's going to be for them to spawn or how long it's going to take the player to either run out of lives or complete the level. So what we're going to do is create spawners for these cars. All right. And these spawners are basically just going to on a set time, spawn the vehicle. And we could have five different spawners if we want to, one for each lane. And let's see. I think that's what I want to do. I think I'm going to have that five different spanors that way, they can all have their own times. And if you wanted, you could just have set as one spawn limit or 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 n2d. I'm just going to call this spotter Do we want to call it SponterO? Here, yes. Let's go that sponsor one, and this is going to control my top spawns up here. And, you know, I think I'm going to use this as its base location as well. 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 if the truck spawns on this position, it'll be right there. Okay. So on my spawner, I'm going to create a new script. This is just going to be a spawner dotGD script. And once again, we're going to use this on pretty well every all of our Swannas that we create here. So what do we need to do? Well, we need to wait a set amount of time. Just going to delete this comment out of there, as well as the one down here on line nine. Whoops. Yo. Alright, so we need to wait a set amount of time. That time should be random. And then based on that, spawn a view. So in our case, we're going to be loading the truck. So I'm going to go ahead and do bar a variable here for my truck, and that's going to be a pre load here. Which 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. And with this, I'm just going to show you the one vehicle here because then we just have to come in and we can tweak this. I'll show you how we can export this as well. That way we could 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. And 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. And in here, we're going to This is where we need a random number. So let's go ahead and call time wait time. Just call it wait time. And we'll set this afloat and we'll set this equal to let's see, and 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. Alright, there we go. And since I want to double check that just to be safe, I'm going to hold control, click on Randi, and that's going to open me up to this page. And yes, I did this correctly. So by using percent 20, in this case, as you see, is going to give us an integer 0-19. Percent 100 would give us 0-99, and if we do percent 100 plus one, that would give us a number 1-100. So in my case, if I do three, then we're going to have a wait time of zero, one, two, I'm going to add one to that. Now we have to wait at least 1 second in between truck spawns. So this is going to be between one, two, and three. And 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. So we'll say await and we have to get the tree in order to do this. And 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 await, get tree dot create timer, and this is going to be our wait time here. Our random wait time that we have. We got timeouts. We're going to wait for that timeout signal that gets sent out when our timer 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 say VT for vehicle or VI for vehicle instance equals, in this case, we're going to say truck, but we should change it to vehicle. So truck dot instantiate And then we'll add it to our spatter. So we'll say self dot, add child to add it into the scene and VI. All right. Let's see how this works now. And it's not going to because we didn't call it. Let's go into our REDI function here and call our spawn vehicle function that we created. Let's try it now. There we go. So we had another truck spawn in, and we're not going to have anymore because we're only spawning it once. So what we can do from there is after we add child, right? After we add the truck into our scene, we'll just have it recursively call itself. So it's going to cause an infinite loop. It's going to spawn a vehicle and do nothing, and then spawn a vehicle. And 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 or in between spawns. So 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. And we went, Oh, we got a really close spacing on that one. So it looks like percent three plus one might be the shortest that we want to go. But there you go. So it's up to you if you want to that's a lot of close ones together. So it's up to you if you want to tweet 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. So since the truck here is at 00 in its position, Oops. This the truck here is at 00 in its position here. And we can see that if we go to transform 00. It's going to be exactly the same as its parent, which in this case, is going to be sponorO. So where my sponorO here is, it's going to spawn in that location just off screen enough. Now, how can we script to run to be able to use it for any of our vehicles? Well, what we need to do to make this work for all of our spawners that we can have as little work as possible here. Well, first off, I'm going to change my variable name from truck to vehicle, now we're going to use it for more than one vehicle, not just the truck. And that means I'm going to have to change it down here in our spawn from truck dot instantiate to vehicle dot instantiate. And we want to have this variable exposed inside of our inspector so we can tweak it on a per node basis here, so we're going to do the at sign with export. And now, what are we going to export here? Well, we could just leave it as such, and this will just work if we look at the inside the inspector. But if you want to get specific, this is called a packed scene. That's how you would export this. And then we could even just delete the preload here. So we just have at sign export our vehicle and declare it as a pack scene. Now, if we click on our spawner and our scene here, we can just open the vehicle and say new pack them or we can load. Obviously, we would want to load, but to save some time, we can just go into our filesystem, grab our truck, drag it in, and drop it in there. And if we run this, we'll see our trucks spawn just like they should, just like they did before. All right? Perfect. And if we were to grab, say, let's see, car one is also going to the left. So let's grab car, replace that scene in there, and take a look at it. And there we have it. We got it working here with a different vehicle. So all we have to do is just change this one out. And that's a lot of cars in a row there. So again, that can come down to you tweaking things. But there you have it. I'm just going to go ahead and replace this one with truck again and stop that from running. And now I can go ahead and I can make more spawners. Oops. Und we do history 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 just come on down, make sure that lines up. That does. And this is going to be car three. So I'm going to look for my car three scene, 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. And we can do the same thing for our bottom here. So I'll duplicate that one more time. I'm just duplicating that with Control D with spanor selected. And I'm just going to pull that down here for this vehicle. And this one is just car. So I'll pull car in here. And we take a look. And we see all of our cars going to the left are all spawning in correctly. Fantastic. And now we just got to get the two over on the right. And the same thing, I'm just going to duplicate my span here and just drag it over to the left hand side. And then I adjust it here for position, that should be good. And that is car four, my car four scene, and we duplicate it one more time and mass it up here for my car two sne. All right. So now I should be able to come in here and delete all of these temporary cars and trucks. And if we run it, it should be working perfectly fine, spawning all of our vehicles in there we have it. Now we can run around with our little I say little froggy here. There we have it. And now we just need a way to hop across this water so we can get in there. And, of course, a way for our little froggy to get squished. I think we'll handle the squishing next time, so we'll get player death in here. 32. Player Death and Respawn: Alright, so how are we going to get little our little froggy to get Gist 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. And we're going to use that in order to determine if he got hit by a car in combination with the Area two D that is on our vehicles. And inside my animated sprite, I created a new animation called death, and I brought in the Frogger dead sprite. And 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. And 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 script, through the code. And I think that's what I'm going to do here 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, and that error is just because we haven't created that function yet. So we see we grab our area two D because that's what's sending the signal. Dot 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. And 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. So on player hit, froggy hit, you can go with that. Player Hit is what I'm going to call mine. And now all we have to do is just come on down and create a new function for it, Bunk player hit. Now, 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, you can see it passes in the body, and that is a node two D type. So it's going to be a two D node of some type. So we have to pass that argument in, so body, node two D. And just like that, that should now connect the signal for all of our vehicles, and to test the cell, we can go ahead and print body, and we'll see this. And something I've also done is I changed my player I've renamed my player from character Body TD to be layer. And 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 slash test lane one. Yep. Lane two. Yep. Lane three, correct? Lane four and our last lane, the truck. Here we go. So all of our vehicles are detecting when we get hit, and we can see we have a lot of vehicles there with this time. So that might be a good amount, or maybe you want to increase the minimum span between them. Again, completely up to you and how you want to go about it. What about yours. But with that, all of our vehicles have now been connected and set up to squish our little frog. So the reason why I told you I renamed my character body TD for the player to player, and I'm using a Capital P is because we're going to use this name on our vehicle screen. So we're going to say if and then pass in a string here, a player. So if player N. So we want to see if this string is inside of another string, and the string we want to check is body dot name. Now remember, body is whatever object we just collided with, whatever body just entered our vehicles area, and the name property of it is going to give us whatever this name is here, which in our case is layer. So basically if our name is player, and instead of in body dot name, we could just do a double equals if we want it to be an exact name. It's completely up to you. In this case, it shouldn't affect anything. Wind our if statement with our colon, drop down to the next line, and now we can execute our PC of code. So what do we want to do when our player gets it? Well, we're going to call the DF function on our player. Now, this function doesn't exist yet, so we're going to have to go create that, but body dot death. And if you want to have an extra case of security here, you can say if body dot has method and pass in the string of death, and then we can tap body dot 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, then if that player, if that body has this function, then call it. And right now, it does not have that function. So if you wanted to put that extra layer of security in there by using HAS method, you can certainly do that. And I'm going to go into my player now and create this function funk Dak And this doesn't. We're not passing any arguments in with it. So what's going to happen when our player dies? Well, we need to play our death animation so we can get our sprite corrected. So let's go ahead and do that. Animated sprite two d dot, la death. And let's take a look at that now. What happens when we get hit by a vehicle? La Di Da, poor little frog crossing the street, at. 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. So let's correct that. After that, we're just going to set its rotation. And we've already done this when we press up. So let's add that into our death function here. And we take a look that should now be acting right, flat or 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 going to being, and we're alive again. So we have an unkillable frog. Yeah. Alright, so one prop 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. And 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. So let's go ahead and fix that on our player. And to do that, we're just going to we're going to get ahold of our collision shape that we created, the collision shape two D, and we added onto our player. And we're going to use something called called deferred on it. And what this essentially going to do if we take a look is calls the method on the object during idle time. Always returns Nou, not the method's result. So there you go. Our keyword here is calls it during idle time. So it's going to call this, whatever 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. And Sum functions is going to tell you to do that. So before we call that, you don't have to delete them. I'm just going to show you here the error. So if we come in here and I go, disabled equals true, we're going to see if we're going to run into an error here. And it doesn't prevent our game from running, you see, we got squished twice, so our disable isn't working for one. And two, if we go into our debugger and look at errors, it's going to tell us that we cannot we can't change the state while flushing queries, use call deferred. Tu it's specifically telling us to use that. That's why we're using call deferred here. Call deferred. And in here is going to be a string of what we want to do. And in this case, it's going to be set disable. I that disabled, and it takes a second argument, and this is going to be what we set it to. In our case, it's going to be set to true. And now, if we look at this, that error is going to be gone, and we're only going to get squished one time. And there you go. It's not going to pop up anymore inside of our code. And if you're worried about call deferred when we get hit by a close range of vehicles, so when it's like three back to back, we can take a look here, and it's already been disabled before the next vehicle even touches us. Now we can actually die here. Now what we have to look at is, how do we get ourselves back, now we're just non killable 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. Oops. I delete a little more than intended there. Alright, so we need to keep track of whether or not our frog has been alive or is alive. And we can do this with a simple function that just checks if alive or if dead. And based on that variable, we can either move or we can't. And for this, we're going to use a set of states, which is going to be an ENOM 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. And it's basically like a list of options that we can select from. And it makes it easier when it comes to checking things. And you can see this when it comes to basic form of a state machine, which is used for characters. For example, if you've played Grand Theft Ato five, for example, you have different controls when you're on foot compared to when you're in a vehicle. And that's because you on foot controls would be one state. Swimming would be another state, and a car would be one state and an aircraft would be another state, et cetera. And we're going to use this to know when we are alive and when our froggy has been squished. So in order to create this, instead of using the var keyword, we use Enum, the name of the Enum, which since 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. And traditionally, from what I've always seen, these are always going to be in capitals, so I'm going to have live, and then coma drop to the next line dead. So these are our two states alive and dead. Alive will be the default state here. And we're going to create a new variable called current state and we're just going to declare this as being a state. So it's going to be one of our states here. Alright, so now with our movement, all we have to do is check if current state is equal to two equals state live, and then tab our movement in. So now we can only move when we're alive. So now when we die, we have to tell it that our current state is now being set to state equal deb. So if we run this now, we should not be able to move once we die and get squished. And there you go. We got all squished in and we can't move. So now all that's left is for us to go ahead and create the respawn. Let's create a respawn function, respawn. And 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. So let's go with, how do we respond? Well, 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, right? Self taught position, and we need to reset this to where our starting position is going to be. And at the moment, that is 169 and 233. I'm just going to copy this value real quick. And inside of my main scene, I'm going to add a let's see. What did they rename it here? Ah, here we go. It was renamed to Marker two D. And give me 1 second. I'll get that up for you. There you go. So we're going to use a marker two D. And I'm going to set it to transform for now. Just going to paste the value in. Going to set it to the same position that our frog is starting at. And I'm going to call this player spawn location. And now when we respond, we can do self dot position equals our player Okay. That's not going to fill out for us, so I'll just have to type it in player, spawn, location, dot position. And this should happen pretty instantly. So let's go ahead and go up to our process here. And we're going to form another check LI current state is equal to state dot dead. You can call Respawn, and this should spawn us right back in the beginning where we started, if you get killed. And we seem to have a cue. What is myth? Oh, that's fair. Players spawn location, we can't get access to that because we actually have to go up the tree, remember we're a player and the player does not have direct access to this playersp location here. So we need to follow this line and go up one, and then that takes us to this no two D, and then that no two D then has access to our players spawn. So we have to go up one. And the way we can do this is a few ways. We can go ahead and do get parent, get node. And this G node is just a long form of writing that dollar sign. And then inside would be a string for the path directly to player span location. Alternatively, to keep this a little short, we can just get node, and we can pass in a few things. We can 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 much shorter. So we can do this with G parents player spawn location. Alright, and that should fix that. Now when we get squished, let me see we get set right back to the beginning. Only we can't move yet still because we do have to set our current stake, remember, we can't move. Current state equals State Live. And not only that, we have to set our animation back to being our idol Wops. So we'll get our animated sprite dot twoB and play our Idol Sprite, set it back to normal. And when we run it now, splat only now we can't really we can't really tell when we get respond to. So what I'm going to do, first of all, I'm going to use Caldeford 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. It does not, okay. Not a problem. We just have to have a small timer, for example, afterwards, which is fine. All right, so let's see what do we need? We need to Our dead symbol isn't working all too well because we dine and we're instantly respawn. We can't tell anything that's going on. So what we're gonna do is inside of this respawn would just create await. And we'll do what we did before using Get Tree and create that timer. And we'll set it to 1 second. That feels like a long time and the timeout signal. So 1 second may feel like a long time here in an old game like this, splat and then we respawn. Awesome. Now we're getting squished multiple times there, which is a little unfortunate. So 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. Okay, 0.5, we can get away with it. I'm going to try 0.2. And I can get away with 0.2, so we may even be able to get away with 0.1. Having that really short delay here. Yeah, there we go. So now we have that 1 second that our death image is going to be on the screen of our poor little squished Bronte. And then the respond happens. Awesome. Now if you wanted, you could set this number into a variable up here to respond timer or respond time, and that'll be your time in between your responds. 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. Now, if you notice here when I was going, if I sit right here, I might get squished by the car underneath. No, I'm fine. Oh, but I did get squished there when I turned to the side. So 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 UI section. But with that, take care. That was a lot of information that we went over. And I hope you're ready. We're moving on to the next section of the game that is. 33. Water Death: Alright, so let's make it so that when we jump into the water, we die and have to respawn. Well, to do this, we could do this a few different ways. But the easiest way that 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. I do this. Let's head on into our players script. Close on the other tabs. So we'll go into our players script. And 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. Alright, so let's just get this and we're going to use the keyword on ready, and 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. So if we said, for example, number in equals ten, it would be the same thing as if we crated number and then set it to ten down here inside of the ready block. That's all on ready means. And this is useful for when we want to get ahold of specific nodes that are inside of our scene. And in our example, we want to get ahold of that tile map here. So we're going to do var Tilemap. And we're going to set the equal to yet part node, and of course, it is currently just called Tilemap. Now, remember what I said, I think it was in the last video. Instead of using getParent here, we could shorten this down and in our get no, just do dot dot slash and have the same equivalent of G parent. I think 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. So I'm going to go ahead and create a new function here. I'm going to call this check, cell ID. Whoops. That's going to give us some void turn. And 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 pause, which will be set to our tilemap local to MAP. And then this will take a position, and that position is 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. And the cells would be each of these orange squares. So since we're standing on here, immediately when the game starts, it would tell us this cell here, the location of this cell. And 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. And to get that ID, we'll create a variable here. And this is just going to be Tilemap. Looks. Tile map. Not yet. Sell source ID. And that's just going to take the two arguments. The first one is going to be the layer it's on, which is layer zero. And the second one is going to be the position, which we already got from our map pause variable here. So now this ID should now be whatever we are standing on. So if we come in and we print this ID, and we just run check cell ID inside of our process, we see one immediately get printed out for the median, two get printed out for the road, and three for the water. Those who run this, we can take a look down in the output. We see one get printed out for our median, two for our road. And if I can make it to the water here, we can have one for the median again, and then three when we hit the water. There we go. So now we know that this is working perfectly, even if we come all the way up here because we'll check for layer zero. So we're going to have three is going to be our water since well, we know that now. So what we're going to do is we can now check I ID is equal to three, and this is where we would kill our player. All right, so we then come in, call our death function up here. Now when we touch the water, we should die. There we go. So now we can die when our player touches the water and wait for the respawn. Now, this is a little could be a little taxing when we're checking it constantly like this, no matter what. So 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'm moving any direction is the only time we're gonna check instead of spamming it. So far, good. Jump up, Dad, wait for the respawn. Now move again. Alright. 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. Alright. So we have all of our deaths in check now. All that's left for us to do is to get our platforms working and then get our little win points at the end by jumping into the right locations and then set up our heads up display with our score. And then I think we'll be about done. I don't think we're missing anything after that. Could be wrong, but there you have. We can now drown our froggy with the water, and you now know how to get the ID of whatever tile your player is standing on. Alright, to do it for this one. A. I'll see you guys in the next video. 34. Water Platforms: All right, let's go ahead and get ourselves our platform setup. 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. So for my platform here, I'm just going with a three sprite setup here so that we have using the log for this example, the end, middle, and the other end, right, middle, and start. So 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 a log if I wanted. And that has an area two D with a collision ship that covers up my log here. And I have connected both the body entered and body exited signal. Okay. So 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. So with the way that we're going to do this, we're also going to be adding things into our player script as well. And the majority of this work will actually be on our player script. So for the time being, let's go to our player 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 boolean, and that's basic 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 var platform, and that's a character body two D that we pass in. Then we'll eventually set to it for now I'll just sent it to N and we're going to need a platform direction, which is an integer default. We're going to set to zero, even though it shouldn't matter. All right. So 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, and we're going to add to our if statement. So we're going to say if ID equals three, and platform is equal to false. That way, we'll say if we're in the water and we're not on a platform, then we'll kill the player. So we have our conditions set there. Let's see. For a player, we're also going to check while we are alive. If our current platform is not equal to null, which it won't be it's only equal to it for now. It'll be have an object assigned to it once our player stands on our log. So say current platform is not equal to null, then we can just go ahead and call our position dot plus equals, we're going to do a little math. 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. So we're going to use this as either plus one or negative one, just like we did with our vehicles, and multiplied by 16. So 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, we're more time based. All right. So the only thing left for us to do is to set our platform direction, and we can do that via a function. Fun. We want to go with, let's go with set direction. And that'll take a argument of an integer, returns nothing. And all this is going to do is he's going to set our platform direction equal to ter. All right. So now we can head over to our platform script, and we don't need this ready block. We can delete that. And inside of our process, we want our log in my case to keep moving. So I'm going to go ahead and do position dot X plus equals 16 times Delta. That's going to constantly move it to the right. I 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. So I'm going to take body dot platform and set that to true because now we're on the platform and body I believe it was curb platform. Yes, curb platform equals so. And 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 cell, set it to know. All right? So what we're doing so far is when our jumps on the log, which is currently moving to the right at all times. While it's doing that, Okay. Restart that. Our log is currently moving to 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. And then we're setting the curve platform variable of our player for the current platform equal to self. So the character body here that's moving representing our platform. And based on that, we'll be able to move our character here. So current platform is not equal to null. So if we're on a current platform, then we're going to move our froggi in the same direction at the same speed. So the last thing that we have left is to actually call this function that we created set direction. So body dot or set direction, and that takes an integer, which means we'll move into the right. We'll use positive one. And 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, we ended up dying there. Might need to update this. One moment there. Bring a 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 reconnect it. 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. I believe I see what I missed here, and we're getting this information a little too quick. So before we have our if statement inside of our check cell ID, I'm going to use a weight and do what we did before with Get tree, create timer, and we're just going to have a small pause there of 0.1 and get that timeout signal. And 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. And still, if we jump in the water, whoop we went ahead and died. Alright, so how can we make this script a little more I guess we could say 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 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. Oh, got the word bar in there. There we go. Now I want to go to my platform. I can change this to one instead of zero. We can take direction and pass it in here when we call set direction. And plus equals, and we could do the same thing here where we have direction Whoops times 16. And we can go ahead and check and make sure that everything's still working. We haven't broken anything. Okay? Archeologs still moving. We can jump on it and good. Okay? So we haven't broken anything yet. That's great. And 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. And then we just create a sponder for it, just like we did with our trucks. I'll be right back while I create a couple of these. All right, so I've gone ahead and I've made some three long turtles as well, and just do a few here in the scene. And as you see, go ahead and play this log, jump to the next turtles. Next one, jump to the right. Hop on my turtle, wait, jump on the log, and I'm ready to jump into what would be our wind space. All right. So our platforms are certainly working just fine now. I is great. I do want to note I did add an await for 0.1 on body Entered before changing the platform on our platform script. So I do want to take note of that. And now all we need now is our spawners. Alright, so let's go ahead and create those. And we're going to effectively make those just like our truck ones here. Then we're going to go ahead and get ourselves or add on a no two D, we'll call it platform spawner. And we'll go ahead and start lining these up. Then we'll have one there. Ha one there. Ha one what looks like there. Okay. That look even does that. Actually, a bit of a weird spot. Yes, go there. And then we need a couple for the other side for our hurdles. A Thank it over and one for our hurdle. All right. So those look like some good spawn points. These ones a little close. Help back those ones up a bit. And we're going to have something similar to our truck spawn, so I'm going to go ahead and just copy our truck spawner. And let's see. Are those going to be At the same, different name the vehicle. Yeah, pretty much. So 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 different one 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 spawner, add a new script. And in here, I'll go ahead and just paste in the vehicle scripts. I'll call these platform. Whoops. That's not what we wanted. We'll change this to platform dot Instantiate PI for platform Instance, self at Child PI. Wait time. See, this is where the issue is going to come in. So I think Let's see. We'll go 1-2, and we'll add three to that. So we'll see how that works. Then we'll change this from span vehicle to spawn platform. So this one here is going to be our log scene. Platform scene. The next one, again, it's going to be the same. I'll go ahead and just drag my script up and attach them to all of my platforms poners. And two is my log scene. Three is the log platform, and then four and five will be my turf All right. So if we now get rid of these platforms, move my player to be underneath the colum so the frog can sit on top. Let's see if the working. Yeah, yeah, I get all the way across. Yeah, there's my turtles. Well, 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. And 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. So this will give us a variation of 11 and 12 seconds. Oh, what did I get between these cars? A So 11 and 12 seconds might be too small of a gap in this case. So at this point, we're just kind of tweaking to kind of see what fits best here. But maybe we'll try five and six. And I'll jump all the way across, and we'll see what this kind of 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. I 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 hard code these a little more or make them different specifically, you come up here and do your wait time up here and we'll make it a float, not a flat. Alternatively, you can 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. I'm going to continue with this bit of randomizing here. And you know what? I'm going to go with Ted there. And I think that'll do it for us because now we've got our sponsors. We have our platforms. So everything seems to be up and running. We could make it across. And 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. Alright. So, that's it. We're done with our platform spawning and riding them. Next, we'll cover the area where we jump into our wind zone and spawn in our little home frog there. Alright. I'll see you guys in the next one. 35. The Win Space: Alright. 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 a sprite two D that just has my home frog here. As a texture, and it is turned off or visible is disabled by default. You can do that by clicking the little eyeball here. And windSpace has a script, as well as a body entered signal connected to it. And for the script, simply, what we're going to do is we have body dot Win Zone set to true. Win zone is a new variable that has been added to the play. Body dot current state is set to body dot sta dot win. So we have a new state added here, so we now have Alive, Dad and Win. Then all we do is we get our sprite two D, get the visible property, set it to true. And on our player to avoid any issues and to fix a little bug, I pulled right here. LF current state is equal to stat dot dead. I put our 1 second awight 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 and that should be all we have to do. Now we can go back to our main scene and import our wind zone, our wind space, and just kind of fit it on in there into each of our little slots. And 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. You? So I have mine covering all my areas. And if you want to check your 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. And 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. So if you're accidentally triggering it or you might be, go ahead and enable that. Take a look yourself. And you'll see once we make our way up. We should have another log. There it is. And we can trigger our win. Yo. And notice we did not get dead printed out to our console down there. And when our state is our current state at dot win, we respawn and then set win zone back to false. Now, we're also using win zone down in our check cell ID. So we added another condition here. So if ID is equal to three and platform is false. So if we're on the water, we're not on a platform and our win zone is not true, or you could say win zone is equal to false. That would be another way of writing. Then we can call death. So 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 stake should be triggered, and we can just do a respond without killing our player. All right. The wind space is 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 timeout signal to our wind space and on timeout. We'll set our sprite two D visible to Voss, and right after we turn it to Tro, we can start the time. So we can get the timer, col 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 start spawning. Come on. Yo, so I can pop on here and we wait to go across. So if we use the timer here, our frog our little home frog is going to show up for the win, and then after a few seconds, then it's going to disappear so you can see it up there and there it goes, it disappeared. So if you want it 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. And when the timer times out, set it to false. Alright. So that'll do it for our wind space, and we just have to take a look at our heads up display or HUD or Qu Wee and look at creating a score system. Alright. So that's it, and I'll see you in the next one. We're almost done with creating ourselves a frog or clone. 36. Memory Leak Fix: Alright, everyone, today 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. And we have this from two points. I mean, technically more around ten, but let's take a look. If we go ahead and play this, play this game, and I'm just going to pull this out here. Its I'm going to have to slide this over for you guys. So you can see everything spawning off screen, and they come, they come, and just look at those cars go 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. And this is what is called a memory leak. All right. So I'm just going to 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 right at the top of our scene tree, which is only available when the program is running. And if 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. And the same with all the other spawners. And our platform spawners our platform spawners aren't too bad because they have a much slower span 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. So eventually you will have this tiny game that could take up 128 gigs of am just to keep playing it. It would take a long time, but eventually it would all add up. So let's fix this very crucial, I guess, we call it a bug, and 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 our window view, I have a set of numbers that I'm going to use here. And 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 got X, now the difference here between position and global position is if we go into our platforms 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 global position that we see on screen, regardless of who the parent is. For example, if we take a look at our win space here, we can see that its position in our main screen here is at 24 and 45. And this is going to be more of a more of a global space, whereas if we go in here, we can see our wind space, our local position here is at 00. So these are two different numbers. So hopefully, that makes sense to you as to why we're using global position here. And, of course, we want the X property because that's going to control our left and right. So if our X is greater than 436, that's about 100 pixels off screen to the right. And based off where our sponsors are, this still gives enough room to go past that. So if our global position dot X is greater than 436 or global position dot X is less than negative 100. So we're going about 100 pixels off screen and left and right direction. So if either of those are true, all we're going to do is self dot Qu free. Alright. So now we should see character platforms disabling each other or deleting each other out of our memory. And this is only one potential solution. For something like this, another solution, which if you're 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 feature video if you right so I'm going to go down to my sponsor dot GD here, My Vehicles. And let's see. Which one are we looking for here? On our vehicle script. There we go. So not on our span on a vehicle script, and same thing aside to the process. I go to paste in the same code. If global underscore position dot X greater than 436 or global underscore position X is less than negative 100, self dot q free. And now, if I go ahead and run this and Oops we're in the right scene, our main scene here. I'm going to go ahead and pause this real quick, go to our remote tree. And we can take a look at our regular spaers here where the cars are going to be here's my game window to pull that out. And if I go ahead and let this play, right? So we have some cars net spotting in here, and we can see this here. And I'm just going to extend the window off to the right. My mistake there. I seem to have grabbed Goto instead. Go. And 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. So, now our objects are all being managed, and we can only potentially have so many on or so many in our scene at any given time. And you can see the platforms at the top doing the same. And the same things happening off to the left hand side, off screen what we can't see right now. So there we go with that simple one, technically two lines of code, we have fixed our memory, our memory oh, that's 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. And 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 use 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 despawn right about this area here. All right. Watch them, they're coming in. So 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 just barely get about here, and they're gone. This is why we have to use the global position. All right. So I just wanted to demonstrate that a little more visually for you there. No redraw. Free. And are just, like I said, complete, destroys the object and takes it out of memory. All right, so there you go. There's how we can fix that memory late. Alright. Next, we can we'll be moving on to the score and HUD, adding player lives and all that in there. 37. Scoring System: A Alright. So 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 frog that gets in and 1,000 points for every time we get five frogs in. So that's what we need to keep in mind when we do this. And I'm going to start with creating a global, also known as a Singleton or an auto load script. And for that, I'm just going to right click in my file system. And create new script, and I'm going to call this my I'm just going to keep it simple and go global. And to activate this, we go up into our project settings. Let's see. Do we have that captured right now? We do not. Here we go. It might be a little big, but here we go. And we go into the Auto oad tab. Hit our browse button and just flops and select our global script. I'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. And right now, I think that's where we're going to hold our score. That's where we're going to hold our score. So if we close that, we can now open our global script by double clicking it, and to give you an example here. We can come down here. We create another function here called Print SCORE. I have a variable up here called SCORE. It's an integer, say you got 50. And the whole point of this function is just to print the school. So with it being a global, I could go into my player script here, and I could just write that name that we had for that I left, which was called Global for the capital G dot, and then we could use the function we just created, print SCR. And then when we run this, we will see that score printed out here in our output. So a global script contains variables and functions that we can alter and use within our game in any script at any point. So let's go ahead and we can remove all of that stuff and set score to zero by default. And we're going to go ahead and have a function called update score. All we're going to do here is we're going to where we're going to be printing out our score. And do we need to display should we display it on screen in this video? Now, we'll save the displaying on screen when we start covering the HUD. So here, we're just going to go ahead and print the score. When this happens, update score will take the new amount to add. Can be an int to do score plus equals new amount. And we can do Well, let's first make sure this stuff works. So every time we hop, we get ten points, right? So we're going to have to add this into our movement in all of our pieces. So we'll go global dot Updates it Update score? Because we didn't save it yet. Yo. 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. Ten, 30, 40, 50, 60, 70, 80, 90, 100, one, ten, et cetera, so this is working. We all of our buttons, fantastic. We can just get our points up like that. So the points here are awesome. I just went ahead and got rid of the other printing there falls just to kind of clear that up, make it a little easier for you. So as we go ahead and run in there and run around, you can see in our output, our number goes up every time we move. So there we go. It's working. Fantastic. Now, we also have to keep track of how many frogs we get in total should we be total frogs doesn't sound like the amount that we want. Blah, blah, blah. We call it a combo. Frogs in Um, I don't know. Let's call it the Multi frog. Multi frog. Starts at zero. Every time you add to the multi frog, right? We do multi frog plus equals one. I remember with every combo of five, we get 1,000 points. So here's where we go I multi frog, less than five, then I'll just tap this line in here. Then we'll just do score plus equals new amount. Else we do score plus equals 1,000. We'll get 100 if we get five fog in that's only going to be if we get into a scoring area, so we can't actually increase our pi frog there. So for that we actually have to go to our windSpace and go into our on body entered, and this is where we are going to increase that number. So we're going to do Global MultifrogPlus equals one. I'm just going to stick it right on in there inside of our windSpace And then we're also going to call our update so global dot update score, and we're going to pass in 50 because we got a frog in. And since we're increasing our Multi frog before, updating our score, right? So we're updating our multi frog by 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 it has to be reset. So let's see if this works. All right. We're all the way up here. Let's go ahead and get in the zone. Fun. Hey, we're up on the log. Now we wait for these turtles to come by. Good on, little turtle. The turtle. The frog and the turtle. So we're gonna have 290. So we should we jump on here. Now, when we go into Zone, we should jump up to 340. And oh, went up to 350 on that one because we also moved at the same time. Got to remember that. Um, we got our ten points. Does this frog work that way? It's actually been a long time since I played, so I'm not 100% sure on that. If that's the case, then to solve this issue, of course, we just we can just add 40, and then it'll count that plus ten from our jump in there. So if we were to go ahead and jump in that now, it would look like a plus 50 torque. Like I said, I'm not sure if it counts that actual jump or not in the actual game. Maybe it's something we can take a look at. Maybe you can just leave that to personal choice on whether or not you want to allow that to effectively count. Oh, my froggy died. Sad. Oh, I seem to have, rod froggy. Here we go. Seem to have gotten into a little bug by jumping at a weird spot. There we go. And now my little Fracki is fine. And this puts us at 5:50, so this next jump will put us at 600. So 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 or count that ten as your main thing. And I just remember we should probably get five frogs in there to actually test this. So I might go ahead and just fast forward on. It's video here for this part just so we can get five in. I All right. I've gone through it. I did my loop multiple times five frogs and went ahead, we got 4,800 points. Awesome. Seems to be working perfectly fine. A score system works. We got our plus 40 or plus 50 depending on how you set yours up 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, and we have our plus 1,000 every time we get five multi frogs. Every time we rescue five of these frog gas. All right. So we got our score set up. And I guess next, we can just take a look at how to display this and start getting our heads up display or Hud or Gooey all set up. 38. Game HUD Score: Alright. Let's go ahead and start creating the game Hud for our Well, game. Today, we're going to go ahead and just get the score up here on our screen. And for this, I just went to MNTD and I added in a Canvas layer. If I could come in here, Canvas layer is what we're looking for, not Canvas grow. And 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. So if you're playing like say Dark Souls, this is where your four quadrants are in the bottom left, for example, if you're playing sky Rim, you three health stamina and matabar Wallaby across the bottom, and so on. And for us, just to do the score here, on my Canvas layer, which I renamed to Gooey GY. Stands for graphical user interface. I went ahead and I added on two labels, two just regular labels here. And I named it score label, which just has the word score in it, and Score text, which just has five zeros. Now, the texts of both of them were too big for this project. So on both of them, I went into the inspector down to Themovides Mont size, and my score tat 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. So once we have our two labels here on our Canvas layer for the score, and 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. Just 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, so now to make this work, all we have to do is add one line to our global script here. And outside of our I and our block. So outside of both of these, regardless of how much points we add, we need to get our score text label and set the text on to actually display our school. So since we are coming from our global script, if I go ahead and run this for a moment and then just pause it, switch over to remote, you can see Global is here. It doesn't have access to anything. So we have to actually go up the tree once to get to root and then come down to our no two D and then down to our Dewey. And then from there, we can grab our Score text. So since we have to go up and then down, we can go ahead and just use get node. And remember this takes a string as an argument. And as you can see, we could just write the whole path, shrootGlobal, slash root, slash node 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. And from there, we access our GY. From there, we get our score text. And if you're wondering, we're just following that white line down. So from our global here, where we're writing this code, we have our two dots, which is the same as writing, get parent, so we go up one to the root. And then we're just pats following down on every stop like this white line. We see this white line comes down and then it goes in, points to no two D. That's what we've written there. Then we follow the line down again, stops and points in at the GY. We write that for the next stop, then we come down and finally points into our square text and we end it there. So whenever you're in doubts, go ahead and click on the Node you're looking for, and just follow that white line to get your path. All right. So on this Score Text, right, this label type object, we're going to access the text property of it, and 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 not the sorry up to the root node, and we just follow this white line comes down, points at node two D, comes down, points Guy, then comes down and points at square text, and we're just following that path here all the way down. And 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. And as you see, we can't really do much to the score in this aspect. So what we're going to do is we're going to actually turn it into a string with STR, and then two parentheses, and we can write our score inside of that. And that score is now going to be treated like a string instead of an integer. So now we can do dot, pad, and we can pad it with zeros. And we pass in the number five, we're going to have five digits, like we see here, one, two, three, four, five. So we're going to have these 50 slots. And 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. So visually, it's going to look just like it would on an arcade and in a typical scoring system. So if we go ahead and play this now, we can see our score there at the top. And if we hop around, we should see our score increasing as it should. That's a lot of cars up there. Ooh. 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. But uh, All right, so our score system seems to be working perfectly fine. It's displaying accurately. It's fantastic. All right. So the last thing for us to do at this moment is, 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 it's going to be reflected visually on screen by showing how many lives we actually have left. 39. 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 Goey canvas layer. We're going to add a new node. And I know that's not visible, just 2 seconds there you go. And we're going to search the word texture. We're looking for the texture progress bar. Alright I'm going to rename mine to the Lives bar. I'm going to move over to the textures section in the inspector. And for the progress, I'm going to move over the Healthbr dot PNG into that slot. Set the max value, again, in the inspector to six. I'm going to set my current value to six, and 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, and I'm going to bring it straight down to the bottom into that empty black space. Yo. And those are going to work as our lives. So 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. So in my global here, again, maybe game manager would make more sense for a name, but for now, we're just going to leave with that. We're going to go to Livest by default six. I'm going to create another function, update Lives for nothing. And we're going to follow Sad path. Only instead of a Scortex, we're going to get Live's bar, and we're going to access the value property here that we can see in the inspector. And we're going to say plus equals amount. An amount is going to be a parameter that we pass in, which is going to be an end, right? So when we lose a life, we're going to add negative one to it, which will make it go down to five. And also gives 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. And now we can go to our player. We can look for our death. There it is. On death. We also need to access our global script, update Lives and pass in negative one, and that should do it. Very simple, small thing to do. And now when we die on screen, we should lose a life, and we should see our life war down there, drop down to five. And I need to pull this up because you guys can't see the bottom there. There you go. And let's see if we drop down to five. There we go. We splat. I ran into the back of that car. Also, I was looking at it and you only gain points when you move forward on Frogger, and we lose life when we go in the water as well. So we can go ahead and update that if you wish as well. If you want it to be a little more accurate. We're only going to update score when we press up. Down left and right will not get us any pins. The only pressing forward, which makes sense because that is a lot of points you can rack off real quick. Dom, d d, d m. By where's my logs. Where are they? There they are. Going. Now, we ride them with the turtles. Doi, doomy, doom. Jump 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. Then won't jump on those turtles and we'll make it home free on this log. We are good. Go Alright. Awesome. There we go. And again, we can lose live heat. Cool. So our live system works. It updates visually on screen, and we have the ability to add in our lives in the future. All right. So I guess that'll do it for this section, unless you want to add live when we get school. Do you want to do that? All right. So 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. And inside of our update score, we're going to perform a new I check here. So we're going to say I score divided by score divided by, we can say 10,000, do 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. And normally we would say plus equals one, but since we want to tap it at six, what we're actually going to do is say lives equal, and we're going to use a function called Clamp. Now, clamp allows you to I have three arguments here. The first argument is what you would add. So instead of plus equals one, our first argument here is going to be one. And then the next argument, it's going to be the minimum and maximum that this value can be. So the minimum, it could be a zero, so our lives will never go below zero here. And the maximum number that we can have is six, so it'll never be a higher number than six. And that's how clamping works. Here we can call Update Lives with one, right? So we're gonna have a plus one to add on to that. Um you know what? We can actually just move our clamp right down here inside of our update lives and replace one with amount. And then we can probably get away with not having anything in there, not setting it up there, but just clamping it down there. So update lives one. And 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. So we want to change this so if we get a life at every 10,000 points, then we'll get a 10,000 10,000 times one is still going to be 10,000. And then the next time, it's going to be 10,000 times two. So we'll need 20,000 points in order to get a new life, and then it'll be 30,000, 40, et cetera. So 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. And now we just got to make our way up, pass through all this traffic. Go, go to make our way to this log. Then we can ride the turtles, turtle log, again, transfer to the turtles. Wait for this log to get up here, and then if our score was high enough, we should get 10,000, W I didn't change it. Now, did I think about it? So that's a little disappointing. But we can check that real quick just by going to 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,000 this 20 shouldn't do anything. I should just give us the one life. Which is fine? 'cause you should never get like 20,001 do anyway. The most you should get at one time will be 10,000. What do you see as we go? Boom, boom. We're almost there. We should see our lives at the bottom increase plus one. And there we go. So our lives have increased. Alright, so our lives is now working. So I'm going to go ahead and reset this back down to 40 points. And we want to make sure we can game over. But that's going to be in I guess inside of our global here, Update Lives. And we're going to go ahead and see, will this let us go negative one, a chance? No, it will not. That's perfect. We don't have to worry about that. And we can say I lives less than actually, we wouldn't have to already we're setting it up here. So we check beforehand. So we say I lives is less than zero, actually already be zero. Let's say we have zero lives left and then we die. 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, 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. And for this, we just use Get three reload current scene, and that'll be the same as if we had just started the scene like this. So 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, I'll say print. Lives. And we'll see if that resets. We're getting squished broad. We're never actually getting our ready back. It's constantly reset itself, right? So instead of in the ready, let's print it down here. Try and figure out why we're constantly done? A. It resets after two. How are we going 6-0? Alright. I'm not sure why, but the clamp seems to be what was causing that break, which is interesting 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. And now, if we run the game, see if we can run through or back to losing lives one at a time. And once we get down, we're down to three lives, two, one. Oop, O. Here we go. And into the water. Well, we're out of live. So when we get hit next, it's going to be a game over, and our game is going to reset. And here we go. We got a reset of our game we quickly run across, and we can 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. 40. Timer and Bonus: All right, let's get our timer going now. So onto our Gui, I just added another label down here with the word time with a override font size set to 12. I then have a texture prods bar, just like we did with our lives here. I changed the film mode to be right to left instead of left to right. I'm also going to rename it here timer bar. My max value is 30, my current value is 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 that I want. I'm just using the timer dot PNG that I have here. I just drag it in as the progress bar or the progress texture. And 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. So this is what we're looking at here. And what we need to do every time this timer times out 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 timer bar and we need to subtract one from the value. So we can just go ahead and grab it with our dollar sign here. You get it? Since this is coming from Mark Bouie, value minus equals one. And now if we were to go ahead and take a look at that and run that, we should now see our timer ticking down, which is beautiful. That's exactly what we want. And now we've got to check. We need to check if our timer our timer bar value, it has hit zero, and if so, unfortunately, our little froggy has to die. That's just how it is when our timer runs out. So let's go ahead and get our little froggy get node. And remember, we're on our ie here, so we're going to have to go up one for our no two D and then come back down. So dot dot slash layer, and we're just going to call our death function on. Oops, and that should be two equals because it's a comparison. Yeah. So if we were to run it now, when our timer runs out, our little froggy so just go splat, and we lose a life on our hut. You know, give it a minute there for the timer to run. Now, having this time you're 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. But I think speed might be the better option rather than changing the delay. But there we go. My little froggy has died, and it keeps dying. That's not great. We need to actually reset that now. So once it hits zero and our froggy dies, let's reset our timer bar. So let's get the timer bar and set its value back to 30 so 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. So we're going to go ahead and get node, go up one, get our Guy, and then get our timer bar and set the value back to 30. All right. Now, before I test this, I'm going to go into my platform here and I'm going to change this to 32 and double that speed. And that means I have to go to my player and adjust that. Well, up there. This is when we are right here, 32. Go. So now these should at least move quicker, and hopefully I can get on without missing. Okay, there's the turtles. We need some logs. Thank you. Log. I don't know if I'm going to make. I'm not going to make it. I'm gonna lose my froggy. Goodbye frog. I hardly knew you. I see this is gonna be a little difficult. Oh, does our time or not reset when we splatter? It does not. So we need to set that, as well. So on our player? Where is it that we die? There's our death right there, and we respawn. Yeah. Okay. And, yeah, let's stick it in depth here. So, 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. And I guess I am going to change or queak the respawn the sponor value, platform spanner and I'll remove the plus six, see how that looks now since we have completely new numbers. Okay. That's licking 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 timers in reset, as well. Fantastic. And I can see I still need a bit of a boost in there, my minimum. So 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. I 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. So 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 just give me 1 second there. All right. It's ten times the remaining time that's left. So let's see. When we get to our wind space before we reset that we need to update the score here again because we're going to add 40, but then we're also going to add whatever is left here. We're going to say, actually, you know what? Let's put this in its own variable here. We call it bonus, not ten bonus, in bonus. Of course an int. I want to set it to this value times ten before we reset. Now on our second update score here, we do time yes. 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. Oh, I might not get there at all. I might be close. Ah, got it. But you can see I got 190 points on that one. All right. So 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 timer left, and we make it to the end. Alright, so that's it. I think that might be it or Frogger. I don't think I'm forgetting anything here. And if that's the end of Frogger, 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, the globals, working with lots of different scripts. But we've completely recreated this old 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. Alright. Take care. Have yourselves a good one, and I'll see you in the next week. What are we going into? Is it Week four now? Oh, boy, Week four is going to be fun. We got a lot of a lot of things to talk about in. 41. Frogger Audio: Alright, we're going to go ahead and add in the audio for us. So this is going to count our hopping when we move, the background music, and arc death sounds. Alright. So for our background music, we can just go into our main scene here, select our root node, which is our no two D. Go ahead and hit the plus or add a new node. And what we're going to add is this audio screen player here. And then we're going to go into our sounds folder, grab the music.p3, and just drag it in there. Make sure you turn Autoplay on. That way we don't have to waste a script and waste writing any code to play And it'll just start all by itself. Now, warning, this might be a little loud when starting. So if you want to adjust the audio for just the music here, you can go ahead and change the volume DB here. The lower you put it, the quieter it's 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 the little audio tab at the bottom down there, and here is all of your audio bus. Now we have the master here, which if you've changed audio settings and games before, you notice you have the master slider. That's what this is here, and we can change the volume of this to whatever we would like. If you do want to add a different audio bus, so you can customize your sound effects from music separately, we can just hit the add bus here and we'll just rename this to music. And now with our audio stream player selected, you'll notice in the bus section here on your inspector, we now have a music piece here from the drop down, and now this music will come through this piece of audio first, and then it'll get outputted to the master, as you would expect. Alright, 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. Alright, 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. And now the rest of our sound is actually going to be on our player our player has the death. Our player has the jumping. Our player has the other sound effect other death, right? The plunk, the squish, and the hot. So we're going to go over to our player scene. We're going to add an audio stream player for them as well. And we're not going to touch anything else in the 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 player scene, we can go into your players script. And what we're going to need to do is set the audio stream by loading in the audio file and then actually play. So what I'm going to do is I'm going to go to our Deth function first, and it's going to have an ID passed into it. ID is obviously going to be an integer because we're going to get a two or three. So I'm going to call an IT, and then I'm going to set it equal to two by default. And 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. So by default, it should be our road, so it should be a squish. So what I'm going to do here is if we're going to get our audio stream player. So audioStream player dot stream we want 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 is going to be the path to our file. So two is going to be our default, so that's going to be our squish, so I'm going to get squash dot Wav, squash dot wave out of our sounds folder and drag it in there. That way I don't have to write it. And now what we'll do is on the next line, we'll say I ID is equal to three. So three, remember being our water. So 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 we set of squash, we're going to load in plunk And 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 dot 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. Okay? If we jump in the water. Okay. And if we get hit by car? Okay, we have the same audio playing on both of them. Well, that's a little interesting. Why is that? Well, apparently, we're not passing in any ID for three, so it's never going to be three. And the reason for that, remember, we got to go down and and check cell ID, we are actually checking if our frog is drowning. So that's what we have to pass three in to our death. Now, it did not air out because we told it that if we don't pass anything into it, use two by default, but since we want specifically an ID of three whenever we're in the water, we have to make certain to pass it in down here on our check Cell ID function. So now if we were to do it, we should have our plunk in the water, right, right, right. And squished on the road. Here we go. So we know that's working perfectly fine. And the only thing left for us is to do our hopping. And for that, that's just going to be up in our movement where we can check our audio stream and set that. So audio stream player dot stream equals load, and we're just going to grab our pop sound effect and drag it in. Go. And on the next line, we can just play our audio. It's audio stream player. Go play. And we can copy that into every button press here. So 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. Whoops. Let's go into our main scene. And try that. Down down. We can jump down. Then get squished down. Down down. As well as ground in the water. Down, down, down, down, down, down, down, down, down, down. Down, Awesome. Now, all we have to do is turn the music back on. So on our main scene, audio stream player, autoplay, turn back on. And just like that, we have the Frogger game complete with our audio and gameplay. Thank Thank, 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. A, there's nothing else we can really do here. You can feel free to add more onto it. You can try adding pickups. 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 it 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. So take care and have yourselves a good one, pat yourselves on the back with completed frog and 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. 42. Transitioning from working in 2D to 3D: All right. Welcome everyone to this week where we're going to talk about our transition from two D into three D. So as game developers, it's important to understand the unique challenges and opportunities that arise when working in three dimensional space, as opposed to two dimension. To illustrate this I'm sorry, let's go back in a moment. When transitioning from two D to three D development, there are several key aspects to consider. Let's talk about the fundamental difference in perspective. In two D, we work with flat objects and layers. As you can see with our example, on the left hand side here, everything is really flat. It's just a matter of what is in front of or what is rendered in front of what, right? So we can get different layers, kind of like when you're working in something like Photoshop, some kind of image manipulator or image editor. I Well, in three D, the ones on the right, we introduce depth and spatial relationships between objects. So you can completely see we have that third dimension on the two D side. We can't see the ground here. We just have the side of this dam or bridge or whatever it is that he's standing on. Well, in three D, we can see that depth going across the top there. We see the depth of that arm coming straight out towards us with that spiked end versus in the two D where it's clearly just moving down screen. And again, with depth, you can see in the top one where you can kind of try and simulate that kind of feel with two dimensions. However, in three D, you can obviously tell there's just no comparison. It's obvious which one actually has depth and which one doesn't when we're looking at the top example there. To illustrate this transition, again, you can take a look at our examples here, two screenshots, one from the two D version, one from the three D version. In this case, we're using Mega Man, which is a platformer side scroller. And here this will help you with imagining transforming this two D game into three D. You can see just the kind of difference that has. Just making that I have one decision whether to go two D or three D, the art styles are completely different and stand out uniquely apart. Now, with this The D environment, we would need to create three D models for the characters, the platforms, and all the other objects in the scene, which could be a lot more time consuming than, of course, if we went with the two D option. With two D, we kind of draw it out and we're good. We're done. Whereas in three D, we kind of got to get those models, and then we have to unwrap the model, and then we have to create the textures for the model, and then we got to create the material for the model. So we have all of these steps before we can even put it in the game early for testing or implementation, things like that. And then we also have to we also introduce a camera that typically in three D, when it's not just something stationary, such as what appears to be a boss fight on the bottom, it has a camera that's going to move with the player, whether that's moving around in a full 360 degrees space, which could happen in those three D versions. Or if they just remain more stationary on the side to give us more of that side scrolling feel like we're clearly seeing here. Now, as you can see, transitioning from two D to three D requires a shift in how we think about game development. We need to consider spatial dimensions, depth perception, the cameras movement, and object modeling. It opens up a whole new world of possibilities for creating immersive and visually stunning games, although some people will prefer two D over three D the majority of the time. So keep that in mind that the type of game that you are creating it might be better or work better, either for the vision or mechanically, whatever, in two D than three D or might work better in three D than in two D. So there you have it with the transition from two D to three D, we need to understand these differences and challenges that arise during this transition process, and you'll be well prepared to embark on exciting three D game projects. Remember to practice and always experiment with various techniques to help you with gaining confidence in working in this new dimension of game development. Alright. Next, the net lesson here, we're going to go ahead and talk about and help you understand some of the differences between two D and three D. And then we'll talk about the similarities between two D and three D. 43. Understanding the Differences of 2D and 3D: All right. In this example, today we have a Mortal Combat shown here, both the mythology side scroller and two D, kind of almost a pseudo three D, as well as the three D iterations that came later, both with a three D menu and a three D store mode that allowed you to run around and explore. Now, today's video, today's lesson, we're going to talk about some of the differences between two D and three D here. And it is important for you to understand these differences as it can be crucial when it comes to creating games effectively to help you utilize the strengths of each dimension. So the primary difference between two D and three D game development lies in the visual representation. As you can see here, it's pretty obvious and gameplay mechanics. In two D, we work with two dimension, just the width and the height. Where objects are portrayed on a flat surface. In contrast, three D introduces the third dimension of depth, as we can see here, allowing for more immersive allowing for a more immersive and realistic experience. So let's examine some key differences in two D game in a two D game. The gameplay typically occurs on a single plane. While in three D, objects can move in three dimensions up down, left, right, forward, and back. Enabling complex interactions and exploration, which is why we have something like conquest mode up there in the top left because you're encouraged to go out, not only follow the story, but explore and do some side things to help or to unlock some secrets and hidden characters and things like that, which you wouldn't really get in a TD game. And if you could kind of squeeze that in, it wouldn't be the same overall experience. Additionally, in two D, collision detection is typically simpler, as it involves mainly just checking if two objects are overlapping. In three D, collision detection becomes more complex requiring consideration of object boundaries and the surface. And as you can see, understanding the differences between two D and three D game development will help us make informed design choices and utilize appropriate techniques, whether it's the visual style, gameplay mechanics or the user experience, embracing the unique qualities of each dimension enhances each qualities of each dimension, enhances the overall game experience. So remember whether you're going to go in two D or three D, embrace the strengths of that dimension. So there you have it briefly the differences between two D and three D game development. By recognizing these differences, you'll be more equipped to create games that leverage these strengths of these dimensions. And remember to, of course, experiment with various techniques and stay creative in your game design. All right. In the next lesson, we'll go ahead and talk about some of the similarities between both two D and three D. 44. Similarities Between 2D and 3D: All right, let's go ahead and talk about some of the similarities between two D and three D development. Now, despite their unique features, both dimensions share certain core principles and techniques. Let's go ahead and jump in and take a look. While two D and three D game development have their distinct characteristics and strengths, they also have several similarities. Firstly, of course, both dimensions rely on key programming concepts such as the variables, functions, logic. Whether it's two D or three D, these fundamental programming principles will remain unchanged. So if you have, for example, a character picks up an item. Well, that character, you're going to go over to the item and touch it or interact with it. And the logic will remain the same, because you're going to take it, you're going to make it disappear and then in the code, you're going to add it to the player's inventory or their collectible count or whatever it is that you're going to do with that. That logic remains completely the same, whether it's two D or three D, is just going to be written slightly different. Secondly, the importance of game design principles holds true for both dimensions. Concepts like player interaction, level design, and balancing gameplay mechanics are crucial elements that impact the player's experience regardless of whether it's two D or three D. So if you're bad at game design in two D, you're probably still going to be bad at game design in three D. It's not going to make any difference which dimension you're working in. If you're bad, you're bad, and all you can really do is practice your skills, maybe pick up some books and just enhance your game design ability through practice. Additionally, both two D and three D game development involve the use of assets, whether this is going to be sprite in two D or models in three D to bring the game world to life. Whether it's a two D character Sprite or three D model, the process of creating and integrating assets into the game follow similar principles of design and implementation. Again, notice I said similar, not the same. Furthermore, the importance of optimization will apply to both two D and three D games. Regardless, again, of the dimension, developers need to consider performance, memory management, efficient algorithms to ensure smooth gameplay and optimal resource usage. For example, I mentioned when we're looking at Boger and we're fixing our memory leak issue, I mentioned object pooling. This is a very important thing. That can help with managing our resources and memory management. And depending on the game that you're creating, this could be a very very optimal way to approach a situation. So as you can see, while two D and three D game development have their unique aspects, they still share the core principles and techniques. And by understanding these similarities, developers can leverage their knowledge across dimensions and create captivating games. And what's even crazier is you could mix both of them into the same game. You could maybe create the same game twice in a sense and give the player the ability to choose whether they want to play in two D or three D. That's something that could be unique to your game specifically or have some kind of mechanic where you jump between going in two D and three D. You can you can use the multi dimensions as a game mechanic or just part of the experience. And there you have it, the similarities between two D and three D game development. And by recognizing these commonalities, you can apply your skills and expertise across different dimensions, making you a versatile game developer. Remember to continually learn and experiment to enhance your game development capabilities. And although they are similar, I do want to I'll note here that personally, my preference, I prefer to work in two D, even though the similarities are there, and a lot of that logic and everything still transfers over and works. Across dimensions or dimensionally. It's kind of weird way to phrase that. But just out of preference, myself, I thought I would enjoy three D. But it turns out, I actually enjoy creating two D. So you might find that you end up after trying out three D here. You might find out that you have a preference for two D as well, or maybe you'll prefer three D styles. Or working in three D, rather than creating anything in two D. So it's okay to have that preference, but it's also good to know that you have both the knowledge and technical capabilities to go between two D and three D at any point and acknowledge all the commonalities, the skills, logic and everything transfers between dimensions. Eight. Alright, let's go ahead and dump into the next lesson and see some things that are a little more unique to three D that you can't really get around. 45. Materials: All right, everyone. Welcome back. Today, we're going to talk about something that is exclusive to or I shouldn't say technically exclusive to three D, which will be materials. So let's go ahead and explain to you what materials are. Here in the goto Inge, materials play a crucial role in defining the visual appearance of an object in your game, and we'll dive kind of deep into materials and at least discuss the different texture map types that are available when creating and applying materials to objects. Materials are used to control how light interacts with objects and how they are rendered. They define properties such as the color, transparency, reflectivity, and more. One of the key aspects of materials is texture mapping, which allows us to apply images or patterns to objects to give them realistic or stylized appearances. So I'm going to go ahead and just open up this you inherited Mega Man here that I just found online. And before anyone asks, no, I cannot share this. But if you look online, you'll probably find it. I'm just going to select Object four here. And if I open it up, I will find this one specifically as surface zero, so it just has one surface. So one material. If I open that up, One moment, I got to make this unique, so I can at least tweak it to show you some examples and make unique. All right. All right, so as we go through the Albedo map, which is right here. It's also known as the diffuse map. Why are there multiple names for the same thing? I don't know, but there are, so it's just kind of keep that in mind if someone says albedo and you are given a diffuse map. They're the same thing. And this texture map defines the base color of an object. It provides the primary visual appearance of the surface. And as you can see here, this is where the main texture is applied. Now, this does affect color. So I can always come in here and change the actual color being applied on top of this texture. So if I want to, I can come down here and I'll have a green mega man. Maybe I want more of a purple mega man. Or pink isn't really not too pink there. We can get ourselves a red mega man. You get the idea at this point, right? So the albedo is the base texture and color, that can be tweaked on it. Normal maps. Let's see, where are they in here? Normal map. Here we are. Now, in Gatto here, you have to actually turn it on before you can apply a texture to. And a normal map adds the illusion of surface details by modifying the lighting calculations or it creates the impression of bumps, dents, wrinkles on a smooth surface without increasing the polygon count. So it kind of bait geometry in a way by manipulating the light and how it affects our objects. Now, I don't know Mega Man might not have a whole lot here, but if we go ahead and play with the scale of it, you can kind of see it here happening especially down here in the lower body. We go back to the default scale and then we tweak it, you can kind of see how it's really affecting the way the light is reflecting off at the top here. The roughness map. Now, you may also get this in the form of a smoothness map, and smoothness and roughness are opposites. So if you have a smoothness map and you need a roughness map, then you can just invert it and it should be fine and vice versa. Now, in this case, this mega man, it has a color texture here, and it's specifically using the green channel for this rather than the standard gray, that's fine. Now, the roughness map, this texture map controls the surface roughness or smoothness of an object, and it affects how light scatters and reflects off the surface, creating variations in an object's appearance. Now, I know this is going to affect the helmet a good bit, so I'm going to come up here for showing you it. So if I were to take the roughness down and make it smooth, look at that. That is, like, super smooth, fresh out of the factory. That's a beauty right there. That is a brand new helmet is what that is. And as you see, as we start get back up to the roughness, all of that lights kind of dissipate once it hits it rather than kind of reflecting off of it. And this worked hand in hand with our metallic map here. This texture map, and again, they're using the same texture for this, but they're using the blue channel. And the metallic map here or non metallic properties of an object and it turns the light or the level of reflectivity and shininess of a surface. So if we were to have a super smooth surface, as you can see, with our metallic being all the way up, it looks like a nice shiny piece of metal. However, if we start bringing that metallic down, we can see we start getting to some other materials, maybe like a shiny or glossy plastic, for example. Until we get all the way down to where we have no metallic, which isn't realistic. Every object at least has a little bit of metallic in it. And specular kind of goes on that. You can see it there. So specular might be something that we use in maybe eyes when we want to have a little more shine in them, for example. Or if you have a wet object, that could be good in there as well. So just going to turn metallic back up and roughness back up to its default. And ambient occlusion, does this model have ambient seclusion? It does not. So ambient occlusion is like a shadow texture that you can put in to add a little more detail, say, right around the edges here to get it more of an appearance of a helmet sitting on top of a head. And it works like that inside of, all of these little creases and crevices that would be a little difficult for us to get into. But in general, that's what it's doing. It's basically simulating the shadowing effect caused by the presence of nearby objects or occlusion from indirect lighting, and it overall just adds some depth and realism to the object's appearance. Now, one more map I do want to go over is located here, emission. Now, the emission map, there is a texture here, and you can see it's almost completely empty, but there are a few objects on there. And what the emission map does is emission map is glow. Basically of your object. So if you had, say, a character with a robotic eye and you wanted that eye to glow, especially in the dark, this is where you would do as an emission map. Now, you might not be able to tell too much, but it's this little spot inside the cannon and the light here. Those are the two main points that we're going to notice. And if I just increase that energy multiplier, Look at that, you can really see that now on there and especially inside the cannon. You can see that red glow happening as we start getting closer to looking directly on, and we can see that tweak here as I turn it down. And as you see all the way off, that's how the texture looks normally. And then when you add that emission texture to it, it all lights up. So if you have lights on an object or you need some glowing or anything, the emission map is what you're going to want to use for it. Now, we do have a bunch of other little things here that can just add to little details like refraction of your lighting, a little bit of backlighting, some subsurface scattering, which is as if I'm not mistaken, light, the way it's interacting with, like, skin. We've got height here. If you wanted to mess around with things like there, which I don't know I haven't messed with the height. I know we used to have a depth map. We got billboard, grow, transform. We got all these new things in here that came with four. And I'll mention something that goes hand in hand with proximity fade here. Hoops. So if we were to turn that up a bit, we could see all these we see these distances here and all the stuff is going to be affected based on how close you are to an object. As you can see here, that's something that would help with performance, for example. That way, when you can set up so that when you're far enough away, it just completely disappears. Maybe something like that, zero, two I'm not getting it in there, but you get the idea, right? So you can best round with all of that kind of stuff going on, as well as if you were to go on, do they have the second pass here? Side of this matures kind of hard with everything opened up here. And I do not see the second pass, which is interesting. But here we go. We got shadows that you can disable, whether or not it receives shadows. We got UV one and two, which can be used as different have different things here we go. Next pass. So you can add another material directly on top of this one. For example, this is one way you can get a blackoline round a character to give more of an anime look. There are some things you could do that, and you would put the outline in a second pass there. Here we go. The visibility range, this is more so what I was looking at, I do believe. So we'll say a minimum of one, and then we'll say it ends at ten. So there you go. So you see as we get closer, the object is in and you back out, and the object is no longer rendered, or at least that part of the object is no longer rendered. So you can keep that in mind when it comes to some optimization, especially if you have an object that might be really bogging down your performance. That's visibility range on that. But that should wrap up materials and the different kinds of texture maps. Oh, I should mention one more thing inside of the materials here is They did change it. All right. So now we just have all these extra options like vertex coloring, shading, transparency and all that stuff. So if you want to have transparency on an object, say you're using a PNG image for your texture, then you're actually going to have to tweak this and set it to, I believe Alpha, and it does not work with this texture. But instead of using disables, so you actually have to enable the transparency if you want to have transparent portions of your texture or mesh, whatever. All right, so that covers materials here. And hopefully that gives you a better understanding of what materials are and the main texture maps that you're going to come across and that you're going to be using as you create three D games. And always remember, of course, to experiment, combine different maps and see what kind of different visual effects and looks that you can get. Maybe you'll find something that you like that is just completely created from just messing around. Alright, that'll do it for this section or at least this video, and hopefully you learn a bit about materials and what they're 46. Lighting: All right. Greetings, everyone. And today, we're going to take a look at world, the world of lighting, and we're going to talk about the basic three point setup that is used when it comes to lighting. Now, obviously, when it comes to lighting up a scene, there's a lot more that goes into it. You have to take a look at things like the intensity of the light for each individual thing that's going to be emitting light. How many lights do you want to incorporate into that scene? That's going to affect your performance and so on. But for now, let's go ahead and take a look at how lighting is a critical element that can greatly enhance the visual quality or affect the atmosphere of your game. Alright, I Goto lighting plays a vital role in creating realistic and immersive environments, which can be said about pretty well any game. And the important thing is, you can have something with photo realistic textures and all your photo realistic maps all set there. But if it can't be rendered well enough or your lighting isn't good enough, then even though it's photorealistic, it may not even look realistic still. So lighting is just as crucial to your materials and your overall scene as, say, shading is in a drawing. I can completely transform what you're looking at. Lighting also helps set the mood and emphasize the important elements and bring your game world to life. Now, when working with lighting, there are several key aspects to consider, such as your light sources, the shadows and your light properties. One popular technique is the three point lighting setup, and it involves using three lights strategically placed around the subject to achieve balanced and visual appealing illumination. Now here in this scene that we're looking at, I just have mega man here from the material section. Again, I just went online and just found this model. Just online, he was free for download. And you can see, even though he's not lit, we have the red portions lit up. We got this bar lit up and the inside this little cannon here, all lit up. And those are from the emission maps that are kind of I guess you could say lighting that portion up that has nothing to do with our lighting. That's just all texture. Alright, so let's break down this light three lights that you use in a three point setup. The first light is going to be your key light. And while we're doing this, I'm just going to click on my camera and click on this perspective button here. This will let me see what the camera sees here. So the first light is going to be your key light, and the key light is the primary light source and provides the main illumination on the subject. Alright. It creates the primary highlights and shadows that define the overall form and shape of the object. Now, do note that if you want shadows on your light, you actually have to go into the properties of your light and enable your shadows. And then, of course, you can tweak some of your settings there, which is going to be up to you on that. Next, we have our fill light, and this is generally positioned on the opposite position opposite to the key light to balance out the lighting, and its purpose is to soften the shadows that are created by the key light. It helps to reduce the contrast between light and dark areas, which result in a more even and pleasing illumination. So if we go ahead and take a look, say, right around the helmet here, I know we can't really zoom in on that section, but I just want to make sure I wasn't moving the model. We go ahead and take a look here. Just looking from the front. We can see how harsh, like this darkness is here in the helmet. And this along the side here, depending on your monitor's brightness, could be pretty dark as well, especially considering our light sources coming from the top left here and coming down. And if we were to again, come down and look more at the feet, we see this harsh contrast that we have going on the feet and legs, as well. All right. And if we enable our fill light, we can see those portions all light up, but it gets a lot softer is not as harsh of a contrast in here. And obviously, that's going to come from tweaking your energy here. And generally, you want the energy to be less than your fill light because remember than the key light remember the key light is your main source of energy here. And depending on your situation, you can use the fill light to either go colder or warmer and have a light that complements your key light. And the last light in a three point setup is the back light, and the back light, also known as a rim light or hair light is placed behind the subject, typically at a higher position, and it adds a sense of depth and separation and highlights the edges of the object and creating that sense of depth and dimension, if I go ahead and enable that, we can see we get some lighting right around the edges up here. And again, we could come in and we could tweak, play with these numbers, find something that works for us. But you see how that rim light is really highlighting these edges here. On this back light or using this back light. So I'm just going to tweak this right back down to its default numbers here. But you can see here are before and after, when we're looking at no lights here versus just a very basic three point setup. That looks miles better already, and we're not even taking other things into consideration like the world lighting or the lighting of the environment that is around us or anything. And we already have a beautiful enhanced version of what we start with. So I hope this help with illustrating the three point lighting setup. I'm going to go ahead and exit the camera preview here. So if we were to take a look, we can see we have our key light over here, again, on that angle coming down on us. If we come up from above, we have our three point setup and it looks just like a triangle. So we have our key light here going opposing in the opposite. It's going to be our fill light, and then our back light is always directly behind our character. Now, in this, I'm just using spotlights. But of course, if we're outside, we could use things like like a directional light, for example, or you might be using spotlights depending on your scene. So these are things that you can take into consideration. The third type of light that we have is called the omni light, and that basically emits light in a full 360 degrees area. So this is that would be more for things like light bulbs, candles, things like that. Now, I can't finish talking about's come back to the camera preview. Lighting without at least mentioning a environment. Now, a camera can have an environment, or you can have an environment that's related to the scene itself. So, for me, I'm just going to add a world environment to my scene here. And it's important that you at least know how to create a basic sky cause with Goto four. You're not going to have a sky of any type. It's just being captured anymore. It's not. Go. So as we can see, we just have this gray background, and that's not very nice when you're talking about Ampeily if you're outside in the world, you kind of at least want a sky, right? So you're going to see how to make at least a basic sky here, so we go to the environment and our world environment. We created a new environment. And click on that to open that up. Then we have our background. We have a clear color, but what we can do is we could do a custom color, Canvas, camera feed if you wanted to. But importantly, we're just going to go with a sky here. And then inside of our sky section, we can go ahead and click New Sky, open that up for the sky material. We can say, we have a panorama sky, procedural sky, and a physical sky. And with our physical sky here, you can see you got a ground color here, and our color is appearing a little dark. Seems like it might have been a problem there. Let me just go back in. And let's go with a procedural sky. Here we go. That's something more normal that you would see. Now, the important thing here is this skylighting can affect your model as well. So this is what I was saying. We were just looking at the three point setup, but your sky can come into effect. So let's say that we're sitting here in a Let's go with a, I don't know, a sunset, right? So our ground, maybe we're going to be more on the green side, doesn't really matter too well on that. For our Sky, our top color is going to be more on the purple side, right? And then the horizon is where we're going to get our orange. Right. Now, it may not look like we're having a whole lot of impact here, but we are getting a bit, as you can see in the lighting here, right across the nose, for example. So if I take this, I'm just going to copy that color. If we come in, there you go, you can see how it's affecting our model here. I'm just going to put that back in there. And inside of this environment is where we can also get other features that can have an effect on our world, such as the glow. And of course, your options of where you're going to go ahead with that bloom. So that's going to go with your excuse me there for a second, the post processing. That's what we're going with? So your bloom, your strength of all this stuff, the intensity. So you got all these things that you can play with, but turning that off, you got fog which can affect your lighting. And then we also have volumetric fog, which can affect your lighting. So we got all different things here to take into consideration. And most importantly, SDFGI here. This will have a performance impact on your game, but we are going to also have a more realistic light simulation here going on with our character. Here we go. And, of course, you can always tweak whatever little effects that we can have in here and come up with something that you enjoy. Obviously, density is a little insane. Oh, that's og, my mistake. Clicked on the wrong one, SDFGI. Here we go. So that's calculating all of our light bounces. And there we go. Now we can have something that's going to be a little more realistic and it could be more dynamic. For example, our bounce feet here. You can tweak with that. Cascades This goes from one through eight. The lower the number, the more performance it's going to be. Then you can see it calculating these bounces out as we get a slight change and then going up to eight. Then you go see we calculated in some more of those shadows, like in here with the neck and then it in the little it's not a clapping in the back. That would, I guess, be our boys traps. Trap Zoids raps always no trapezius. It's like, wait a minute, that didn't sound right. But you get the idea. With that, we can create a basic sky that can have an effect on our character, as well as I showed you how to do a basic three point setup. So you're going to have a triangle. Back lights always directly behind. Wherever your key light or your main light is. The fill light is going to be on the other side of it with a lower energy level just to make the shadows not as harsh. Of course, word environment, create a new environment, sky for the mode, create a new sky, and you'll go with the procedural sky material. All right. So hopefully I gave you a pretty good idea on that as to how well light can really affect your object at the end of the day and just how important lighting can be. I'm going to go ahead and show you just a couple of comparisons here at the end of things with no lighting versus after they've been All right, so here on screen, you're saying the wrong window there. But here you're seeing a before and after when it comes to lighting and just really helping with setting that atmosphere, especially with an image like this, you can see just how important getting good at lighting can really be and just how much you can really affect or seen. I'm taking it from something that looks maybe old or just kind of okay to looking newer, maybe a little more realistic. And if maybe going for more of a spooky vibe, and that just gives you a pretty good idea here. So before and after when it comes to lighting. So don't slouch when it comes to lighting. It's very important, and especially if you're going to be working alone and you want to do something in 380 like this. We sure put the time and attention into really learning lighting. And there are people out there that purely focus on lighting environments and scenes and things like that as their job, I'd say, right? Now, they may do other things as well, but they focus on all the small things that you may not notice as a player in a game, for example, or if you're taking lighting into consideration when lighting a scene, maybe for doing some visual effects. But there you go. I'm not going to rant on any longer. I just wanted to let you know how important lighting is going to be when it comes to three D as opposed to two D, as well as show you how you can at least create a basic sky and visually show you the huge difference, something even just a basic three point lighting setup can make. 47. 3D Assets: Alright, welcome April 1. And this section, we're going to go ahead and we're going to create Frogger again. Only this time we're going to create it in three D. This way, you'll have a fair one comparison, I guess, could say, of working in two D versus three D, and that should give you an idea of both the similarities, the differences, and maybe give you an idea of your own kind of personal preference that you would want to irk it. Alright, so I'm just going to use basic cubes, just basic meshes when I go ahead and create it, but if you want to use three D models in your program, you can go ahead and do that if you want to create them, go crazy. If you have some already, that's great. But if you want to use some three D models and you don't have any available to you, you can go online and you can find three D models all over. For example, this place here is Sketchfab, and they have both free and paid models. All you got to do is you can go ahead and make your search up here at the top. Hit downloadable so that all your results can be downloaded. And that way it removes any situation where someone's maybe just showing something off. And now if you don't want to put through any money, there are plenty of free options out there. And these ones here with the dollar sign up in the top ight corner. Oh, I can't see that one. So we'll come over here with the dollar sign, top ight corner here. Here. Those are ones that are going to cost money, but the ones that do not have that dollar sign. And that will just take a second to load. And you can go ahead. You can take a look at it. You can view it, which is great about fab. You can go ahead and just hit the download button here on your free Moth. Obviously, if you're willing to spend money, then you have to go through the whole putting in your cart, checking out and all that stuff first. But that's only if you want to. I did find some free frogs here that you could use. I don't know if any of these come with animations or not. You'd have to check individually. And for that, you'd go to more model information here, and then you can get all the information, all the different model types and GLB, GLTF and FBX, as well as OBJ will work. However, OBJ, I can guarantee you has no animations as an OBJ just for a static object. And you can actually come down. You can see PBR. It's all your materials. It's got four textures for the sproc specifically. So you'd have to if it doesn't apply automatically, you'd have to go into the materials and load these textures in, like we saw in the transition section. And as we come down, we can see, in this case, this one has no animations, and it is not rigged. So you would have to rig it before you can animate it if you wanted to make your own animation. And there are no animations that come with it, obviously, it's not rigged. Alternative, we also have some logs here that you can get here's a truck here, perfectly free. So if you wanted to get models, you can head over to a place like Sketchfab here and you can take a look for some free models and download them. If you just want to use the basic shapes like cubes like I'll be using for this, then that's perfectly fine, too, because we're not working with three D models. We're not doing anything fancy or specific. We're pretty much just moving things around on the screen. We don't need any fancy animations to make any of this work. Alright, it's up to you which route you want to go, whether you want to make some, find some free ones and download them, or if you just want to use the basic shapes that come with the engine. Up to you. Now to do it for this one. It's up for you to think about. And if you want to use three D ones, go ahead and spend your time now collecting them and getting them together. If you want to import them, it's just like your other assets to drag them in to your project folder. Alright, let's get started. 48. Gridmaps: Alright, everyone. Just like in the two D version, we're going to start with creating the background for this. And in order to do this, we're going to need a few things. First of all, we're going to need a camera here that is pointed down so we can actually see what's going on here. So go ahead and preach a three D scene, which would just be a no three D for your root. I've renamed mine to say Main. Add a camera three D in here, and you can go ahead and add a grid map. Grid map is the three D version of a tile map. And with your camera three D, you can go ahead and set your Y position underneath the transform section to 25 and your rotation of the X to negative 90. That way, you can look straight down. Now, if you were to run this scene, you'll see a gray box. Fantastic, but at least we know the cameras working or at least shut by default. If you're paranoid about that, you can go ahead and tick current inside the inspector. But since we only have one camera, this should be the only one that activates right now a grid map. NRT is a grid map. We must have our tile set, right? Art is a tile map. We need a tile set. Well, for a grid map, we need a mesh library. And we can create a new one, but it doesn't have any resources in it. So what we need to do actually is create this library. So to do that, we're going to go ahead and create a new scene, and you can just make a node three D as your root node again for our scene. And again, that's just new three D scene, and you'll have one. And all I'm doing for the road, water, and median is I'm just bringing in the textures from the two D Frogger, bringing in the sprites and using them as the albedo texture. And I'm just leaving their default position in the middle. So I'll show you how I do that. So I went in and I create a mesh instance three D. I go ahead and rename it. This is going to be my brass block for my mesh, I go ahead and open this up and select a box mesh. Now, if you had a custom mesh, a custom model here, if you wanted to bring in specifically for this block, you could go ahead and drag the mesh into this specific spot. This mesh, this object. This is where you would do it. Now, for just these blocks and the grid map, you shouldn't need to unless you're bringing your own custom, again, meshes in for each of your blocks. Now, this block is just completely white here, and you'll notice it's much smaller. I'm just going to hide the other ones here so we can focus on this one. All right. So the first thing is we have to go to scale and set XY and Z all the way to two times on its scale. And the reason why we're doing that is so that it fits an entire block of our grid map instead of being off to the edge or off to the side in some weird position. It's just easier for us to go ahead and do this, just double. Alright, so we have our little cube here. Now, what we need is a texture on it. So what we're gonna do is we're going to open up the surface material override. And the reason why we're going to do that. Oh, no, this mess comes with it. So we can just open up the mesh section, and there's the material. And we just add a standard material, open that up. And here is our albedo texture. And this is where we would go into our Frogger sprites. And for my grass block here, we could go ahead and bring home in if we wanted. We could do that, but it doesn't look all that great. It's kind of weird. And personally, I'm not that big of a fan of it. So, personally, what I'm doing with this is I'm going to grab the median texture, and I'm going to place that on there. And then just out of personal preference, I'm going to come down to the U V one, specifically, and I'm just going to set my scale here from my UVs to two. I think that at least looks a little better. Now, the problem is, this looks exactly like our median, and we wouldn't be able to tell the difference. So this is where I'm going to use the next pass here inside of our material, and I'm going to add another standard material here. Now, when I open that up, I'm going to set the albedo to being a nice green that's semi transparent. I'll go up to the transparency section and set the transparency to Alpha. And there we go. We have, like, a green version of the median, so it stands out and it's different enough. Now, you would only have to do this for the grass block if you're copying me with this. And the median, you just use, of course, the median texture, double the size, water. You can do the same thing and same with the road. And once you have that, I would recommend saving this, so Control S. Or, of course, you go up to your CN and save and save this as your mesh lib, mesh library. And this will be just in case you want to come back and edit this in the future, which we probably will at some point, just the heads up. And once you've done that, we can go up to SN and go to Export As, and you'll see mesh library as an option. I know you can't see it on my screen now, but just SN export as Mesh Library. And when you do, you'll be presented with this screen. Not is big. There you go. And just for safety, I'm going to go ahead and make sure fly meshed instance transforms us on, even though we should be fine. And just save it somewhere. I just called Min MAP, and I use the mesh lib extension just to keep things organized because I don't want everything to be named Res or Trez, for example. I like to keep things named properly so mesh lib or material, shader, things like that. I like to keep them keep the extensions relevant to what it is. So once you have that, go ahead and say that and hit the Save button. If you already have one created in the future and you come back and edit it, you can go ahead, just overwrite it. You'll be fine. And back inside of our main scene, we can actually go to our grid map. And you find where you saved your mesh lib, you can go ahead and drag it into the mesh library section of your grid map, and there you go. You have all your pieces there. Now, I went ahead and I've got Grass block and grass end just because of my naming, and I went ahead and just have my set to add instead of overwrite what I'm going to do is I'm just going to come back in, go to export mesh library. And I'm going to say I'm going to uncheck, merge with existing. That way, I just completely overwrite it and replace it. And now when I come here, I just have my normal blocks. Awesome. Alright. Now, for the project, I'm using the same resolution that I use on Frogger on r2d3 36 by 256. And if I go ahead and run that, I'm going to have an easier time when it comes to placing my blocks. All right. Now, you'll see while we have the gray block there, or it doesn't look like we have anything on our window. You'll see if we go ahead and place something, it'll appear. And that's how we're going to determine where our limits are. That's what we're going to do. We're going to outline our limits if I come down here. That's the top, which means I should be looking this way on my camera. Let's see. That's still on screen. That's a little too far. Okay. So that's going to be that block. You can go over one. And I'm going to call it there on that block. And now, it's just a matter of finding the other corners, which if you count out the grid spaces, you should be able to find it easy That should be my corner there. And then our corner should be right on here, one more? Yes. All right, so there's the corner of all of our positions. Now, if you want to place it left click, if you don't know how to delete it, you didn't figure it out. It's a right click. And now we can start placing our objects. So our median is our second row here. We had the road on the first row. We had road on third, fourth, fifth, sixth and seventh. Then we had median again. We go across, we had another five rows for water. One, hooks two, three, four and five. Let's see what do we have next? We had our wind zone. So for these, I'm going to double up here on the ends. This because it's Oops an odd number here. And we'll have doubles, like so. Three bone, one, two, three, down, one, two, three, down, one, two, and three down. I'll fill in those empty spaces with water. And then we had the back row, which was just water where some of our UI was. Now, let's go ahead and fill that in again. And there we have it. We used the camera to make sure that we filled up our entire viewable area here. Now, this is kind of dark, as you can see, and that's because we don't have any lighting. So I'm going to click on my main note here and I'm going to add a light. And specifically, we're going to add a directional light just so we can kind of emulate a sun coming down. I'm going to lift that up above, zoom in so I can see what angle it's pointing at and point it down. Here we go. Now we have some light shining on our tile set or grid map that we can view and actually see what's going on here. All right. So that's all that we need to do here. In this video. Now, I will note that we are on floor zero here. However, if you wanted to drop down to negative one, you'll see we'll go down space here. If you wanted to go down one, you can certainly do that just so it levels out so that 00, zero would be sitting on top of our objects, or so that we can have, say, a frog sitting at zero, zero, and would be on top of the ground instead of having to raise it up, which I think I'm going to go through and do real quick here. Alright, so I went ahead and lower mind by one, and as you can see in the camera, I am now just slightly off on my numbers. So we can come up and we can just fill those extra spaces in. Just make out one wider. And that'll fix that. Boom. Boom. Simple fix. Easy to do rs. You know, I think I'll just bring in more water there on the edges. All right. So there we go. There we have it. I need one more road on the bottom to cover up that bottom grid. Here we go. All right? I screen is fall again, change my floor down to negative one. So now when we sit at 00, we'll be directly on top of it. And there we go. We have our grid map set up. We have our camera pointed down at our grid map so we can look at it from the bird's eye view. And that'll do it for this one here. Now, you can see that's very easy aside from having to create our own mesh library, which I mean, to be fair, if you're in two D and you're working with tile sets or tilemap, you kind of have to create your own tile set, right? So it's not too big of a difference going from two D to three D so far. We had to add a camera in, and we had to add a light. Other than that, our process has, for the most part, been just about the same. I mean, with a mesh library, we had to export that to get that set up. Was a tile set, we had to mess with a special tile set section down here at the bottom. So small differences there, but a lot of that was the same. Not too different there. All right? Once you go ahead and get your map set out, get on the floor that you want, your camera set, we can go ahead and move on to the next section. I forget what we did second on, so I'm gonna have to go back and take a look. 49. Creating the Player: Alright, so here we're going to go ahead and create our player, and I'm going to show you if I go ahead and stop this real quick. I'm going to go ahead and show you if you choose to use a three D assets here and maybe downloaded some or created some. You see, I have a GLB for ug here. With three textures here. Now, this should automatically be applied, and I'm just going to right click on it, and I'm going to select new inherited scene. I know you can't see that, but I'm going to select new inherited scene. And you'll see I now have my new froggi as its own scene, and it should have all of its textures completely applied for me. Now, if you wanted to use the model, by all means, go for it. If your model had animations, you will see an animation player inside of its scenery. And if this is what you want to use as a player, you can go ahead and save it as a player. Now, this is, in this case, a Node three D. So we would have to change that out. What you do right click and change you have the change option there? Now, if I go ahead and double click on my frog here before we open up the scene, changes to C, I do not have an option for that. It is interesting. Let's see if I have an option if I'm going here. Okay, so you double click on the scene. We'll get the importer for three D frog. And we can just come into the root type here. Click on that and select Character body three D. There's no reason for me to capture. It's the same thing as creating a new node, same screen. I can just click on Character body three D, hit Create. And now that I'll have a character body or it should hit the reimport button down here at the bottom. Close that old scene, right click and do inherited scene. I can see that my new froggy here has a tendematic body. So if you want to use a three D, you can go ahead and do that. Make have yourself a little happy frog, move around. Like I said, this one does not have any animations. So he would just be jump Well, I'd say jumping, but not really jumping, right? He'd just be moving one space at a time. And if you want to go with just the basic, the basic version, maybe you're not super instant in three D, but, you know, you got to at least learn a little bit, dip your toes in a bit. What we're going to do is we're going to go into cred a new scene, go to the other node, do a character body three D. And we'll add a mesh instance as well. The mesh instance where you can just use a box and to keep it in line with everything else, we'll set the scale to two. I'll add a standard material. And since he is my little froggy I'm just going to go with this, like, yellowy green. And that's all we really need to go with. Now, if you wanted to, you could come in and tweak some of your other sliders here. See, we got kind of a shiny froggy going on here now. Specular going up, and frogs aren't super metal, so just have a little bit of metal in there. And you could just do that with a little froggy. Now, if you plan to have just the top down look like this, and you don't at any point, plan on moving the camera maybe down here. But if you do move it down here, I would suggest adding a second layer to the wind the wind area on the grid map, just so that we have it popping out of the ground But if you just plan to go from the top down, uh, what are we looking for? Material. What you could do go into your frog or sprites. Hey, you can bring the little froggy in there for the texture, and Oh, he's not looking too great, so maybe we don't want to do that. Hmm. Well, I expect that to go a little differently. But I guess not. But I guess we could go ahead and just use this texture for the froggy color if we want it, or you can just make it green, or again, you can bring in your own three D model, make sure that your root node here is a character body two D. Whichever route you want to go with it is going to be completely up to you. I said at the beginning of this that I'm just going to go with the basic shapes that are already in here instead of looking for and finding a bunch of three D models. But if you want to do that, make your look extra good. Fantastic. I encourage you. Okay, so I'm just going to go with this and rename my character body to Frog, or do we want to go play? I'll go with renaming my player, and I don't really need anything else other than this at the moment. I'm going to go ahead and save my scene as player scene. I can go into Maine and we can bring in our player. All the way back to the start. Since we got all this snapping with the grid, perfectly lines up. He's right in the middle. Alright. So let's see. Would he would indeed line up with that? Perfect. All right. So with that, whichever player route you decide to go or I'll pull our little buddy up here. You. Alright, with that. Go with whatever frog or cube, texture, whatever you want to go with your frog. Once you have that, go ahead and save it. Do that right now. And I'll see you in the next one where we'll go ahead and start getting the little movements in. 50. Player Movement: Alright, let's go ahead and create the basic player movement for our little froggi. So I've just gone to our player scene here and slap is script on. Our little froggy and inside our script, we're ready to go. We can jump right into our process function. Now, since we are working with three D, I should say that anything that has to do in the future with collision detection and physics bodies, it would be best if you stuck things that had to do with them specifically, like movement under a physics process. Instead of the regular process, these are two different times in a frame. And again, for this game, shouldn't be that important, but I figured I'd just let you know for the future, if you do decide to continue with developing three dimensional games that anything physics related like movement should be under physics process instead of just regular process. All right, so I'm going to go ahead and we'll create our movement function. So movement this will return nothing. Now, I already have my functions or not functions, sorry. My movement still set up since I'm in the same project. Remember, go to your project project settings. Go to your input map. And from there, you can go ahead and set up your inputs. If you don't have that set up for whatever reason, maybe you're doing this in its own separate project, which again, would be nice would be good. But yeah, I just wanted to have a still mine setup just like it was from the two D froger. All right. So inside a movement. All we need to do, of course, we need to check say I input dot is action pressed. Say just pressed because we don't want to spam it. The action we want to check is going to be up. That's what I named by action. And in order to move our little froggy I remember before, what we did is we moved self dot position. Do, in this case, we're in three dimension. We have to go with a z or z axis here. And let's see what happens if we do this. Whoops, egg on my face. I was never calling movement. That's why it's not work. So, you do have the position way of calling things. We have the transformed basis way of calling things, and that's going to tell us that we can't use a single number. We have to go with a vector three, and that's for a far more advanced topic when we start going to things like matrix, matrices, and things like that. So transform dot origin dot z would be the other simple one that you could use. You can see, to us, they're working identical. Although, depending on your situation and your game, you may need to use or prefer to use one over the other. It's one of those things that may be situational. Now, if you want to keep things as close to the Tut version as you can, you can go with position D, position DZ. I'm going to go transform.org just because it's something that we want to go with typically when it comes to three D, I would say. A lot of times this is what you're going to see on the back end. You're looking at other people's code, at least through my experiences when I see other people. So in this case, you can go ahead and I guess use whichever one you want to go with here, and we can leave that to personal preference. I'm going to write the whole thing out. That's up to you. And we can go ahead and fill in the others, these last three for our updwn lefthand All right, so now their axis have been changed to down left, right, and they are all else if statements. Now, if up is going to be negative, then down is going to be positive. Now, left is going to be negative, but it's not going to be on the z axis. It's going to be on the X. And if that's negative on the X, then right is going to be positive on the X. So we can go ahead and try that. And there we go. We should be moving around in all of our directions, since we need and fit inside all of our wind zones. There we go. Awesome. All right, so far so good. Now, what if you want to rotate a little Froggi? Especially maybe if you're using a brought in your own three D model, then you might want to rotate him again as he moves, just like we did with our two D froggi. Well, here we're going to go ahead and get self rotation degrees Y, I believe it's going to be here. And I'll set it to zero on down is going to be 180. Left is, I believe it's 90, and then right is negative 90. Let's go ahead and check that. And every time we move, there we go, our little froggy rotates around in the position they need to be in. Now, again, that's going to be completely up to you if you want to set it that way. And again, if you really want to, you can come in and you can have an s to default it back down to looking forward on its rotation so that when you move, you can see it doesn't we're not getting that instant flip around, like we would expect in two D. So we'd have to come in and put just a slight pause in it. I don't mind it myself. Might just be because I'm doing the cube, but I'm just not going to have that s block in there. But with that, we have our basic movement, and we can start getting things like like cars, getting squished by our cars, and then getting our platforms to jump on death by water, wind zone, get our gooey set up again. And unless I'm forgetting anything, we'll have our three D version all set up. Oh, well, not the respond will be part of the death, yeah, so there we go. Alright, so there's the controls here. That we're getting for our three D broger, remember to call you movement function inside of process. And remember, in the future, if you're going to continue doing with three D games, anything to do with physics, like movement because I'm sure you'll have collisions set up in there. You're going to be preferably sticking in physics process instead of process. But right. There you go. There's our player movement. And let's go ahead and jump into the next one. 51. Creating Vehicle: Alright, so let's go ahead and build our little vehicles that we can use to spawn in to the game. Now, of course, again, if you went and got some three D models for vehicles, and then just like the frog, we can go ahead, bring them in. Make sure they're facing the right direction, which should be obvious by the time we get to the end when you see them moving. What? Go ahead and spawn them in or create an item out of that scene. Save it as your vehicle. And if you're doing the basic blocks with me, then follow along, we'll go ahead and we'll create ourselves. We'll make ourselves a little truck. Going to stick to the two D version as close as I can, and we'll create our character body. It's named this truck. And of course, this needs a mesh verus the add here. And I'm going to go ahead and add a box. Go. Now, to keep in with our two by two, I'm going to increase the scale here by two and I will lift it up. I all right, so that should be on par with our player character. I'm going to make sure all this is evened out flat even position. Now, you, of course, don't have to name any of this stuff, but that's going to be the tab, I'm going to create another mess here, and this will be my trailer. Transform scale goes up to two. That's also going to be a box, position, one on the Y. I'm going to pull it back to two on the X. And let's see. I'm going to go ahead and give it a different color. And we don't have visibility. We do modulate. So I'm going to go ahead and add a material onto this mesh. That's going to be my trailer. Let's say standard material. Open that up and go to my albedo, and I'm just going to go ahead and give that a color. I'm going to go with something in the orange hue. And now if I want it, I can go ahead and I can change tweak some of these valves, so I can set my X to two, and now it's longer, which now it'll look a little more like a trailer. Set my position back down on my transform three so that lines up a little better. And as a bare essence, going from a top down view, that'll be our truck. Now, if you want to go the extra mile, you can go ahead and bring another messin If you want to you can use as an example here, we go to cylinders Great. So we can bring that in and you can see how we have our sides. And then we can go and you could tweak the size of all of this. Let's say you take our height down to one, 0.5. We're getting there maybe 0.25. And there we would have a wheel from the side. So if you wanted to go that extra mile and use another mesh to create your wheels, give it a shader, color. It's like that. You can certainly do that. And then, in that case, I would say to just move the entire mesh up a little bit more so that the wheels are what's going to be on the ground here. So if you wanted to do that, by all means, go for it. Go crazy. If you want to again, bring your own truck in, you can. And when you use these shapes and create your own truck, then go ahead, come back, and we'll finish up the next piece that we're going to add onto the truck, and then we'll create our spinners and write our scripts. Alright, so I've gone ahead. I've added some wheels onto it, and I've just lifted the whole thing up just by selecting all of our meshes and raising it. I'll hit escape so I can unselect everything. And there's my simple truck. Now, if you want, you can go ahead and you could follow through with this, of course, and create yourself more vehicles. I'm just going to go with this easy truck here get going. And to keep through with the with the two D aspects for that fair side by side comparison. That way you can have an easy or a better idea of the transition of what it's like working in two D versus three D. We're going to go ahead and continue and do this with area detection. So we're going to add an area three D just like we did in two D. And on that area, we're going to go ahead and add in a collision shape here. You can see here I've had an area three D and a collision shape. That collision shape, of course, it's going to be a box. There's no reason not to. And then just make sure that your box covers your whole vehicle. But there's no mistake when your poor little froggy gets squished. Grabbing these orange handles and pulling them out. Somewhere about the middle of my truck close out. There we go. Now, there's no mistake. If my frog gets hit, then he gets it. I'm gonna shrink those in a little bit. Yeah, 'cause we got a lot of base on the side there. Alright, for now, I think it's fine. If you want, you can always come back in and tweak this later. Alright? So I'm going to go ahead and save this my three D forager just says truck dot C. And now we need our truck to have a script, right? Because they need to be constantly moving. And let's see. We're going to be moving on the red line, so that's going to be on the X axis across. That's fantastic. Et's go ahead and add a script. Get our truck script. And again, we're going to keep things as similar as we can for our three D as we do two D. And we don't need to worry about any of this. If you got all this, just go ahead and delete that portions. These are for a completely different completely different kind of game. Yeah, what was there if you didn't pay attention and you just clicked through it like I did there, and you didn't have an empty or a no default script. That was a character controller. And character controller is typically one that has well, these aspects you can think, I guess, more of like a first person shooter or a platform or things that are more along those lines in terms of RD, para can run around, run around and jump around. In our case, our truck doesn't need any of that. So let's go ahead. L the same thing we did before, like export our variable of direction. Which was an integer, and we used the default as one last time. We then had a variable for speed, which was also an integer that we had at 32. That might be super fast, now, but I guess we'll find out. So I guess for now, I'm going to set it to one. I can change that later. Inside of our process. We'll go ahead. We got our velocity. We got the X property of it, and we set that equal to our speed times direction. And, of course, we need moving slide otherwise our velocity won't do anything. Let's go to our main scene, bring our truck in and see if it works just as we expect. I'll go ahead and place it there and run it. Okay, we're set on a speed of one, and it's going in the opposite direction for us. But, that's fine. On this truck, that means our direction is minus one because we want to go to the left. And there we go. We can see our truck going across. Awesome. And, of course, we can run into it right now because we don't have any death scenes for little froggy to get squeezed. But our truck is moving Now, let's go ahead and now that we know it's working in the right way, let's run it, see if 32 is too fast or if it's still good. To me, that looks like it might be a little too fast. For you, you might like that speed. So I just put it in half to 16. That might be a little quick for me too still might want to go with eight my speed and give it another run. Okay, I think I'm going to go with eight, at least for now, again, you can always come back and change it later. And now let's go ahead and get our spanors created here. All right? So I don't have vehicles going in the opposite direction, and it would be boring to have us all going in one direction. So I'm just going to have this one truck, and I'm going to have it go in, you know, different direction. We're going to have some go left, some go right for this. Of course, if you've got multiple vehicles, by all means, have a different vehicle for each sponner so we're going to go ahead into our main scene, and we're going to add the same thing that we did in Tot, we're going to add a marker D and this is going to be our spaner. I believe we use a marker or did we use a node? I think we used a node. Let me just go ahead and right click Change type and change to a Not change it to a plot spanner now. And what is this truck's position? Pull it back here a bit. So we can say 32 and 12. Yeah, that looks good. So spanner, transform position, 32 on the X, 12 on the z. And that's where we're going to spot those vehicles, right? Let's go ahead and add a script for our spawner. And again, keeping as close as we can to the TD version. We're going to have our truck variable, which later we just called a vehicle. You know what? We'll just go ahead and call a vehicle now. Why not just in case maybe you guys have extra vehicles. I go to equal a reload, right? Of our truck. But of course, you may want to set this separately. That way we can use the same script on everything. There we go. We just jumped ahead and exported it for a packed scene. And in this case, of course, I'm just going to inside of my vehicle. And inspector, I'm just going to drag my truck in my truck scene. There we go. And ready, all we need to do is call our function that we're going to create here, spawn vehicle. Okay. Rate that funk span. Vehicle. And we can do what we did again, previously where we can get a random wait time here. And this is a random integer. And we use percent three or at least I use percent three plus one. So remember, this percent three is going to give us zero, one, two, and adding one that'll give us a random integer of one, two, three. So one of those. And since we're using this as seconds, it's going to give us one to 3 seconds in between each car. Looks like tree like we did before, create our timer, we'll pass in our wait time and get our time out. So after we've waited that long, we'll create an instance of our truck or our vehicle. VI equals vehicle dot, instantiate. And we need to add to the scene so self dot ad Child, our vehicle. And since this sponsor is on the right hand side, you need it to go to the left. Now, since I'm just working with this one vehicle, I need a way for this vehicle to be set by default or rather by default, when it spans in in order for me to have them going on both sides. Because if I don't, it's going to come back to the span here for a second. And when that's done, we're just going to call it self Curt span. So if we go ahead and take a look at this now, what three D. Make this truck, delete it. If we spawn it now, here we go. There's a truck. It's another truck. Here we go. See, I think that is a decent speed for this. But you can see here that all my trucks are obviously going to be going to the left. So if you're going to use one vehicle like me, just to help with learning here, then you can go ahead and you can set an extra parameter, specifically for your spinner. And that parameter here, I'm just going to go ahead and export I'll call it VD for vehicle direction. That'll be an integer and by default, we'll set that to one. And specifically this spotter, we're going to have it set to negative water, obviously, because it needs to go left. So all I would do here is I would just do V dot Direction, right? That's what we named it. Yeah. Direction. Equals BD. All right. So now if I come over here to the truck, if we come over here and if I were to set my default direction back to positive one, save that. So now still move in the negative one direction because my sponsor should be setting that direction for us. Here we go. So there's the truck coming. So now I can use the same script if I'm going to use the same vehicle. Now I can just set it between negative one or positive one or direction. All right. So now if we were to do the same thing with more vehicles, well, if we had the same thing each vehicle going in different directions, we obviously going at this variable. But let's go ahead and get our other sponsors set up here real quick. All right, have all my sponsors here. So sponsor four is going to have since I'm using one vehicle, I'm going to set up a VD set to one. Sponsor two is also going to be one. And of course three and my original spon are all going to be negative one because they are on the other side. And now if we were to go ahead and take a look we should have something following, and that's going to be a lot of traffic to squeeze through for our poor little froggy. So again, you can come in here, you can tweak with things like the wait time. Oh, boy, that one's a little messy. But, yeah, there you go. You can come in, tweak that. It looks like we might be able to squeeze another truck in at the top, maybe. There you have it. That is awful dangerous for our poor little frogie That is really close. We have to see in testing if maybe that's a little too close, and if so, just delete that row. That is, it looks like it might be touching our froggy. Alright? There you go. There's as close as we can get it for our three D version. In relation to our two D, so we have our poor spinners all set up. We have our rock that has our area three D and a collision shape, so we can detect it when it comes to squishing our frog and there you have it. We have our vehicles set up. Again, if you have other vehicles, go by all means, bring them in, take a look at them, use them, have different ones set up for different directions. And I'll see you in the next one. And what is it that we are doing next? After these vehicles, we take a look at our player death of response. So next up, we'll be squishing our frog. 52. Player Death and Respawn: All right let's get our player death and respawn all situated. Let's head on over to our script, and we can go ahead and connect our signal for our truck now, our signal is going to be connected through script, again, keep it just like TD. Although as normal, you can always come in, select your area, go to the no tab at the top and go ahead, come down, take a look for the signal that you want to connect. But it is good for you to know how to connect them through code, just because in the future, you'll probably have to deal with creating your own signals at some point, and then you'll have to connect those, and it's just nicer if everything is in one place, like inside the code to look at, especially if anyone else has to look at your code or maybe you have to come back and look at your code in the future. But let's go ahead. Let's get our nodes get our area three D. And we're going to connect the body entered signal, the body entered dot. Connect, and we're going to connect to a callable. And just like in Tutti, we're going to call it player hit. This has a body. We'll make it up tight node. I forgot the E at the end of the word callable. There we go. So we just had a little bit of spelling error there. No problem. All right, so we should be in a very familiar situation right now just like when we created it in two D. So we're going to check if player. Now again, keep my capitals lowercase tier. If I look at my main, I see player. I have it spelled here with a capital P. So if player and body name. I would say, I body dot has method and the name in the form of a string, we'll call it death just like previously. And we'll say body dot death, so we'll call it. And there we go. So far, this side is exactly the same as in two D, except for we use three D instead of two D for the area. Everything else is identical. All right, so now our player, we don't have that depth function. It doesn't exist, so it's never going to be called. So let's go ahead and call it for us. And all that's going to happen is we need to disable the shape that was used to collide with the truck. And then make sure that it's facing the right direction or a little froggy just in case maybe you're using a three D model and then respawn him in a different position, right? So let's go ahead and we can do that. So our player, we need to open up that scene and give our player a collision shape. That we get rid of that warning triangle that our player has had all this time. Our collision shape is going to be a box for you. You might want to go with a different shape. You might want to go with a box. It's up to you. Can I just come down here and this to fit as a perfect size. Now that our player has a collision sheet, he can be detected when he gets hit by the truck. And when we get hit by the truck, we want to call our function that we call death. And on death, we want to set our rotation, just like we do when we move up, so I'm going to set my rotation to zero. Now, if your model is facing in the opposite direction, then obviously your up would be 180 and your down, it would be set to zero in your movement, and that would be reflected in depth. So whatever your up is, it's the same degree that you're setting yourself to upon death. We want to disable our collision shape so that we can only be hit the one time. All right. Let's go ahead and do call deferred. So let's get our collision shape and call deferred. And that's a lot of stuff to go through. I'm just going to start typing it set disabled. Second argument will be true because that's what we want to set we want to set disabled to true. All right. The next thing we're going to do, if I remember right, we went up and we created our alive and dead states. Added that to this. So let's go ahead and head up top and create our states until we have our Enum state, and we had alive and dead, and later on, we added another one. We'll create another variable here called current state. And the type that we're going to declare it as is a state All right. Now, we can go ahead and set current state down in our death. Let say current state equals right? State dot dead. And let's go ahead and get our respawn set up. So funk respawn. And just like this, we're going to be setting our collision shape and our current state. All right. So we want to do, we'll move it first. We'll say set disabled, it's set to false. Our state will obviously be changing from dead to alive, and we need to actually change our position here. So for this, we need to get a player position in here. I'm going to add a new node. You've seen all this before. We can go ahead and use marker to node, whatever you would like. I'm just going to use the marker three D. And let's see what is my position at here? One, one, 15, so I'm going to set the same thing to my marker, so I'm spawning in the same place that I'm starting at. One, 115. Here we go. So where I start at the beginning of my game is where I should be starting when I respawn. And we'll go ahead and call it player, spawn, location. And we'll set our position. Self dot. Position equals and we need to get Node of a player spawn. Now remember, our script is on our player, so we have to go up one. So we can write Get parent or we can just say get node. And for the path here, we can dot dot slash as a short form of G parent and then type in node here, player Bond Jason Got position. Alright, now when we get hit by a truck, we should be able to respond. And hopefully this truck isn't too close. And whoops. We got one thing here. We're not actually going to have a response here in our process. We need to change this, so we say, we need to check if our rockie is alive. Almost forgot that. And in two D, we also had a timer in our respawn, but that's fine. So let's go ahead and end up. So we're ready up there. I say if current state equals state dot alive. We can do our movement. LFOs that's a W, LF current state equals state dot dead. R spot. All right. Now let's go ahead and try it. Alright, we can move ahead, left and right. And yeah, that truck is too close. Okay, so it looks like I'm gonna have to remove one of my sponsors or tweak them a bit. But I think for myself, I'll just completely get rid of it. I'll just remove it. It's not a problem. And now we should be good. We should have a little space at the top and bottom. My froggy is not going to get squish, and you can see from the looks of it, we were moving fine. As soon as we got hit by a truck, we respond. Hope. Okay, so we don't have a whole lot of wiggle room, so I might want to go in and tweak my collision boxes on my trucks. Hyloiss gonna be pretty difficult, spicy with this mouth going. But that's just comes in from doing some tweaks. I'm going to go ahead and go do that. I'm not gonna keep you guys here. But there we go. We have a death and respan working here on the road portion. And the next thing up is we can take a look at dying on the water, creating our water platforms. 53. Water Death: Alright, so just like the two D version. We're going to determine if we're on the water by getting the ID of our grid map in this case, because we're in three D. It was the tile set, the tile map in two D. So first of all, just like in Tut we're going to start with an ready variable, which, again, basically just sets the variable inside of the ready function. So in other words, this variable does not get spit until after the game is already running. And since we're the player, we have to go up one to our parent and then come down to get our grid map. So we set it to G node, and we have our dot dot slash our equivalent of Get parent and grid Map. And then we come down and we have our check Bell ID down here. Function, ready to go, ready to code up here. And this is going to be very similar to our TD version. Now, for our TD version, we had a variable for MAP pause, which was our grid Maps translation would be gridmp dot Local TMAP and that map took a position. It took sorry, one argument. And that was our player's position that we passed in. And we also had a variable for ID, which was the equivalent of our grid map Yet sell source ID. But instead of source ID, what we're doing is we need to get sell item when we're dealing with grid maps. And this doesn't take two parameters. I only has the one, and that one is going to be our map position. So we don't have to pass it any layers or anything. Now, at the end, this is it, and this is all we needed, and we would say if our ID, in our case was equal to three because three was the ID for the tile map, the tile set. In this case, if I go ahead and look my grid map and I open up the mesh library, I can see water is associated with the ID one here. So I'm going to say if ID equals one, and this is where we would call. And then we check cell ID pretty much every time that we move. Boom, but a boom. But a boom. And I'll just pull it out of the process for now, so we're not spamming it. Now, we're going to go ahead and run it, and we're going to see an issue. See, nothing is really happening here, okay? But we're not printing anything. Just get a le on there. And when I step on the water, you would expect me to die here, and I do. Now, is that because I forgot to I did? So I forgot to reset my player here, and that is why it worked. Now, normally your player, again, should be up and above the map, and you'll see here, I'll just go ahead and rush it that it doesn't work. And the reason for that is, well, the reason that you saw my player was sunken in down there, we're checking too high. So in the position that we're checking, it is zero. So we actually need to pass in a lower position than what we're using here. So I just create new variable called cur pause for our current position. And this will be a vector three specifically, it wants a three I. So we're just going to go ahead and pass that in. And for that, we'll just use our self deposition X or our Y, we can use negative one. That'll be low enough, and self deposition Z for the third argument. Then instead of passing in our self position to the local map, we pass in the current, right, curve pause. That way we can get our position, but one block lower, which should give us the location of where our cell ID is, right? Were the grid map is sitting. So now when we hit water, There you go. We go ahead and we die, and our respawn doesn't screw that up because we're checking one block below the player. All right. So we have our water depth all set up now. All we have to do is go ahead and get our water platforms in our wind zone, set up our score system and the overall I. And then if want, maybe we can set up an alternate camera that goes behind the frog so we have more of a greedy experience. All right. But that's it. We have our water depth working. So you can see it's mostly the same all except for this line where we just have to check one block below our player. But most of that, again, it's the same. So if you like working in two D and you're asked to do something in three D, you can see that by now, we've done a lot of roger here. And with keeping things mostly the same as we would when we made it in two D, you can see the majority of everything transfers over. We had to write our position. We wrote our position in Little different and our rotation. I was written a little different, but I mean, it still makes sense. It's not a whole lot different. And we had to add one line here to check one below our player rather than our player's complete. So if you do prefer two D and you have to do something in three D, don't feel intimidated. Pretty much just about everything you learned in two D will transfer over to three D. We just got to remember, like when setting doing the current position here, we do have that third dimension to work about X, Y, and Z or X Y and Z. All right. So that'll do it from here. Next, we'll go ahead and jump into the platforms. 54. Water Platforms: All right, let's go ahead and get our platforms all set up. Now, I've gone ahead and I've created my log here. It's just a cylinder with a material on it on the mesh instance, and I've colored the albedo, the brown. It also has an area three D holding a collision shape, and this collision shape is just a box shape, and I'm just covering the middle piece of it so that there's no issues when it comes to hopping off it, and the game somehow thinks in that we're maybe still on it just because we might be barely touching or anything. So I just went with the middle plus. When we jump on it, we should be on the middle anyway. So, I'm going ahead and done that. And I've also connected two signals, the body entered and body exited signal onto my log script. And just like in the two D version, we have an exported direction. And in our process, we just have position dot X plus equals one times Delta. And if we were to take a look at that in three D, you can see with the scale, remember of the logs because it's got to match all of our blocks. I scaled it up to a scale of two instead of one. And you'll see what position dot X. There's how far removing with that one. I believe one is what we are using, correct? Yes. 01 times Delta. That's how quick our logs are moving. You can change that if you want to do two times Delta, three times Delta, whatever you feel is necessary for you. For me, I'm going to leave it on one times Delta for now just for testing. And then just like my trucks, I can go back and tweak things later. All right. So if you want to go ahead and take a moment, make sure your logs are created. You've got your areas set up. And if you want to go ahead and just lay out perfectly five of them across like this. Go for it. You can. Go ahead and pause the video, go ahead and do that. And when you're ready, let's go ahead and continue on, and we'll get the actual platforming part of it done, because as you see, if we jump on it, nothing happens, we just kind of die standing on the water. But as I said, the first one in the Tut section, it's kind of weird, considering we're a frog, we shouldn't be dying in water, we shouldn't be drowning. But there we go. We have our logs. We have our froggy now the question is, how are we going to get on top of it? Well, we're going to take this just like our two D, right? We have our body entered and body exited on our player, we have our three new variables platform, which is a boolean, set to false by default. Current platform, which is a character body three D this time instead of two D, set to null by default, and a platform direction, which is an int, an integer, and that's just set to one by default, and that one will set us going to the right. Alright. So on here, we don't have to do anything necessarily at the moment. Although we could go ahead and Y, let's go ahead. I'm going to set our ID here or not ID, but our second parameter, our second condition, rather, if ID is equal to one. So if we're on a water block, and our current platform is equal to null, right? So basically, we're not on the platform. Actually we switch that around. We use disuse platforms. So we said platform false. So that's just a shorter way of doing everything here. So if we're on a water block and we're not on a platform, we die. Well, how do we know when we're on the platform? Well, when we hop onto our log, which I should rename that just being platform. Do GD instead of log. So just give me one moment there. All right? Everything seems to work, and I went ahead and renamed it platform. That way, if I want to create little disks for representing my not frogs, the turtles, I can go ahead and do that still use the same script. So what we're doing is as we were going over here, we got a platform is false, then we will die if we're on the water. So we got to change platform to True. So once our Brogi enters this area, let's go ahead and set platform to true. Oops, I butchered that bit. It's body platform. So you want to access the platform variable that's on the body touching it, which of course is going to be our player. And again, if you want to be extra careful here, you can say player in body dot name and tab everything in. That would be okay here. To the embodied platform equals true. All right? And what else do we have? Well, let's see. Current platform. Well, if we look back at our two D version if our frog is alive during our process section, then we also have a check for I curve platforms not equal to null. And then we moved our frog, right? So we would change our position dot X equals, and then we had a bit of math here. We had our platform direction. Times our speed, which I'm just going to go with one so that we can match our logs, and we can come back and change it later. And then we multiply that by Delta. Okay? So if our current platform is not null, I mean, we should be standing on a platform, right? Then we'll be moving. We should be moving with the platform. Okay? So we're going to go into our log, and when the body enters, we're going to say body dot her platform. Make sure that I spelled that right. Per platform, yes. And what set that equal to self. Now, remember your log. Your log here should be a character body three D. I'll go ahead and just reopen mine here. I didn't change anything. Interesting. Must have to restart the project. My log is a character body three D. And, of course, the ion see the log and the area three D, which is rousing our tear. Okay, so let's see what happens. It's just our log. Let's go ahead and run the tire game here. T's run up and get those logs, we see they're moving, hop on and we died. Well, that's interesting. Why did that happen? Well, that happened because we're actually moving too quick. Oh, that's the two D one it's up for some reason. Yes, come down, and that's because our death is happening too quick. We need to have a little bit of pause in there so that there's enough time for things like our platform, that to change in between. So it's just having a wait, get tree, great timer and 0.2 should be all that we need. I know we use 0.1 in two D, but was 0.1 I tried, and it wasn't enough. So we're going to go with 0.2. And if we go ahead and try that now, we should be able to Ooh. What happened there? Oh, it's 'cause I sent position dot X equals Intent a plus equals. Here we go. Now we're going to hop on this log. I can go ahead and ride them across. Fantastic. And as soon as I hop off, well, if I hop off onto this spot here, Oh. Well, we're not safe because we've never calculated getting off the platform. This means we're also forever permanently moving to the right, so let's go ahead and fix that. When we get off the platform, we obviously need to reverse these. So platforms false and our current platform, it's going to go back to being null. And just that one change to solve this riding along. Oh. And we just died there. A, well, that's not. That's not great. Let's find out why. Well, if you remember, back on the two D version, we had Well, two more things missing out of this. The first one, when our body enters, we actually had another timer, and that's just set to 0.1, which is fine. Us now when we go in, we hop on. There we go. And we can hop across without being killed. And as soon as we hop off into the water, which would be our wind zone, we get killed. Hop across, and into the water, we die. And it still happens when we get hit by our trucks. Fantastic. So everything's still working fine. This one tiber is enough to fix that one small bug that we have. Great. And the only thing we had left is I believe we created a function to set the direction here. So that would just pretty much depend on whether we're going left or right, what we're setting a great. And that would be direction that we can pass in. Which for this log is zero right now, but it would be one. And in this case, on our player script, we can go ahead and create that function, funet direction, and you take an ID, which is an int and you just have our platform direction equals ID, we call it IDA, I think we call it DR, so let's just keep it there DR. And then on our platform, we can go ahead and body dot set direction and pass in our direction. Alright, so now, it wouldn't matter on our play if we came in here and changed platform direction to, there we go, 8,967. Wouldn't make any difference because that will be set once we hop onto an actual log here. There we go. So if our logs were going in the other direction, then we're going to the right, keep ending up. How does that keep happening? So we go in there. So if we set this to negative one, That would be negative one on our speed here as well. So we could just completely change this and say direction times Delta for the moment, but we can see that log is moving in the opposite direction. And the only reason that is we changed one log specifically. For example, we can come in here and set this one to negative one, as well. Now we've got two logs going in the other direction. Well, we should. Why didn't this one change? I did get the right log. That is negative. Mm. Hmm. Let's have to go ahead and read see. That's fine. We saw are the logs completely moving in the other direction? And let's just go ahead and set that for our main log here. And we can see they're going that way, we hop on and we are moving that way. All right, so all we need now is if you want to, you can create little disks at a scale of two to represent your little hurdles or lily pads or whatever you wanted to do with them. And basically just use this script and set the direction. There you go. This our little platforms going on there. For our logs. And these sponors we can go ahead. Just go to call set these positions here. So remember, we're going to alternate on each side. Left. And then to the right. Alright? Now, all we need is a spawner. Set up. And for that, let's see. Could we use our spinner scripts? Well, those are vehicles, so it wouldn't really make sense in terms of that code. But the rest of it, looks like it would make sense. That's what we're naming here, right direction. Yeah. So we could use the same spinner code and just create more of these spinners. And that is perfect fine. I think we do that. Go ahead and create this spawner. Is this sponnorFive, clear out your vehicle, find my log, bring that in. And we may actually have to set, I'm just going to run this real quick. I think we have to set the rotation of our log as well. Where's my log? I'm kind of confused here. Yeah, okay, so there's the log. It's going completely vertical. So we would need to set that up. All right, so let's just go ahead and create a new script then platform spawner since we have to tweak a few things with that. So we've gone ahead and we basically have the same stuff here although we have platform and spawn platform, PI platform instance. Oh, that looks good. Let me just go to my sponsor and pull the log scene in. Again, platform. Yo. And now we have to take a look at our logs here. What is the rotation that I have it set? Y is set to negative nine. Okay? So we have to make sure to set that. So say pi dot rotation We can do that, right. It's a rotation R Y equals negative 90. And let's just see if that sponor is working. Remember that sponer down here. Matt on a close type int. So I just had the idea. Now, first of all, I completely screwed up. I was trying to load in the wrong log scene. I was trying to load in from the two D instead of three D, so that's part of why I was getting some errors. But then on our platform here, we can go ahead and just we could inside of our ready here, go ahead and just set our rotation degrees here. If you wanted to do that, you could. Just hopefully that doesn't affect any of the other platforms that you create later. But just to well, prevent that. Actually, I guess I wouldn't really prevent that because it's gonna come up with the same situation. It's going to spawn and be rotated. I'm just going to go ahead and down one. I'm just going to go ahead and put it here in my spot so we're just taking i BI platform instant and setting rotation degrees, and I'm setting it to a vector three, which is just three pieces of data, right? X, Y, and Z, or in color, it'd be like RGB, right? So zero, negative 90 and zero, and this now positions it correctly on the orientation, I would say. So now we just got to get our logs moving in the correct direction. I as well as the Well, correct direction as well as the sponor position. So for that, I'm just going to pretty much look at where my logs are set. So example, this one, the transform here, negative 29 and negative one. That's good enough. Position, negative 29 and negative one. Now that log, I can completely delete and we can have another sponnor with this transform, which would be negative five and negative 29 as well. This is negative 29 and negative five. Here we go. Now that log should be able to be deleted, and we should still have our two log sponsors from the right, going to the left. Except my direction is off, so we're actually moving off screen continuously to the left. Okay, so let's just go ahead and you don't have to do this part, of course, because if you're creating different platforms, you're going to have your turtles going left, your logs going right. So that's going to be perfectly fine. But since I'm just going to use the logs here instead of creating multiple things right now, I'm just going to create a variable for direction. By default, we'll just set that to one. And when I spawn them in, I'm going to say it diconolrecon. I set these two to negative one lock spawners, they should go to the right now. So as the spawn in hopefully they're spawning in here. There they are. No. All right, so where are my logs? No, the log is here. Direction is negative one, so it should be going in the other direction. Oh, I set the logs that way. Whoops, that was a me mistake then. And better set them all in a negative one by default, then. And we got this platform time here, which is a little annoying, but there we go. There's my logs going that way. And I can just set three up on the other side and have negative one as their direction. So I'll do that bro. All right, so I just set up my sponsors on the other side, so we can go ahead and run the game, pop across. We're all good. And we just wait for these logs to appear, and we'll see if we can jump all the way across, even though we're going to die when we get to the side because we don't have our wind condition yet. So at this rate, yeah, I think I would want to speed my logs up now, for sure. And I got to reset those directions for three, four, five. I do believe three, four, five, that's positive one. To should be negative now. Awesome. And I said I wanted to change the script say direction times. Let's do three. We'll see how fast that is too fast, we'll drop down to two. The top across. Let's see what three will give us. Logs. Where are you at? Okay, threes not too bad. We can go ahead and hop on there. And now, my froggi isn't moving too isn't moving fast enough. I'm kind of hopping along here. Stay caught up. We got to fix that. Here we go. We could make it across, and that would be a well, a theoretical win. So on my player. I'm just going to go ahead and change that one, two or three, cause I think I'm going to stick with three. Try it one more time. Just to make sure everything is going good. Bring me my log. Here we go. And now our speed matches up. I can hop onto the next log. Poop Poo. Here we go. All right, so we can make it all the way across. Excellent. And everything's working out. We have our platforms working, and now all you have to do if you want to create your turtles, do the same thing. You can just create your little spear over years, right? Your little cylinders and squish them down to like little disks, and then have an area just like this, just the spot covering the middle for that detection. And just like that, you'll have a new platform all set up. Alright, so that does it for our water platforms. And next, I believe we have our winspace. 55. Memory Leak FIx: All right. So before we jump into our wind condition, now that we have our vehicles and platforms are all done, let's again, come back to this memory leak, where we have infinite platforms and vehicles that are constantly moving in the void and constantly taking up memory. Let's go ahead and get rid of them when we no longer need them. All right, so let's go ahead and open up our platform script and our truck or vehicle script. And we're going to solve this the exact same way, very simple. Inside of our process here for our truck, we're going to go ahead and we're just going to do if our global position dot X is greater than 436 or however wide, right? However wide your window is, I'm going to say plus 100 is about the space that we're giving or global position dot X less than negative 100, self dot free, and we're going to do the same thing for our platforms. And let's just run this and see if we have any issues here. Okay. We're not running into any. And let's just see at what point do they de spawn on us? Okay. Now, remember that 100 off quite is going to be hugely different than in two D. So we should probably turn that down from 100 work with you. So let's try ten So say 346. We've got a try and ugly looking at platform there. But let's just copy that over to our truck. That's right. See our trucks spawning in. On the other side, that's not enough space. We can kind of see our trucks and our platforms glitching out there. So they clearly need more space than that for the negative ten here. So let's go with negative 20 and see if that's enough space for them. Not enough for our trucks. It doesn't look like it's enough for platforms, but no. So now we're just kind of dialing. So that negative 100 seemed kind of ridiculous, though? Let's try negative 50. We're just going to kind of dial this in. See if our platforms are able to spawn. And our trucks do go faster, though. So let's see if they can disappear on screen here. If we just open this up so we can see the outside of it. Okay, so the trucks go a fairer distance. You see, they disappear right about here. This is about where our platforms should be disappearing as well. And the other side, they just keep going and going and going. Okay, so we'll add 50 we're on that side, 346. How is 336? 336 needs to be fine. Will the trucks disappear? They'll disappear at some point, that's the important thing. But if you want to come in and kind of dial this side down now, certainly, go ahead and do that. But the important thing is that we have our objects deleting, so we are freeing up the memory with the objects that we no longer need. So with that, we've fixed the memory issue that we had in the two D version that we now had three d version. I didn't forget about it. I was just putting it off and we're getting our main components in first. Alright, let's jump on to that one condition. 56. Win Space: All right, let's go ahead and create the wind space for our player. I kind of clear up all these areas as we go. So we're going to need our player script, and I have a winspace here I created. It's just an area three D, and I'm going to rename that to win space. It also has a collision shape three D that I added. Its shape is a box, and to match everything else, we gave it a scale of two on our three axes. So now we should fit in with anywhere that we place it. Let's go ahead and add a script to this, our wind space script. And this is also going to have a couple signals connected to it. It's going to be our body entered. And I believe that's actually all we're going to need here. And on our player, this is where we added in our new state, our win state, which means we have another LSF condition down here, LF current state equals state, win and this we would do our respot and then set win zone, I believe is what we called it. Go ahead and add our new variable, our win win zone. That is a bull set to falls by default. And let's see, in our death, we say if ID is one and platform is false, and wind zone is false, so we're not winning. So we're not in the wind space. We're not on the platform, and we're in the water, then we end up calling it death. Excellent. And let's see. In our wind space, we call two things. We need to get our body dot wind Zone. Equals true. And then our second spot is setting our current state body dot, current state equals stat win and make sure I type that right. Current state, I believe so, but I'm going to copy and paste just save identifier state not declared current scope, right? Body stay dot win. There we go. And for now, that should do that shouldn't really do anything. So in our death, let's actually you're going to say print dead. So we'll just make sure that everything's triggering the way it should. Respond print out the word respond. And in our winspace Well, we also need to set wind zone back to Walls. But also print out Win. And we can go ahead and test it. We can go to our main scene now. Main, instance in with this little chain icon, remember? And just go ahead and perform a search for your winspace. Bring it in. Hooks. Here's mine. Back it up. Gonna be two wind spaces for these zones. To fits the whole thing. Awesome. And now we just duplicate it. Second slot. And I'm just gonna keep going all the way over. Fill all my zones. All right. So I've positioned all of my little positioned all my wind spaces. Let's go ahead and see make sure our text is being printed out to our console correctly. Let me just fix that game now. I'm back down to a small thing. Here we go. Alright, so let's see. We squished by a car. We died and respond. Excellent. Okay, we jumped in the water, and we died and respond. We hop on the log. We're good. Pad, and we're good. Turtle, log, pad, log. And we jumped in. We got a win. I see a win, respawn, dead, respawn. That doesn't sound like how it's supposed to go. Let's make our way back up. Go ahead and pause it here. So I can clear out going on there. And continue with this. S. Okay, so far so good. We jumped in. We got a win, a respawn, a dead, and a respawn. Okay, so that's not great. That means we have a bug in there. We should have got a win and a respawn. We should not have gotten a dead. I'm guessing our respawn hasn't gone off yet. It hasn't changed our position or any of that. We should set our collision first. Yeah. Death recalling. So the only thing I can think at the moment is possibly something here. But we'll try with just disabling that earlier. See if that works. We'll find out. My logs, let's go. This is probably the one thing I dislike about testing the most. Is constantly doing the same thing over and over. And we wait for a log. There it goes. When Respawn then we got a dead and respawn. Okay. So I'm going to try a few things and see which one of these fix it. Maybe it'll just be maybe I'll be back in 2 seconds. And let's see where the source is here. I Alright, I had to look at the two D versus, see what we might have done to have solved that. And I was just a short delay here at the top of heckll ID. We had a small 0.1 timer before getting our position and everything here. So there you go. Not a big deal. But with that, you'll see that we can now go ahead and jump all the way across the screen. Enjoy being a little froggy. Come on. Bring out the logs. Let's go. Here we go. We hop on the log. We wait for little turtles or lily pads, whatever you want them to be the log, the next pad, the log, and the wind zone. Here we go. We got a win and respond, no death. Oh, I ran into that truck. And Z, we still die if we jump into the water. Alright. So there we go. We now have our wind space all set up and the last thing for us to do. Am I supposed to set up a scoring system and our hut again. And then we'll have our three D version all set up. 57. Score GUI and Timer: Alright, so here we're going to go ahead and get the score lives and our Hud all set up, and this is going to be much easier because we can reuse the HUD that we created in the two D version. So the main things we're going to do is we're going to reuse our global. Then we use some of the TD. And we're just going to have to rename part of our path here, and we can make this work with both the two D version and three D version if you wanted. But we're basically going to use the same script. So if you have three D version and two D version in two different projects, you can go ahead and just copy that script over and then head on up to your project settings and set it up as an autoloa All right. So in order to make this work in three D for global. Now you notice mine says main for the root node of my main three D scene here, which is a node three D, and in two D, it was a node two D. So I'm going to go ahead and re rename this to Min because that's what I'm called, and I'm going to go ahead and replace that in Update Lives, as well as update score. Alright. And for our Guy, I'm going to head on over to the two D version, open that up again. And I'm just going to right click just so I don't have to recreate the Guy again, since it's just going to be exactly the same. I'm just going to right click and I'll select the option. Where is it? Save branch as seen. And when you do that, you should have an option. You should have this screen pop up here and you can go ahead and save it. I'm going to go into my frog or three D scene here and just resave Gooey scene in there. All right. And that's all we need out of the two D. And of course, you don't have to do that. You can go ahead and recreate it. Just add the canvas layer, the texture progress, labels and everything again. If that's what you wanted to do. I'm going to go ahead and add this in now, add my Guy scene. And notice we cannot see it here. If you are recreating your Guy from scratch, you're going to have to click into the two D option here and take a look and recreate it this way because the canvas layer is a two D object, right? Something rendered to the screen on top of everything else, but it is two D regardless of whether the rest of the components are two D or three. So if we were to run this right now, we can see everything is on top and the way it should be. So just remember if you are creating this yourself, keep that in mind. If you're going to recreate this, that you may have to run the game to give yourself a good estimation of where things are. And the good thing is, is if I wanted to come in here and edit some of these components, I could come in and move things around like, and you can see update live in the game. So you could always make sure that you have things in position that All right. I'm going to stop running the game there. So if you recreate the Guy, I'm just going to go ahead and show you it right here again. Hand this layer at the top. To labels for the label and the score text. Our lives bar is a texture progress, and we have those Frogger lives texture that you can bring in as the progress texture if we open up textures here for progress. We have a timer bar, which, again, is the same thing. It's just a texture progress bar, and it's got the green square rectangle, whichever one it is that I created, just to use as the bar here. We have a label that just says time so that the user knows what this is, and we have a timer node with the default wait time of one auto statrt turned on, and the timeout signal is connected up to our Guy that has a script. Our Guy script is simply on timeout. The timer bar value is minus equal one. So this will make our bar continuously go down. And then if the value is zero, then we get our player node called death on it, and then we reset the bar to 30. All right. Hopefully, with that, you had enough time to either save your Gui as it on scene, bring it over or recreate it. And I will note here that in the Lives bar, our film mode is left to right, and in our timer bar, it is right to left. All right. But once you have those two things set up, remember on our Global, we have to change this from no TD to the main. And that's just because mine is labeled main. We could just label it no two D. It be confusing, but could. Or if you left it as a default, then instead of main here, you'd be writing no to three D. All right. So what are the things that we have to change? Well, that's going to be on our player here and on our windSpace. But let's start with the player. That's going to be remember every time we move up, that's going to be in our movement here. It's when we go up, we get points, right? So we access our same global or if you copied it over, update score, and on the two D, we went by ten points. Then on death, we go ahead and we have to update our lives. So global update Lives. And this was set to minus one. And the last thing we update on DEF is our timer bar. So with this, we'd have to get node, right? And we'd have to remember our players, we're going to go up to our vein, so get parent level, and then we can come all the way down to our Guy get parent one level and then get our Guy. And then from there, we're able to grab our timer bar here. Timer bar. Just make sure I spell that right. Capital T, capital B, timer bar dot value equals 30. All right, so that'll be reset. And now we just have to go to our Winspace here. And on our wind space, we just have to make our few cheap weeks here. So we need to update our multi frog value. So our multi frog plus equals one. You remember in our global, the way Frogger works, we increase our multi frog, and once we get to five multi frogs, we get a 1,000 square bonus, and then our Multi frog resets back to zero. The wind space, right? So we add to our multiplier there. We add to our SOE Global dot update score, and we're going by 40 points here. And then remember we had the timer bonus as well. So based on the amount of time left, we got additional points added to our score. So let's go ahead and get the time bonus. That was VR and we just called it time bonus. This was an integer, we said it equal to node and we had to go up one, get our parent, right, and then it'll take us all the way up to our main node at the top. Then we can get our Guy and get the timer Bar. And we want the value of that multiplied by ten is what we're using. That gives us a theoretical maximum bonus of 300 points, but that assumes that you get up there in less than a second, not going to happen. And that gives us a minimum bonus, assuming you got 1 second left of ten points. So again, that's pretty decent on the bonus, somewhere 10-300. Although realistically, it's probably going to be more 10-200. All right. And now that we have our bonus points, we can go ahead and update, call the update to our score again, global dot update score and use our time bonus. Now, going through this again, of course, we could just do time bonus plus our 40 for the update score. If you wanted to combine it all into one instead of calling our Update score twice. You know, personal preference, and that's something that you can do on your own. When we talk about clean code and giving you the ability to come back and brief actor code and clean up areas that you think maybe are a little messy. So you are going to have that option later on. And the last thing that we have to do is reset our timer bar to 30. So we're just going to get node, in our parent into the Gooey, get the timer bar, grab the value. I'm just going to copy it there and just reset that to 30. All right. And just like that, our game should just work with our old global and Goey scripts and check. Every time I go forward, I gain a point. I die, I lose a life. T got reset. See if we can make it across, wrap on our log or hanging out, de da de dah. We start hopping across. And we get into our wind zone, let's see what we're going to have. Went from 180 up to 320. So we got a pretty good bonus there in our time. The time reset, and we did get one of our lives back. So that's fantastic. Everything seems to be working perfectly fine with transferring our tote stuff over. So again, Guy, that is a canvas layer. With a label with a score label, a label with a score text. Our Lives bar is a texture progress, and we set the progress texture to our lives texture, let me get the exact name of health bar dot PNG. The timer bar, I just called Tr dot PNG. It's another texture progress bar, and the progress texture is set through the timer dot PNG. We then have a label the word time beside that. We have a timer node with auto Start turned on with a default weight time of 1 second. It has the timeout signal connected up to the Boy script. On timeout on our Gooey script, we subtract one from the value of our timer bar. And if our timer bar is zero, we call death on the player and reset to 30. On our player on death, we call Update Lives on our global that we were using from the two D is minus one, subtracted life. We also get our timer bar so we go up one, get parent. Then we go through our GUI to the timer bar, access the value property. We set it 30, and when we move up and only when we move up, we access our global again, update SCOR function and pass in ten points. And our global script will take a run through this again just in case some reason you couldn't find it in your own for whatever reason. Here you go. So we have a couple of variables of the top scores an integer set to zero by default, multi frog, an integer, zero by default. Lives, you set it to six by default, again, another integer, and multiplier is an integer set to one, our function update score takes one parameter of new amount, which is an integer. And we have our ILS check if multi frog less than five, then just score plus equals our new amount. So we just add the new amount onto our score if we do not have the five multiprogs. So the only way else we could have here is if we have five or more, then instead of adding the new amount, we add 1,000 points and resettle Multi frog to zero. And then we check if score divided by 10,000 times our multiplier is greater than or equal to one. Then we update our lives, we call it update life function and add one to it, and we set our multiplier, plus equals one. Okay. Now, after that, outside of those FL blocks, we get our score text, and we just simply update the text with our new score, and we convert our score into a string, and we call PAD zeros, and we add five of them. That's going to give us our padding here at the top. Make sure that we always have all five of these zeros, even if our score is only one digit. Then our update Lives function, we have an amount as a parameter, which is an integer. If lives are zero, we're going to get Tree and reload the current scene, so effectively restarting the game. Otherwise, we're going to do Lives plus equals amount, and we're going to get node, go up our parent, go down our main node, down our Hoey, to our Lives bar, get the value and add plus equals the amount that we're updating our lives by. Alright. So that's our global script, again, if you didn't catch it or you couldn't find it, somehow lost it. There you go. There it is again, quick run through, as well as the Goey script and the Gooey setup in the scene as you can see over there. As the small changes that we added to our player to make it all work. And if for whatever reason you're struggling with enabling your global, if you rewrote it and you brought it in, let me just see if I can capture that real quick. So you go up to your project, go into your project settings. Don't you autoload, hit this little button here, and you can select your global script from the pop up. The node name that automatically fills in here is going to be the name of your script, which would be global. And you just hit the ad button and it'll appear down here. Just make sure you have it enabled, and the name is how you access it. That's why we can type in the word Global and have access to the script. But there you go. There's our score system, the timer bonus, and the Gei all re added into our game. And now we can go ahead and we can play some Ride Boger. And not have any issues as we go. All right. So that's it with this. Take care, have yourselves a good one, and we can move on to the next week. If you wanted to add audio in, it's the same thing. Just add a stream player and load in the what are they all MP threes or some waves vv? Files. Yes, the two P threes and the files. So you can go ahead and use those the exact same as the two D. Just add an audio stream player into your main scene and the background and your main theme for the background music is sent it to autoplay. And for your player, you can go ahead and just add an audio stream in there and load the audio sources and play as you need it from squish, punk and all that. Exactly the same as it is with the two D. So if you want to add that you forgot, you can head back up there. Week three, take a look. But I think that'll wrap it up for this week. We now have a three D version of our little Frogger game here, so we can hop across the little road and get to our little wind zone, hop through our little platforms, and hopefully not get squished by the trucks. 58. What is an API: Alright. Hello, everyone. And today, we're going to embark on the exciting journey into the world of APIs. If you've ever wondered how different software applications will communicate and exchange information, this is the perfect place to start. Now, imagine you're at a restaurant and you want to order your favorite dish. Well, in the world of programming, this process is similar to how APIs work. Let's dive in and explore this fascinating concept together. Firstly, let's understand what an API or what API stands for. API stands for application programming interface. Think of it as a menu or a set of instructions that allows two software systems to talk to each other and share data. Just like you order a meal from a waiter and a waiter takes a request to the kitchen, the API serves as the intermediary that facilitates communication between different software components. So to make this concept even clearer, we're going to use the restaurant analogy, which you see on the screen here. So you, the customer, represent the software application, and the kitchen represents another. Now, this could be your own tool that you make, and you want the other application, the kitchen, maybe being Spotify, for example, or Twitter or maybe an Aime database, something that you want to talk to and get information from. Well, you want to order a delicious meal, get the information, but you don't have access to the kitchen directly. So instead, you communicate your order to the waiter who acts as the API in this scenario. The waiter understands your order, takes it to the kitchen, the other software application on your behalf. The kitchen prepares your meal according to your request and gives it back to the waiter. The waiter acting as the API, then brings a freshly prepared dish back to you. In the world of programming, APIs work in a similar fashion. They define a set of rules and protocols that allow different software applications to request and exchange data seamlessly. APIs can be used to access data from web servers, integrate third party services, or even interact with hardware devices. So let's say you walk in to a restaurant, right? You sit down at the computer, what you're doing. You're using your application, and then you tell the waiter or the API what you want by formatting the data correctly. The API or the Witter then goes back to the third party software application, database, whatever it may be, gets that information and then brings it back to you. So then you have the information to do with as you will. So in summary, APIs are like intermediaries that facilitate communication between different software systems. Just like a waiter takes order to the kitchen and a restaurant, they allow applications to talk to each other, share data, and perform various tasks without needing to understand each other's internal workings. Alright. There you have it. A quick introduction to APIs using the classic restaurant analogy. I hope the analogy helps you grasp the fundamental concept of APIs and their role in software development. Remember, APIs are powerful tools that enable seamless integration and collaboration between various software components. 59. How to Use an API: All right, everyone. Hey, we're going to take a look at where to get an API, as well as how it is if we can use them and specifically the one that we're going to use in our code example to help with learning, it's going to be the open weather API here. So if you go ahead and come over here to open weather, you can go ahead and sign up for an account, and you might notice that you might have to come to pricing and actually select a plan here, but they do have a free plan that gives you 1 million calls a month, 60 calls a minute. And we're able to see the current weather and that's going to be the more important thing here. Now, all this other information and all these calls and everything, of course, you can always feel free to do those, but those APIs are pretty expensive. You do get a lot of features and a lot more calls per minute and per month. Obviously, you're not really going to get anything anywhere near that. Unless you have a publicly released application that is quite popular. So for learning and especially if it's one of your first applications that you're putting out, the free tier is probably way more than enough than you're ever going to need. So if you need to, go ahead and subscribe to that. I already have mine, which, as you see, it says, get APIK. Now, how is it we actually use these APIs, though? Well, if we take a look at the top, we see we have guide here. And click on that, give it a second for it too. There we go. We here. And it's interesting that they called it Got here. Most places we'll call it documentation. And this is where should be where we can go ahead and use the come down here and we take a look around, see if we can find the exact second for using it. Specifically the open weather torsion. By call. So here we go. So now we're on the page here for the documentation specifically for the weather here. And we can see the product concept. We have our how to start, current forecast on weather data. We have our API call here, which I see, we will need an API key for this one. We have all the parameters listed here, which ones are required, what's optional. And then we have an example of an API call here. And an example of the type of response we would get. Now, when we get a response like this, we're getting a JSON response. And if you look closely, we can see it's a lot of key value pairs. So we can treat this response and get information out of it the same way as if it was a dictionary. And you can see all the different information that we're getting out of this. Which is a lot of info for us to go through. So once you go ahead and sign up for an account, you can go ahead head on up to your user in the top right hand side, go to my API keys, and sure to see a key there. If not, you can go ahead and generate one and keep this in mind or keep this page open because we are going to have to come back here and grab your API key going forward. All right. So let's go ahead. One more thing I'll mention is, if you're looking for free APIs for you to use free and open APIs, you can just do a simple Google search and you'll find there's places that have full list of all the different kinds that you or different kinds that there are with links going out to all of them. So feel free to, of course, always practice and check out some of the others, see how maybe one company's API operates a little differently from another. But that's it for this one, we're going to go ahead and jump into Goto on the next one. Keep our API key up? Oh, I hide it a bit, so we don't really see it for the majority of our code. And well, we'll take it from there. 60. Script Setup: All right. Again, you can go ahead and create a new project if you'd like. I just created a new folder for the API and websocket section here. And obviously, for the stuff to run, we're going to need a scene of some sort to be running here. So I'll go ahead and create a user interface, which of course is going to give us some control for our start here, going to call this API demo or you know what? This API. That's fine. Then I'm going to save it, keep the same name and store it in my folder. I have a scene called API. And of course, this is going to need a script. Now, the the actual scene here does not matter unless you want the user to be able to input information here, such as, of course, a text box or a line edit route, I should say, for the user to type in the relevant information, and then maybe you have a button that grabs all the text out of those boxes. But for the most part, we don't really need anything in there, but we are going to need one more piece to this scene here, that's going to be an HTTP request, so we can add one of those into our scene. I and an HTTP request is actually what's going to allow us to make a call to an API, to a website or web service of some sort. And then once that gets completed, some information gets sent back to us, and based on that info, we can use we can either parse that out to get the data that we're looking for, or we can take that information and maybe assign it to some variables to send out another request to a different section because some APIs will require extra data in the form of something called headers but for this, with this being a simple API, it's not too difficult to follow along. All we have to do is make the one request, and we'll get the JSON data back. All right, so on our APM, I'm going to go ahead and add a script. And we're going to have some variables here. So variable, I'm going to have the API key, which I will say that you should have your API key. It should be hidden. It should be never uploaded anywhere. This is something that you should keep as secret and as hidden as much as possible. So API key, that's just going to be a string. And you can get that again from the website. I can just copy and then you can go ahead and just paste it in there. Now, you can see this one. It's either going to be blurred for the video or I can just disable it so it no longer works. After recording this, so it's not that big of a deal right now, but just keep that in mind, this is something that you should keep as secret as possible. Okay, what other information are we going to need? Well, if we go back and take a look at the data, sorry this one. Let's see what's required. We're going to need a lot, so a latitude and a longitude. App ID, that's going to be our API key. We have that. Exclude is optional, and everything else is option. Okay, so we can just put it in latitude and longitude for this. All we're doing is looking at the documentation for this Davar Long, and that's going to be float and we're also going to need one for lap, sauce float. And these are the minimum pieces of information that we're going to need. Now, if we were to take a look at the API call, how we would do this, this, copy it over, trade another variable here for the URL string, and there we go one really long string. So we have HTTPS colon slash slash gmther or this the example call that we saw earlier. So you see we're going to have the latitude put in here, the longitude here, exclude, we saw that that is completely optional. And since we have no additional information here right now, I'm just going to delete that portion and app ID, which is where our API goes. Okay. So what we're going to do is we're going to use a placeholder that is a percent in a lowercase S. And we're going to use that for getting rid of these curly braces and what's inside. So we're going to have the latitude, longitude, and API key, so that's three things that we need to remember. So the first thing I want to do is we're going to need a latitude and longitude, which for now, we can give it a default zero, zero. And inside of our ready function, in order to make this API call, we need to go ahead and get our HTCP request, but we'll just call this the setup portion. We'll split that the next one. So we'll go to our HTCPRquest and we're actually going to connect the request completed signal to the API. And you'll see we get a result, a response code, we get some headers, and we get the body. The body is going to be the important piece here. I'm just going to go ahead and save that, close all the other tabs. Alright, so I'm going to end this video here, so we can just split this up here next. And the next video, we'll go ahead or the next lecture. We're going to make the actual API call, and we're going to parse out the data that we get back so that we can actually use it and see what we have. 61. Making API Calls: All right. So I do want to make one note here is one we're looking at was for one call. So the URL is slightly different. It's api.weathermap.org slash data. Then slash 2.5 slash WE Question Mark. And then that's where we have our parameters to Lat Long, and App ID. So it's slightly different the URL here now. For this version, it did yell at me when I was testing, but one call being having to subscribe to a different service. So it's just a little weird trying to find the documentation on this one, but we go ahead and we get our HTTP request node, and we call the request function on. We pass in the URL, and in order to fill in those placeholders, we do a percent sign. And then we have a pair of square brackets just like an array, and we pass in our variables lat, on, and our API key. Now, you'll notice if we try to just print out the body here, that well, we have a lot of data here. None of it really makes any sense to us, but we're getting something back, which is great. Now, generally, you'd probably want to make an F check here with a response code to make sure that what's being returned back that we're not having any errors. So if we just print out the response code, you see we get code 200, which means that everything has gone fine to go through it. Now, if we got a 400 error, then, well, I just spoiled there, it's an error. So that means something went wrong, something's not working. The data didn't come back, the service is down on their end, the request is not formatted correctly, incorrect information, whatever it is, there is an error. So we could check if response code is 200 just to be safe. If response code equals 200, right? So we can say if everything went well, now, how do we actually get this data? Because we saw it it was an array, but an array of just a bunch of random numbers. Well, we have to parse that out. So the first thing we're going to do is create a new variable for our response, and that gets set to our body, but we want to get the data from. So we say dot and if we type UTF eight, we'll see it string from UTF eight with an underscoring between each of them. So now if we go ahead and print out our response, let's see what happens. Okay, well, we have information. However, in many cases, you are going to take the extra step here, Anine. I'll just create my temporary variable here, TD for temporary data. And for this, we call our JSON parse string, and we can pass our response into there. And now let's take a look at what we get back after we've parsed out parse the string. There you go, something that's a little easier to look at spaced out a little better. We have comas in between, everything. It's it's nicer to see, but it could always make it even nicer to really want to just looking at things. But at the base right now, TD now represents all of our information that we need or would need. Right. If that was hard for you to see to read, I get it. That's fine, but we can pretty it up a little bit just to make it easier for us to look at. And here we just go ahead and call the JCN class and we can call the methicon stringify, pass in our data, TD and a second argument of a string that only contains a space. And if we were to look at the output now, everything's going to be a lot easier to follow read. So if that's what you need, fantastic. That's how you can make it nice and clean. All right. So now we would know that if we come in here, we could print out TD and we can get a piece of information out of here, such as see Maine is what we're looking for. So we can get Maine and print that out. And we see down here, if I just comment that out, comment the line with Control K so we can not you confuse the old information. We can see here's the temperature. Here's what it feels like. Tempman Max, the pressure, humidity, sea level, and ground level. Now, I mentioned before that we need latitude and longitude. So a place that we can go for that, if I just go back to the display capture here. Is this website here called latlondt net. And as you can see, you can just click anywhere in the world and you'll get a latitude and longitude position. So for example, if we were to come down, I'm going to go with Vancouver here, and I'm just going to click in there. We've got 409-25-6791. Just going to go ahead and copy that over and set that to my operation here. So first is at. They side in and my longitude here. Makes s. So you can go ahead and get anywhere in the world here, get your latitude and longitude. As you see, you can also just type a place here and it should pop up for you. Alright. So with this information put in, let's go ahead and run this. See what we get now temp 288.11 feels like 288.14. Now, obviously, these numbers seem pretty high. So the question would then be, why would that? Well, this is where comes into play with the data that we're getting. Here you go. I just brought us on down to the fields in our ATI response here on the documentation. I scroll in here, we can see where are we at here? Dot right here. So the temperature inside of Maine, the unit default is Kelvin. So that is why it is so high for us for the number that we're seeing at 200 and something degrees. Remember, optional, you had the option of putting in metric or imperial inside of our optional if we go to units here, right? You see we can put in standard metric imperial. And standard units will be applied by default. So standard would be our Kelvin, and then we have our Mexican imperial, right? So how would we add these in for information? Well, we simply just as you see here, if we follow the pattern, we just have the ampersand, parameter equals, and then whatever we're looking for. So if we want to add in units, then we should just have to do ampersand units equals, and I believe it is a spring that it takes. So let's go ahead and hop back over. And let's add units or units. And like I said, I believe that's just going to be a spring. And for us, let's go to something like could go to Celsius. And I think that's what I'm going to go for. It's not Celsius. We need to go with Mexico or Imperial. Let's go ahead and go ahead and type in metric. And I'm just getting that from looking at the API. I see a metric in all lowercase, as well as Tempio, so I'm assuming this is all lowercase. So we need to add that into our URL. So I'm going to go ahead and after my longitude, but before my app ID, I'm going to put Ampersand unit equals. And then we'll have our placeholder here again. Now in my request, we have latitude, longitude, and before the API key, I can pass in units. And if we were to take a look at it now, you see we get back 14.85. And same thing if we were to replace metric with imperial, we should now get the Fahrenheit equivalent 58.44. All right. So that's how we can get this information. And now you can set the text of, say, a label on screen, or you can have different images inside of your application and you can change or display the image based off what kind of weather it is, right? So we can see the temperature, the pressure, the humidity. But remember, that's all that's not all the information that we have, right? We can take a look at the temperature is weather dot Main? I might have this wrong, hopefully not, but if so, I guess we're going to get an error in our print. Yeah, we got an error in there. I'm just going to take a look at uncomment my string of fine information so I can take a look at it. Wind, weather. Okay, so it looks like it's just weather. No main. So TD and I'll grab the weather attribute out of that. Clean that up. And actually, the ID is 81 main clouds. Description, few clouds. So you see now we can see, okay? The main weather here is considered clouds, so that would be cloudy. So now I could display maybe a cloudy image on the screen to go with that or change the background of the app to be cloudy. As you can see, there is an icon here as well in this data. I'm not sure where this icon is coming from. But if you knew where and they gave you a link or an ID or something for an image, it is possible for you to go through and fetch that image from the Internet, so you could use that, which would be more ideal. But again, I don't know where this icon is coming from. So I'm not 100% sure of where to bind dynamo gar to do that. But that's the basics there making these simple API requests. And some requests will get more complicated than that and will require you to really sit down and look through documentation that they may require authorization, certain permissions granted. You might have to wait for the user to authenticate. You might have to have a bunch of information that are put inside of your headers, which the headers would come after the request. So we have the URL here. We would just have comma and then our custom headers, which would be in the form of, I believe, an array. That you could pass in, and then we can get other information like G, post the method that we want to use. And G is simply the default, which is what we're doing here. We're asking the API for information from the database, and post would be like sending information to the database, such as a leaderboard, for example, if you have some kind of leaderboard setup where you work with an API, then you could push information there using the post post method instead of the default get here. But there you go. There's how we make these This is essentially the core of making an API call. Anything past this is just a matter of making calls to get information for you to use as headers in order to get the data that you want. But at the CR VIT, this is what you'll be doing. And if it's simple, this is all you need. If it's more complex, such as Twitch, for example, you're gonna have to go through the documentation, but Twitch's documentation is not that great. So you're probably going to have a headache and give yourself problems trying to go through Twitch's documentation phases. But there you have it. There's the basics of how we make API calls. 62. RapidAPI Python to GDScript: All right, everyone. You can ignore the error that's on screen there. That's just because the variables don't exist yet. But I wanted to talk about here and I'm going to be using I have a separate scene open for this. It's identical to the first. It just has a dk script, and this is going to be going into an anime database. I pick this one just because anime popular. So as popular as Anime is and the amount of shows out there. If you guys are watching, probably a good chance that you like anime or you've at least given it a shot at some point. But this is the actual topic here is relevant? It just happens to be what I'm using here as my example. Now, what I want to talk to you about is using APIs online and when you're looking around, because you're not going to find anything for Goto or GD script. The closest thing you're going to find is something like Python, which is pretty close. So I'm going to show you how we can take the Python example that it gives us and use it in GDScript. Now, what we're using here is from rapid API. And Rapid API has a lot of free APIs out there that are well, both free. This one, as you see, is premium. So if we go to pricing, we have multiple options here. The basic is free, which is what I'm using here. And you see I can make 100 requests a day and only two requests per second. So these obviously wouldn't be that great for a deployed application because you might get more than two requests per second, and if you start getting any popularity or you have a really heavy user, you could easily surpass that 100 per day. So obviously, up there, if you're going to do something and pass it or it's going to be passed out. And, you know, the $5 or $10. Seemed like some pretty good plans. So $10 completely unlimited, and the $5 is 5,000 a day. But you notice we don't have any you don't have a limit on how many requests per second. I also pick this one because the latency is only 591 milliseconds, that's approximately five or 6 seconds from making the request to when we get our databa. Popularity, 9.8 out of ten, so it's a very popular one. It was updated two months ago, so it's still kept up. Service levels been 100%. So there's a lot of reason as to why this API makes a good one for our example here. All right. So all you can do is just go up to the Rapid API, sign up for an account, and you can come in and just make a search for whatever you're looking for. In my case, again, I come up and I search anime, and then we have all these APIs here. Some of them might be mandatory money, some may be completely free, and some might be premium, like I showed you with the other one. Now, the first result here is the one that we're using, and we see if I help role but we can get information by ID. We can get all, we can get genres. So there's a few things that we can do and this one here called A Animation, we can get something about a gift or GF, however you want to pronounce it, an image, which information it's not too much for us. In this case, it starts going a little past scope here, but you can see, they're not all the same. They all offer different services here. That's what you can get ahold of. And see, as I'm popping up, some of these say premium, some say free. You might get a premium somewhere where it's paid only, I don't know, but it's not looking like it. It looks like these are all either free or premium, at least on the first pagier. So I'm just going to go ahead and click on one just to show you an example. So once you decide what you want to do, what you want to get, you'll notice on the right side, these are all the things that we can use. So let's say we wanted random wallpaper. We would click that and we would get our information on the side here with our example. And you can't really see any of that. So I'm going to readjust this now. So one moment. For now, that'll do for us. But you see on the right hand side, these are all the different I guess can say services or information that you can get out of their API. And just by clicking on one, you see the information changing on the right hand side as well as middle. So that's essentially how these are going to work. And you can see these ones are all get, but some of them might be a post depending on what you're trying to do. And that's the method that I mentioned at the end of last video, where a lot of times we're going to use get to get information, but there may be occasions where you have to post and push information. And if you decide this is one that you want, you just go ahead and hit the subscribe to test button here. And that should bring you to the pricing phase pricing page. You can also just come to here and you can select which plan that you want to subscribe to. And these all have a hard limit here, as we can see. And you want to be careful. Some of them aren't a hard limit, as you can see here, in the case of this one, you're going to be charged, which will go to your account, you get charged that you have to pay. This 1.5 cents for each other. Each additional request, right? That fall in line with that one and $0.03 on this one. And that's of course on mega. These obviously go up higher, as you go, but the basic plan only has a hard limit. So just be aware of that some do have or do extend past a certain limit at the cost of you actually paying them, even though it might be a free plan. Alright, we're going to jump to Whoops, that's the rapid API. We don't want that one. Just gonna go back here. Go back into the anime DB that we're using. And I'll just reposition this better for us. So, just for this, I'm gonna be using get all on the right hand side, or sorry, the left hand side here. So that's the one I'm gonna be using. I'm now going to just slide the screen over so see things better for our use. There we go. All right. So for this, what we're going to use, and I said Python. And specifically, if we open this up, we can see examples for all these different languages. And Python is the one that we want. And we'll be looking at the HTTB client as well as the request library. Now, in Python, you can do this either way, but for us, we need to do this kind of looking at both versions, to give us an idea. And you see here, we have headers. I'm just going to copy the headers out of there. And if we go right back to Goto here, we can go ahead and create our variable headers. Now, theirs has curly braces and it's a dictionary. Ours has to be an array for our headers. Those are square brackets. I'm just going to paste that in. Now we're going to have an error. Simply because well, we have key value pairs. That's not how a an array works. What I'm going to do is I'm going to go in the middle, highlight this quote, the colon space and the other quote here. And I'm just going to put in delete that colon space there. So we're basically removing the quotation marks around it, making them one single string. And you see at the end by devolve, you copy both of them. We've got that separated by a comma already, and we're going to do the same thing here in the middle. Delete, coal in in space. So we have two pieces of strings here, and that's going to be our headers. And I got that from the you should be able to get that from either the request or HTTP client from Python. They'll both be exactly the same here for this piece of information. And I'm going to go ahead and just zoom this in further, just because this is the only piece of information that we should really be focusing on here. Alright. So again, the headers here. I went ahead and just copy the information here. And this is essentially the as it says here, our host and API key. That we're going to use specifically for rapid API here. And this is going to change per my brain's having a pause in it there per database, per API. So this is always going to be different. Now, the URL that we want, well, we can see connections animated db.p.rapidpi.com. And then in their request, we have this whole big thing here. Well, that's not going to do for us. So let's just drop down and go to Python Quest, and this is going to be our base URL. If we just copy that and take a look back here. We can create var URL. And that is our base URL. Now, I said we're going to use get all, and that's where this last variable comes from. Just creating that there. And this is where you have to be a little observant when combining things because you could merge everything into one URL, and then you can have a merger of the get all go around the genre to go around, et cetera, but what I'm going to do here is we're going to go we're going to head back over here, and we can see this ends with slash N, rapid api.com slash anime. So we need to keep that in mind. We're going to go back to Python HTTP client. And we can see down here at the bottom, we have slash anime, question mark, page one, et cetera, right? So we're going to ignore the slash anime and grab everything after that. And we're going to jump back over to Goto. And there we go. Then we can see the searches, full metal, genre, fantasy, sort five ranking, sort order ascending, there we go. We have all that. So now we can just merge our base URL with whatever we have here. So as another example, if I were to come down to the G one anime. G one anime, by ranking. All right. And I jump back here just to show you here, and I go to HTV client. Wills anime, but then right here, B Ranking slash one. This would be as an example. Read another variable here. Right? We'll say get ranking. That's a string. And we could do that. So now we can just swap this out with get ranking, we want or put back in. So that's why I like separating here then I can just change specifically what I want there. And of course, if you were going to implement search results and things like that in here, I see search here, the genre and all that. You can put that in as placeholders like we did in back here with the weather, right. With this, we have that, and then we can see what is it that we need to get? Well, if we take a look, it's going to go back to the get all here. If we look down here in HTTP client, we see G response, and we're looking at all this, and we see down here, all they're doing is decoding UTF h. So that's all hoops. All they're doing is they're decoding UTF eight. So that should be all we have to do for this API. Now, if you're working with a different API, you might have to do the full JSON parsing, like we did on the open weather. So here, we just have our response and all we're doing is we're getting the string from UTF H. Now, if we print the response here, we run this, and remember, we're getting all. We got to wait a couple of seconds. And here we go. We have a whole list, so we can see comedy fantasy episode 16 that does have the episode ranking true. We can see the image here to WebP. We have a link that goes directly to it. So you could take that link and provide that link to your users. If that's what you want, but you can see everything is in here as their data. And we can access all of this individually. And just to show you that we have curly braces here at the beginning. If we come in here, we just get data, it's coming through as right. So we would have to find a way to actually sort through the information that we're looking for. So in this case, since we're not getting Jason back, that's a little annoying, I suppose. But as you see here, since we need to go the extra step, even though the API or the page, told us all we have to do is parse the UTFA. That's fine. But since we want to get the extra data, went ahead and parse the string using the JCN class. And as you can see, now I can get that data, the first item of it because data was an array of items. And then I can grab the title of that first one, which is, I believe would be the first episode, right? At least the result. And if we change this to the second item, we should get a different name down there. Yeah. So we've got Brotherhood. I'm going to go to the next. We have the conqueror of Shambala, whatever that is. I've never seen this. But there you go. You see, it's not too difficult to work with this Python or converting the Python example into it. So our arrays, we copied them in and put them in GD script here as an array instead of a dictionary. We deleted the quotes in the middle. So that our API key is one long string, and our API host is one long string. We switch back and forth between HTTP request and http dot client and the request library for the two Python options here in order to get our base URL here, as well as the different searches here that we can actually put in. And all we do in the request, we pass in our URL, and in this case, I'm just going to add to plus my G A and the headers. Now, if you have more than that, for example, if you have one where it tells you that you need to push, right? You need to post instead of G. This is where these defaults come in, right? So we can just come in HTTP client method under Square Post. Now, the default is G. That's why we don't put anything in there. But if you ever need to post, instead of G, that's how you would do it. You would just add it in after the headers. Alright, so there you go. There's how to There's both a large collection of APIs that you can look to work with, practice with. And if this is what you want to do, provide things for your client. As well as how do you use their Python examples and convert them so that we can use them in GD script. So now you've gotten a wider collection that you could work with. You now know how to work with headers here. And I've shown you how to do a post instead of G. Now this will air out because we don't post. We get for these. Yeah? And that'll that should round us out there for the API portion. And next, we'll go ahead and jump into taking a look at what web sockets are, why they're useful and how we can use them and why we might want to use them. 63. What are WebSockets(filled space): Hello, everyone. Welcome. And today, we're going to talk about what are web sockets? What are they? What are they poor? Well, if you knew the programming, which probably are here, you might have heard this term before, but what exactly are they? What are websckets and how do they work? Well, by the end of this lesson, you'll have hopefully a self understanding of what web sockets are and the magic that they can kind of provide to us. To put it simply, web sockets are a communication protocol that allows real time, bi direction data or bidirectional data transfer between a web browser and a web server. You can think of it as a virtual persistent connection that remains open enabling instant communication between the two ends. To understand this better, let's imagine you're chatting with a friend on a messaging app. When you send a message, your friend receives it instantly, right? That's because the messaging app has a similar concept. It establishes a connection between your devices allowing for real time communication. Now, how do web sockets work? Well, when a web page that supports web sockets is loaded in your browser, it sends a special HTTP request to the server requesting to establish a web socket connection. Once the server approves the request, the persistent connection is created and both the browser and server can send data to each other in real time. The magic of web sockets lies in their ability to handle two way communication. This means that not only can the server send data to the browser instantly, but the browser can also send data back to the server in real time. It's like having a live conversation between the browser and the server. Web sockets are incredibly useful for building applications that require real time updates, such as live chats, online gaming, stock market tickers, and once more. They eliminate the need for constant page, refreshing, pulling, making your web applications more efficient and responsive. So if you need another kind of explanation to help understand with this, you can think of it as you think of it as two people meeting, possibly for the first time, person A, the client, person B, server, they meet, they shake hands. And they try to establish a connection, right? They meet up, shake hands, and they determine from that point if they want to keep this connection, and exchange information, have a conversation with each other or to walk away. If they don't wish to talk, then the connection we can say is closed, and they go their separate ways. However, if they decide to continue their conversation, then the connection was accepted between both members, both parties, and now they can exchange information live in real time. Hopefully one of those three Sho examples will help you with understanding exactly how it is that they work. And though you have it, that's a simple introduction into websocket is what they are, how they can be used. And they're an essential tool when it comes to a lot of modern programming, and again, this is going to really depend on what kind of field, I would say that you want to go into with your development skills. But they do help with enabling that real time communication between your application and the server. And as you dive deeper into programming, you'll find web sockets to be a powerful and versatile tool. Create interactive and engaging applications. But remember, they don't only just work with servers that are off somewhere else. There are some existing applications that use websockets that you could create your own tools to work with. We'll take a look at that in the next video. 64. Establishing A Connection: All right, so let's go ahead and take a look at how we would set up a web socket connection with ourselves here and how we could connect to something. And the thing we're going to connect to is going to be OBS. Now, if you want, you can go ahead and look for the websocket server plugin, the websocket plug in for OBS Studio, if you want to follow along with this and just run through the installer. I should only take you a minute or two. And what you're going to see is if you go up to Tools on OBS, you should see a web socket server settings option there. And by clicking that, you'll have this window here Popo. Make sure you have websocket server turned on. And all we need is we need a little bit of information here. So if we go to show Connect Info, Then what'll pop up is your server's IP and the port. And the IP is the main thing that we want out of this because we can already see the port right here in this window. Now, down here at the bottom, you'll see when or however many people connect to this. And as you see, you'll also have the option to kick a user from here. So this is where we're going to get our information from just so you know. And again, we're going to want the IP and the server ports right here. So you can go ahead and take that information, remember it, have it off to the side. And let's get started here. All right. So the first thing we're need to do is I just have a control node here, my scene, nothing big to something that we can run with. And I'm going to add a script to it and just call a websocket client. Doesn't really matter. And now we're ready to create this connection. Alright, so how do we do this? Well, we're going to we're going to need a new socket, right, in order to get started. So we can create a variable called socket. And this is equal to a web socket peer dot no. We want to create a new item, right? A new object, this web socket. And I'm going to go ahead and put in the socket URL here as well. Just store that as a variable. Socket RL. And that's going to be your IP address. But not just in any way. We're going to have WSS, ClonAS then our IP, and I can't paste it in, so I'll have to type it 100 dot zero dot 19. This one is I don't know if it fails, then we'll take a look at the other one. So inside of our ready, this is where we're going to make our connection. So socket dot connect to URL, and we'll just pass in our socket URL. Now, this can take optional parameters, but we don't This is not a thing for us to put in here. Next up, that gives us our process function here. And the thing you're going to need to do is whole. And what that is is that's basically constantly you can think of it constantly as exchanging a very, very tiny amount of information just to keep up the connection on both sides. Otherwise, if nothing is received, then the connection will be dropped and you'll be disconnected from that web socket, right? You'll be disconnected from that server. I and nobody likes that. All right, so now to use these, we need to decide what we're going to do, and we can determine that based off of the state that our socket is in. And the states that it get lets us know if it's open, closing, it's closed, or if it's still connecting. So let's go ahead and store that. Bar state equals socket dot get ready state. And now that state will be able to tell us what it is. Now we can say if state equals websocket here, t and here's all of our states. So we'll say state open. And I'm just going to pass there for a moment. And we're going to create our other ones here as well. We're going to say, s if state is equal to state closing. And that leaves our last one to be closed. Now, we could have one for connecting as well, but there's no real point board. Now, when the state is closing, we don't have to do anything here. We just got to make sure that we're still polling at this point in order to actually close properly. And let's see, Let's start. Let's go ahead and do when our state is open. Well, here we're going to have a wild loop, and this is where we're going to get our packet information that's being given to us. So we can say Wil socket available Pack account. While there is data being sent to us, right? So we have packets. We're going to go ahead and we're just going to print out what this is, so we're going to say pack Base. And then for the second argument, we're going to pass in whatever that packet is, right? Socket. Yeah. Packet. All right. And that's all we need to do while it's open. Let's take a look down here where our socket will be closed. And bar information, we can go ahead and do bar code, and that'll be able to socket, get close code. This way, we can have some information when we do get disconnected as to why or maybe our connection fails. So it tries connecting, and then it just immediately closes. We can again find out why so we can get some information back to us. And speaking of reason, that's going to be our next one here, that's going to be socket Get close Reason. We can then go ahead and just print out our options here. And this is just going to be websocket closed with code, placeholder, reason, placeholder, clean placeholder. Go. There you go. You can see it there, webs closed, code, reason, clean. A one extra there on the end. And we're going to fill those in with code, reason, and then code not equals to minus one. All that leaves us one last thing to do is to stop polling, and we can do that by just calling set process false. So when you set that to false, whatever is in here, this process function is no longer going to run until you set it back to true again. All right. So with this, we should be able to connect to our we should be able to connect to the OVS in there. So if we just We do our window go? Think our window closed. Just go ahead and open that up. There it is. Alright, so I'm just going to go ahead and hit Run here. But I'm going to make sure that we can see this side when I do it. I'm just going to go ahead and run that. Give it a second, and we see we have no connection. Now, the serious part is going to be as to why. Well, let's take a look. Well, the reason it's not connecting is because we didn't do anything with the port. Now, the port can be if you make your own application, it could be pretty much whatever you want. Just about as long as it's not already being used. And the way we add a port onto the end of our URL here is just a colon. And then the port that was available there on the service setting, which is four, four, five, five, save that. And if we look back over here and run it, give it a second here. There we go. We can see if we're connected. We can see how long we're connected, messages in and out identified has not been identified because we're not using any passwords here and our information, and we have the option of hitting it. Now, if we take a look at the Goto side here, we can see here's our packet of information. It looks like an array of numbers, but it does have data in there. Trust me. We just can't see exactly what it is. So we'll fix that here in just a moment. And underneath that, you can see where when we kick the user, which will be our client here, we can see that websocket closed, and it closed with code 40 11. The reason for session has been invalidated. For the reason is our session has been invalidated, and it was a clean close, which is good. But how do we get data out of all of this packet here, packet of byte. Well, socket dot Get packet. This is in a pull by array. So we got this as UTF eight format, so we need to get the text out of it. So after we do socket dot Get packet here, we're going to call Yet string from UTF eight. And save it. And when we go and run it again, when it connects, we can see we got the actual data that was inside of it. So we can see the version that we got and the RPC version. And that information that we're using here that I got here with the current version of the server that I'm using. Yours might be different because I'm assuming you're going to get it brand new. I've had this installed for quite a while now. I'm just going to go ahead and stop running here. And you see we did not get any kick message there. But if I run it here and if I hit the kick button, you see, there's our kick message. All right, so unfortunately, I can't really help you past this point. Past how can you get a connection here as getting information or sending information in a particular way is going to be dependent on what you're connected to and how they want their data, I guess you could say structured, and how they send data back to you, you may or may not have to get data in different ways out of it, but going forward, which you can do is if we hold control, we can click on websocket Peer. And if we come on down, we can see here's all of our properties, our methods, and all our information has to do with this specific thing here and how to use everything in here. So you can go ahead, you can run through, take a look at that and I guess cross that with looking at documentation or whatever you're trying to integrate with. And at that point, I guess it's kind of like best of luck. I kind of sucks to say, but we got you connected, it's up to you to read your documentation and that to figure out how to exchange that information. 65. Sending Data with WebSockets: Alright, so I have a button and a line edit here added into my scene just for some visuals here. And the button has the press signal connected up to my web socket client. And I'm going to show you at least the idea of how to send, say, a message across this websocket. Now, ours is well, I'll show you. Fact you can see it down there at the bottom, but we'll see it here in a minute. So on the press, we're going to have a message screen for this variable, and this is going to be set to our line edit text. Text. Stop with the autofill. Stop it. So we have that. And now we need to actually send this. Now, you could put this send portion into its own function, which would probably be a smart idea because then you could just call send whenever you need to send data. But this is how we would send it. So we say sock it, put pack it, and then we have to put in our message. However, we can't just put in our message like this. That's not going to work. But we could come in with our UTFA buffer, for example, and this is going to encode it. So if we go ahead and run this, now this is still connecting to OBS here. If we type in, say, hello, send, we can see our wipe socket was closed because the encoding is sent to Jason, but binary message was received. So you can see we're sending the wrong type of data. So this is where this is where the type of information needs to be or is based on your project. It's based on what you're connected to and why you need to look at documentation. Alternatively, doing it this way is also JSON dot StringfiO message. And then we can encode that to UTF eight, like so, and that's going to give us the same result in this instance. Our socket is going to close. And of course, when you're sending, you probably want to make sure that the state is open state here. But there you go. There's the idea of how you would send data across this web socket. Now, like I said, didn't really work. We were closed because we sent the wrong type of data, so we lost our connection. But you're just going to have to read documentation of whatever you're trying to connect and whatever program it is you're trying to talk to. Right? So if you guys have Python installed, feel free to take a look at this and copy this code to make your own little web socket server in Python to mess around with things. But ultimately, we're using Async and web sockets, of course, web sockets would have to be imported. And all we're doing here is we're creating an async function, and this is basically just starting up our server for us, or sorry, down here, we'll be starting our server. But up here inside of our server, we're looking at four message in web socket, so right, every time we send a message here, our message is going to get decoded from UTF eight. Whoops. And then we're going to print out the message that we got from the client. So if this was, say, a chat app, then you would take this and you would send it to whoever they're talking to, right? Based off their ID or whatever. And here we wait a moment and send the message back. We're sending the message back to GOTO here just so we can take a look at it and we can see that we can both send and receive data, right, back and forth. And then we're just starting the server on the local host, which in GoTo, if you were unaware, the IP address have a local host. It is 127.0 0.0 0.1. We're also using the port 5,000 for this. That we're just printing out to our console down at the bottom down here that the server has started, and then our two loops here is basically just having our server continuously run. All right. So if I were to come on in and run this, we can see server started here. And I'm going to go ahead and run this on the gatto side so we can get that nice connection. Oh, and we can't see that now because of that layer. That's fine. I'll just lower it down for this. Okay. So there it is. And you'll see I'm going to go ahead and type in here, say, hello, new person. Welcome to the chat. And I'm super excited. I'm going to hit my Send button, and there you go. We can see message from our client. So we can see that we receive data on our web socket server over here. And if we hide this, we can see it on our GTO version here. The packet that we got back, right, was a message that the server sent to us saying, Got your message and repeated back what our message was. So you can see this works, it's just a matter of having or formatting what you're sending, right? You message that correctly based on whatever it is you're connecting to. So you see this method here works or this set up here works with a simple web socket server and Python here, but this format does not work when connecting or sending data to OBS. So that's where some of that reading comes in, but I did want to show you I did want to show you the working web sockets with a server. And you see what we have here is our base set of creating a chat bot or creating a chat room that we've done here already, just with our server and client. You just need to differentiate which client is who and who they're sending each message to. I mean, you kind of got a chat set up, at least between a server and client. But before I start ambling on, there you go. There's some proof, I guess, you can say that sending this data does work. It just depends on how it's formatted and what it is you're connected to. All right. I'm going to put that up there again. So if you want to pause the video and go ahead and copy that out if you would like. And you have Python installed on your computer. If you want to do this, and create your own server, go for it. With that, take care have yourselves a good one, and that's how we connect and use websockets. 66. How is Desktop Development Different: All right, everyone welcome back, and we're going to be diving into the software development section here. Now, what makes software development different from gaming development? Well, let's discuss that. Software development or desktop applications involve creating programs that run directly on a user's computer. These applications serve a wide range of purposes from productivity tools to creative software and everything in between. As a desktop application developer, your focus will be on designing intuitive user interfaces and crafting efficient solutions to meet users' needs. One of the primary differences between game development and desktop application development lies in their intended purpose. While games are designed for entertainment and interactivity, desktop applications are built to solve a specific problem or improve productivity. In the world of software development, you'll encounter a diverse range of applications, such as word processors, spreadsheet tools, image editors, video players, and more. The possibilities are limitless, and you have the power to create tools that can positively impact people's lives. Additionally, as a desktop application developer, you'll be able to work with different programming languages. Some of these popular choices would be Python or C SHARP, that you could use alongside GDScrp to enhance or bring more features to your application that you may not normally have. Obviously, this is optional, but the ability would be there for you. Another key aspect of software development for desktop applications is the user experience. Unlike games where immersion and gameplay take center stage, desktop applications prioritize usability and efficiency. You strive to create intuitive interfaces that make users' tasks simpler and more enjoyable. Now, one thing that's also going to be very important when it comes to software development is how everything looks overall, the way you've presented your application. If your application looks like it was built back in the days of Windows 95, then it's going to look old, dated, and it's not going to be attractive in comparison to another application, even though yours might be far superior. If it doesn't look as good, not as many people are going to try it. It's just the unfortunate reality of the world. Not only do you have to make a program that work exceptionally well, it has to look good as well. So it won't hurt for you to take a user experience or user interface kind of course as well to go alongside this afterwards to enhance your user interface design skills, if that makes sense. And that is, of course, only if you choose to go down the software route going forward. But there you have it simple introduction to the software development for desktop applications. As we dive deeper into this section, we'll explore some of our essential tools, I guess we can call them while using TDScript here. And some of the things I can help you with some of your design principles to help make a user friendly desktop application. 67. Anchors: Hello, everyone. And before we get started with actually creating anything, we need to talk about anchors. What are anchors? Well, anchors are powerful tools that help you create responsive and flexible user interfaces for your games and software applications. Anchors are effectively used to adapt your UI element to different screen sizes and aspect ratios. Let's dive into that. In Goto, anchors are invisible tethers that attach UI elements to the edges of the parent container or screen. They define how the UI element should scale and position itself when the parent container or screen resizes. This ensures that your UI remains consistent and user friendly across various devices and resolutions. To better understand anchors, let's imagine you have a UI button on your game's main menu. You want the button to stay in the bottom right corner of the screen, regardless of the screen size or aspect ratio. To achieve this, you would anchor the button's position to the bottom right corner of its parent container or the screen. So to this, we would grab our button, and these little green pins are our anchors. So if we move them all to the bottom right corner, and we were to take a look at the scene here, no matter what size we make it, it's always going to remain in that bottom right corner consistently, whereas if we left it at its default, which would be in the top right corner, sorry, top left corner. And we set that. And if we were to run that now, you'll see it's staying in this position relative to the top left corner, regardless of where the bottom corner is. And as you can see, the bottom of it does not matter and we can completely remove it off the screen just by making a small. However, if our anchors were in the top left and bottom left, and we were to take a look at that, it's going to remain in that position, but it's also going to stretch out on the bottom, because it's going to be that close to the bottom and that close in the top towards the other corner. And we can still, of course, go past. So you can see how the anchors can affect how your UI is going to look at the end of the day. So if we wanted this in the bottom right corner, we're going to put our anchors in the bottom right. And now that part of our UI will always remain in that position relative to that corner. Now, when you run the game on different devices or resize the window like you're seeing there, the button will automatically adjust its position based on the anchors, ensuring it remains at the bottom right corner at all times. Now, in goto, you can use the anchor presets to set the desired behavior of UI elements. These presets include top, left, right, bottom. Anchors are elements at the specified edges of its parent container or screen. Vertical center, horizontal center, anchors the elements to the vertical or horizontal center of its parent container or the screen and fill our last option here, anchors the element to all four edges causing it to stretch and scale with the parent container or screen. So if you wanted, say, an image to always fill in the back, for example, if we came in and we made a color rect here, and we filled up the screen. We come in. We have this nice dark color. We have a dark brown here. Maybe we want to go with a subtle dark green for our background. And if we don't touch the anchors, we leave everything default, and you can see we have a problem here. However, if we use in this case, we can just use the preset to bull wreck to put our pins in all four corners, we are now always going to have our screen entirely covered with this background. In our case, our color. So by using anchor presets and customizing their values, you have full control over how your UI elements respond to changes in screen size and aspect ratio. All right, there you have an introduction to anchors in Gato. By leveraging the power of anchors, you can create responsive and adaptable user interfaces for your games and software. Now for games, of course, this is usually only going to apply to your heads up display, ensuring a seamless user experience across different devices. 68. Search Layout: All right. The first thing we're going to do is we're going to create we're going to create our search bar first and what we're going to be creating here. Is we're going to create our own little desktop application that will allow us to search for an anime and it'll give us a list of results. It'll have all the images for all the results for each individual anime. I'll have the title. I'll have the genres. And if we were to click on one, it'll open up. It'll give us a synopsis. It'll have a bigger version of the image. And if we want to take a look at, take a look at it further, we could click on an external link to take us that'll open up in our default application, which would be your default web browser if you're on PC. And open up the anime page for it. And the first thing we're going to do in this video here is we're going to create the search bar and button sent you for it. But we're going to start out with putting a background in here because this is kind of boring, right? We open it up and we have this boring, gray image. Here we go. We have this boring gray box. It's not too exciting. And even if we put, like, a line at it in the middle, it's not gonna be all that appealing. It looks kind of M, right? So the first thing I'm going to do is I'm going to get my brand new scene here. Of course, I named it Main. It is a UI scene. So my root node is a control. And I'm going to go ahead and add in a texture rect here. I'm going to rename this as my background. And for the texture, I just went online and I found an anime background because it's an anime background would fit for Anime. So I just went ahead and found one, brought it in. Now, that's obviously way too big for my application here. So you'll notice if we grab the handle, we can't change it, but we can make it bigger, but we can't make it smaller. So I'm going to go into the expand mode on the inspector on the right hand side and change it from keep size to you could say ignore size, fit with portion, fit height. I'm just going to go with Ignore size and shrink this down until it PS covers all of our sides. Something like that. And then I'm going to go ahead and set its anchors to bull wreck. Here we go. That'll set. Now, that's going to be too bright for us to display anything on. So I'm actually going to go into the visibility section on Min Spector. I'm going to go into the modulate. Actually, I'm going to go self modulate on this one. In this case, it wouldn't matter. But if you use modulate, it would also affect all of its children, with this being the background, it's not going to have any children. So it'll be fine, but if you want to just affect this one node, you're just going to use self modulate, and I'm just going to darken it down because mine's pretty bright. I think something around there will probably be good. So if I go ahead and run that all right? That is my window. That's not too bad. It's not too bright to take anything away, even though we have a lot of whites in my case. All right. So that's going to be my background. Now, what about the actual search? Well, the actual search, we're actually going to stick that inside of a container. And this is going to be put inside what's called a VBox container. And this is a vertical container, right? So everything you put inside of it is going to be placed are equally spaced out vertically. So if I just go ahead and I bring in a texture, let's say this texture right here, right? Use this as an example. So as you see it, we're just going to keep going like that in the following way. So there you go. Now obviously, we're not going to have all of those in there, but you get the idea here. And just to take a look here, if we had a control in there, that in there, it wouldn't make any difference. All of these would remain the same. I delete all those go. Now that's because our control by default, has a size of zero. Put it under layouts. There it is. It's transform. So you can see our Y sizes completely zero in this case. And we can see that with our transform is actually the bigger, so we can't have it control. So what we would do is have our own container inside cert. So in our case, let's go ahead and although containers could be nice, I think we're just going to go with a Mrvust setup I suppose here. So let's go with a line it for our SRT now, I can see that my background really hides up, so I'm just going to tweak this still. Darken a little more so my line at it actually stands out a bit. Placeholder Text, search anime here. And we'll go ahead and add a button with that as well. And the text on this will just say, sir. That a little wider. Here we go. Now, you can see we do have gray on black. It's going to be. It's a little hard to see. However, the only thing we can really do about that at the moment would be to go in the opposite direction and go with a lighter approach, which is perfectly fine if that's what you wanted to do, something like that, maybe. Obviously, this is going to depend on your background, but this is something that would be fixable when we get to the next section when we really talk about customizing everything. So nothing looks very default and everything looks a lot more professional, I would say. Now as a little tip here when it comes to doing UI, if you actually come up to the top here, we have two magnets. One is going to be a snap here. As you see, we've got some smart snapping going on, and the other one is going to give us a nice grid that we can snap along. And this is what's going to help with making things look nice. We see this goes all the way up to middle there. Let's construct this to be in relation to the center top. And I'll do the same thing with my button here. A Okay. And now in relation to that, I obviously going to be a little too high. How's that gonna feel? Let's see if I run that. Take a look. Okay. I'm feeling that though maybe I bring that in there and extend that out so we can fill out our full box here. Then we bring our search button down. As small as we can go, so maybe we go like that with one box in between. If we get something like that, I think that's fine for what we're going with here. At least, in my opinion, I'm no UI or expert, but at least everything's lined up with the grid. So we got a nice start going. Now, notice how my button and my line at it is also the same height as well. That's just another thing that's going to make it look a little more cohesive and give it the appearance of being nicer than maybe what it is. All right, so I'm going to go ahead and name these, so I'm going to call this my search bar, and this is going to be my search button, right? That's going to take up the top here. And is there anything else for us to cover in this book? I'm going over search. I believe that's it, and then we're going to have our search results. We'll do our search results in a separate video. All right. So there's our basic search. We can now come in and start typing things in. We got one. Attack on Titan is a popular one, and we can hit our search button. Now obviously, it doesn't do anything right now. But you get the idea, right? Now, just make sure this looks nice. So we know where the center line is right here. S one, two, three, four, that way, one, two, three, four, so you notice that. We're four blocks out to the left, as well as four blocks out to the right, so we kind of keep that balance going on in the imagery as well. Thought I'd mentioned that as well real quick. So we do have expanding out from the same size, so we are staying relatively balanced. And aside from this empty space, we're pretty balanced visually on both ends. All right. That's it for the search. In the next video, we'll go ahead and set up the section to show our results. 69. Results Layout: Alright, we're going to go ahead and set up our search result area. And I just want to note here something afters. We're going to have an option button in here as well. And this is going to be for our genres that we'll have a drop down selection for. And I'm going to go ahead and rename my option button to genre Optas and you'll notice that I just move my search, my button out to the right more and line at it to the left a little more, and I've got to set the anchors for my option button here. I believe that was centered. It's like so. Now we can come in and I can resize this and be good. Test. Now if we want, we can go ahead and get completely based across the top. That would be fine, too. All right. So let's go ahead and set up our results section. So for that, I'm going to go ahead and add in a scroll container here. And what this is going to do is going to allow us to or allow us to be able to use our mouse wheel and have that scroll bar on the side like we see here. Right? And that's going to be whenever we have something inside goes, extends longer or wider than the box we are using here. So, for us, I think we'll be fine at that, and that's going to be too ours out. There. Now, even this I think is going to be a little too much for the info that we're going to have here. But who knows? Maybe we can make it work. So I'm going to rename my scroll container to be salts Container. All right, so with our scroll container, we can see that we have this little triangle here. And if we were to hove our mouse over, it's just going to tell us that a scroll container is intended to work with a single child control. This would be like a V box or an H box, et cetera. In our case, we're going to use a V box. So it's going to be a vertical box container. And that'll allow us to keep adding items vertically, and we'll be able to scroll straight down when we exceed it. So we're going to do we will add that VBox container here. And we can't really do anything from there. So what we'll do is we'll head into a new scene. I'm going to select other node here so I can create an H box container as my roof. I'm going to create two blocks I and let's see, two or six. We'll just go six wide for now. Now, this is all going to depend on how you want to sort yours, of course. Now my alignment is going to be from the beginning, which means going to start from the left and pile out pile out to the right. If we start on the end, then our items will start from the end. So see once I add a texture rect in here, I'm going to give it the goto icon as a default. So you see starting from the end, it'll start from that side. Start from the beginning. I'll start from the left and start from the center. I'll build out from the middle. All right, so I'm just going to use it to start from the beginning. That way, our image of our anime is always going to be on the left. And this is going to be anime thumbnail, anime Image, Anime image. Call this anime result, I suppose, from my container. And now I want to have I think directly beside the image here. I think we want to have the title on top, and then directly below that, have all of our genres. So if we go ahead and do that, we're obviously going to need a V box because we need to take up one slot inside of our H box, right? Otherwise, you can come in and we can add some text here and we add another label, it's going to be directly beside it like that. But we want it directly underneath it, right? We want to go vertical. So if I just leave it that, for example, and add the box in, you see when we add these two labels inside of that VBox, it becomes a vertical stack like that. Right? So we're going to do that. But we're going to set the alignment here to be in the center. And we'll set the first label will be anime title. Second label will be if I can rename it, Anime genres. And we'll just call this container Anime Info. Now, I don't like how close this is to that area, so I'm going to go up to my H box here. And inside of the inspector, I'll go to the Mvides Constance. Check the separation box, and I can add a custom amount here. 20 pixels. 30 pixels, who knows, right? It's going to be completely up to you taking a look at it, testing, and seeing what it is you like. I'm just going to leave it on 30 for now. And I'll save my scene Anime result. That's fine. Now when I go back to the main scene to our results container, click on the VBox container. Now when I come in and I can instant in my anime result and you'll see if I use Control D and just duplicate it through. We get a whole bunch there. And when we run it, it is what it would look like, and we can scroll down through all of our results thanks to the scroll container. All right. Now, just like the eighth box, how we can have a custom separation there. We can have a custom separation with our V box as well. However, I don't want to touch that until after we get our thumbnails and that in there, and then maybe I'll come back and tweak it. But with that, we have our results screen setup. All we have to do is just instance a result for every result that we have and fill in its information. So for now, go to select all my results here, and I'll just delete. Okay. And that'll do it for this portion. Next up, we take a look at actually making a search in order to make a cert we might fill out our ondas as well in the next one. 70. Making A Search: Oh, boy. Alright, let's go ahead and take a look at our results. Now, for the results, we're going to use that anime database. If you go back and take a look at the API section when we talk about rapid API and how to convert from Python to GD script, we're going to use that database. And as such, I've just copied the code from that lecture. So you didn't do that, or you need to go back and take a look to remember how to do it or to see what database it is, go ahead and do that. Get yourself set up. I'm just going to put a script on my main node here. A and I'm just going to paste in all of my variables. So we have our headers that we looked at. How to set up. I have my base URL here, and I have my three gets here, right? It allowed us to get. I think it allows us four different ones, we got, two of them, three of them, sorry. We have get all, get genres and ranking. Now, I think we're only going to need get all for this rather than get genres. But who knows, maybe? Maybe we can Oh, no, we're going to need our get genres in order to fill out our drop down menu. So I think ranking is the one we're not going to need. We're just going to get all and get genres. I'm going to get rid of the ranking one. And then we have our search or search bar text here, our genre that we're going to be searching, and EXT stands for the extension of the image that we're going to be getting now let's see what else are we going to need here? We need anything else by default? I don't think we need anything by. So let's go ahead and I guess, the first thing we're going to do is get our genres and fill up our option button. Let's do that. We're going to need an HTTP request. So I'll add one to the scene. And I'm going to name this my genre request. Just like that. And as well with that, I'm going to go ahead and connect my signal for that, the request completed signal into my main Script here, delete process. We don't need that. So now in our writy function here, I can go ahead and I can get our genre request, and we can make that HTTP request, right? And that's going to be our URL plus our et genres. And we can pass in our headers as the second argument. Now, when we get that data back, remember, we need to parse through it, so we're going to say, we're going to create a new variable called response. We're going to set that equal to body, string from TFight and we'll see what happens if we just print the response, and see what we get back. Okay. So we can see all of these individual little dictaries of one key one value, and it seems that all of our genres are values of the key underscore ID. Okay? So inside of our response here, we need to actually have this Jsonified right, because we just have one long string at the moment by technical. So we can call this our genres, if I can spell, JSON string and put in our spot, right? No error is good. And now we can come in and we could print say response. We can say four genre and genres print genre, and we want we want remember the key for underscore, lowercase I, lowercase D. So if we play this now, we should have all of our genres. There we go all printed out for us here, Award winning action suspense for Etti Avant garde, sports, supernatural fantasy, gourmet, drama, comedy. We get it. So we can see all of the genres here now. Fantastic. So now we need to actually add these into the options menu that we have, right? Or genre auctions. So we have printed them out. What we need to do is add them. They'll say genre, auction we need to actually get ahold of that. Genre Options. At item. And now we're going to add is that genre ID that we're printing out. And now we play it now, we can take a look, and there's all of our items. Now, we see this is a little bigger than what it was. So it's kind of bumping into our search bar there. So in this case, I might want to take a look at it and then maybe slide it over now that I know how big it is. How to find a balance somewhere in there. Does that look I think that looks good. When we're actually in side of our project now. Here we go. Now we have all of our options here. Always take a look at these at all of our options. Fantastic. So we have our genre set, and we're able to type in what we want there. Now, we want to have a noun octen at the top. So I'm actually going to add an item before we even start. So in the ready, and I'm just going to set this to. Non I like that. And that should automatically be selected by default. I'm not mistaken? Yes. There you go. And instead of none, if you wanted to, you could make it select genre if you wanted. The point is, if we have that selected, then we're not going to be introducing any genres, right? It's going to be empty in our search. But there we go. We have the genre portion filled out and ready to create our searches. And now we need the actual search to get all our information, right? And you can see here, I'm getting one page, but my size is 1,000 items per page. So that could be more than enough to fill out any of these. So we're going to use get all in our next request here. So let's go ahead and add one more PTP request here. And this is going to be our call this the anime search. And we'll also connect that request completed signal. And just like the top two here, we're going to parse the body, right, get the string from UTFA and then we have a variable, not genres, but this animes. And we'll have a list of all of our animes now. So if we were to print these out, and we go to I guess we can do this hypothetically for now. Actually, we'll set up our button. So far our search button when it gets pressed, connect that press signal. And this is where our request So we'll get our anime search quest, and we would have URL plus G all and pass in our headers second argument. And before that, we need to actually fill some of the cell. Our genres, if we have any, we need to fill in. You do have them built there. Okay. So we'll say get all. Then I'm actually going to put parentheses around the or get all variable because inside of here is where we're going to add placeholders, right? So percent and then a pair of square brackets. And that goes into search for the first one, placeholder and genre or genres for the second. All right, so let's go with what do we have to get? We have to get our search text. So our search text is going to be whatever is inside of our search bar. So we're going to say search equals our search bar, text. And then we'll clear out our search bar. Or actually, we don't need to in this case, since we're doing an actual search search. And we'll make sure if search is not equal to an empty string. That way you have to make an actual search, and this way we actually get results back no matter what. It doesn't matter if we have no genre. It only matters if we have a search. Now, we don't have the genre parts set up, but let's go ahead and make sure that we can get results here. So we'll come in here and we'll say tack on Titan search. And there we go. We have a lot of information, and as you see, output overflow, print less text. So we have way more information than the output wants to allow us, which is perfectly fine. But we can see the important thing is, we can get we see all this information from our search so we know our search is at least working. All right. So what about our options here? Well, for genre options, we select our option menu. We're going to connect the signal item selected. Connect that to our main script here. And we're going to create a temporary variable here. And we're going to call this genre text, and then is equal to genre options, our option bar. Yet, item text, and we pass in the index that is automatically passed into our function with our signal, right? So we get our index. When we click on something from our drop down bar, we're going to get the text of that item, and that's going to be set to our genre text here. And now we're going to say, simply put, we can just use a match here if we want. Say match genre text. And if it matches whatever we put up talk, which we're using select genre. Now, if you're using none, then you would put none in there. If it matches that, then the genres equal an empty string. And we'll use this underscore to act as a wildcard. So if it's not select genres, then we'll just say genres equals the genre text. Right. Now, if we want to test this, we can go ahead and back out there and just print genres every time we select a new option. So we'll see down in our output every time we select something, sports, comedy. So we see this is all working fine. And if we select select genre right here at the top, nothing gets prnted out because it's an empty string. So there you go. We have our genres working, and we have our search text Now, the last thing we need to do when we get our result is we need to know how many results that we have. And based off of that, we can add our result items, right? So if we come in here, we put a search in here. Actually, I want to make this a little bit nicer to look at. So I'm going to use JSON Spring Pi animes. This way would be a little easier to tell what we're looking at. I'll do attack on Titan again, do a search, and Yeah, I'm not printing it out. There we go. All right, so I tack on Titan so I can get a better view of what we're looking at here. That is not how I wanted that we'd all the way up to the top. So we see everything's going to be inside of data. Okay. So we're going to print animes and go into the data section. And we'll check that. Back on Titan, form a search. And invalid get index the. Okay? What did I do wrong here? Just think, oh, that's gonna give us nothing. That actually did give us some things. That's interesting. Oh, it's a lowercase D, that's why. I had a capital capitalization matters. Let's go data. Form the search in, take a look. And I'm just gonna scroll all the way up. Okay. So now we have all of these. So for each result inside of data, we can create a new thing, right? So we can say, we could set our animes now again, so we'll say animes equal anime data. That way, this now just contains the data instead of having to go through this extra key for no reason. Now we can go ahead and check. We can say four anime and animes. Anim is going to write past here for a second, we do not have an instance or we do not have anything loaded to create an instance from. So I'm going to say bar result equals anime result here. And we're going to load that G. And come back down to anime and animes. We're going to do RI for result instance result, instantiate. Oh, because we're getting it passed in there. All right. So say anime result. Yes, far because we have a confusion here. It's trying to grab it from the function here, so it's thinking it's an integer instead. So let's go ahead and call this change this anime result dot instantiate. All right. Now we'll get a VBox that is inside of our results container. And Child. And we're at RI, right? So now if we run this and we make a search that should completely fill out our result attack on Titan search. There we go. And look at the amount of search results we have for attack on Titan. That in here, high school search. And we have so much more. So what we actually need to do is we need to clear that out because though you couldn't see it, our results are stacked on top of each other, adding our new results to our old ones. So before we search all those, we need to go to our VBox container. And let's see. Do we have a clear or anything All right. I don't see any way to just clear it out, so we can just run through another loop as well before we go into that. So we can do either a while or a for loop. So how do we want to say while R VBox container dot Children. Is that going to give us an integer back? Parents in array of references. Okay, that's going to get to that. So we want child count. So Wilchild count is greater than zero. We're going to get our VBox container, and yet Child index zero, right even if we have one child that'll still have an index of zero. So we're going to basically constantly remove the top child until we have nothing left and ir quarter. Put a little spacer in there. Now you see if we come in, tack Piton search we have the L filled out. And if we were to look at the remote Rsults container or VBox, we have all of these in here. So what it is now, what we're going to do when we perform another search, we're going to grab the top one here, delete it. It's going to check. Yeah, we still have at least one child in here. Grab the next one, which will be moved up here, delete it, and so on. If I come in now and if you keep an eye on the side here, if you remember how small that got, you come in, make that same search, high school search, and we see that did not get massively smaller when we did that. Although it is going to take a bit to run through and delete them all, which is a bit of a problem. So it might just be easier to completely delete the entire VBox. Okay, so let's try just deleting the entire VBox instead and creating a new one when we need it, so we'll say, we'll get our VBox container u three. And then we'll just add another one. S V NuBx equals VBox container, NuGet our results container, add child Neubox, right? So we'll see how that works now. That should hopefully be a lot faster since we're not going through potentially 1,000 results now. So same thing attack Titan search All right. We had a null value option, so we come in we say what has come right on in here. Results container, and we'll just say get child Child zero BRVbx every time. Allright let's try that. All right, so we solve the issue by changing instead of getting the VBox directly, since it's always changing and it's having a different name. Of course, we could have just named it our new box here, and that probably would have solved it as well. But instead, we'll just change it to yet Child zero. And we do that as well up here when we cue free. And since it seems like we're trying to do both things at the same time, remove and add, I just went ahead and called and wait for 0.1 seconds, which is fine. It's a tenth of a second. It's not going to kill you. So if we go ahead and run it now, we can go ahead and make search attack on Titan search. Give it a second. There you go. We see how big our bar here is on the side. When we type in high school or any animes that show up with that, and we search, we notice the bar gets smaller because it's going to be more results. And we notice the whole thing is just going to flash, which is just completely clearing. There you go. And you see we have this small bargain. And then to show you that it's not stacking results, we can go back to that attack on tight now we should get our bigger bargain. There you go. Alright, so in the next video, we'll go ahead and let's see. Thumbnail we'll do our thumbnails and our information here. So the titles and the genres. We'll fill that information out next. 71. Thumbnails, Titles, Genres: Alright, let's go ahead and get those thumbnails, titles and genres all filled in here. Just go to space this out a little bit, to make things a little nicer to see here. Go. Alright? So this is obviously going to be inside of our anime here. So we're going to add is fine. And let's see. We need to get our so Let's go ahead and we start with we take a look at our result. See, we got to come down to animate Info and then into the anime title. So we'll say RI and we can say get child, get node. Fine. We're going to just use get node here. And from here, we can see we go down to animate Info. My case, and then inside of there, we can get anime title text. And we can set that to anime. I think it's called title in our results. Find out real quick, as I just test our main scene and perform a search tack on Titan, search. And it is not nonexistent function, it's getting nulled. I mistake, Typo, Alright, so now we have all of our titles set up here. So now the question is, where are these genres located at? And for that, I honestly don't know off the top of my head here. But what I'm going to do is I'm going to print JSON, stringify, animes and get our first result. I'd like this to be easier to look at. So I'll add a space here as my second result to string of Pi, and I'll just run that again. And that's going to be a lot cleaner to look at down here. Status ranking synopsis. Really, genre is nothing. It doesn't have any. That is quite interesting. Yeah, it looks like it's just called genres. So much like the title. We're going to get our node and get that text property of it. And this one was called anime genres. And that's equal to anime genres? Yes. All right. So if we take a look at that now, let's see tag on Titan SERT. And no. Invalt? Yeah. Oh, because it's gotten array as a result. Okay, so we'll have to turn this into a string. Let's take a look. So if we go to Search help and we go to array, we take a look? Let's see. Does array have any two strings? I don't think so. No, it's not appear to. So that's fine. We can just convert it into a string and spiking STR and wrapping it with a pair parentheses like so. However, however, I believe we're not going to get the desired result here. So if we go ahead and complete this search, you can see we're getting these square brackets and that still involved. So what we should do instead is run a loop here. I'll say four genre in anime genres. So say text plus equals genre plus I will put a comma with the space. You know what? I think we'll do that separately just to avoid any issue. So we'll have two lines here. So if we have more genres in there, then we'll add a comma with the space, and then we'll add the genre. That way we don't end up with a comma space at the very end of our list. Now we're only adding genres when if we have genres to add. So our first result isn't just going to be a pair of square brackets. It's going to be empty. Oh, well, in this case, it's going to be completely have our default thing in there, but we can see action drama, action award winning, drum, suspense, action drum, suspense. A lot of action drama. Some of these, there we go. Adventure comedy fantasy. Our default tax needs to clear out of there. I'm so that's fine. We can just we can clear that here, right? Or we can just go ahead and clear it here. Either way is perfectly fine. And I think I'll just clear mine right there. No problem. So if we run it now, we should be good to go. And there Although we have the com at the beginning, little unfortunate. Should be an easy fix. I should be a quick fix. No problem. Once we're done with all that, I should be able to just call Oops. Actually, yeah, dot text. All right. So we just trimmed the prefix of it. So outside of our fore loop when we're done, we grabbed our text property, and we set it equal to whatever our text is on our genre stele. And we call trim prefix, and we're just trimming that comma space. All right. So there you go. That should completely fix that. So if we go ahead and form a search now, we do tack on tighten search. Here we go. We see everything showing up Justin should. It's great. So now we got to look at our image. How do we get that image for each of our things? Well, we're going to need another HTTP here. And we're going to call this image quest. And you guessed it, we're going to connect the request completed signal to it to our main script here. And I'm going to move that on up. And I think I'm going to put it up here with the rest of our stuff and space those out. Alright. So now when we get this, we have what we would have our images here. So we would need to form our search here. We're getting a lot of it. So in our anime search request, above our for loop, we want to do it above Let's see. Let's do it up here. Once we have our anime data, then we'll make our request. They'll say image, quest dot. Quest. And we'll place our URL, which is going to be animes. And I believe it's just called Image And to check that, we can go ahead and we'll just print out Gotcha, sure. And we don't need our JC five fact, we can actually check it here before we start printing it. Yes, image is exactly what we need. Perfect. See, now we make a search. Oh, invalid Get Image on Base array. That's a little town, right? How is it on a Bs array? Let's see. Alright, so we'll go ahead and request animes image. And then inside of our fore loop here. Let's No, down here where we get our request. We can do we can create our tech, save our image image new. And we'll we can match here depending on what type of extension it is. So we'll match EXT to the extension. Is that going to get rid of our error for now? Okay. So we'll have to get our extension up here before we can do anything. So say, XT just before we make our result. EXT equals Anime'simage. Yet extension. And that's going to give us the end of URL, it's going to give us PNG, JPEG, web P, TGA. And that way, when we match extension, we can match EG. We can match JPEG or JPEG. We could match web P, or we could match TGA. And like normal, none of these match, We'll go ahead throw in a wildcard and just print out systems saying, can't image. And inside of all of these, we'll go ahead. We'll do image, load, and we're going to be loading from buffer, so load E and G from buffer. And this is going to be our body. This is our body, and we're doing the same thing in Ali, just different types. Load from JPEG from buffer, load P from buffer, and load TGA from buffer. All right. So that's going to give us our image. We can go ahead and after this is I do want to do Du. All right. So we'll go ahead and get a new variable, texture Image, texture new. We do texture dot set Image. And we pass in What do you Oh, because we're still inside the Battery. This shift and tab. Yeah. So set image, and what we're going to set in there is going to be our variable image. And then we're going to return texture to us. That way we can use it elsewhere, which means when we make our request here, say, our thumbnail equals our return value from our request here. I can spell correctly. Right now inside of here, of course, before we finish, we need to actually get our thumbnail here, which is our anime image. Dot get node, Anime. We going to add Manfo? No. We do not. All right. So what stuff. Here's some anime image that's with api, I believe. Anime image. Do. Texture equals texture. Actually, thumbnail. How is here? Alright, and it looks like I'm pointing out a void here, so we need to finish fix that. Maybe return back in image texture. And that's only if you have the arrows pointing, right? So if you have these arrows here, pointing at void, saying that return void on your HTTP request for the image request, you have to go over there and change it to image texture. W point it because that's where you are turning here, the end. And I would show you this working now, but I actually use up all of my requests per day. So I'm going to have to put this on pause and either throw it right at the end of this video or come back at it next time and show you it working. I guess that'll do it for now since I have no more EPI requests. I've hit my daily limit. So that'll do it here and I'll see you in the next section. Alright, so I didn't need to make a small changer. I moved the info that we had at the top of our Animate search request complete. I've got these I've moved those three lines down and added in a wait. So we're assigning our extension right after the four loop to, of course, animate and then image dote extension, so we know what type of image it is. We then get our image request and perform the URL request, right? Anime image. And we should probably be passing in our headers as well there. We then await. And this time in the past, we've always created a timer to wait a set amount of time. This time, we're using a wait to wait for our image request, request completed signal, so we're waiting until we've already gotten the info that we need. And then we're setting the texture of our anime image to our variable texture, and this is where I've made a slight tweak. I've changed texture to just be a global variable here. Well, global in the form of being at the top of our script. And if I scroll down, where is it here, I went ahead and we're doing the same thing here. We're just not returning texture. I just created texture as an outside variable, which means I had to come back in here and paste from a miss texture back to void. Now the reason why I did that is because for whatever reason this was coming back as an integer rather than the data. So I just switched it this way so that we're setting the data here, here, but the variable exists outside of that function. So that's why we don't have to return. And also to avoid issues, I really issues, but API limits here. I went ahead and I changed my size down to three so that I only get three results because we are making an API call for every result that we get, right? Or not really an API call, but we are making a UR call, which is why we don't need the headers here. What am I thinking? Not for the image? So if you wanted to keep that higher, you could. It's not going to hurt anything. It's just three is going to be a lot quicker. If we come into the default, which is 100 and we take open that up that's captured already and we already say attack on Titan, former SERT. This is what we should be looking at here. And we see we got our name, we have our anime, and we have all of our genres that underneath. Right? So there you go. Blah blah, blah, Sam, and we SERT, boom. There we go. We see everything's working perfectly fine. And if you wanted to, if you were doing 1,000, like what I had up there, it'll just take a little longer. I don't know why I thought I was going to use my extra API calls there, but slight loss of thought, I guess. We can come in and you can see we get somewhere which I think high school had even more results, right? We come in, go like that, and you can see, look at that bar. Just keep going real tiny, still going, still going because we got to get all those images go, and it's finally stopped. And you can see we have all the images, all of these. Nothing is missing. But there you go. So that works. We just had to basically move our texture variable to being at the top of our script instead of returning it. And I can uncomment those we can take our genres now. And basically moved our extension and image request down after our Those are the only changes that I made there, right? Before I ramp on and add too Much on because I think I'm just going to add this onto the previous video. Alright, there you go. So it works perfectly fine. And next up, we'll take a look at opening up our page with the synopsis of the story and our any other info like the external link and all that. 72. AnimePage: All right. So let's go ahead and show our panel that's going to pop up with the details for our show, such as our synopsis and we'll have a clear view of our thumbnail. And if we want to, we can go ahead and put the title and tags in there as well if we wanted to. Now, what I've done is I've gone ahead to my results, and I've added in just a button that says view. Now, there's a variety of ways that you can go about doing this, but I just have one that says view. And on my main scene, I've added a window. I just has a text direct inside. And do note that you cannot move the window itself because you can't grab ahold of it. So you'll have to go into the inspector and go to the layout and transform. There it is at the window and position. And then when you want to move the things on the inside that are children of it, such as my thumbnail here, which is just a texture, right? I have to go down to layout Transform and play with my numbers here in order to move things around. For example, the position here, if I want to move it, I got to go like this to place it. But I'm keeping in mind on the left hand side there for my thumbnail. I'm also going to add a label, and this is going to be my end of a title. I'm going to put some words in here just so I can get an idea of where this label is placed. I'll go to layout Transform, and I'll find a good spot to position it, say, What if we go 300 over? That might be a little too excessive, 203 20. Oh, that's right. We're in the center. I do believe. Let's see. I set that at 200, which would be way up here, actually. That's interesting. So I'd want to maybe back it up a little more, drop 50. All right, I'm going to go with 160 and maybe lower it down by ten. So I can get it away from the edge there. So that's going to be our title. And I'm going to go ahead and duplicate this just with Anime title selectic D. Call this our anime tags, right? And this where we're going to have drama, action, fantasy, et cetera. So this is going to be low. Our title. So come down here, layout, transform, and we'll lower RY down to 30, 30 could be about right. Maybe 40. Just to clear it up a little bit. And now we need something for the text. So what do we want to put in there? We could do label gets a little wordy. We could do a rich text label. Well, I think that's what we'll do. I had a writ text label, just like you see here, side. Now, the downside is we can't really see anything. I'm just going to go ahead and put a bunch of text in here just so we can get a good idea of our size to just spam a bit in there, go to our layout, transform. Size. That's 100. I think 300 is probably good there. Maybe 400 there. And let's see about that position. Now, where exactly am I going to want this? Do we want it directly below. It might be the best option for that. In which case, what are the X for these? 179. Do you have any Oops. That's the size. W position 160. And then I'm going to drop it down by about 100, and this will be our story. Where a synopsis goes. So we'll say anime synopsis. Alright, so that's what my window is going to look like. I might need to adjust this after I see the thumbnail get put in. But for now, I'm going to be happy with that. And I'm going to go back to my anime result. I'm going to add a script to my anime result, and I'm going to connect the pressed signal. I'm going to reconnect that here. Disconnect just connect that again. All right. And we're going to need a few custom things at the top. So we're going to have a custom signal here and it's going to be show details. And we're going to have a custom variable here called synopsis, which is just going to be a string. And we'll have our ready function here. And on our ready when this object loads into our scene, we're going to go ahead and connect it with our custom signal to our main node here with its script on it. So we're going to do self dot connect, and we'll go ahead and show details callable and remember the first argument is what you want to connect it to, so we want to go three parents up, say get node, and do dot dot slash dot dot slash dot dot slash. That will take us three parents up. And the second argument is going to be the name of the function. So I'm going to call it Show Window. And I place that on the inside of G node instead of the outside. Here we go. And I'm going to go ahead and make that function before I forget in my main script show window. Now, when our button gets pressed, we're going to emit the signal, emit our custom signal, show details. And we're going to do a comma because we're going to pass some additional details or additional information with it, right? So we're going to pass a texture, so I'm going to create a new variable sort. So thumbnail, that's going to equal our anime image texture. So that'll be whatever thumbnail this is for this specific object. And we're taking that texture and we're going to send it over with our signals. We're going to send that data over, and we're also going to need to send over our synopsis. Our title and genres. That's a lot of information here. And we're gonna have to done this as well. So let's see. Down here, let's see our title equals. And we get this from Anime title here. Anime title. And this is all stuff that we've already set text. And it's going to tell us that genres is not defined. Genres equal Anime genres text. And synopsis is already defined at the top. Awesome. All right. So we're now sending all of our information over. Now, I'm just going to copy all of these arguments so I get them in the right order. Go back to my main script, my show window function, and I'm going to paste my arguments in. So what we're going to do with this is, well, first of all, we need to actually show our window. So I'm going to get my window down there, and I'm going to call Pop up centered so it shows up right in the center screen. I'm then going to get my thumbnail here, the texture wrecked inside the window and set its texture to thumbnail, the data that we send in. We need to set the anime title. Anime title text equals title, Anime books, tags, text equals genres, and then we need synopsis. Anime synopsis do. Text. Add text with a rich text label, add text and synopsis. Now, at the moment, we haven't passed any synopsis in to our objects. So we're going to need to take a look and see how that is structured. So I'm going to uncomment my stringify JCN file here. That way, I can take a look at what the name of the synopsis. I'm pretty sure it's just called synopsis, but I want to make sure. I'm just going to go ahead and run this and perform a search. These attack on Titan again. And yes, yes, yes, that's fine. That doesn't need to be there. You guys shouldn't have that in there. I forgot to delete that earlier. But we got the output, and that's the main thing I was looking for. And yes, it's just called synops. All right. So let's see. When we put in, we do our genres a text in the extension and thumbnail. We set the texture, we set the text. And just before we add it in, add our object, right, our result instance, we're going to go ahead and we need to set the synopsis. So i dot Synopsis. Sure I spelled that right. Yes, yes, all lowercase equals anime synopsis. Alright. I'm going to go ahead and run that again. Say attack on Titan search. Gonna run through. We have no issues. Fantastic. Now our view is kind of all over the place, which is a little unfortunate. But I'm sure we can fix that just by manually setting the size. But I'm going to go ahead and just click view, so we should get this thumbnail. Well, let's get one that's got two tags with it and genres. And as you can see, I need to shift everything over to the right. And that's what this testing is for, right? So let's see title inspector, so I'm just going to leave it running here. And let's try 2025250 looks better. And I'll do the same thing with our tags, 250, and our synopsis 250, right? So everything's been shifted over. And let's see, we can scroll down through our synopsis if we need to. All right. The reg. We have that set up. Now, we can't actually close our window, so we need to fix that for ourselves here. So we'll go ahead and close that. And for that, we're going to have to go to our window and connect the closed requested signal. We'll connect to our main, and I'm just going to go ahead and move that up. Go. So when we get a request to close, that's going to be whenever we click that X in the corner. All we're going to do is we're going to hide the window. So we're going to get our window, and we're going to just call Hide. As simple as that. And let's see. What can we do about our box here? Well, we could make it wider. What about our anime title? I believe we can just set it to click. All right. Now, what are these auto wrap modes specifically? Because these weren't herb force, let's say, arbitrary wraps text inside the nose bounding rectangle, allowing break lines. Yes. Alright that one sounds good. Soft breaking, no. Alright, so I'm going to use Word Smart. Oh. Maybe we won't use that. That completely broke it there. Arbitrary. No. Word could go with word, but that's just not going there. So, right, what am I going to do is I'm just gonna hit Clip text. I don't like that that went a little That size only went to one. You're not like that. So what can we do here? So what I'm going to do to fix that I just want my button to be inside of my animate info box here. That way, it's just in line with our title genre then our button. And I've set my button to I'm not a button. I set my anime info box here. I set the horizontal to fill and turn to expand on. And now what I'm going to do is I'm going to set anime title, the horizontal alignment to be in the center and vertical center. And I'm going to do the same thing with the genres here, center center. And then for the button text, the button text should be centered, though that should be good. So let's go ahead and open this up, see what it looks like now. Let's say, attack on Piton Alright, so there we go. So it stretches all the way across. Oh, that one's gone a little too far. That might be a me problem, though. Might set something, screwing around. That might have been it there. Let's try that again and make sure that that was just something that I left in Okay, so that's just stretching all the way across because we've got a title or something being along. All right. Well, you can see, it's just a matter of playing around with this stuff now and getting something that you like. So maybe I'll just come back to my anime info, and maybe I'll just turn that off. Maybe I'll just turn Phil off. I just tab back and take a look. See that looks fine now. Again, our buttons just aren't about the same size, so it's just a matter of playing around with it and finding something that you like visually after that. But the important thing is, we can come down and we can pick one, boom, and there we go, unfortunately, we picked one without tags in the SEC. Even though we've already selected one, we can select another one, and it doesn't affect anything. We still get the title tags, and I can see all that default text there. We need to clear that out. So let's see. It's going to be in our main script. Let's see before we set that text. Where's it? Well, if I erase that by fault, we still going to have? That's the question. Let's see. Synopsis, delete all that. And let's see if that works, or if we still have old synopsis in there. Right and let's go with that again. Funny enough, I've never actually watched it. So let's see. On his first day of junior high. On his first day of Junior. Okay, so, yeah, we still have old text in there. So we need to make sure to wipe that when we set the title synopsis right there a text. So before we do that, let's go ahead and get our anime synopsis dot. Big text label has a clear function. And I should solve that. Now, we take a look. First one on the first day of junior high, second one, Gabby Braun and Falko Grace. Next one, Aaron Yeager. Probably pronounced that one wrong. Centursgo Van kind slaughter. Don't threatened by the Titans. There you go. So we've got that completely updated now and it's getting the right text in there. All right. So it's up to you how you want to make this look visually. But that's what we're going with. That's how we're doing it, and what we've gone with. Alternatively, if you wanted. I'll show you an alternate way that we could do this if you don't want to go with a button there. And to keep that instead of using a texture wreck here, we could come in and I'm just going to right click and hit Change Type and change that to a texture button. And then I can just drag that in for normal. And now we have that button. Let's see if we need to tweak any text. I don't think we would, but actually we might the text, we might have to specify that it goes to the normal. Let's go with Narrato this time. And yeah, okay. So that would break it. So we would have to specify specifically that it was that the normal. I'll take a look here. Anime Info. That. And it's going to be texture, underscore, normal. Okay. So that would just be a small age. So where we set our animate image texture, do dot texture, underscore, normal, like that. And that should be it just one line change. And that functions correctly, right? We got our thumbnails in there and it looked exactly the same. And since this is now a button that has our texture, we could set it up, so that when we click that instead of clicking that view button, right? So we can take the animate image there. I'm going to copy the same copy. So on our animate image, I'll click Press, and I'm going to go to make sure they go to the same function. And now you'll see W we go in? I can click on the thumbnail, get our Windows and underscore normal. Change. But that's two texture lines that we had to change. If you wanted to go this route, the button, then we can click on that, there we go. And that might be a little more natural or a little better for you, and then you can just completely remove this button off together. So I'm just going to hide it from view just so you can kind of see it this way. And then you can have there. So there you go. Here's how you can do it with having our buttons in there. And then if you wanted to get rid of that, just make the actual thumbnail clickable for it in order to pop up our window. That's all you have to do. Connect a press signal, change this from a texture rec to a texture button, and then change all of our animate Image dot texture to animate image dot texture underscore normal. And there you have it. So we have this all sorted out, I'm just going to comment out it's printing down here again. Once again, we no longer need it. Here we go. So we can now search for animes, get a synopsis, see the tags, get titles, and we can scroll through a big old list of 1,000 or 2000 or however many we want to go. And it'll be one API call per search. Um, actually, it'll be two API was initially, because we have to add our genres in there. I'll just uncomment that. Put that back in there. You guys should not have had that commented out. I just turned that off just to save on some API calls while I was testing some things, right? So now we can come in and we can do, like, supernatural and frozen search. Not frozen. It's freezing that I was looking for. Freezing. Search nothing for supernatural. How about fantasy? Interesting. So we're not getting anything there. If we go to No genre, there's breezing. Sci fi. That's what that might have been the one I was looking for. Di Pi action. Breezing vibration. I would. So I was just completely off on my secret just to make sure that works, right? We'll go to action search. And there you go. We only got one action. So if we have all those, if we go to drama, we'll have even less. We can see we can filter it down more and more if we want to use the genres. We have to fill in a search, but the genres are auction. Alright, so there you go. There you have it. We have our little pop ups. We have our information. We have our searches. So there you go. You now have yourself a desktop application that you can use to maybe find yourself samatam. Maybe find something to watch when you get bored. And I would encourage you to go ahead and add more features to this. Maybe add a favorites list if you wanted, or a watch list or something. That way you have something that you can kee track of. Alright. That's it for this section. And we're going to go ahead and move on to our next week where we're going to talk about some of the more advanced customizations to really make your programs look more unique and more professional looking. 73. Fonts: Alright, so one of the things that we can do to make our application or games stand out and be more unique or be more professional looking? Well, one of those things are fonts. Now, fonts can get looked over a lot, especially by newer developers, but fonts can change the whole field of your game or your software. And it's like when you have a font for say, a restaurant, right? If you have a font that has just say a bit of a slant to the right and its characters, then we get the impression, whether we realize or not that it is something fat, right? We have that sense of those letters moving quickly with them being leaning over like that, especially if they're leaning over to the right. So with that impression, we can internally make the assumption that this is a fast food place. And we have all of that without even knowing the name of the place or what kind of a place it is, how big it is, what kind of food it serves. We don't know anything except for that the letters on its sign are tilted. That's just how powerful fonts can be. Think about if you were playing say dead so Oh, not dead souls. Dark Souls. Dead souls is a completely different thing, but imagine you were playing dark souls and we had this bubbly font. There's all over the place. It wouldn't it wouldn't fit in because it wouldn't have that same kind of vibe to. Right? I would feel misplaced. It would distract you from the feeling of the game, or it would take away from the game's seriousness and those serious tones that it gives off. So fonts can be very powerful when used. So it's important not to overlook these things. So I'm going to go over to our anime results, and I'm going to use our title here so we can get a nice good view on it. Now, without touching any real customizations, I'm just going to come in and go to the themoide section inside the inspector with my title selected. And you can already see we have colors for the font, the shadow, and outline. So if I set the font to white, maybe set the shadow to a little more transparent. Okay? We've got something going on here. We can move down to the next section, which are constants. We can give an offset to the shadow. Okay. So now we have text lifting off of the page. We can give this an outline size that can really make our text a lot more visible. Shadow to the outline. We could do that, as well. That's really going to enhance our shadows down there. And we could add a line spacing. We can go down to font sizes, and we could, let's go up to 23. And in this case, that's all the options that we really have here, but let's go ahead and increase the offset here of this a little more, and maybe we change the shadow to be a little more purply Okay, so we can have more of those cool tones in there. And now let's go ahead and if we run our main scene, I'm going to go ahead. We'll do our usual attack on HtonFmersearch. And you can already see that even though we haven't done much, in fact, just even adding that outline to this default text here has already made that text stand out and jump out at you a lot more. And we've hardly done anything. So you can see just how important even small tweaks to your fonts can be. Now, you are stuck to these default fonts, of course. Because we can actually use some custom fonts altogether. Just go ahead and turn all these back off. If we head into the fonts section, we can use a custom font here. Doesn't want to turn off there. That's fine. I'm just going to open the drop down menu here and select a new font file. All right. And I'm going to open that up unable to preview font. Whoops. Alright. It appears in four point. We don't need to select any options like we used to in three point X. So I just downloaded a font file here. It is in TTF format, and I'm just going to go ahead and drag it in to the font section, and you can see, just like that, we have a new font. Now, we don't have a whole lot of options set in there, but as you can see, we can still come back in here and tweak our sides and everything that's on the outside here and still have those same controls that we had before. And like I said, just even putting an outline. That. Even putting an outline will really make that stand out. Just adding that one small factor to it. All right. Now, in Goto four here, it appears we can add complete variations. So we can have our base bond. You can set up some fallback bonds just in case. And you can set different features lining, old style figures, stylistic sets, alternatives. So you can really come in here and start customizing very specifics in your fonts. So you can go almost as detailed as you want to go. But what's great is the fact that we can control the font size, even if we don't have a custom font in bind at the moment. This allows us to at least have some more control over how we want it to look generally, and we can always decide on a font later on, which again, is great for prototyping, so we can quickly get something out. But there we go. If we can use custom fonts and you'll see if I reset this, Oh, font disappeared. Here we go. There you see. You can have completely new fonts just by simply dragging our file in it uses TTF, and I believe you can use it OTF file as well. But it's as simple as that as to dragging the file over into the font section of the thmovides. And we can see if we head on over, and again, we'll go ahead and run this real quick again and we'll say on tighten search. And there you get a look at that. Beautiful. Now, this is obviously a little too big for some of our titles here, but you get the idea. Now, you would have to come in and change every single piece of your UI, and that can get extremely annoying or take an extremely long time to end up doing. And there's a quick there would be a quicker way to go ahead and do something like that. And to do that would take us into the next video where we start talking about themes. H. 74. Custom Themes: Alright. Now, I told you there would be an easier way to apply your font to everything, and that easier way is going to be through is going to be through what we call fonts or themes, rather. So we can come in and I'm just going to go ahead and zoom in here, and a theme will apply to the nodes on, as well as everything that has a child of it. So if we stick it on our main node here, then everything in our scene is going to have that theme applied to it. So this is how you would do a dark theme and a light theme. For two examples, you would just swap out the theme file and everything will change. So if we just come over here with our main node selected, which is our control node of our scene, head over to our inspector, come down to theme, and just go to the drop down and select new theme. And you'll notice down at the bottom, we have this theme tab now, and we pull it up, we can see all of our options. And these are our previews for all of our buttons, sliders, as you see here. So we can play around and we can basically see how everything is going to look, even if we don't have things in scene. Alright, so that preview is fantastic for us here. Now, we have a new theme, and we can bring our font in. I'm just going to grab our font, and as you see on the right hand side, side of the here, we have a default font. If I just drag it in, now everything shares that font that quick. Everything shares. Which is fantastic, of course. But what about everything else, right? What if we want to make things more unique, more special looking? Well, we can go ahead and head on up to manage Items. And with that, that'll open up a new scene that I'll hopefully capture here. That did not capture. One moment. Try Window seven. There we go. All right, so we have our manager here, and I'm just going to go to Import items. And from Editor theme, I'm just going to hit Select All down at the bottom. Import selected. And there we go. I can go ahead and back out of here once that's all done. And now I have all of my items. Now, I can control everything from the inspector here. You can see all the different things, everything from spin box, progress bars, all of my pop ups, panels, the option button, menu buttons, labels, line edits, right, my sliders, containers, and tons and tons of things that we haven't used our butts checkbox. Everything can be modified right here on the right hand side, right? So we can go into our colors of our buttons here, right? And we see a font color is white, and you can see it has changed to white in our scene, as well as in our preview. We can say font focus or font hover color, right? Maybe it's more red. So something like that. Awesome. Now when I hover over the button, you can see, we can now visually tell when our mouse is hovering over it. From our preview because obviously, we can't do it here because it's not running, but we can test it in our preview here. And like I said, if you don't want to go through everything in the inspector, you can actually do it right here inside the theme manager section here them tab. So we're editing our button, so I'm just going to open that up, and you'll see a huge huge list here. And give me a moment for that. I'll show you that. Alright. So as I was saying, everything that you see on the side here will be shown when we open this up, so you can see everything here, all the parts that we've added in to edit. So we were editing the button. So if I open that up, we can see all the same properties are here, but not only that, they're also organized to just how you might imagine them to be. And you can also come in here and you could rename them. If you don't like outline size, you can rename that whatever you want. Here is all of our colors. So it's very easy for us to go about. We come into font. Nope, got that outline size, font size, that. So let's take a look at here, these little not themes, but the style. So let's go to normal, a normal but here. I'm going to do a flat box style. Just give that a second. The themes seem to have this little slight hiccup in them. But that's fine. Open that up. And you see that open up here in the inspector, so you may just want to use the inspector anyway, but you don't have to. And you see now come in I can add borders here. So we can add this border width on our buttons, as well as, of course, selecting the color of our borders. We can go in bright green and just start adding them in. So we can do something like that if we wanted. But what we can do is we can come in here and we can just add corners. We can round off our corners. And now, without having to do anything complicated, we've got these nice rounded buttons, and because things like the option button all come from the base button, that's all being rounded as well. And if you wanted to get much more extreme, for example, that as that. We're getting closer to creating a rounder and rounder button here and getting closer and closer to just creating a circular button. You see, it's only going to let us go so far on these actual buttons, so just keep that in mind. But still, we have a beautiful at least, in my opinion, buttons that look nicer than those pointed boxy rectangles. Rounded corners just always look nicer to me. Maybe you prefer the points, but I always prefer veeven just a slight rounded corner to them, right? So even if we just come in with, like, a three, right? On our corners, to me, that would still look at least a little nicer than having those points. But you can come in here and you can completely change those up as much as you want. And then whenever you're satisfied with modifying all your different aspects of your theme, you can just go into the drop down here and save your theme. And you can do that a few times and whenever you're ready to whenever you want to have the option to change different themes, all you have to do is just load your theme and put it into the theme property here. And you can do it in code, right? Just access the theme property and load your theme file into it. And there you go. You've applied your theme. You have different theme options put in. Alright, so if you want to once you have a few themes set up, now you can obviously set this up with a light and dark toggle button. So if I were to come back to Hootie here for a second. If we go ahead and set this to a let's see. It's not a toggle button. It is a just come in and search button check button. That's what they're called here. I'm going to go ahead and just bring this over. It's not really going to matter. And the style is the reason why we have that background. That's fine for now. So say we have this check button. I'm going to go ahead and hit the toggled press signal, attach it to my main script. And all I'm going to do because this kind of rose up because I don't know, themes seem to like cause things to pause at least on my side all the time. So if I just come down here and based on if it's pressed or not, right, we can load different themes. So I'm going to say if button pressed because that's the argument that's being passed in, right when we toggle it, if button pressed. So if it is true, if it's turned on, then we'll set it to theme two. Else we'll come in and set it to theme one, save that. And all we're doing is we're getting the node that it's on, right? So we don't have to type self, but I like to do that anyway, getting the theme property, and we're just loading our theme file. It's all we're doing. It's now when I run this. I can just simply click this toggle. And just like that, we can swap between a light and a dark mode. So it's as simple as that when you have if you want to swap themes, it's just going to be time consuming for you to build up and create all the different themes that you want to have. Although the plus side is, is if you just want to have a light and dark theme, and of course, going through, if you want to create a bunch of other themes as well, you can keep these theme files since we save them out as a theme, right? You can take them, and you can bring them into other projects in the future, and you can just apply, and now you just have a light and a dark theme ready for everything, right? All your future projects. But it's as simple as that. It's one line of code to change the theme. It's just as simple as that. Set the theme property equal to load you theme file. All right. So themes are powerful. They can be even if you just want to set set your font for all your different node types. Instead of wasting time, you just create a theme, throw your font in there, and you're good to go. Alright. Now, I will make one more note here if you wanted to remove something from your theme. Give this moment because obviously this is going to lock up for a second because themes for whatever reason, right? So let's say we want to remove something out of our theme because maybe we don't need it or it doesn't affect our project, whatever. All right. We can just go to Manage Items button here and just open this up, cap to this again, right? We can just go to edit items. We can find something like editor, troll editor pop up, color preset but, editor the belt, right sons there, the help on the. So all these things that are up here that don't matter. They don't affect us, so we can come in here and we can just Well, we can just start deleting all these things that don't matter. That way, as well, it starts looking a little cleaner. Of course, you didn't have to bring this in these in to begin with. You can only bring select items in if you wanted to. But if you're going to make a theme, I find it better if you just do it for all of them anyway. That way you can, like I said, just bring the theme into any project and just be good to go right out. There you go. There's how you can remove things that you maybe don't want part of your theme anymore. There you go. Themes very powerful, very useful, give your program a more professional look, make it look less defaulty, especially among other Goto developers and allow you to have more customization for your users, clients, customers, et cetera. Now, obviously, this is going to fly a little more or it's the software side than it will on the game deb side, but maybe you can think of something unique that you can do on the gameplay side. Alright, that'll do it for this one. Next up, we're going to talk about making our windows actually pop out and be part of controlled by the operating system. And what I mean by that is when we come in, I know this is hard to see for us now because we mess with themes. I'll get rid of those the default this, right here. This window that we have all kinds of messed up right now. We can't move it, right? Like, it's going to be stuck inside of this window. So we're going to make that into its own window and be controlled by the operating system. 75. Multiple Windows: Alright, let's talk about having windows controlled by the OS. And what I mean by that is you see how this window here is its own window controlled by the operating system. We can't move We don't necessarily move it anywhere. It's just kind of there. Hold on. This will be a lot easier. One moment. Alright, if I just come to the display mode here and we take a look. We can see this is its own free standing window that can be moved around any point. It's not trapped inside of the main editor here, right? However, Oh, that is a little too big. However, if we were to come in and, again, perform our search say that Titan. That's been a thing to time. Alright, come down, whenever we find a show, click on it. And now our windows you can see how it's stuck here, right? It's not free. And the reason that is because it's embedded inside of our main window here. So it's not going to be it's not free, right? It's not controlled by our operating system. So that's what I'm going to show you how to do. That way you can have your own window. So, for example, you open a settings window, a settings panel, preference panel when you're doing creating software. You can take that and you can move that window around. It doesn't have to be stuck inside of whatever application. Running. And that's pretty much a standard thing. So it would be good for us to know how to do that. So if we just turn this off real quick, just jump into our script, and we can fix this with one line of code, and that's it. So we get a viewport, and that's going to get the viewport of our current window, right? The main window of our program. And all we're going to do is Goey embed sub windows and set that property to box. That's it. Now, if we run that, we can see this still works exactly the same all time. And if we go ahead and do our search. Plastic attack titan, whatever, we scroll through our results. Doesn't matter. Blah. Let's pick this? Now it's its own window. We can move it around, can have its own window title, and it's created and managed by the operating system itself. Three size and we can do everything we can just like our other windows. So it's as simple as that to add that little feature in there. It would be very useful. Another instance of this is if you wanted to have say a tab like this, to be able to undot just as you can do in here. We just pull it out. All right. Here we go. So we open up the setting here, and we can just say make floating. And now it is its own window, right? And it's managed by the operating. So this is working the same way of what we just did with the Dewey embed sub winds? What we have to do, close it and that can push right back in there. And you can do this with any here. So, for example, you can do it with the script here. You can just click this button here, and now the script window is its own thing. And if you have two monitors, you can now just stick this on second monitor on its own, and you can focus on the actual scene on one screen and your code on the. So you can see how doing floating windows like this would come in handy just through development and depending on your application, be more productive for the end user, which, of course, means your product is going to be liked more, it's going to be enjoyed more, and it's going to become a preference, and that one small feature, that one line of code could increase the user base of your program, your application. Of course, your program has to be good to begin with, but Yep. There you go, though. That's all we have to do to create these floating windows and have our windows controlled by our operating system instead of being stuck inside of our main. 76. Menu Bars: So let's go ahead and let's talk about how we can make a menu bar. Now, by menu bars, I'm referring to what you see at the top of most applications with things like file, edit, view, maybe layer effects, and so on. All right. Now, how can we go ahead and do this? Well, I have a new scene here it's using a menu bar as my root node here. And I just place a color rect in the background because without it, you don't really have anything back there, and you can't really tell or differentiate it from the rest of your program. Now, depending on your design and how you want your stuff to look, you may want that. Other times, you may want something to differentiate, even if it's just a slight different shade of the standard background of what you're working with. So for me, I just want with this dark red, kind of maroonish color going. And if you're curious, the color the hex color is 391715. Okay. Now, what can we do? How can we add bars and earrings? If we go ahead and play this, and I'm going to have to capture that for you here in just a moment. Oh, no, that automatically captures. Fantastic. It's a little big. So I'll bring it down a little bit. But as you can see, there's, of course, nothing for us to click on. It's just a bar. Nothing happens. So it's not very interesting. So how we can actually add items into this menu bars, of course, we can do it through code. But we can actually eve ourselves of some of this by using another node. And if you actually want to if you just have simple menu items, this would be the quickest way to go about it, as well. Alright, so we're going to go into the menu bar, and if we just search menu inside of the create new node, which in case it's been a while, and you haven't seen that for whatever reason, go ahead and pop that up again, right there. Let's go ahead and search menu, and we got the menu bar, but what we want is the menu button at this point. And now with that menu button, we can go ahead and we can call it the Bo button, for example, give it a good name like that. The text, of course, would be File, Bio not Bilk. Alright, there we go. And I'm just going to make sure it's a good size there, fill in. And this is the point where we can now go in, open up our scene and run it. And you will see if we click on it. We kind of get this tiny little pop up here, but there's nothing inside. Now, the easiest way to add things into it would be inside of our menu button. We have this section called items. We can say Add element, right? Then we can say like new file, add element open, add new. Maybe we have save, and let's add one more for quick. And it's all right there in the inspector. So if that's all you need for each of your menu buttons, boom, there you go. You've got it. Now you can click on it, and you just got to provide a little bit of code to make these. Of course, that also means we could just duplicate our button, slide it over, of course, change whatever options you want in there and we have a second menu button. Now, I'm only going to have one of them set up here just to show you. But if you just need simple menus like that, that's all you have to do. Now, if you want to have a menu that sticks out a bit in terms of if you hover over it, right, and then it opens up another menu, if you want to do something like that, then we're going to have to go into the code to access that. Now, I've got my script just sitting on my menu bar. You could set them on your menu buttons if you want. That way, each button can control itself, which would probably be the better and smarter way to go about it if you're creating an actual product. So for me, since I only have the one menu button here, it's not that big of a deal. But again, if you had, maybe five different buttons there, maybe some of them had multiple different menus, then you're probably going to want to at least break it down into each button that way. Alright. So the first thing I'm going to do is well, I'm going to show you how we can add these buttons in. With this my menu button, I'm going to delete new file, open, save, and quit. So I have no items here in the inspector, and I'm going to show you how we can add those in through Code. All right, so I'm going to create a variable. We'll make it on ready. Bar, let's call it, Bile button. And that'll be, of course, our file button. The class we can cast it as is a menu button. All right. So we have ahold of that. Now we can go flebuton dot. And we just say add item, I believe it is for us here. Oh, no, my mistake. We actually have to get ahold of the pop up because it's a pop up menu that shows itself. So we want to get pop up. Now we can create a variable here, for example, we can say file we can call it the File menu, which is, of course, a pop up menu. There we go. Now we can set it equal to file button dot Get pop up. And all we have to do now is bilemnu dot, and we can go add IM. And we can see ad icon item, which means we can have an image displayed on there. So if you want to have, like, a small floppy disk shown next to your Save button, you can do that. We've also got check items. So if you want to be something that you can just tick on and off, you can do it that way. The radio check, which is just the circle button. And then we have the again, check item and radio check and all that without the icons, and sub menu we'll get into in a moment. And what is this multi state item? Well, let's take a look at it. I'm going to hold Control click on. And he adds a new multi state item with text label. The label is a string, then maxmun of state, the default state, ND, Excel, let's see. Contrarily to normal binary items, multistatoms can have more than two states as defined by Max state. Each press activate the item, but increase the state by one. Default value is defined by default states. So it looks like we get an increase or we can have multiple states. So every time we click on the button, it maybe changes mode. Let's take a look at that. Let's change to set the state to mode, and we'll set the maximum of states to three. All right, so let's go ahead and run that. Let's take a look at this multi state. We click it? Well, we can click on it, and we don't see anything happening. But if we were to take a look, if we were to take a look at this, we could have the states getting the state's affecting what's going on in our project now, as you see from us here, it doesn't really it's not going to do anything by itself, right? It's something that's going to require additional additional things to help us. Whereas something like a check item, right? Calls check me. And if we were to run that, even though we don't have anything here, we can go at that and click on it, and you can see we have this little checkbox, and we would have to set up getting that item and setting the check ability on it or the check property. Alright, so how can we go about? Let's take a look at how we can add our items back in. Can we just say add item, and this way we can put it in a string and we can do our new file, I think, is what we called it. And at this point, we can go ahead and we could just copy, paste these in. So we can say new file open. I believe we had save here, and then we had quit. All right. So if we were to run this and take a look at our menu, you would see all of these options are now in here, just like we did when we did it through the inspector. So if you prefer doing it in code, you could. But if you just need a simple menu like that, going through the inspector would be the easiest or quickest way to add new items into your menu. Now, I did say that we could have new or files that would open up into other menus. And to do those, it's a little more complicated. In that case, we actually need to create ourselves a new pop up menu for this. So I'm going to save New pop. And that's going to be a pop up menu that'll be equal to a new pop up menu pop up menu dot new. And I'll just go ahead and turn this down a bit. Pop up menu dot new. So then we have to go to we can add a new item into it just so we can actually see it. So we'll say newpop dot add item. We'll say this is my new item. Alright. And now, in order to create this or add this into its own little menu that's inside of our original pop up, we just go ahead and get our we get that file menu. And we add sub menu item. Now, the first thing is going to be a string. So let's go ahead and take a look. We'll call this my sub menu item. And what's next? Next is going to be the actual sub menu. This is going to be the new pop up menu that we created, which I call new Pop. And that's all we have to put in. We don't have to put we don't have to put an ID in. It's going to automatically just be added onto the bottom of our list just like these go. So if I wanted to, we could go ahead and set that. Oh, that's right. This is supposed to be a string, which should be called pop up menu, but I'm going to go ahead and just make sure we don't run into any issues in the future with this. We would go ahead and do pop up dot name, and give it a name, right? Change this property. So we'll call this new pop name. Oops that should be a string. There we go. And we changed this to the string variant. There we go. That's what it's going to be looking for. So now if we were to run it When did we get here? As index name on type string. What are you referring to here? Let's see. All right, see the issue. That's right. And GB Script name has a lowercase. I was working with C Sharp recently, so got that little mixed up there. And the other issue is we actually need to put this in as a child of our menu. So we go to the file menu, add Child, and we would add our new pop up menu. There we go. So now when we run it, you can see, we have our file, we open that up. And now we have this item called submenu item, and it's got an arrow pointing to the right, indicating that it opens up, and there's our new item there. This is my new item. Go ahead and let's call all of that our setup. And let's go into our It's our final menu, I do believe, right? And we can connect. And we can connect a signal. What signal? Well, that's unclear. So let's take a look at the pop up menu. Methods. We're not looking at those theme properties, constants, fonts, font sizes, icons, styles, signals. Here we go. ID focus, ID press, index press, and menu change. These are all the signals that we can take a look at, and just by immediately thinking of it, I would imagine we're going to either look at ID press or index press. Emit when an item of some index is pressed or its accelerator is activated. The accelerator has to do with the multi, the multi state. And let's take a look at ID press, emitted when an item of some ID is pressed or it's acceleratorsted. No, I ID is negative, either explicitly or due to overflow, this will return to corresponding index instead. So the question is, which one do we want to look at? Well, I think I'm going to go with the index for this. So I'm going to connect my index press. Come in, connect index press. It's going to be a pllable connected on Self. And we'll say, we'll call this item. I'll call it item selected, and I'll create a new function for it. Well, I'm assuming this is index press, we're going to get an index in here. This is my assumption, so I'm going to find out. I'm going to go ahead and print the index, and we'll see if that works. If not, then we'll have to go back, take a look at the signal again. File. If I click, quit, I got Index three, new file, index zero. Okay, so this is working exactly as I would think. And of course, if I go into the new menu, this is my new item here, click on that. I'm not going to get anything because that's going to have its own signal that you would have to connect up. We got the index working. Awesome. What can we do now? Well, we can take a look at our bio menu and see what our options are. Oh, I hope that wasn't showing the whole time. So items selected index, and our item is just going to be file menu dot get item text, pass in the index. And then we're just going to do a match statement here. So match item, and we're going to match this text if it's equal to new file, open, save quit, and we're going to do the corresponding block of code. Now for quit, we're just going to do Get tree dot quit. So if we were to run that and select quit from our menu, our program should close. And it does. So that's how you would set that up to do whatever it is that you need to do. Obviously, your options are going to be different and it's going to vary based off of your application. But there's how you go ahead and set those items up in order to get those to work. So you've got to connect a signal. In my case, I'm using the index press signal instead of an ID. And then I'm just passing in the index so I can get the items text. And then I just match the text and perform the appropriate section of code. Alright. Hopefully that was clear. Hopefully, I didn't block anything that was too important as we went through that. But that's how you go ahead and create some menus for your applications if you do go down the software route. Of course, not all programs need the menu bars, but the ones that do, it'll be nice to know how to do it. 77. Whast are Particles: All right, everyone, welcome back. And we're going to go ahead and talk about particles today. Now, particles are it's a whole fascinating world surrounding the particles and particle systems and their crucial role in game development. Particle systems are a powerful tool that allows us to create mesmerizing visual effects by adding a touch of magic and realism to our games. What exactly are particle systems? Well, imagine tiny dynamic entities that could be spawn, move, and interact with the world in chaotic yet controlled manner. Particle systems are a collection of these small entities known as particles, and they all come together to form stunning effects like smoke, fire, sparks, magic spells, and even things that you wouldn't think of such as maybe bats quickly flying out of a cave as you enter it. Those could be particles. The magic of particle systems lies in their ability to create the illusion of complex phenomena using simple individual elements, whether it's creating a starry night sky or a powerful explosion. Particle systems give us the flexibility to craft visually healing and immersed experiments for our players. Now, you can do this in either two D or three D. And the systems, for the most part, are going to work the same. There might be some small differences. One of these, of course, being that extra dimension that we have to worry about, which is just natural when moving from two D to red. And it's just how easy it is to create particles in the Gatto engine here. As you see here, I just added some GPU particles into my scene. I'm just using the icon as my texture. All I'm going to do is go to process material, and I'm going to select particle process material. And just like that, you can see we already have particles working in the engine. Now it's just all about tweaking and changing a bunch of different values to make things happen. Eale would just increase the lifetime of this. And look at that. That's increase these maybe 50 on the amount. And there you have it. We have this simple, but technically, it is a particle system of just the icon. And when you get into things like three D, you can use these particle system to create additional things such as weather effects like rain and snow. All right. Hopefully this got you to know exactly what particles are, different ways that they can be used, and hopefully got you a little excited to start playing around the particle system yourself. 78. Creating a 2D fire: All right. All I have here is my GPU particles two D added into a scene. And from here, we're going to go ahead and we're going to create a two D fire effect. Now, you can go ahead and of course, experiment further, increase your fire, make it something a little more unique for yourself. If you wanted, um, let's go ahead and jump in. Now, I'm going to be using a smoke. What is it? Smoke texture. And you can find these all over the Internet. This one is specifically comes from Kenny Particle Pack or Kenny's Particle Pack. And you can find I believe it's on Kenny dot NL. It's got a lot of free assets there for you to play around with. And so I'm just going to take that smoke and bring it into my texture. For my particles here. And now I'm going to go to process material here, and I'm going to click on the arrow here, and I'm just going to select new particle process material. All right. And that's what I got. Now, this is pretty large. So the first thing I want to do is I want to adjust this scale. And I'm going to come down to the scale section here inside of my material. Go to the scale curve and select a new curve texture, open that up, open my curve. And just because I already know what I'm going to put here, I'm going to go down to about 0.34 for the left hand side and the right hand side is going to come spot all the way down. And that's what I'm going to work with. Now, I might come back and tweak this later, but that's what I'm starting. All right, so let's start at the top, time randomness, that's fine. Date. We can do a point. In certain situations, use a sphere and you could play around that, but I'm just going to use just one point. Particle flags. We don't need any of those. Direction. Well, we don't want to go anywhere on the X, but we do want to go somewhere on the Y. Now we want to go negative one, direction on the Y because we want to go up. Gravity, we can just remove if we want. And the initial velocity, I'm going to go ahead and say 32. I want to take a look. That's not really going anywhere. We increasing that playing with that a bit, so we can see it's moving up. And what if I just increase my lifetime to 2 seconds? So we can see it's starting to take shape. So I'm just going to go ahead and play around with some of these here. I'm going to lower my spread maybe down to 16. Now, we don't have a whole lot of particles. We're only working with eight, so that's why it's looking the way it is. But what if we come up to the amount at the top here and maybe go to 50 even? Okay, so that's looking a little closer towards a fire. And if I change my lifetime back to one, how does that look? That looks okay. I think I'm going to tweak inside of my scale here a bit in the beginning. Right now, I'm sitting on 0.19 for the beginning. We'll see how that goes. And of course, with a fire, we're going to need some color. Do inside of the color section, I'm going to go to my color ramp. And from the drop down, it's like a new gradient texture. Where did that go? There it is. So I'll click on my color ramp now, click on my gradient texture. And now I'll click on the black section. I'll turn that to a yellow. I'll click on my white section, pull it in maybe about halfway, and I'm going to turn that to a red or an orange. I'm just going to click into my texture at a random position to add another slot. And with that, I'm just going to turn the opacity all the way down on it. Now we kind of have that fade off that you're seeing here at the top. And I'm just gonna pull that in bit. Now, let's see. Can you tell a difference if we go like that? We cannot. Okay, so I'll show you that little trick later. Alright. So we have our yellow, our orange, and a transparent section inside of my color ramp. Now, to make this look more like fire and not this cloud that we're looking at, I'm going to scroll all the way down to material under Canvas item. I'm going to click the drop down. It's like Canvas item material. And for the blend mode, I'm just going to set that to add. All right. So now with that one opson change, we already have something that looks a lot more like a fire. Now, if you want to have that white center on your fire, Then all you have to do is just take your color and see how I've got Oh, you cannot see on there. All right. One moment. All right. I'll pull that display capture open for you there. Would you see how I have my color right here on the edge? Well, if you want that white center, the white hot center, all you have to do is just pull away from the edge a little bit, and you see the close more you pull it, the larger that white hot area is going to be so there's a little tip for you that you can do for your original color there. I'm just gonna pull it away just a little bit, maybe go a little more closer to the orange. We don't want to go all the way to orange, right, 'cause we don't want orange going into orange. I'm going to go a nice yellow orange, a golden orange and pull away from the center of bit so I get that nice white hot center. All right. And with that, we basically have ourselves a fire all set up here. Now, depending on what you're looking for, the amount, right, can vary. So if we go to 12, we can get something like that, which we lose that white hot center, but this may be something closer to what you're looking for. Eight was the default. So depending on the artistic visual that you're looking for, you can tweak the amount here to whatever it is that's going to fit you and what it is that you want. And this is why when you're looking at a fire, for example, in a game, if you have a lower spec machine, you might lose a bunch of frames when looking at the fire. And then when you look away, your frames shoot back up because a fire can have a ton of particles to it. Especially if we're talking more in three D. I suppose, but that would be why cause particles can have, say, 1,000 parts to them, and then each of those parts is going to have their own texture. So it's almost like adding 1,000 sprites to your screen, right? All of a sudden. Well, with that, we have ourselves a fire. I'm going to turn mine back down to 50 because I really don't feel like we need 100. And we could come in and play with something like hue variation here, which is going to tweak the hue, which is going to look like the color. So if we were to say, turn the minimum up to maybe 0.2 and then change the max up to 0.6, or, you know what? Let's just turn the max all the way up. And look at that. Now we have like this magical fire instead. That we have coming up. Now, we could use this since it's in a vertical form, we could use this for something like a campfire. Now, if this was to D, obviously, we'd probably tweet the scale and make things even smaller, even smaller than this. But of course, that's going to depend on the texture size that you're using to begin with. So you can see with that, we can have these two variations and have more of this magic look. And just like other sections, we can add a curve if we want to do that for our variation. And we can play around with those, and it would affect base off of Although, mine is not changing. That's a little interesting. Minimum value is zero that we had there. Quite interesting. It's not affecting. Maybe it's a little bit of a bug with that curve or something at the moment. I don't know. But you can see how hue variation can instantly just add that magical feel to it with all those colors. If you want, you could maybe tweak angular or velocity if you wanted to, that's going to have to do with turning, right? Your Texas turning in that, so you see if we turn that all the way up, that's really spinning in more of a ball. I'm just going to lower that back down. Orbital is going to be as you see, the whole thing is going to be going in an orbit around your point here in the middle. Now with it up there, obviously, that's not going to make a difference, but here you go so you can see some shooting. Now, so you can get dif these different kinds of effects, and it's all these little effects that we kind of take and piece together to create these awesome visual effects inside of games. But I think that's all we need to cover here, give you a good a good base to go off of? Lifetime obviously goes with how long that fire is going to last. You see the reason why we get one little puff there. And there is because the other fires is still existing. And we told it that so many, 50 can exist at one time. They're lasting for 200 seconds, so they're going to live for quite a while. But you see 1 second, obviously, they die quick, so they're going to keep respawning. One shot means it's going to go just once, just one quick poof. So that's something that you would use for something like an explosion. Current emitting back on up here at the top. And we can easily adapt this. So if we say zero on the direction there and you can see one on the X there and you can see if we made it longer on the lifetime or something, you can see immediately how we can go from a campfire. And then with some slight tweaks, we can now modify that into maybe a flame thrower attack or consistent fire breath for a dragon or something. And all we have to do is just make maybe three very tiny tweaks. But right, I'm going to prevent myself from rambling on. I'm going to go ahead and leave that there. There you go. We've gone ahead and we've created a two D fire for our world. So if you wanted to add something like smoke, you would just add that as a secondary particle, right? So as a quick show, we just have another particle. We want the particle to be behind our fire. I'm going to pull my smoke texture back in again. At a particle process material, change my scale with a new curve. And all we're doing is just going over those same steps that we did previously. Like we did before. But we went with there. I'm going to go with color instead of a ramp. Just going to go with a dark gray on my color here. Let's set our direction. Negative one on the Y. Give us some initial velocity. Gravity set to zero. My spread to be similar to smoke. I'm going to add a material to this, as well. A Canvas item just so I can add set it to additive. We get something a little more smoke like like you see there. And as you see, just by making these few tweaks, we've almost got got the look that we're going for. The amount here and eight maybe we'll add a couple for 12, and all we have is it's not lasting as long. I'll just go ahead and the velocity up a bit. There we go. I'll just move that right back over. You can see now we got this smoke coming off of our fire. Right. So there you go. I'll pull that back down, increase my smoke a little more. But they have just that simple and those few twits going from a start. And you see we've added a smoke onto our fire. Alright. So with that, we've got a fire. We've got smoke with it. That'll do it for this one. And next, we'll go ahead and take a look at how to create a fire using particles in three D. This way, you can get a sense of how similar and different two D and three D is when creating particles and how much of your knowledge will transfer from one to the other. 79. Creating a 3D fire: Alright, everyone, we're going to go ahead and create a fire effect again, but this time in three D. So I just have a three D scene here, and I'm going to go ahead and just add a whoops. Just add GP particles three D into our three D scene. Now, at first, you may be a little confused because you don't see a texture anyway anywhere. Well, in order to create this fire, what we need to do, since we're using two D sprites we're going to go to our drop passes. Go to pass one. And from your drop down menu, just go ahead and select a plain mesh. Open that up. Now, you see it's pointed up. Obviously, that's not going to work because we're going to be looking at it, you know, from the side like this, right? So we need it to face us instead of facing the sky. So inside of our pass one, inside of our plane mesh, we look down. We see orientation, and we can go and change that to these different directions. And if you see set it to face X, we can see it's going to be facing us, which is great. Now, the other issue that we have is, obviously, if we turn around, the fire, right, the plane disappears because the back isn't rendered. We look from the side, we can't really see it, so we can only see it from one side. That is not great. We need to do what's called a billboard. But I add add this billboard to us so that we can always be looking at it. We're going to go ahead and add material here right under our orientation and just add a standard material. And inside of there, if we go in and we scroll down, we'll see a section called Billboard. Now if we open that up and set the mold to enabled. Well, it looks like it just disappeared from us. So let's try why billboard. Well, that's not working either. How about particle billboard. Now you might be wondering why none of these options work under billboard. And for us, because we're using particles that here, we actually have to set this a different way. So none of these billboard options are actually going to work for us. So in order to billboard this properly, we actually have to come up to our process material and, of course, add that particle process. And then under drawing, you see, it's still the same way, nothing's changed. We go to the transformer line and send it to Z or Z, billboard, and Okay, nothing works there. Let's move to the next one, wide to velocity. Take a look. Okay. Okay, it looks like nothing is really working here. Well, that's interesting. Now, you might be a little confused. Why is nothing going on? How come nothing's happening? And this is why it's important that I wanted to go over this three D section as well instead of just calling it particles and saying, Hey, your two D knowledge transfer is over, because three D might be a little confusing like this when you haven't worked in it. So with transformer lines set to Z or Z billboard, we need to also come on down to our orientation, and we change that to face Z or face Z. And now we can see it. And as we spin around, we can always see it. It's always going to face the camera. Alright, so that's awesome. So now we can actually start working on creating this buyer for us. Well, we're going to go inside of our material on our plane, right? So drop passes pass one, our plane, inside of there, material read under orientation. And inside of Albedo, just like in regular three D, everything looks the same. We're going to go in texture, and I'm just going to bring my smoke in. And you'll see that it's got a black background. Well, that's not nice. That's not really what we had planned. I thought, well, what we expected. So what we do for that is we actually come up to the transparency section and we'll set that to Alpha. And you have other options here Alpha scissor, Alpha hash, and depth pre pass. Now, depending on what you're doing, that may have different effects. But for us, the only what we want specifically is Alpha here. And for the blend mode, we're going to set it to add, just like we did in two D, when we added that canvas item, material. Okay, so now we're getting something closer to what we're used to. Call doesn't really matter. We can leave it on back just so it doesn't render the other side since we never see the other side anyway. And that's what call means. So if we set front, it's still there, but it's not rendering out the front. It's rendering out the back, but since the front is always facing us, we're never going to see it. So we're going to set it or leave it on the default of back because we never see the back. We only ever see the front. And this is something that'll help out in performance for your games as well, if you're making something in three D. That way, you're basically not rendering what you can't see. Now, for shaded, if we spin around, you'll see that it gets dark here. And obviously, if it's a fire, it has its own light, so that doesn't really make sense for the fire to be dark on one side and bright on the other. So we're going to go into the shading section of our material, and from per pixel, we're going to set that to unshaded. Now, the last thing we need to do inside of this material is under vertex shader, turn on use as albedo. And if we don't use that, we won't be able to use the color in our particle or the hue variation or the color ramp. We won't be able to use any of that. It'll just stay plain white with that turned off. We have to use the color here in Albedo, and that's it. Now, obviously, we don't want that. We want to actually use the color ramp in that, so that's why we're going to use this albedo and turn that on under vertex color. Alright, so draw pass. We can completely minimize that section, and we're done. We can just go specifically into the process material or our particles. Now, just like before, we have our time, our emission shape, and everything. Now, since we're in three D, I'm actually going to change our emission shape into a sphere, and I'm going to set my rtus to 0.4. Now, basically, this is going to give us a little bit of depth ifier so it doesn't look as flat. Article flags, we don't need to worry about that direction. Well, we want to go in the other direction, right? So we have our Y set, is it negative Y here? Well, we have gravity pulling us down. And if down is negative, then we want to go positive. So I'll just say gravity to zero and set our Y to positive one with a direction. Initial velocity, I'll set it to four. And the reason why I'm going so low, as you can see that four is actually a really high number, whereas in two D, when we're looking at pixels, it's a very, very small number. Now, we can see it going out in this huge directional area, and that's because our spread is 45, so let's turn that down to something like 12. Now we can have something that's a little more reasonable for a fire. We go. And even then, you might want to lower it even further than that. 12 looks like it would be pretty good for a smoke, though. And I'm going to go in and just like we did before, add a new curve texture to my scale. And I'm going to shrink that down for starters and then shrink it down towards the end and just kind of find something here that works for me. And yeah, I think just going from one down to zero like that over time, I think that'll be fine. My color, I'm going to use a color ramp, a new gradient texture. And just like before, I'm going to go with some kind of yellow here at the start. I'm going to throw orange somewhere in there. Towards the end, we'll be transparent. If I just move that over, get something like that, and I think I'm going to throw some more orange cue on the other side. Just to really, really affect a whole lot there. I don't throw black in the bean. Just to get more of a fire gradient, although, as you see, it's perfectly fine here. I'll just throw another black on this side. All right. So just like that, we're getting a nice fire going on here. And of course, depending on the amount of particles that you want to put in here, maybe 200, as you see, that's going to make a huge difference to the visual look of it. So eight obviously isn't the number we want to go with this. 50 that we were using in two D is pretty decent. So you could probably get away with 50 for performance instead of something like 200, but you could always go with 200 if you wanted to. But for the most part, we've gone ahead and we have our two D fire re created here in red. And, of course, we can come in and we can play with the Q so we can have a magical fire, get created, our Que variation Now, let's go ahead and we could look at angular velocity linear radio. You can play with all that stuff if you wanted. Angle is the angle that the texture is going to spawn in at. So if you wanted to play around with that, could. So if I come up, say up to 45 degrees, so that's going to give it a little more variation and hopefully make it look less copy paste, make it look a little nicer. But overall, that's it. Everything else is going to be exactly the same as two D here. Safe little setup that we had to do in the beginning. And you'll see that sphere, if you change that spear radius. The bigger we make that basically, the bigger the fire is going to be. I'm just going to set that back. D 0.4, just purely for looking. Yep, there you go. We have that. So something I'm going to mention here is since you're in three D, you're going to have a world environment, of course, and if you want to add a smoke, it's going to be exactly the same like we did in two D, right out of smoke, do the setup like we did in three D here and just kind of stick it inside of the fire. But you're going to have a world environment in three D at some point. If you're making a just about any three D game, especially if you want to have some kind of post processing. So with world environment here, I just added one into the scene. And I'm going to go to a new environment, and this is where, of course, you come in, and I think I went over this at one point. We're going to come in and create a skies. That's come in sky, create a new sky. I say seeural sky like that. And we can have our skies set up for a three D game. But what you can also do in this world environment is if we come on down to glow, turn that on. Look at our fire has this little orange glow around and what's nice for especially with fire here, blend mode, if we set it to additive, take a look at that. Now we have that fiery look coming off of it, like bloom, right? And we can tweak bloom here. If we wanted to, I can get real insane real quick. That's where your bloom option would be if you wanted to have that. And your HDR threshold, you can really come in and tweak all of these things, and you can see exactly how it would affect something like our fire here. You see, we even got that flickering going around. I just wanted to show you how your three D particles can be affected by the world environment, by options like your bloom, your blend mode, having glow enabled and things like that. But right now I'll do it here for three D particles. 80. How to Code any Mechanic: Alright, so let's take a look at how we can code virtually any mechanic that we can think of. So for this example, we're going to go ahead and create a double jump for our little guess platform or character. And if we think about it, we have to know we're going to jump off the ground and jump once in the air. Now, to keep track of that just those two times, we need to know how many times we have jumped so we know whether or not we can. So for this, I'm going to crink on the variables here to keep track of that, right? Jump count by default is zero. All right. And when we jump off the floor, obviously, our jump count has to go up by one plus equals one. Cool. Now, what about when we're not on the floor? But when we're not on the floor, we can do the same thing that we're doing here where we check if we press our jump button, and this where we can say, and jump count is less than two. All right, so this means we can jump when we have zero and we can jump when we have one on our counter. That gives us two jumps, right? Zero and one. And all we're going to do here is the same thing we do when we normally jump, right? We go up and add to our jump count. Now, you're going to notice an issue here. We're going to jump once on the ground, once in the air, right? We have our double jump. But if we try again, it doesn't work. We're back to a single jump. Now, why do you think that is? Well, it's because our count never resets at any point, right? Starts at zero, right? Let's take a look at this. We start at zero, and we jump. That's one, two, three, four, five, six. So after we take that initial double jump, we're already at two or greater. So this statement will never be true, so we can never get that mid air jump again. Which means we have to reset this jump count at some point. So when do we reset this count? When do we let the player have their double jump back? Well, typically, you let them have their double jump back after they land back on the ground. Okay? Well, how do we know when we are on the ground? Well, we already have that check, if we're on the floor. So if we're on the floor, jump count equals zero, right? We just reset it. And now we have that double jump. Here we go. So all you have to do is slow down, think about the problem and what it is you're trying to do. Think about it logically and break it down into each step. And if you do that, you can virtually work your way through creating any mechanic that you can think of All right. So there's how you can create pretty well any mechanic that you'll be able to think of for your games. And this can work the same way with creating your software as well. Just, of course, not going with jumps, but maybe implementing a feature or implementing a tool or an action or something. 81. Gravity and Jumping: Alright, so here we're going to talk about how we can add gravity and create a jump in our game. And I'm doing this here in their bonus section because it doesn't really fit in with roger, per se. Though you could go back in if you want, you could try and add this into three D version. But Madness, because if you're making two D games or three D games, you're probably going to need to be able to jump or work with gravity at some point. So I'm going to throw this in here anyway. So what we got here first, I'm going to explain is the three physics body types. The static body, which is down here on the bottom, is working as our floor, and the static body is something that does not move no matter what happens to it. So you can think of this as like the ground, a tree, a building, right? It's something that's not going to move, and it's not going to have any impact. The rigid body two D here, which is on the right hand side, in our picture is already by default. Set up to have physics applied to it. So this is something that's going to be just interacted with, kicked around for something like maybe a ball in soccer, right? Running around on the field, kicking it. Or if you've played sky Rim, all the clutter, the food, the cheese wheels that go flying all over the place when you run around or use fuss ro Da, right? These are all rigid bodies. It's something that acts when something interacts with it or force is applied to it. Now, if we were to run this, you're going to see the rigid body falls straight down because of that natural physics, and the static body doesn't move, so that is why we use it as a floor. And of course, other things like buildings and that. Now, no matter what kind of physics body we use here, you have a collision shape, and that defines the shape for that specific physics body. And all of these have sprites just so we can visually see what's going on here. And our character body, as you know, from Froger is what we use when the player is going to have control of set character and it's going to take inputs. Now, there are rare occasions where you might use a rigid body, but that's going to be very niche and specialized at that point. Let's go ahead and look at our character body. I have two variables here, one for our gravity, one for our height. All right. And inside of our process here. Now, again, this should probably be under physics process just because it is related to our physics bodies moving around. But for this example, it's fine. Now, to use these instead of movement, we're going to use velocity, and a character body has a velocity property already by default as a four point X. So in order to use this velocity property, we have to use move and slide or move and collide. I'm going to use move and slide here. Now, let's think about this. When do we want gravity to apply? Well, we only want it to apply when our character is up in the air so that they can be brought back down to earth, right, back down to the ground. Okay, well, how can we say if the character's not on the floor, then add gravity to them. Well, we can do it just that. Goto has a function built in called is on the floor, which performs that check for us to see if we're on the floor, which by default, the direction of up is in the negative Y direction, so that means positive Y. When we collide with something below us, that's going to be considered the floor. So we can say if and we said not is on floor. And we need to add our gravity to it, right? So, so we take our velocity, and we're in two D and it'll be the same in three D. We access our Y axis. And we set that with our gravity. Now, we don't set that equal to our gravity because we want our gravity to pull us down, right? And as you fall down, you build momentum and you move faster and faster. That's how things work, and if positive is coming down, we need to add plus equals gravity. All right? So if we go ahead and play this, we will see now that our character body falls just like our rigid body. Play that again. Right? So our character body might fall just a little faster than our iced body, but you see they work the same. So that's how you would apply gravity to a character to a physics body of some sort. Alright. So now, what about jumping? Well, I have a variable uptop there for my jump height, and this is going to represent the velocity that we have going up in the air. Well when can we jump? Well, we can only jump when we're on the ground, right? So instead of checking when we're not on the floor, we want to check that we are on the floor. I is on floor. And we can add this as a second argument and just say, and we press our jump button, or we can have it as a separate indentation here, if that makes sense for you, whichever one is easier for you to follow. It would be cleaner just to have the two statements in one line here. But again, it's up to you. You just want to try avoiding having too many nested statements whenever you can. So we'll say if input is action and we don't want to say pressed because we're going to be sitting there bouncing like a bunny. So you want to say just pressed or just released. So whenever our finger goes down or when our finger comes up, that's when we're going to get a jump. And that's personal preference. I prefer pressed myself, and I'm going to set this to my upkey my jo and how do we go up? Well, we do the opposite of gravity, right? If gravity is pulling us down, we do the opposite to go up. So let's get our velocity on our Y axis. And if positive pulls us down, let's negative go up, so minus equals our jump height. You see we're on the ground and we can go ahead and we can jump. So just like that, we've already created a simple jump mechanic for us. And you'll notice that we can't jump when we're in the air. If I spa the button, we can only jump once we hit the ground. And if you wanted to have movement, you're left and right at work with your velocity as in most games, you will. It's going to work the same way as our jump here. So if we go ahead and check, so I'm going to back out of my if, so I'm going to make sure that we're still on the floor. I'm going to say I input is action. And this where I'm going to say rest as long as we're holding left or right, we want to move. I'm going to say right. Then we're going to check our velocity, and we're going to go on the X axis this time because we're moving left and right. Now, if you're in three D, you're going to be working with the X axis and the Z axis, and this is going to be obviously have more dependency. But for us, I'm just going to go here. We just need velocity dot X for this example. And if we're going to the right, that's going to be a positive. And we can go ahead and just set this to something like ten, and I'll copy this for the other side or left, and if we're left, that means it's minus equals. I'm going to make this else if. So if we press up, we jump, and then we have a separate second if chain here. If we press right, we go positive X, else if press left, we go negative X. If we take a look, there we go. Oh, there we go. Sliding back and forth. So if you don't want to gain that speed there, you can just set it to velocity of X equals, and that'll just have you going that fast immediately. Now, as you can see, we're going a little slow here. So let's see what happens if we move it up to 100. Alright, so there you go. And we can still jump this whole time. Now, we have an issue here, in this case, see if I stop pressing left or right, M E is going to keep going in that direction because this never gets set. And this is why this if chain has to be a separate block. So we got if we press right, se if we press left, and we can finish this chain with an s of Velocity X equals zero. And that's all we have to do. And now it'll stop moving when we stop pressing our button. And there's our jump. Here we go. Alright, so there you go. There's how we can work with creating a jump, as well as working gravity into your games. And I suppose a quick showcase of how you would use velocity instead of position or something like this. All right. So that'll do it for this quick showcase for again, just show you how to use gravity and creating a jump because it's something that you're probably going to need to know when you're creating some gigs for yourself. 82. Saving and Loading Files: All right let's talk about how we can save files and the different types of files. So we're going to start with the text file, classic text file here. So let's go ahead and we can create our save function here. I have a random scene here. That script on it. No big deal. Doesn't really matter it's saved just so I can run it. And I'm going to create my function, save text. All right. So what is that we need to do? Well, think about this logically. We need to open up a file somewhere. We need to have the writing permissions, right? Because we want to write a file, saving it. And we want to be able to modify the contents of that file. So line Goto four with D descript two here, we can actually do most of that in one line. So I'm going to save var F to be my file here. And we can do this cleanly just because it's only going to be used here in this one function. It's not something that's going to be used everywhere. So it's only going to have a use of maybe one or two line, right? So we're going to get the file access class, and this is what we call open. Now, even if the file doesn't exist, we still have to open it at that location. As a string, I'm gonna pass in Rs. Pooling slosh, we should put it in our side of our project folder here. And I'm going to go ahead and give it a name and say I'm going to call it text test dot TXT. Then the second argument is going to be the mode that we give it. Which depends on what we're doing. Now, we're saving a piece of text. So like I said, we want to write to that file. So we're going to use file access dot. And at this point, we have a file. We have a file that's been opened or my specific directory with permissions to write for that file. All right. So what is it we need to do next? Well, we have we need to actually store a piece of information. Well, to do that, we got to have a piece of information to store. So I've got a handing on the A MIPsum downp with text that we use as placeholders. So I'm just going to create my variable here at the top and call it not text. I don't want to confusing. Let's call this maybe a story, right? Maybe we have story application or writing application we have all this all this text here that we're going to store. Now, it doesn't really matter what it is, but we're going to do that, so we can go F dot Store. And what we can do is we can say store string, store R, store line. All these different options here. Right now, I'm just going to go ahead and say store line, and I'm going to store story. All the text that's in story. But my ready function, I'm going to go ahead and just call this save Pet function. And when I run this, see, initial, it looks like nothing happened. We're going to close and take a look at our files. We see text tests, TXT right here, and there's all the contents within. Okay. So how can we actually load that information? I'm going to go ahead and delete everything in there. So we can see that story is a D. When we start this off? And let's take a look at how we would load a piece of text or load information from this text file. Load text. Now, starting off the same, we have to open up our file. Only this time, we want to have the read permissions because we want to read the contents that's in it. So read instead of write. And if we used store string, we can now get as text is what we can call on our file. Now, in our case, we can go ahead and we would assign a story to equal whatever this text is in this situation. So if we load text, we can then hook auto filled in there, print story. I we take a look at the output. We can see our story did get printed out, but our story started as empty. Obviously, it was loaded in just fine, and we got all of our data out of it. So that part is fantastic. Alright, so I'm going to go ahead and show you the store VR, if you want to choose that instead of store line. You have to store your variables individually one by one, like so. And if we were to take a look at the file afterwards, we see we can't really see anything. We can't really see the information that's in here. And there may be a good or bad thing depending on yourself, I suppose. But then in order to load this information up, we have to use Get Navar, and we have to do this continuously for as many variables as we stored in there, and they're going to come back in the same order that they were saved in. So you would have to make sure that you're loading them in the exact same order to save them. So whenever you save the file, you're going to have to go into your load function as well, and edit that every single time. So you could do it this way, and there are some people that do personally. I don't like this. If I want to store multiple pieces of code like this, or multiple pieces of data, I should say. There are better ways, in my opinion. And one of those would just be a JSON file. And, of course, with that, we just save it and load it. It doesn't matter if we add data to it later on in the future or not. So let's go ahead and take a look at this. I'm just going to go ahead and push all that down there. And we're going to create a function here, right? So we're going to say funk, save Jason. And how would we save the JCN file? Well, much like we did previously. We need to have a file with writing permissions. Obviously, it's not going to be a text. It's going to be a JSON. And all we have to do all we can do is we can store line here as well. So we can say r not Var FDA store line. And the way that we store this would be json dot springify and pass in the dictionary of information. So I'm going to go ahead and create that dictionary with the same three piece of information here. All right, so we've gone ahead and we start that. We have that save set up, right? Store line, stringify, and buy data, which of course is our dictionary that we have here. And we call our function Save Jason, so let's run this. Okay. That should be long enough, close it, and we take a look in our files, and we have JCNFle here. There you go. So this is what our JSON five would now look like. And now we can go through and we can assign individual pieces of information, so we can say experience equals, and then just grab the experience out of this, for example, or we can just go for the whole thing and just say that my data equals our temporary data once we've actually loaded it. So you can see how this would work a lot nicer, and there's even, of course, the store bar, right? But Even if we store VR, we would have multiple dictionary sets, right? So we have multiple JC Bile or JSON Lies in there. But let's take a look at how we would load this information. So I'm going to go ahead and erase everything out of my data. For the time being. Actually, no embrace it. I'm just going to comment it out so that it doesn't exist. So it's the same thing as if it was an empty dictionary at this point. And let's take a look at how to load a JSN file. We create a function, load Jason and just like everything prior, we need to have a file opened with the correct permissions. So we're going to read instead of write. So what do we do that's different? Well, for this, we're actually going to need a JSON object because we can't call the function that we need without creating an actual instance of it. So I'm going to say var J equals JSON. New. All right. And we want to parse it or check for any errors while parsing it, so we're going to say, parse error equals. It's going to be J dot pars where we pass in our text Val, right? F dot as text. And now we can check. So we're going to say I pars error. Is equal to zero, right? So double equals here. And if it's zero, that just means that we had no issues when it came to parsing out our information. Which means it's safe for us to use that data. As such, we can go ahead and sign my data. Is equal to J because remember, we parsed out so that the information is stored inside this JSON object. JG data. And if we were to come up here, we can go ahead and we can even do everything before, right? So we print, by data, see that it's empty. Go ahead and load our JCN file, print your data again afterwards. See that run. See we had an empty dictionary, and then we had everything loaded in afterwards. So there you have it. And it doesn't matter what order these things are in since they are key value pairs. It could be an alphabetical order, it could be a random order. As long as the key and value still match, it wouldn't make any difference. But there you go. That's how you would do something for JSON files. And personally, I used to absolutely hate them and avoid them at all costs. I was being stubborn at the time, and I would much rather at the time, I would have rather used like ten random text files instead of just one JSON file. It was a very bad habit at the time, but now I use JSON Files, and that's one that's my preferred way to store all my variables personally, at least. So if you have multiple variables that you want to store, there you go. You can go ahead and set that. And even if you wanted to even if you just create a temporary dictionary, just to store everything. But that's not the only data that we can do. There are more pieces of data. And importantly, the one that's really going to be important for software developers here, especially for game developers where you want to organize things like your audio options and display options, we're going to use what's called a config file. Now, a config file is very professional looking. And if you've moded sky room, touch the INI file, you'll know exactly what this is going to look like. Look like. These config files or I&I files are configuration files. And they allow us to keep all of our information even cleaner and even more organized than something like a JSON file, for example. All right, so I'm just going to push those off to the side, and we're going to say funk, save config. And unlike JSNFles, this is going to be saved quite differently. And we're going to need a dictionary for this, as well. Only this one, I'm going to call this my settings. So we come in, and we would have, say display display settings here, right? And that would be set as its own dictionary. I'll go ahead and delete those. Inside this display, I don't know, maybe we have like graphic. Well, obviously, it's going to be grabbed we have preset. Maybe the user has medium by default. And again, maybe that's option index two, you know, whatever you're going to store the Alright, we come down. We can do another option, we'll say there's a lucian and I'm going to go ahead and just completely fill the soap for us with some example information. Right? So I just have an example of some settings here of some display, some audio, and of course, you can keep going, add as many pieces of information there as you want, add as many what these are going to be a categories, we would say. So this is the dictionary that we're going to use when saving and loading for config. The first thing we need to do in our save function is we need to have a config, so I'm going to create a new config file object. Config file. New. And now we use some four loops. I'll say four section in settings, keys settings dot keys. Okay. So for all of our sections, so it's going to be display and audio. So we have two sections in here. So for each of those, and then for P in settings section, we're going to go say inside display and we're going to say, for each of these preset resolution HDR, do this next block of code. Then inside of audio, we're going to do this same block of code to this next collection of keys inside that section. And thing we're going to do here is we're going to set some values. C dot set value, and set value takes a few arguments. It's going to take our section, follow our key. And then settings section and key. I have a typo somewhere, don't I? Yes, I'm using all lowercase. They should be uppercase. Here we go. All right, so we set some values inside of this conflict file. And you note, we haven't opened up our file or anything yet. So outside of this double four loop, we just now call C dot save And the location that we want to save. So in our case, res, collash for this. So I do want to note here that the saves location across all devices is going to be the user location, and that's going to be different based on each platform, right? So Mac is going to be different than Windows, which is different than Linux, it's going to be different from Android. But every location is going to have a user user location. So I'm just using bred just so we can see it easily in the file system without having to have a bunch of captures and trying to figure that out. And I'm just going to save this as my setting dot INI file. So if I save this config now and we run it, that's enough time. We take a look at our file systems, and you can see here, I have a settings INI file. If I open that up, you can see how everything is nicely organized into categories for everything. So you can see how confit files can look both very professional, as well as very organization. And still just using a dictionary. Technically, we're using dictionaries and side of dictionaries to achieve this. And configs would be my biggest preference, as I stated there, anything related to settings or preferences in a game or application. All right. So how would we save not save. How would we load the CIfO? Well, let's take a look at loading a config. Load config. And of course, we're going to need a new config object to use. And we're going to check for any errors as the first thing we do. So we're going to save error c dot load, and we're going to look for that setting s file. It's probably going to be down near the bottom, folks. I'm just going to hit up on my keyboard. There's T and there's my settings I and I. All right. So now we'll know if we have any errors loading that. So we can say, if Oops. Error, not equal. Okay. So if we have an error loading for whatever reason, we can go ahead and, we can just print something else failed load, and we actually have an error code, this as well. So we can say error code and do our percents. We can just go that in with the error. Now if I were to hold control and click on Okay, you can see this brings us to this section here. Okay is zero. But if I were to scroll down, we can see all of the different error codes here. Can't write, can't open, already in use, no permission, bad path, not found, corrupt, can't create, timeout can't connect, method not found, link not found, parse error. So you can see all of our error codes here. So if you were to ever be given an error code, all you have to do is just come in here and look it up and you'll be able to see exactly what the issue was. Alright, so now assuming that we did not have an error, we can go ahead and start running our four loops, and I'm just going to copy the same two from above. So we have a four section in settings keys, four key and settings section. And inside of the loop this time, we just go ahead and we see it. We set our settings section Kos I can write that proper. We set this equal to the information we get out of the conf C dot t value. And it's literally going to be the same thing here, setting section. It's going to be written a little differently. We just pass in the section E. And then our last argument, we just put it in null, which should be the default. But just put that in anyway. And now you notice if we come up. Notice how our master is pen here, right? For audio. And we're going to know this works. So I'm going to pert this up. I'm going to go into my settings on INI and change Master 10-100, save it. Now we'll run the load config. I will see a set of ten printed out here for Master. We're going to get the hundred after we load. Take a look, and Audiosecon Master 100, so we know it loaded successfully. There you go. There's how we can save and load config files, JSON files, and text files. Now, it's up to you to determine which file type is going to be best for your situation. But there's how you can do all three of those. 83. Triggers and Pedals: Alright, so let's talk about having support for the triggers on a controller, such as, you know, left trigger, right trigger, L two, R two, what is it? ZL or ZL, and Z Z, ZR. I don't really take a look at the Nintendo buttons, but I think those are it. Now, unfortunately the switch switch controller for that they're just clicky so they're not really triggers. They don't have that travel time, that travel path. They're either pressed or they're not. So unfortunately, for me, I can't use those to show you that here. So what I'm going to use is my analog stick to kind of simulate that for you. But you can use this for those triggers. You can use this for an analog stick, for example, when you move forward, you walk, and when you press it all the way, your character's running, that would be another use for what I'm going to show you here. And another use, which I think is cool is you can use this concept to support steering wheels and pedals if you're going to if you're creating a racing game, for example. Because you got that travel time that's going to work for the steering wheel being turned, how far it's turned to the left and to the right, how much your accelerator pedal is pressed down, how much the clutch is pressed, how much your brake is pressed. So you can use this for a wide variety of controllers, as you can see. And you can think of so many different uses for this. One of the old uses is you press the shoot button down part of the way, they aim, you press it all the way, and they shoot. So what I've done is I've created a shoot button in my project settings. And like I said, I'm just going to use my analog stick to simulate this because my triggers are clicky. They don't work like that. This is a I have a super Nintendo controller that's been modernized, so I don't have the right kind of triggers to show you that. So again, I'm just going to use my analog stick to kind of emulate what you can expect. So here in the process function, I'm going to go ahead and print it out for us. Just so you can see, and this will be input dot. And we're going to say get action strength. Now, you see raw strength and strength, and you might wonder what the difference is. Raw strength is going to ignore your controller's dead zone. Get action strength is going to take the dead zone into consideration, right? So I'm just going to use strength, and I'm going to use shoot to show you this. So if we go ahead and run this, you can ignore that. None of that matters. And we can just look down here in the output, and you'll see as I start moving I stick to the right, which you can imagine again, is moving for blocking around or it's triggers. As you see I'm in my dead zone. And as I leave the dead zone, there you go. So you can see just how far my stick is being pressed here all the way up until we get all the way, which in my case is about 0.98. And you can use this as I was situating or suggesting or your different situations. So now I can go ahead and show this. And sometimes using my analog stick, I'm going to use this as walk and run. So we would say, if input Dot get Ax and strength, it says shoot, which you can imagine just walk or forward or whatever. If the action strength is greater than, say, 0.9, we're going to print out running or shooting and then we can have another if or else if either one will work here. And we're going to have almost the same situation here if input, get action strength, shoot. It's greater than, and we're going to say 0.01. So this way, basically, we're out at the dead zone and we know we're moving. All we're going to do is we're going to print out, and we're going to say walking or aiming All right. So now you'll see right down here. As we go, if we have our sprigger pressed partway or our analog stack only move partway, we're walking or aiming with our weapon. And once we go all the way and hold it there, we'll be running or our triggers pressed all the way, we're gonna be taking the shot. Bam. There you go. So you can see how useful this is. So you can take this into a series with in terms of an accelerator pedal, right? How quick or what your speed is going to be at, right? So you're going to have, maybe your speed multiplied by your action strength, and that'll show how fast you're going and same thing with stopping, right? If you're hitting the brake pedal, you have how quick you're going to reduce speed. You're going to take that and multiply that by the strength of the brake pedal. And now, the harder you press it, the quicker you're going to stop. All right. So that's how you can use something like action strength, which is something that's kind of exclusive to controllers. You can use it on PC as well. The problem is with things like keyboards and that usually a button is going to be pressed or a snot, so it's either going to be zero or one, which is why on PC games, we usually have an alternate button, right? You have a walk button or a walk toggle that you would use, whereas in controller, you just move the analog stick partway versus all the way. 84. Controller Vibration: All right. So here, I'm going to show you how you can add vibration to your game. And we're talking about things like your controllers. Now, I don't have a controller that supports vibration, so I can't the controller on the microphone or on the desk or anything and let you hear go. So kind of going to have to take my word for it on that. And if you don't believe it, you can go ahead and read documentation, look it up, search for, and you'll find you're just going to get the same answer of what I'm going to tell you here. So whenever you want to create vibration, now, for example, I could put this here, right? I can put it in here or up here, you know, wherever I want this vibration to occur. And typically you'll have this on a strong attack or when the player gets hit, for example, whenever it is that you want this vibration to occur. So in order to make this happen, we just go we get our input class, so input dot start Joy vibration. And this takes four arguments. First is the device, and this is the device ID here. And for first player, your first controller, this is usually going to be device zero. All right. Next up, we're going to have the magnitude of our weak motors. Now, the weak motors is usually located towards the top of the controller, and they're obviously not as strong as the bottom because they just want to get shaking, some rattling up there. And the reason why they're weaker up top is because you have a firmer grip on the bottom of the controller than you have at the top, right? They just want to shake it. They don't want to make it hard to hit the buttons or make you miss. So we can say 0.5 string. Third argument is going to be the same thing, but our strong motors. The strong motors is located at the bottom of the controller. You can usually find this pretty much where the palms of your hands are. So it's going to be nice and tightly wrapped in there. And note these magnitudes go on a scale of zero to one. So we can say 0.5 here as well. So at this point, the whole controller is shaking at half its strength, both top upper half and bottom half. And the last thing here is the duration, and this is the amount of time in seconds of how long it is going to vibrate if we put five, it's going to vibrate for 5 seconds. So if you have this plane with an animation or an attack and you know how long it's going to be, you can go ahead and put that in there. And since I have this in the ready function, if I were to play this and I had a controller that supported vibration, then my controller would start vibrating immediately for 5 seconds as soon as my game Alright, it's as simple as that to add vibration into your game. You take that one line of code and place it wherever you want to have vibration.