Transcripts
1. Welcome!: There. In this course, you're going to be
learning how to build from complete scratch
the game that you're currently seeing all
inside of the Godot engine. It's an endless runner game with a character that is going to
be able to dodge obstacles, basically the vehicles
and collect coins. The project stands out for
its outstanding game fiel. Just take a look at the auto scrolling background,
vehicle particles, player trails, coin collection, animations, smooth scene
transitions, and more. This is a super comprehensive
project designed to give you a solid
foundation in the god engine, allowing you to build
your own games. What are you going to be
learning throughout this course? Fundamental good a
concepts such as scenes, notes,
instances, signals, scripting and much more, and also more
advanced techniques, including the Singleton pattern. Finally, you learn how to write clean efficient
code by following the official godd style guide. Complex topics are going
to be taught with slides, so everything is going to be clear and easy to understand. Each video chapter is kept short under 10 minutes so that it is a little bit easier
to follow along. This course is perfect for
both beginners and for also people that already has some kind of experience
in the engine. I've taken and created
dozens of courses, so I really understand some of their pain points in
structures going too fast, unclear explanations or
unnecessarily complex code. You won't face any of
that in this course. Alongside running a
GDA YouTube channel with over 10,000 subscribers, I've also been a course
instructor at Seva. SEBA is one of the leading programming and game
development platforms with over 1 million learners. At Seba, I created
ten GODAt courses, totaling up 25 hours of content. Even the CEO of
SEBA Pablo Farias, left me an amazing review, highlighting the high quality of the courses I've created
for the platform. Based on all these
professional experience, I created this course just
for you in order to take your GOD a game development
skills to the next level. So enrolling the course right
now, I will see you there.
2. Downloading Godot: Hi there. In this video, we are going to be downloading GODed and we'll also
be able to download the specific version that was used in order to
create the game. At the moment of recording, the latest stable
version is GODed 4.3. But, um, for this course, I basically use GO dot 4.45, which is not a stable release. It is a dev release, which means that it
may have some errors. But as well, I basically use this one because it was
still quite stable and it basically had
minor book fixes that if we were using 4.3, we would have okay if you are seeing this
course in the future, and 4.4 is a stable version, you can go ahead and download latest 4.4 if that is the case. And you can try out
following along the course, and if everything
looks the exact same, then go ahead and
use that version. However, for you and
for your comfort, in order to avoid having
any kind of problem, maybe something in
the user interface is a little bit different. I would really encourage you to download this exact
version over here. Go to a 4.4, five. So in order to actually
find this version, you have to click over here,
previous version, okay? And here, you'll find
literally all the versions that have existing
forego that, okay. So here you may have to scroll down a little bit
and find this one, 4.4 Dev five, which was released
21 November 2024, okay? Once you have successfully
found this version, you will click or here download. And then over here, we have two versions
standard and.net. As you can see,
dot net basically also offers support for C sharp, which is basically other
programming language. But with the standard version, we are going to be good to go because we are going
to be using GD script. We are not going
to using C Sharp. So basically, we're
going to be clicking here in Standard. And now we simply have to
extract this ZIP file, so I will right click. In my case with Win r, I will extract here depending on your operating system
on the software that you may already install
in order to extract files. This process could be
slightly different, but well, extracting a file, you should, for example,
here, extract all. You should have different
options to do this. So as long as you are able to extract this, you
are going to be fine. And this will give us two files. The first one is
basically the console. We are not going to
be needing that, and this one is the
actual Godot editor. Now with this X file, I recommend that you save it in your hard
drive, for example, over here in your C on your G, et cetera, so that it
is in a safe place. And then you can also pin it to your task bar by
basically doing this, o, and there have it. If you are asking here
by the how to go dots, because this one is
exactly this version 4.4, five, and I also
have here 4.3, okay? Just if you are
asking that, yes. Indeed, you can have multiple
good versions installed. Basically, with this, we have good successfully
installed in a machine. I will be leaving in
the resources to Links, and the first one is going
to be to go.engine.org, basically to the
homepage of Godos. Here you can browse through some of the features
that Godot has. And I will also leave another
versions for those who want to use the exact
same version as I am using basically this link. Once again, to
avoid any problems, I really recommend
you use 4.4 D five.
3. How To Follow Along: Hi there. In this lesson, I want to share with
you some pieces of advice on how to exactly take
advantage of this course. Basically, how to follow along as effectively as possible. So first of all, how to
actually watch this course. I recommend that you have
your Godot editor open, okay, right like this and that you
maximize its screen going to Editor and then
toggle full screen. Okay, so that you will have a little extra
screen over there. And then that you have
basically your course, okay? Using the shortcut Alt Tab, the tab is the key that is on top of the capitals of
locking the capital letters. And while holding down Alt
and then pressing Tab, you can switch between
the different tabs that you have opened,
here I have mind. But the thing is that with
this, you can quickly switch from the video to the engine. So you see some
parts of the video, you understand what I'm doing, then you can pause
it and Alt tab, you come back to Godot and
you do the exact same thing. Now, I don't recommend
that you split the screen in two because if you were to do
something like this, you wouldn't have enough space here just to see the
code right here. The code would be super small. Like, the video itself
would be super small. As you can see, you can't
make the window even smaller. And if you were able to
make this smaller, um, it would even be
more complicated to see what is actually happening
here in the engine itself. So that's why I recommend
that you have everything nicely maximized over here and that you basically do this Alt Tab to change
from one to the other. Now, of course, if you
have two monitors, you can have the Gage
editor over here, and in your second monitor, you have the video. But, well, maybe
that's not your case, and it is understandable. So just with Al tab, you're going to be able
to follow along nicely. Now, second, I'm going
to be sharing with you a notion template that will allow you to take notes as
effectively as possible, ok. You can take notes
however you want. You can do it in
paper, you can do it in a word document, whatever. But actually notion lets you
organize this amazingly. So I will link this
in the resources. This is a template that
you can use on your own, so you can press over here
at the top, duplicate. And well, if you aren't
logged into Notion, it will ask you to
create your account. It may ask you here
some questions, so you just answer. Now, as you can
see here, how the semply that you can customize. I put here the God's
icon and discover, but you can press change cover and you can put any of these. You can even upload your own or even search for some stock
photos if you wanted to. The same thing with the
icon, you can modify it. Here in the title, you can put the course title if you want it. And also, I really
recommend that you download the application
because as you can see, it is much faster
than the web version, so you can do that if
you really want to. And the idea here is that I have already created
here the sections of the course introduction, Jump EO and congratulations. Probably the largest
amount number of notes is going to be on
Jump EO because it is the section in which we
actually create the game. But anyway, I created the
three of them just in case. Then you have the subsection. Basically, maybe
you are in Jump EO, and the subsection of
this or the subchapter or chapter is I don't know chapter number ten in
which I don't know, maybe we are doing
the player movement. Uh, so the title for that
lesson or for the exact topic here is how to create player
movement, for example. And then these of topics, this is for self organization. If you're having a lot of
notes in one specific topic, you can categorize it here. I have created an example. So, for example, if
throughout the course, you are able to learn a
lot of goaded shortcut. Okay. And you know that
in section number two, subsection two, there
were some shortcuts. Okay, so go to
shortcut you know how to quickly do something, okay? So there you have your note. And here you can open this and literally write
anything that you want. For example, I know,
Control plus C is going to be copy, okay? And the good thing
about notion is that if you write slash code, you can literally paste
here any kind of code, and you're going to to
paste it right there. Here in Bram language, you can select Python. This is the one that I recommend you choose because
by doing this, you will have color
highlighting. So for example here,
I have some code, and you can see we have some
highlighting over here. So yes, you can save your
code right here, okay? So yes, make sure that you take advantage of this template, the link is in their resources. And also, you can
customize anything if you want to delete I know you
don't like here the topic, you can right click, then press Delete property,
and that's gone. If you don't want your section or here, you just delete it. And also here, this board is set in a way that it's
going to be ordered. So if I have here something
for subsection ten, and then I add something
from subsection five and then subsection one, is going to everything
be ordered, okay? So just for you to take
into account that. By the way, in Ocean, you can do even more interesting
things and different stuff. So here, some stuff was also created when I created
this new account. So you can also see this. But, if you're just going to be using this
for this template, you can basically delete all of this so that this is
even cleaner for you. Lastly, you will also find in this lesson the
complete source code of the project in a ZIP file. So once again, you can just
extract this over here, and you will have all the files that were used in order
to create the game. So you can open up go
dot and Import it. In this case, it was
in my download. Okay. And here I have it. I can click Import and Edit. It may take some time
to import everything, but it shouldn't take too long. And to see right
now I have this. Now, if you receive any
kinds of these errors, do not bear in mind
just press Okay. Then go to two D.
And here in since, you can open any scene
that you may want. I know that maybe this will be a little bit
overwhelming at first, but this is just
for when if you get stuck in the player
movement, well, then you can open up
here the player and take a look at the final code that was used to create
the player movement. So this is all for this lesson, and I will see you in the next.
4. Godot User Interface: Hi, there. In this lesson, we're going to be
taking a look at the God user interface. Something for you to consider. This is going to be quite quick. Because actually, I
believe that the best way of learning all these
tabs, how they work, what they are used for is
basically by using the engine, and that's exactly
what we are going to be doing throughout
the course. But, I just wanted you
to know the basis, at least. So let's
go quite quickly. I also here another slide with the actual project
that we are going to be creating so that we can actually see
this in action, okay? But once again, once again, do not throw over if
you're not able to understand everything
because I know that there are just
too many things here, you're going to be
able to learn a lot of this user interface while
we create this project. So first of all, we
have the scene winds, okay, over here. This is basically where
the different nodes. Basically, the nodes are the basic unit of GDA that
allow us to create anything. And this is basically
the place in which these nodes are
going to be appearing. For example, in this case, in the scene, we are inside
of the players scene, so this is where the player is, and we have the different
components of the player. We have what is called
a character body. We will see what a character body is
throughout the course. But you can think of it as
basically a type of node that allow us to quickly set up a player movement
with a template. We also have the
animated sprites, which basically renders the
image of the sprites and also animate sets to actually be able to walk,
fall, et cetera. Then it has the
collision shape which is basically the hit box
unless it has an audio. So all these appears
in the SN tab. Basically the different nodes that our scene is
going to contain. The other one is quite
simple to understand. This is the file system here, the different files
are going to appear. For example, right here, we have the different assets, scenes and scripts that
our game will contain. We can also see the
icon of the game. So basically, any
file that our project contains is going to be
appearing over there. The other window that we
are going to be using a lot is basically
the inspector, okay. And this is the tab
that allow us to modify the properties of the nodes that we have on the scene table. So for example, here,
I have my player node, and this is a character body as I was explaining
a second ago. And in the inspector, I can modify different
properties of it. To keep it simple, for example, here in the transform, I get to modify the
position of the player, also the rotation
and the scale of it. So I am basically able to modify the different properties, the different values that the
nodes have and basically, those are the three main tabs that we are going to be using. Throughout the course,
we are going to be using some more, for example, here, the null tab, but it is better if you just
see throughut course. It is not something
that we're going to be seeing from
the first lesson. So I think it's worth
explaining right now. We can also see
some options here. These scene options
allow you to, for example, save the scene. Then project here, we find the project settings
in which we can modify the window size, the stretch of the
window, et cetera. Then, for example,
in the editor, we can find some
editor settings. For example, how much
Zoom we currently have in our gods
editor, et cetera. And then, for example,
here at the top, we can see that the environment, as you can see right now, we are in to the
environment because this is the one that we are going
to using to build our game. But, we would also be able to change to the
three environments, but we are not going to be
doing anything in three D. Then we have the script tab in which we are going to
be writing our code. And basically, the game and the aclary we are not going
to be using those, so I am not actually going
to be covering them. As well as, for
example, the import tab. We don't care about it. We are not going to be using
it and the history as well. These three things that I have not mentioned
are things that then eventually you will get to
use when you are a little bit maybe more advanced because
they are secondary, okay? The things that I actually
took the effort in explaining are the
ones that you are going to be using
throughout this course, and the ones that you
are most likely to be using as a developer or
at least as a beginner. If not, I could explain
literally every single tab, and this lesson would
be 10 minutes long just hear me explaining boring
things about tabs and windows. So I prefer just to give you a super solid basis of
the most basic stuff, and from there, you start
building your own path. With this, I will see
you in the next one.
5. Assets: Hi there and welcome
to a new lesson. In this one, I want to explain something that a lot of people actually do not really
address in their courses. And I think it is vital
because it is something that you are always using
in game development, and I'm talking about assets. But what are they exactly? They are the components the
player can interact with, and this includes in most cases, just audio and images. Of course, in more complex
game or in three D games, you can have more elements. But anything that usually has to do with files with which the player
can interact with, that is called an asset,
an audio, an image, a three D model in a
three D game, et cetera. So that is an asset. Now, how
can you exactly get assets? Because, of course,
in this course, you are going to be given
the assets that you can use. Then when you
finish this course, the desert that you are
able to continue on your journey and hopefully create and lodge your own games. But how do you exactly
get these assets? Because all the time, probably you are just given the
assets, and that's all. But when you have to
create your own stuff, you don't know how can
you actually get them. And there are multiple paths. You can basically
create them, which, of course, takes skill and time. Or you can also download them
from any kind of website. Always, when you're looking for some kind of asset,
check the license. There are some assets that you can do whatever
you want with them. You can sell your
own games with them. But there are others that
have some kind of license that either do not
allow it at all, or you have to pay in order
to use them commercially. So that's something
to take into account. Now, just for you to know, how did I go the ones that you are going to be
using for this course? The images I basically used Kenny so this is a website that has a lot of assets and even more stuff that
is not just assets. But in the asset sections, you can find things quite amazing with amazing quality,
and all these are free to. So you can launch
commercial games with this. But the thing is that
I have not just, like, took one package,
download it and using no, no, I had to actually,
like, combine like, three, four packs that
I found over here in order to actually create the game because
sometimes I know, I found a an element from a platform from a platform
that was interesting, but then I was also
lacking a background, or I was also lacking a ground, so I had to browse through
all these and actually find the assets that I wanted to
use for this specific game. But, well, you can find
a lot of things here, and this is an amazing website for you to get assets for free. And once again, you
can use them for commercial projects
for anything that you want because their
license is free of use. And now, in terms of music, I used free sound. Now, this is basically a website in which you
can find sound effects, even music completely free, or you can also find others
that you have to pay for or that they have
some kind of license. So really consider that. But if you want to look
for anything here, for example, you
know, chill music, I probably find some. So here I have some.
But when I open it up, I really have to take into account the attribution
that is required. For example, in this case, you can do mostly
anything that you want, but you have to credit
the author of the song. In this case, this
person over here. And you actually get
the attribution text that you have to include. And here, the good thing
is that you can look for creative common zero license. And this is basically a
license that allow you to do mostly anything
that you want. Because, as you can
see, you can copy, modify detribute and perform the sound even for
commercial purposes, all without the need of asking the permission
for the author. You can still get the attribution text if you wanted to attribute the author, but well, you are free
to do whatever you want. All, I found here browsing
around a little bit, the music track that I
wanted for the game, and it is completely
free of use as well. And lastly, for
the sound effects, I basically created
them myself, okay? So just for you to know where the assets that you
are going to be using are coming from.
6. Jump ‘Em All Overview: Hello there to start off
creating the project. I believe that
before doing that, it is actually better to know exactly what the
project will look like. And that's the reason why I'm going to be doing
this quick overview, highlighting the main things
that the game will contain. So let's start right away. First of all, we're going
to be having a player that is going to be able to
be moved using the keyboard. Then it will have its own trail. We are also going to be having the coin that the player is
going to be able to collect. And when that coin is
actually collected, animation is going to be played. We also have the vehicle itself that is going to be
like an obstacle. Basically, if the player
collides with that vehicle, the game is going to be over. And also the vehicle itself has some kind of particles to try to emulate the actual
engine particles, the actual smoke that vehicles
in real life produce. We'll also be adding
some decoration, okay, that is going
to be randomly span. In this case, that
is a blue signal, but there are also
going to be signals, green signals, red
signals, et cetera. We are also into implementing some interface in
order in this case, to count how many
coins have been collected and also
another interface that will count the number of seconds that have passed
since the game start. Now, for the main
mechanics of the game, I like to divide them in
different sections, okay? This is going to be
the core gameplay. First of all, in the
control or the input, okay, but I wanted to use the term
control because maybe it was a little bit easier to
understand than input. As I have already mentioned, we're going to be using
the keyboard in order to move our player and
the mouse click in order to jump the aim or the win condition because actually the game is
going to be endless. So it's not that we're going to be having levels or
anything like that. It's going to be infinite unless the player
dies, of course. So that's why the
aim is to run for as much time as possible
while collecting coins. And while that is happening, the player must
avoid the vehicles. If a vehicle is hit, then the game is
going to be over. Now, for the progression, there is also a core
mechanic, a main mechanic, part of the core gameplay is basically how the game
evolves throughout time. Basically how the
difficulty changes. So in this case,
every few seconds, the game will speed
up a little bit. So vehicles will move faster. The player will move faster. So, of course, if
vehicles move faster, the player will have
less time to react and to jump the Now, in terms of secondary mechanics, I wanted to show you here this video so we can
see the last bit more. And basically, these
secondary mechanics aim to provide some
game polish, okay? And this first game polish is
basically syn transitions. You can see how the
game has a menu, okay? And when the play
button is pressed, there is a syn transition. Okay, so that is
something that is part of the secondary mechanics that aims to have a
better game polish. Now, besides this, we are also going to be having that auto scroll background. Let me show it to
you over there in the video that you can see how the background is
automatically scrolling. We are also going to be having these user interfaces that we have already mentioned
at the beginning. We're going to be having once
again, the player trail. The collect coin animation. Let's see if I can
collect a coin here in the video so
that you can see it. And we'll also have those
vehicle particles as well. So here we can see the
collect coin animation. There we have it twice. And also the vehicle particles, we have already seen them
and the decorations as well. We can also take a look at the different decorations
that there are. There we have, like a light
over there, more lights. So as you can see,
there are more than just one decoration
that it could be a spawned in the game. And we're also
going to be adding some sound effects and music. This is all, so
let's get started.
7. Setting Up The Project: Hi there and welcome
to a new lesson. In this one, we're
going to be creating and setting up the
project, okay? So open up the Godot engine, and let's go ahead and
create a new project. You can click on
this button over here or in this one over here. They are the exact same ones. So first of all, you will have
to provide a project name. In this case, for example,
I will call it jump space, and I will just make
sure here that this is the diversion for
the course itself. And then you will also
have to select a path. I recommend that you create a path specifically for
game development projects, okay, just to have everything in the same place and you don't lose your projects. So, for example, in my case, I go to the E, sorry, to the D drive and
or here I have work, then I will go to the path in which I want
to save the project, select current folder,
and there it is. What you should maybe need
is to turn on and create folder m so that in the
path that you selected, you will have a new folder created to keep everything tidy. And then you have to
select the render. In this case, we're not going to be doing anything
crazy with renders. You can actually take a look at the different renders
that without support. But just a quick overview about the forward plus
is the most used one. Then mobile is meant
for mobile platforms. As you can see, it supports both desktop
and mobile platforms. So if you want to
build a game for both mobile and
desktop platforms, then you should use
mobile and compatibility. It is meant to be
used for desktop, mobile and web platforms, and it's also the least
advanced in terms of graphics. But the default one
is foward plus. And in most cases, if you are a beginner, if you're
just starting out, the render that
they're going to most likely be using is
four Ward plus. So once that is done,
let's click Create and edit and let's wait
a couple of seconds. So here we are by default, Good opens up in the
three D environment, but well, this game is going
to be completely two D, so we don't really
care about three D, so let's switch to two
D. I'm going to be giving you the assets
for the game in the resources of
the course itself, so you can go to that section and
basically download them, and you will have this
folder over here. If we open it up, we
are going to be seeing. For example, this is the font that we're going to be using. We find some audio over here, music, collects coin, die, Jumiimages and more stuff. So we will just grab
this folder and I will drop it inside of
Godos on my file system. So when we give it a second, everything will load in. And as you can see now, we have everything that we used to have in
the File Explorer. We have the same images, the same audio, et cetera. So we are everything okay to actually start
building our project.
8. Creating The Main Scene: Hi there, and welcome
to a new lesson. In this one, we are going to
be creating our main scene. So basically, the main scene is the place where our game
will actually be happening. Basically, we are going
to be having our player, the road, the vehicles, the background, et cetera. So basically, what are scenes? Sins are basically
containers for a small and specific
portion of your game. As I have explained, we're going to be creating
the main scene. And what it will be containing
is something specific. It will contain the
player, the background, the road, the
vehicles, et cetera. It is not going to be
containing all the game, okay? Um, and then we could define them basically
as the different screens. Let's call them that
the game will have. The first bullet is basically
like the formal definition and the second bullet is basically an easier way
of understanding that. And now, I wanted to
show you this with, like, the real
example of the game. In this case, we're going
to be having two scenes. First of all, we're going to be having the menu scene, okay? Basically, this one over here that will contain, in this case, just the game title that you
can put wherever you want, actually, and the play bottom. And it will also have this main scene that
I was mentioning that will be this one in which everything
is going to be happening. So right now, what
we are going to be focusing in the first lessons is basically on creating our main scene on creating the different components of it, such as the player,
the vehicles, okay, the road, the decorations, the interface, et cetera. In order to create these scenes, Good actually makes
the process a little bit simpler
because it allows you to create a root node to the scene, a three scene or
a user interface. Or actually to choose other node if you want to create something
a little bit different. So in this case, what
do we want to do? We want to create
a two the scene. So we're going to be
pressing over here, and this will add,
as you can see, a node to the. In order to rename this node to the there are two ways,
or actually three ways. You can double click over here, and as you can see now
I'm able to rename this. Or actually you can just
first select the node, click another time, and
you're going to to rename it. You can also right
click it and plus rename or directly press F two. I really recommend
that if you're able to basically always
use shortcuts or at least try to get used to
using them they really save a lot of time and always bear in mind that in game engines, you're going to be
spending a lot of time. So if you're able to actually make things
a little bit faster, you're actually
going to be saving a lot of time in long term. So I will use the
shortcut F two, and this will allow
me to rename my node. How these nodes are
going to be called is basically main, okay? And now, as you can see here, I have this message
here that tells me that this scene has
not been saved. Once again, you have different
ways of saving this scene. You can go to sin and save sin or you can use the shortcut
Control S. Once again, let's try to get used
to using this shortcut. So I'll press Control S, and it will tell us where do we want to
exactly save this scene? The game is not going
to be like super big, so we could technically just
save the main scene there, and it wouldn't be such a mess because we are not going to be having dozens of scenes
or even hundreds of scenes. The game is going
to be quite small. In spite of that, I
really encourage you to from just the beginning
of your projects, even if it is your first game,
second, third, et cetera, to always keep things organized because
in the longer term, you will really need
to be organized. As a result, let's
create the folder, in this case, sins, okay? And inside of this folder, I will save my main sin. Something that I want to point
out here is the fact that usually nodes are named
used pascal case. Basically, as you can
see, they are named with the different
words altogether, but in capital letters, okay, the different words. But then for files and folder, you usually use snake case, which is basically
everything in lower cases. And if you want to put a space, it is going to be
with an underscore. Maybe here you will see in the font that it is
named like that. But because it is an asset
that the name was like that, and I didn't want to rename it just because it's
not really necessary to have every single file name like that because it will happen that sometimes you will import
assets from any website, okay, and they will be named differently
from this convention. So you don't really have to
go over them and rename them. It's going to be maybe something that is not going
to be worth your time. So as long as a list
the folders that you yourself create
are named with snake case and your
notes are named with Pascal case, that
is going to be okay. This is basically what
Godot recommends. So I would really stick to it. And also another thing that I encourage you to do if
you want to work a little bit more comfortably is
to turn on a full screen. So if you go to Editor and here a press toggle full
screen or also once again, the shortcut Shift F 11, now it is in full screen. So that bar at the top is
going to be disappearing. I will press Shift F 11 so that I am not
anymore in full screen. So as you can see, this bar
over here will disappear. Okay, and we have a
little bit more space. So I will see you in
our next lecture.
9. Setting Up Player: Hello, there, and
welcome to a new lesson. In this one, we're going to actually be creating the player. Well, actually
start off creating the player because we will need a lot of steps in order to get our player
working completely. We have to first
actually show the player because there is no texture
for it, no image for it. Then we also have to go its own player
movement at the trail, a collisions and
much more stuff. So, of course, the
player is going to be a section of our game
that we're going to be going back a lot of times. So to begin with this, we are going to be selecting
our main node because how game engines tend to
work not only GO dot, is that they have a hierarchy. So they have a parent or a root a parent's
node or a root node. And from there, they have
different children, okay? And at the same
time, those children can have different children. But well, do not
feel overwhelmed because we are going to
be seeing this right now. So from now, let's select our root node
that we're parent, and let's press the plus icon. Once again, I really encourage
you to use shortcut, in this case, Ctraa A, as
you can read over there. So I will use that shortcut. And this will open up
the create new node Tav. Basically, the node
is the basic unit of GDE that allows you to create
anything that you want. And there are specific nodes for specific features that
you may want to add. In this case, we want
to add a player. But what exact type of player? We wanted to have gravity
as in a platformer game. We wanted to be just a
wall that doesn't move. So Godot provides a lot
of different nodes. For example, in o2d, which are meant to be related to the environment.
We have a lot of them. You don't really
have to understand the mold because you are
just a beginner right now. So really do not feel overwhelmed because
you are going to be discovering them as
you create games. So for now, we're
going to go inside of collision Object
two D. Basically, these are the ones that
will allow you to play a little around with physics and also with collisions themselves. And inside of here, you
have the physics bodies. Basically, these
three bodies are here static character and rigid, they tend to be
affected by physics, whereas area to D
as you can see, is not inside of physics body, is not meant to actually
be reacting to physics. And here you can see a
little bit about this, the thing about how Gos and in general game engines
organize the hierarchy, we have the node to this
section, okay, the no toy, and this node has a lot of
children inside of here. Inside of not, we
have static bodies, we have areas to the, we have animated sprites, et cetera. So, for example, right now, we are going to be adding a character body to
the you may think, why not a static body, a character body, a rigid
body or an area to the. Because basically here,
character bodies encoded are meant to be exactly
that characters that you can move with a script. Basically, a script
is a file that you can create in which you
write your own code, which will actually code the behavior or determine
the behavior of that object. In this case, a node. Basically, when you're creating a kind of character or player, in a lot of situations, you may want to use the
character body today because it provides some features that
make it quite easy to use. And we are going to be seeing that in the following lessons. Whereas, if, for example, you just wanted to create, for example, a world, maybe a static body would
be a good choice. Why? Because as you can
read over here, this is a body that
actually reacts to physics but can't be moved. So exactly that's what
you would use for a wall. You want it to affect
the physics of the game. Basically, you want it to
stop the player from moving, for example, you wouldn't
want the world to move, okay? You want it to be static
at the exact same place. Rigid bodies, we
are not going to be using them in this course. But basically, this is mostly used for physics
simulations, okay? For example, if you had a ball bouncing or
something like that, you would definitely
use a rigid body to D. So let's stop with
so many explanation and actually start
creating our player because you're going to be able to understand all
these things much more when we actually
start creating things. So once it is
created, once again, I rename it, remember, you can click it once, okay, and it's
going to rename it. Actually, if first you
have to select it and then click another time
in order to rename it, you can right click and
rename it or F two. Okay? I always encourage you to use shortcuts. Let's
call it player. Once again, remember, nodes
are named using pass Calcas. Check how all the nodes here
follow that convention. So that's the convention
that you should be using. And as soon as we do this,
we see this warning. Basically, we should be using
a collision shape two D. Basically a collision
shape is what you would call a at box in games. It's what determines
the actual shape that will determine how the body or the node can collide
with other things, okay? So I will go ahead and
add this collision shape, make sure that they
actually have your player selected and not the main node because what would happen if you
select your main node, is that when you add it, okay, it's going to be added inside of the main node and not inside
of the player itself. You can press Control
Z of Zebra in order to undo and I will add
it inside of the player, and there it will be, and
that warning had disappeared. Or, well, if you actually make the mistake and
add it like this, you can drag and drop it inside of the player. Okay?
It's the same. And here we have another warning basically telling us
that a shape must be provided for our collision shape because we do have
a collision shape, but we do not have
the shape itself. As you can see,
everything is empty. So I will select my
player another new node. In this case, Sprite. First of all, basically, a sprite will allow you
to render an image. I want to render the player so what I will do is in this texture, I will
click over here, select Quick Load, and
this will allow me to browse through all the
images that my project has. In this case, I will
just use man dot png. Okay? And if I zoom in, you're going to be seeing this. As you can see, this is blurry, this is because it is Pix alert. So you just have to
go to the spit itself texture and in filter,
select nearest. Okay? This will make
sure that everything looks correct in
terms of Pix alert. And then we are going to be able to add this collision shape. So we click over here
on the empty field, and you have different
shapes, okay? And the shape that
you choose will depend on your actual
sprite that you're using. So for this sprite,
I would say that a rectangle will be enough. So we may want to
resize it a little bit, maybe something like this, okay, using those orange dots
and like that, there we go. Now, you may see that the collision shape is actually behind our sprites our image. So let's wrap the sprite on
top of our collision shape because Godot draws things in this order from the
top to the bottom. So in this case, it will
first draw the sprite, and on top of that sprite, it will draw the actual
collision shape. Also, whenever you see
this icon on the scene, it means that it is not the
changes have not been saved so make sure to press Control
S or go to SN and save in. And with this, at least
a pretty simple setup for the player has been done.
10. The Other Functionality Of Scenes: Hi there. In this lecture, what I want to be covering is the other functionality of sins. Because AND, you should
already know that scenes are a small
portion of your game. In this case, we're going to be creating the main scene that will contain the core gameplay, but sins also have
another functionality. So I want to wrap up sine functionalities into two groups. First of all, the
container sins. This is the functionality
that you already know. This is basically containing a small and specific
portion of your game. And basically, they are
the different screens. This would be like the
informal definition for this for you
to understand it. And the second functionality
would be as a sub container. So basically, sins
inside of sins. And basically, their
functionality is sub dividing container sins
in smaller portions. And why would you
want to do that? Because if you just have one
container scinok having, like, all the components of your game and
everything like that, what's going to be happening
is that you will end up with a scene that handles everything and the
notes that that scene has a would it be maybe a
little bit chaotic to organize and to do more
and to make changes? We'll actually see this
in a second in the engine itself so that you can
understand this idea better. But basically, this organizes the project much better
and it has a lot of advantages in terms of a project organization and also in efficiency when
creating the project. Let's see this inside
of the engine. So here we have the main scene, okay, which also
contains the player. But actually, the player
is like a section also of the game itself is
a key part of our game. So a pretty good practice
is to break down these container scenes
into smaller scenes. So how we do so is by right
clicking on this player, and we will save ranch as scene. It will basically create
a branch new scene, but instead of having to create it completely
from scratch, we will already have these
notes that we have set up. So I will save ancha sines. I will make sure
that I'm setting, saving it inside
of my sins folder, and I will press Save. So now it will have
this icon over here, which will mean that this is a scene that has
been instantiated. That is the technical
term, which would be like, added or put inside
of another scene. And here in our sins folder, we now have our
actual main scene and also the player scene. If we swim in using the mouse wheel, you
will see that indeed, this is just like even a smaller portion from
the main scene. And what we have in
the main scene is called an instance
of the player scene. And something that, for example, this allow us to make
is that if we go to the player scene and we, for example, move the player, so I will move it
to the right using the move tool and make sure that you have selected
your player or note, I will move it to the right, let's say, to something
like the middle. Okay? And I will make sure
that my changes have been saved so no icon is over here. When I come back,
what I'm going to be seeing is that the player is now going to
be at the center, and I haven't modified
it in the main scene. So basically, the changes that I've made on my player
scene have also taken place in the instance of the player that I
have on my main scene. So now I think that you
can sell a little bit better the advantages
that this has. Because in this game, we
are not actually going to be a lot taking
advantage of this. But, for example, in a platformer game where you
would have different levels, this is super useful because
you will have one player and that player would be insentiated
in a different levels. So if you want to change
anything of the player, any changes that you make to the player scene will
then take effect in every single level
scene that you have. Because if you wouldn't
do this like this, you would have to go into every single level scene
and modify the player. And, of course, that
is not something that is sustainable at all. That's why using instances is so useful to basically
have everything a little bit more
organized here in both your hierarchy
and your file system, and being able to just see
one portion of the game here and just seeing
the player so, indeed, this is an
amazing practice and an amazing resource
that Godex provides. And by the way, let's make sure that
here in the transform, we basically reset the
position and save the changes. Also, another thing
that you may see here is that the player
is super tiny. So let's go to the sprites
and in the transform, this is basically the property that controls the position, the rotation, the
scale, mainly, okay? Those are the three main things that you're going
to be modifying. So in the scale, I will
just put a scale of six, which would be six times bigger
than what it used to be. So now it is much bigger. And what you will see that now the collision shape
is super tiny. So let's adjust it as well
using the select mode. You can once again use
the shortcuts if you want and let's resize
this collision shape into something like this. And by the way, they don't
have to be perfect, okay? In no game, collision
shapes are perfect. At least into the games I'm
talking about, because if, for example, I would make
the collision perfect and touching the hair over
here and super accurate. Sometimes that feels a little
bit aqua during gameplay. So that's why usually
the developer tends to give just, like, a small advantage to the user that is
playing and just make the collision shapes
of things a little bit smaller than being
100% accurate. And now what we will
see is that if I do not save the scene
and I come back, this will look like
a little bit weird. I have the collision bigger, but my player self is not big, so make sure that you
have saved your changes, and when you come back,
you will see that everything is as it should. So with this, congratulations on completing another
lecture in the course, and let's continue
with the next one.
11. Adding A Script To The Player: Hello there, and welcome
to a new lesson. In this one, we are going to be adding a script to our player to basically start coding
its animations and movement. Or you have to remember here
is that in our main scene, we have an instance
of the player. So any change that we do to the player and that
we actually want to apply in any instance
of it should remain in let's call it the
root player scene. So that's the reason
why I will attach the script in the
root player scene and not in any instance. So to create a script, you select the node which you
want to attach this script. So in this case, I
want to attach it to the player node itself and you press on this
icon over here. Now, this will give
you these options. First of all, you
have the language, good supports different
languages, but, in this case, we are going
to basically be sticking to GDScript that is the
native god language. Inherits this
basically means, okay, which is the node the node type that is script is attached to. In this case, if you remember, this was a character
body two D. So this is correct and you at
least in these cases, you don't have to modify it. And then you also
have templates. Now, for some specific nodes such as character body tutti, you have a specific templates for that specific type of node. In this case, here, it says character body
Tui basic movement. So this is a template that only exists within the character
body to the node. And then you also have
more standard template. This is basically no default. This basically has
some default code, okay, that you may want to use. But if I am not
using this template, I tend to just use object empty, which is exactly that
an empty script. In this case, I'm going
to start off with this template because literally
with this in two clicks, you have a player
moving around with gravity and jump implemented.
So that's a lot. And then also built in script, we are not going to
be covering that. This is a little
bit more advanced. And well, we can select a path. So indeed, we have to select a so I will go to
the parents folder, basically on the first
folder that I have, and I will create
the scripts folder. Okay? And basically,
I will save it. Then I will press Create, and here we're going
to be having it. By the way, make sure that
the script is inside of the scripts folder and not
inside of the sins folder. Now, a couple of things
here for you to know. First of all, if you go to
editor and editor settings, you can modify here
the display scale. By default, at least on
my monitor and on my BC, it was in 100%, but this was super small for me. So I changed it to 100 set five. So if you are seeing
the user interface, the code or something like that, quite small, you can play
around with different values. And you can also modify
the code font size. I have set it to
something like 17. But once again, this may depend a little bit on how you like it on the size
of your monitor, on your exact PC
configurations, et cetera. So well, play around
a little bit. A here, in this
button over here, you are able to zoom
in a little bit, okay? But with these settings, I think with 100%, in most cases, we are okay. And if you hold down control
and you use the mouse wheel, you can also zoom in in
smaller proportions. So I know this that maybe now reading this code
could be a little bit complicated, but well,
let me show you. So first of all, we
have two constants. Actually, in the next lesson, we're going to dig deeper
into the basics of GD script, and I will explain better
what a constant is, what functions are, et cetera. But I first want to
give you an overview, okay, of how this
script actually works. So these two are
basically constants, these are values that are
stored and they never change. That's why they are constants. Basically, speed will always 300.0. It will always be that. The same thing with
jump velocity. It will always be
-400.0. I can't change. Then we have the physics
process function. This is basically the
function that we would use to code anything
related to physics. Basically, what we
want to happen to the player is that
it has some gravity. So it should have some force
pulling it down permanently. And then if we jump okay,
we apply that force, but it will continue
to fall down. As in real life, basically, you as a human being, you are pulled down by gravity. And well, when you
actually jump, you are applying a force in the opposite direction
that the gravity is going, so that's where the
actual jump is happening. So basically here, the code is nicely broken down into
different sections. So for example, this one over
here is adding the gravity. And this is called a comment. So basically, this
is something that is ignored by the engine. This is something that is
just for the developer to know what the lines do,
what those lines do. So this is basically checking. If the player isn't
in the floor, we want to apply gravity. Once again, do not feel worried if you don't understand what this
line is exactly doing. Basically, we're going to be
seeing this as the course goes by and in the
following lessons when you actually know
the script basis. But I want to I want you to know the pretty basis on
how this script works. And then here the jump
is being handled. So as you can see,
here we see if input action is just
pressed and is on floor, basically, this line over
here applies the actual jump. Now, what is this? If input dot is action just press, UI accept. In order to understand this, we have to go to project project settings
and then input map. Then here enable show
built in actions, and here we have to
look for the action. In this case, I accept.
And here we have it. Basically, this
action is called when the Enter key is pressed or when the space key is pressed. So this would be equal
to saying, Okay, if the Enter or the space key is pressed and the player is
on floor, apply the jump. Then here, this is a variable. This is similar to a
constant because it is still a value that
is going to be stored, but its value can
actually change. That's why it's a variable. And basically, this is
going to be equal to input dot G axis
UI left, UI right. So first of all, what are
UI left and UI right. Once again, we go to project
project settings input map, and we make sure
that we have show built in actions enabled. Let's scroll down
little bit and we find this UI left is going
to be the left key. It also has a deep path left. This would be for Joystix, okay? The same thing as this. This is for Joy six. And then UI right is the
exact same thing. The right arrow and the
same thing for Joy six. And this is way of
understanding this is to somehow see what
this value is or has. So basically print, okay? And between parentheses,
I will write direction. Print is basically show a message that will
tell me something. In this case, I want to print the value that
this variable has. So what I will do is to press on this button right here to
run the current scene. In this case, the player. By the way, changes are s automatically when
you run a scene. You will see that the
play will fall down, because gravity is being
applied over here. And what is it that here
direction is zero, zero, but I'm going to be holding
down the right key, and now that direction is one. And then if I am not
pressing anything, that direction is zero, and if I am pressing
the left arrow, that direction is minus one. So basically, that's
the direction itself, I will delete this
print statement. And this is basically
what this input of the Gaxs I left,
right is doing. If you actually hold down
Control and click on Gaxis, you will get the reference
to what this exactly does. And as you can see, basically, this basically gets
the acess input by specifying two actions, one negative and one positive. And also, in this case, this is the first one is the negative action and the second one is
the positive action. So going to the left
as in math, okay, we can check it in the
transform is going to a negative number
where it's going to the right is going to be
towards a positive number. So that's why you are left
and then you are right. Then if direction, what is
doing here is to check, I direction is not
equal to zero, which means we are moving, then we basically up
the velocity based on this direction and also using the speed that we
defined at the very top. And if not, this move towards is basically going to move
our velocity towards zero, basically de
accelerating the player. And finally, actually
move a slide, apply the changes in
these velocities. Without this line, the
player won't move. Don't worry if you weren't
able to understand everything, it is going to make
much more sense once we dig deeper
into the course.
12. Introduction To GDScript: Hi there, and welcome
to a new lesson. This one's going to be the
introduction to GD script. So we'll start off
with constants. That was the first thing
that we saw in the script. So basically, the
definition for it is a value that can't be modified. If you define a constant, you're not going to be able to change its value while
the game is running. It will always be
the exact same one no matter what happens. And the exact syntax for declaring a constant
is the following. You use the constant keyword
followed by one space. And then you use constant case, in order to declare
the constant name. Constant case is
basically this of writing everything
in capital letters, spaces with underscore
and once again, everything in capital letters. And then you make this
equal to sum value. This is exactly what
we saw in our game. We have this constant
speed and jump velocity. And as you can see, their
values are just being used. For example, speed is used
over here and over here. But we are not directly
assigning their values. We are just using those values. And in reality, if you wanted to modify their values,
for example, let's do speed
equals to, I know, 200 dot zero, you will
actually receive an error. As you can see, cannot assign
a new value to a constant. So let's say that goat is
clever in that manner. And by the way, the exact same
thing with jump velocity, its value only being
red but not set. Now, remember that
the other thing that we have was a function. We had the funk physics process. So these basically
are code blocks that perform a specific action. And of course, they
have a specific syntax. Their syntax can be
done in two ways. You may use you will use the funk keyword followed by the function
name in this case, in a snake case, basically, lower cases and spaces
with the underscore. And you may also have
some parameters. We're going to using this thing about parameters in a
second in the code. And then you may also find
them declared like this. You may have the funk keyword and then the actual
function name, once again, declared
with snake case. The parameter itself
with a column, and by the way, here,
this ends with a column. A codon and the
type of parameter. Is the parameter an
integer basically one, two, three, four,
five, et cetera? Is it a boolean, basically two or fault or
what is it exactly? And also then you
will put a dash and a vigor symbol over here
and the return type. Will this function return an integer a float a
vulean once again. Once again, here we
can see the example actually with the second
syntax that we saw, we'll actually see the
differences a little bit in the future about why would you prefer to write your functions like this
and not just like this, even though it would work, okay? But, just for now,
let's ignore that. And we have here basically
this exact same thing. We have the physics process with the exact same
naming convention. We have the parameter
that is in this case, is given by the function. This is the Delta parameter that we're going to be
seeing in this lesson. And then the return
type, which is void. Oid means that it
returns nothing. Now to demonstrate this a little bit more in this case
of the functions, I want to do a simple example. But before doing anything,
let's take a look at how this is being created. We can see that we
have two spaces between the constants
and the functions. So between functions, you should always leave
two empty lines. Okay? That is what
is recommended in the GDScript style guide. So I would how to leave two empty lines exactly like this. And here I would how
to write my function. So I want to do a super
quick function for you to understand this thing
of return types, parameters and that. I will just declare a function
here called Sum, okay? And this will have
two parameters. Basically, number one, okay, which is going to be an integer, Make sure that they're
following the exact syntax. And the other parameter is
going to be number two. And it's going to be
an integer as well. Now, usually when you are putting the type of a parameter, you put colon and then space. Okay, you don't
write it like this and you don't write
it like this, okay? And then for the return type, I want to return the sum
of these two numbers. So I would do that this
will return an integer because I am adding
up two integers. Then I would put
colon and Enter. And this will indent
my code, okay? Because anything that
I write over here would be executed when
I run the function, and anything that
I put over here would not be part of
the function, okay? So what I want to do
here is to return number one plus Number
two, as simple as that. So basically, we have
here a number one and a number two that is
going to be requested when we call this function because we are not
calling it anywhere. And then with those two numbers, they are going to be
added and returned. So what we can do with
that, once again, I will make sure that
I'm living two lines. I will use the ready function. This is a function that
Godot automatically creates and it's basically called as soon as
the game starts. So I will basically print
and now I will put here sum, I will press Enter so that the parentheses are
automatically put. And as you can see here, God is requesting me to put
number one and number two. So I will put, for
example, I know, five comma space four. So we will print
the addition 5-4. And if I run this scene, Asganc is going to return nine and make sure
that you're pressing over here and not over
here or anywhere else. And for example, we can see here an advantage of declaring
things like that. For example, if we didn't put this and I provided here
a different data type. For example, I will
put I know, hello. As GNC Godot is not going
to be able to recognize that something is not going
to be working because here, what we're doing is number one, basically, hello plus four, and in reality, you can't add up like a text and an integer. You can do, Okay, hello
how are you plus 11. It's something that
is not logical. It's something
that you can't do. So if I run the game like
that, as you can see, hear is telling me
invalid operands string, this is basically a string type. It is basically text and int, okay, these four
in operator plus. You can join the map
exactly like this. But this can be actually spotted previously if we just
write the code like this. As you can see, now I am not playing the game, I
will stop digging. And I am having the
error beforehand. Cannot pass a value
of type string as in because I have the find here that number one must be an integer and I am not
providing an integer over there. So now let's just make sure that we erase this code
and leave two lines. Okay, there we have
it. And by the way, you can also see these
lines over here. And also another thing
that you have learned with that example are function types. We saw, for example,
the ready function, which is a built in function. It is a function that
Godot provides itself. So that is a built in function. And the main
characteristics is that they are provided by the engine, and their behaviors
can't be modified. Their ready function
will always be called at the beginning of
the game and that's it, you can't modify that behavior. And on the other hand,
custom functions are created or declared
by the developer, and their behaviors
are custom, okay? You can set whatever you want. In that case, we create
the function to sum, but you could create a function to wherever behavior
you may want. And also a quick
overview to variables. They are a value
that can be modified unlike a constant whose values
are the exact same ones. The syntax is basically the keyword followed by the
variable name in snake case, and then the value
And with this, you have actually
learned a lot of things of GDScript quite basic, but that you are
going to be using a lot throughout the course. Once again, do not worry if you weren't able to follow
along a little bit with some self or if this code is still unclear because I
understand that for a beginner, this is super difficult
to understand completely. But as the course goes by, you're going to be able
to understand it a lot. So I will see you
in the next one.
13. Understanding Delta: Hey, there, and welcome
to a new lesson. In this one, you're
going to be able to completely understand
hopefully this go over here. First of all, what you
may find a little bit, maybe that's not the best thing, is the fact that
you can't scroll a little bit more than
the end of the file. So if I wanted to go some
more stuff here or I want to just scroll down a little bit to have a
little bit more freedom. Good doesn't allow you
to do that by default, but you can actually do it if you go to Editor,
Editor settings. And then if you scroll down a little bit until you find
text editor in behavior, you can enable this option
scroll past end of file. So you can enable it over there. I don't know, it isn't
an advanced setting, so you should be able to find it even with advanced settings off. So now, as you can see, I can
scroll much further away. So the first thing that I
want to explain here is what Delta is because we
have it over here as a function parameter
that by the way, this is a parameter that Godet provides by default in the
physics process function. We can see it here. We see here. We also Well, that's all. We see it over here, but what is this exactly doing over here? So if you want, the technical
definition of Delta, it's basically the
amount of time that has passed since the
last frame was run. That is a technical definition, and maybe you well,
quite probably, I would I would say that you weren't
able to understand that because sometimes technical
definitions without a practical example,
are in vain, okay? Maybe you are not able to
get what they exactly are. So Delta, what is
exactly doing here? First of all, what do we
know? It is a float number, a float value, actually. So we can actually use a
print statement, okay, and basically see
what that value is. And here we see, in this case is 0.166 6667 or
something like that. And as you can see here it is being printed like all the time. Why is this? Because we are inside of the physics
process function, which is called
like all the time, all the time, it's being called. And usually you write code
inside of this function that has to do with
physics themselves. So why is this
value so important? Let's run the current scene that will be the player as well, the player just falls. If we do not multiply here how the velocity
is being applied, the exact same code,
as you can see, and now runs like a complete different
result because Delta, and this is the
important thing besides the technical definition
that of course is important to at least try
to understand a little bit, is that Delta is usually used as a time frame
independent factor. So you would use that factor. Basically, you would
multiply anything by Delta to make it frame
rate independent. If I do not use this factor, if I do not multiply
this by Delta, the gravity that is
applied to my velocity to my player is going to
depend on the frame rate. And in most cases, I would say in 99% of cases, when this is something that has to do with applying gravity, moving a player or
something like that, you would always use you
would always use this factor. You would always
multiply by Delta. And you may think, why here
when I am actually moving, remember that if direction, it means that direction
is different from zero. So if we are moving, we are applying
here the velocity. Why here we are not also
multiplying by Delta. Because in character bodies
to this in physics process, the velocity is already
being multiplied by Delta. So if we multiply
twice by Delta, we're going to be
having some issues. There's also another
advantage on using a character body
because if you use an area to or a chi body, you would have in most
cases to multiply by Delta. So as you saw, if we
had or here Delta, we have this result, and if we do not have Delta, we have this other result. To understand this a little bit more, let's
do the following. I will go to project
project settings, and I will make sure that
advanced settings are on, and under application run, I can limit the FPS,
the frames per second. So let's put this to
something like 30. So my game will play at
most 30 frames per second. Okay, so there we
have the result. The Zagazi was quite fast and it wasn't quite
smooth at all. And if we actually
multiply this by Delta, what are we going to be
finding the following? We find a smooth movement. Maybe it's not that
smooth because a frame of 30 is
not super smooth, but if we said this to be 60, for example, there you
see smooth movement. And if we do not use Delta, we have a completely
different approach. And now let's do the following. Let's make Max FPS, zero, basically, limit it. Basically, the power of my machine is going to
determine the number, the amount of FPS. So if I just play like this, this is going to be
like super fast, white. Because in my case, my PC
is not like super powerful, but it does have pretty
decent components. So physics process,
as I told you, it's like, called every
time, every frame. So in a high end PC or in a PC that has
considerable components. In a project like this small, it's going to be
it's going to be having a pretty high frame rate. So it's going to be
happening is that physics process is going to
be called a lot of times. So if I do not normalize, in this case, this gravity, as you can see, what is
happening is that we have different results in
different frame works. Here, how much time does it
take the player to fall down? I know it is super fast, but what happens if now
we are playing at 60 FPS. It's going to be much
slower, in this case. Well, it is a little bit complicated to actually
sit like this. But maybe if I put it at 30
is going to be more obvious. Or maybe in ten, then we see that it
is not smooth at all, of course, but that has to do
with the frame rate itself. But what I want to show you is that when I multiply
this by Delta, I'm currently at ten FPS. As you can see, it is
much more smoother and goingto to keep that frame rate in dependency. And
that's what we want. If I set Max FPS to 60, it will take the exact
same time than if I am playing at 120 FPS, for example, you're going to
take the exact same time, as you saw, and we
are in twice the FPS. And for example, if
we do not use Delta, let's see, with 60 FPS, I don't think we
are going to able to notice the difference a lot, but well, there we
have with 60 frames per second and with 120. That we see. So I think that it is something
that you can see, the fact that the more FPS, the more times physics
process is called. So basically, make sure that, in this case, you are
multiplying by Delta. So anytime that you want to, um make anything frame rate independent in some kind of
physics process function, or you also have the
process function, which is quite
similar, but it's not meant to be running
physics related code. I am, by the way, writing
here pass because if not, goes goes mad and puts red everywhere and doesn't
let me compile the code. But, well, this is a
parameter that exists in physics process
process, and process. So anytime that I want to make anything, frame
rate is independent, make sure to use the
Delta factor, okay? And once again, we
are not using here Delta because this velocity is already being
multiplied by Delta when we are calling the
move and slide function. And by the way, I want
to show here that if I comment this move and
slide with a hashtag, basically, this is
not going to be run. It is the same as
being like this, but basically, if I
delete this hashtag, I can recover the code,
let's a bit easier. So like this, the player
is moving like this, it is as if this code
wasn't here at all. So that's basically what
move and slide is doing.
14. Creating The Road: Hi there, and welcome
to a new lesson. In this one, we are going
to be creating the road. So as we have been discussing, we're going to be breaking down our container sins into
sub container sins. So that's why I'm
going to be creating the road in a complete new sine. And for this, you will
have two methods. You can, as we did
with the player, create everything
in the main scene. And once everything is set up, you right click and save
the branch as seen. But, well, I'm going to show you a second method so that you
have both ways of doing this. And then in the future, you can decide which of the two you feel the most
comfortable with. And by the way, the
one that I will show you right now is the
one that I believe that most developers tend to use because it's basically at least at more organized as you start from complete scratch. Until now, of course,
we don't have that many things
in our main scene, so it wouldn't I believe
that we wouldn't mind if we created everything here and
then save a ranch the scene. But then bear in mind that maybe then you create
bigger projects and your scene here would
have tons of things. So that's why starting from a complete empty scene
would be a good thing. So for creating the road, we have to think, first of all, in which type of
node we will need. So, of course, it's going
to be a node to the, and it will have to do with collision and
physics themselves. But which of these
three, we have already worked with
the character body. So remember that
this is meant to create characters that will
be moving with a script. Um but well, in this
case, we don't want that. So we have three options
left static, rigid or area. And well, remember
that rigid body, it was moved by physics, but the road is going to be, like, in the exact same place. So we will not take
advantage of physics, so it wouldn't be worth it. And then static bodies, this is basically what we need. These are objects that can't
be moved by external forces, so they will always be
in the exact same place. Or well, actually, they can't be moved by external forces. So if, for example, the player falls towards a static body, the static body will not move. We would still be able to move the static body.
Let me find it. We can still move it manually, which would mean via code. And then finally,
just for you to know let me open up
this once again. The area, you would use it
just to detect collisions. It is called an area and
not a body, as you can see, because it is only
meant to just, like, have a collision
and detect collisions. Just for you to know,
we are going to using this for our vehicles, for example, because our
vehicles will not be static, for example, they will not be moved as a character reacting to inputs or
anything like that, and they will not have physics. So the only option that
we have left is areas, and we will see in the
course how areas make collision detection
super easy, okay? And to react to that collision. Because remember that if the player collides
with a vehicle, we must end the game. So to start off with a row, select the static dy
and rename it to rod. And usually after adding the ody or the area and
these kinds of things, you will need your sprite. And then I will press
the up arrow so that I select my actual rod, okay? I will press Control A again, and I will add the collision. Sorry, collision shape to the. Yes, there it goes. And I will save the sin
into my sins folder, rod there we hold. And in the sprite,
let's load in the rod. Now, we use quick
load because it basically give us all
the different images, but you can also use load, but you how to go
to Assets images and you how to browse through
the different folders. That's why Quick oad is
quite good for this. So we just select the
rod. Okay? And then we have a piece of rod. And well, I want the rod to
be at the bottom of my game. So I will select the rod node. I will go to transform. And in deposition, I
will put it in the Y of 616 616 because as you can see in the Y
that would be like barely at the bottom of it. And then I will put
it in the X in 576, okay? And why 576? Because if we go to the project
settings and in Window, we copy the viewport width. This is basically
this width over here, and I paste this value. As you can see this is
going to be at the right, but I want it to
be at the center. And if I divide this by
two using slash two, this will be put at
the exact center. Now, what I need to do is to
actually modify the sprite. So in this case, I feel that the sprite is a
little bit too big. So I mean, to be in the Y axis. So let's change the Y to 0.5. Okay? There we have it. And then I will
disable this because this will unlock basically the fact that this
will be proportion. So if I wanted to
make the X bigger, let's say ten, you can see the Y would also be scaled
in, and we don't want that. And I will put an
X scale of ten. Okay so there we
will have everything positioned correctly as
we scaled correctly. And lastly, we would need
the collision shape. I will create a rectangle shape, and using the move tool, I will move it a little
bit to the bottom, maybe something like this,
and I will extend this, okay? I am not covering
the entire road, maybe something like
this, as you may think. Because basically, I want
the player to be able to, like, land inside of the road. Because if I put the collision, at the top, we're going to
be seeing this in a second. It would be like, quite weird the point of view
that we would have. So let me now go
to the main scene. And well, we don't
have here the road. So let's select the main scene, and I will instantiate
the road, okay? So now if I run the scene, okay, there we have the player, and we see the
first problem that the player is
underneath the road. And that has to do with the
order that we have set. Remember that Godot,
in this case, will firstly draw the player
and on top of the player, it would draw the road. So we want it to be
the other way around. Firstly, the road and on top
of the road, the player. So there it is, and
this is the point of view that we would
want for the player. Remember that any change that
you make to the road scene, it will take effect
on the main scene. So if I make this collision
shape like bigger, to cover all the road and save and then played
in this scene. Okay, this is what we would see, and that's not the effect
or the appearance, the perspective that
we want to give. That's why I have
chosen to actually make the collision
shape much smaller. And also something else
that you have to know is that we have using this button
to run the current scene. So if we are in the main scene, the scene that is
played is the main one. We also have this want
to run a specific scene. So I am in the main scene, but I could run the road scene, and there it is just the road. And well, this is a
movie maker that we are not going to be using
actually over here, but we haven't used this button. And this is to actually
run the project as if we have built the game and
send it to somebody else. And if we click
here, it tells us that we must select
a main scene. And basically, the main
scene is the one that will be run when the
game is actually played. So our main scene will
actually be the menu, okay? It will usually in games, the first scene is the menu, and from the menu, you can go to the main scene to where
the gameplay happens. You can go to a settings
scene or whatever. But, well, the menu we're going to be creating
it in the future. So let me just select here the main scene
as the main scene. So that we can at least
just use this button, okay. It is much easier because I
can go to the road scene, play play, sorry, press play and basically
play the main scene. So it's going to be
a little bit easier. And also note how here, if I maximize the game,
everything breaks. This is because there
is no stretching. So if we go to project
project settings, and then under Window, we scroll down here in mode, we can just select canvas items, and this will make
sure that basically the aspect is kept and
everything stretches nice.
15. Polishing Player Movement: Hi there. In this lesson, I'm just going to be polishing a little bit the player
script because, well, we have a lot of
comments and also we have here a comment
from the template. As good practice,
you should replace UI actions with custom
gameplay actions. So basically, UI
left, you are right, I accept we should modify
them with our own input. So let's just follow that
suggestion from Godot. But first of all,
let me just delete this code instead of
having to do this, okay, and select over here and delete this,
which would work. Basically what we
could do is just anywhere in this line of
code, press Control X. And that would cut the line, but, would delete it anyway. And by the way, you could
paste this line with Control V as if you
were pasting anything, or you can also, for
example, I will copy, move a slide and paste it
multiple times if I wanted to. And, of course, with
Control D of Zebra, you could undo any change. So I will just delete
all these comments over here because we have understood correctly
how this worked. And also how notes here, there are some lines
in between this is, like, all together
like this because, of course, it is much more
complicated to be read. So you should make
the good practice of dividing your code with different spaces for
different functionalities. In this case, remember that
we are managing gravity. Here we are managing jumping. And here we are managing
left and right movements. And finally, here we are
actually calling move and slide. So these are, let's say, different things, so that's
why we have different spaces. So now, basically do
the suggestion that we had of replacing
these actions. So let's try to remember
the actions that we have to create on our own basically
left, right, and jump. So we go to project project
settings Input map. Well, we can enable it here
to show the built in actions, but I am going to disable them. And to do this, it
is super simple. You just add a new action, and usually actions are named with verbs
like for example, move left jump, move right, I don't know, pause game
or something like that. If we go to the
built in actions, you will see from UI
accept UI select. They are not called accepted, selected or anything like that. They are in verb
in the base form. So I'm going to do in
to be adding left. Okay. And here I have them, and I will press at event. And now I will press
the left arrow, okay, and press Okay. So that will add it. And I also want to be able to move to the left with
my A on my keyboard. Okay? Then I will
at the right Okay, so D and right arrow,
there we have it. And finally, jump. Okay? Jump in my guess with the space bar and the enter key. So whenever this one or
this one is pressed, the jump action will be called. And by the way, here,
let me just call this one, move right and this one move left to be a little bit more
specific left, left, what? Move, left, move right. Unless now basically
replace here, this is going to be jump. And also another circle
that I want to show you is that instead of having to elite
everything like this, what you can do if you just hold down Control and
press any arrow, sorry, the left or right arrow, what you will see is
that the mouth cursor will move to the end or
the beginning of a word. So what you can do is to hold
down Control and combine this with shift that remember that shift allows
you to select stuff. So if I am currently pressing Control shift
both at the same time, and now I press the left arrow, I have selected all UI left. So I can replace
this to move left. I will do the same
thing with UI right. I am over here, Control shift, and the right arrow
and then move right. And I can also use here the
arrows to go to move right, press Enter, and this
will be auto completed. Once again, I understand that I am just mentioning
here shortcuts, ways of winning a little
faster, et cetera. But, well, in the long term, if you are able to implement
them into your workflow, you will save a lot of time. You will be able to develop
more games in less time. So it's important that
from the beginning, you start practicing,
so that as soon as you have created three,
four, five games, you will already have a
lot of experience by then with shortcuts and
being productive inside of the engine itself. So, nice. I will see
you in the next one.
16. Starting To Animate The Player And @onready Variables: Hi there and welcome
to a new video. In this one, we are going
to be animating the player. And for this, we will need a new node that is called
an animated sprite to. It is actually quite
similar to the sprite to. But the main difference
is that you can change quite easily
the sprite texture. Because right now,
if we wanted to actually play this
animation with the Sprite, it would be a little
bit more complicated. So instead of having to add the animated sprite
from complete scratch, actually GoTo makes this
process a little bit simpler. We can right click
on the Sprite two D, press change type over here and type in animated sprite to, and then we can press Enter. So there we have this. Now I'm going to rename it to animated, animated Sprite two D just to
match the exact same name. And now we will have to create
a brand new sprite frames. Okay, so this is just the
animation, and by the way, when we do so, the warning
over here disappears. Now we can click over
here and we have here a new tablet that I'm going to make it
a little bit bigger. And basically, over here, we can start adding our
different animations. And if we check out
the character images, we have just the man over
there that is not moving, the man falling and
the man walking. So let's create
these animations. I will rename the first one and I will call
this one fall. The next one is going to
be idle and lastly, walk. You can see how
these animations are usually named with verbs, walk, fall, die, et cetera. So in work, I will select both images and drag and
drop them over there. In idle, I will drag and drop just this one and
in fold these two. These only image, sorry. And now I can, for
example, go to the walk animation and play it, and there you can see it. But I feel that it is
a little bit slow, so I will change its speed
scale to something like 1.3. So now when I press
play, as you can see, it is a little bit faster and actually it
looks a little bit better. Let me hide the
collision shape for a second so that you
can see the animation. But now we actually have to play these animations
inside of the code. I will leave just there the idle animation so that I don't see, like this sprite over here, and I just see the idle
animation over there. And now we have to change a
little bit around this code. And in order to do this, we need to have a reference
to our animated spread so that we can actually change the animation that our
sprite frames is playing. And in order to do this,
there are numerous ways, but the best way of doing
this is to catch a reference to this to basically the node that we want to
reference and use. And we achieve this through using what is
called annotations. These are basically
special tokens that exist in GDScript that
basically modify how some code works or actually is treated by the
engine or the editor itself. They start with
the ad character. And basically, there are
a lot of annotations that you can browse through
in the documentation. I will go to them so that
you can check them out in this specific web
page that I'm going to link in a linking down below. You will see all the
annotations that currently exist in GDScript and a pretty well known annotation
that you are going to use a lot of times in dscript
is the unready annotation. And basically, it
assigns the value of a variable right before the
ready function is called. Remember that the
ready function is called as soon as the
node they loaded in. Well, this readian
notation will define the value of a variable right before the ready
function is called. So to avoid complicating
the explanation too much, whenever you add the readian
notation to a variable, it will set its value as
soon as the game starts. And it is usually used to catch node references as we're going to be
doing in a second. And we'll also do or see another usage that this
radian notation usually has. And it is also useful
for shortening the code because if you don't
use the radian notation, your ready function,
you will have to catch all these
references inside of it. So by doing this
in just one line, you both declare the variable
and assign its value. That's why it is so useful. And to do this, there are actually
multiple ways. You can, for example, type at ready then bar and the
variable name, for example, animated sprite
and make it equal to dollar symbol to reference
a node, animated sprite. Okay? This dollar symbol
will basically allow you to select any node
from the hierarchy. And as you saw, if I
type it in like this, I am going to help
to both reference the animated sprite and the collision shape
if I wanted to. But of course, here I
want my animated sprite. This would work, but there
is even a better way of doing this and
easier and faster. You can drag and drop this. But before dropping
it over here, you can hold down Control, and it will automatically
create the reference for you. If you do not hold down Control, it will just reference the node, but it will not be stored
inside of a variable. And here we also
see a difference. We have this thing
over here that we have seen previously here in
the function parameters, and I'm going to explain
that in a second. But before I'm
going to be leaving here an empty space over here, and I will delete this
space over here. Why? Because in this course, I want to teach you how to write clean and efficient code, basically using the official
GD Script style guide provided by the
GOTO documentation. So here we have
here, for example, an example script and some
parts of it could be a little bit complicated for a beginner to understand but for example, some stuff that we
can see here is that between the variables, declarations and functions,
there are two empty lines. Or, here's going to see
these are two lines. And also between functions,
we have two lines. That's why I'm leaving
here, these two lines. And also, if you
continue to scroll, there is a section that
is called code order. So we actually had to scroll
like a lot. Here code order. And here you can
find some stuff. So for example,
we're going to be seeing some of these things
throughout the course, so do not feel overwhelmed. But important thing
is that, for example, we have constants here, and constants are over here, and below constants for we
have unready variables. So we first should
write constants, and then below constants
should be ready variables. We shouldn't be writing
this like this, for example, I would work, but it would not be
the cleanest way of writing this according to
the D Script style guide. We're actually going to be
learning much more as we code throughout the course
about clean code techniques. And by the way, why I am only leaving one line
over here of space, because in all space
like here in this guide, it is stated that between extends and the first
line that you have here, there should be two empty lines. It doesn't say that as
far as I have read. And here in the example script, they do not leave
two lines, okay? They just leave one.
And for example, here with these
comments, it could be a little complicated. But let me, for example,
copy this, okay? And let me just
leave here a lot of lines so that we can
actually see this. And if I delete these comments, you will see that indeed I
only have one line of space. That's why I am basically designed to only leave
one line of space. Du doesn't really matter if you wanted to leave
to go ahead, okay? Once again, because here we have four lines of comments
and one line of space. If you delete these
four lines of comments, then you would have only this blank line
over here between extends and the first thing that you would
have over here. Also, another thing
that I just want to do is to delete this underscore two D from the name because as this is a
complete two D game, I don't care if the
animated sprite is two D, three D, or whatever. I will always be two D. So I will just rename
my variable like that, but you can leave the two
D if you really want to. So this is all for this lesson, and I will see you
in the next one.
17. Clamping The Player Movement: Hey, there, and welcome
to a new lesson. In this one, I want to
address the problem that we currently
have with the game that is actually quite
simple to solve. So I want to actually make
sure that the problem is sorted out before we
actually animate the player. So *** right now we have a
player here moving around. We can jump and move, but I can basically
exit the screen, okay, and the players not
going to be able to come back because it
will basically fall, okay? And to do this, we
basically have to clamp or restrict
the player movement. And in orer to do
this, we must have a reference to the screen size. And for this, we will see the other usage that I told
you about unready variables. We have already seen
that we can indeed use unready variables to reference
node in the hierarchy, as we used it here to reference this animated
spread to the. Not only that, but we can also reference some data that is only available
when the game starts. For example, the screen size, the screen size doesn't exist
until the game loads in. That's why we must put
the unready annotation, because if not, we
would be trying to get data from the game
that hasn't started. So I will declare this
variable as screen size. And I will basically
make this equal to get view port underscorct dot size. Make sure that you exactly write this now, let me add, okay, with two lines of space
in between to follow the GD Script style guide that we discussed the
previous lesson. And I just print the
screen size, okay? So let me now play the game. And here we have
the screen size. That is exactly this one. And these numbers, okay, come from project project
settings and window. As you can see, both numbers
are the exact same ones. So we are basically
referencing those. Now, if we deleted this already reference and we
actually wanted to just print this value, as you can see, it basically
says 00 when, of course, our window is not 00 in size,
and we receive an error. This error basically means
that we are trying to access some data that currently
is unavailable, okay? Because once again, the
window wasn't even created. We have to wait until a game actually loads in to
access that data. Now, once we have
this, let me erase this and make sure we
leave two lines of space. What I will do is that
after moving slide, okay? I will clamp my position
to my screen size. So I will do position equal
to position dot Clamp. And this will require
me to write as you can see a minimum
and a maximum. What is going to be
our minimum position? Basically, it's going to
be vector two dot zero, which is the same
as saying this. Okay, but it is like a
shortcut to say that. And then screen size. It will basically clamp our position from
00 to screen size. 00 in Gode as you can see, is basically at the top
left of the screen, okay? And if we were to use the screen size on our position, let's
check what we have, so I will just copy and
paste the width and height As GC is going to be
our bottom right corner. So it will basically
cover all the screen. Okay, so we won't be
able to exit the screen. And when we play,
as you can see, my player can no longer
exit the screen, neither on the left
nor on the right.
18. Static Typing: Hi there and welcome
to a new lesson. In this one, I want to
address static typing. Basically, this is what we
can see over here in which we are defining the type of the variable that
is going to be stored. In this case, animated sprite is indeed of type
animated sprite. Basically the type of
node that it is getting. In this case, we also
have an example of static typing where we define
that Delta is a float. Well, this is actually a
parameter given by Godot. And also the return type of
physics process is void. I returns nothing. But as you can
see, we don't have a static typing in sal
fower screen signs, and we indeed saw that everything
worked perfectly fine. But I want to dig
deeper into this topic because it is quite
important in coded. So here we have a static typing. First of all, what is the
definition of static typing? It is basically a way of
writing code in which you say the type of
different things. As we have seen variables, you can also define the
types of constants. Function parameters as we saw
Delta that we defined it as a float and also function return types such as void
that we have already seen. Now, which are the exact
advantages of doing this? Actually the advantages,
you will be able to realize them as you code as you
become a better developer. But well, just to
mention some of them, it is more performant for Godot because Godot doesn't have to predict the type of variable function parameter, et cetera. It is given to it, so it doesn't have to do any
kind of extra calculations. It can detect errors without
even running the code. We have seen something of this previously throughout the
course when we were defining the parameter types
inside of functions with a return function that would
sum two different numbers. So that is exactly that. How GoDat was able
to tell us, Hey, there's something
going wrong with your goal without
even running it. So that's an advantage
of static typing. It also improves auto
completion. In some cases. We are going to be seeing
one exact situation, a little bit more advanced in the course in which we
actually see an example of how static typing
can actually help you improve auto completion in let's say, more advanced cases. So once again, don't worry that right now you haven't seen any example because you will
see later in the course. And finally, because
it is just clearer, if you have a variable that you statically typed as Bollan, it is clearer to you as a developer that there is
a Bollan and therefore, you're going to be able to
better understand your code. Once again, right
now that you don't have a lot of functions, a lot of variables, this may seem a little bit like that is something
that is not worth it. Trust me, that in the long term, as you become a veg developer, as you write more code, as you create more projects, this will be a super
valuable feature. Now, when should you use it? Basically here, the
official GTA documentation gives us three answers. You can use it in
only certain scripts that maybe are a
little bit complex. So static typing can help with
the advantages mentioned, the texting errors beforehand, making your code clearer, et cetera, improving
or completion. So you can choose to only use it in more advanced script or just in scripts
that you feel like static typing would
be something useful. You can use it in every single script
throughout the project, as we are going to be
doing in this course so that you are able
to actually learn it, or you can never
use it actually. The decision is up to you. It is not something
mandatory that you must use in every single script
in every single GA project. However, developers
tend to use it because it really helps a lot while
you're creating your games. And as you have seen already, it is not that
difficult to implement. So that's why you should
really consider it. Now, how to exactly
use static typing. We have seen a little bit of it. We write a column
after the named, followed by the type,
as we have seen, we had ready var colon sorry, ready, var, animated sprite, colon, animated sprite two. So for example here, we have
some example Bar lives, colon, int equals three. We also have here an example with a constant, in
this case, speed. And also in constant, it is stated in the GDScript style guide
that it is not something that you must do because
the value never changes. So it's something that maybe
you don't really need. You can, if you want
it in this course, I am not going to be doing
that because I think that it does make the
code a little bit untidy. But, well, you can still
use it if you think that it makes the code
a little bit clearer. And for example
here in a function, we can see it in both function
parameters over here, something quite similar
to what we have seen in previous lessons. And also, for example
here, the return type, we have set it to return
a float because here we return A plus B and
both are float numbers. As a result, what
type of value is our screen size that we
could type in right here? Some ways of knowing
this when this could be a bit complicated is to hold down the control key and per example here,
get viewport wreck. For example, right here, get viewport red
returns erect to type. These words over here, let me enable my mouse
here quite quickly. This word right here basically
means what it returns. So we can actually control
and click on size. And in this case, as
you can see, size returns a vector too. And also we have seen that
when printing the message, this print is
something like 1,500, okay, or something
like that, exactly these values over here. So, indeed, this
is a vector, too. Now, also in the
physics process, you may have seen this a
colon and an equals without statically typing the value of the direction variable
in this case. Once again, coming back to
the DScript style guide, this is an inferred type. This basically we
don't statically type the type of the variable, and we basically let
go that inferred based on the value
that we are providing. And as it is stated
here, in most cases, you can let the compiler
infer the type. But we have to take into
account some things. For example, here, a variable is defined an integer
because health can sometimes depending
on the exact game. It can be both an integer and
a float or a float sorry. So that's why they are
statically typing it here as an integer,
and that is okay. But here, in a vector three, they are basically using
inferred types because if not, this would look like
this, and it is like, maybe a little bit repeating itself two times vector three. So right here, technically, it is doing a good
job here inferring the type because remember that this input dot get
access move left move right, return minus one, zero
or one, based in input. So it will be able to
infer the type correctly. But you could, if
you really want it to just type it in like this. It will work exactly the same, but I will just leave
the example code that was provided
in the template. And well, actually, if we do so, here float is converted to
int and loses precision. So just to avoid any
kind of problem, we could make this float and every warning
would disappear, and the code would work the
exacta the exact same way. But I personally
prefer to static type most things because
it is just a way of not overcomplicating
ourselves more. And also, because I believe
that it really helps when you have the
type over there of the variable just for
clarity in the code. And by the way,
for example, here, we should do it like
this and not like this. Because basically it
gets perect dot size, maybe it is a little bit ambiguous if this
is a vector two, a vector three, an
integer or word. And we also don't see
the vector word here. So that's why it is
worth putting it here. So this is all for this lesson, and I will see you
in the next one.
19. Animating The Player: Hi there and welcome
to a new lesson. In this one, I want
to actually get into coding the player animations. So in order to do this, we have to take into
account a lot of things. Remember the different
animations that we have them. And when implementing this, we first have to think of when we should be playing
the different ones. For example, when
should we be playing the walking animation
if we are moving? And how do we detect
so in the game itself? Basically, if direction,
um is different from zero. If direction is zero, it means that we are not moving. If it is minus one, we are moving to the left. If it is one, we are
moving to the right. So that's it for the work. If it is the other animation, then it must be that our
player is not moving, so direction is zero and fall, it must be if the player
is not on the floor. And remember this is
something that is provided by the character body today
if not, it's on floor. So considering all this, we can indeed code
our animation. Now, we could
technically just code it here directly in our
physics process, but this would make the
code a little bit untidy. That is why I will create a
specific function for this. So I will create my
function over here. And if you find that you
can't scroll like correctly, go to editor settings, and then you have to scroll down a little
bit until finding text editor behavior and enable
scroll past ends of file. So now you are going to to
scroll a little bit more. So once again, make
sure that you're living two lines to follow the
GD Script style guide. And I will declare
this function. This is going to be
a custom function. Remember that the physics
process is a built in function that GDA provided as we have seen
a couple of lessons ago. So now, I'm going to call this function underscore,
update, underscore, animation. Okay. And this will return
boy, basically nothing. I will put the column
and basically pass. Pass would allow me here
to compile the code without any kind of error because if I do not
write anything, well, good wouldn't allow me
to actually run the project. And something that
you may be wondering why I have put here
an underscore here, shouldn't it be named
like something like this? As I have explained
multiple times, the idea of this course
is that they are also able to write clean code, following the official
GDScript style guide. And over here, they say
that you have to define the function names
differently depending on something that will explain just a second, just in a second. So let me scroll a little bit. In this specific
section functions and variables, here
they see the following. We have to put a
single underscore to virtual method functions. They use must overwrite private functions and
private variables. I am not going to dig
deeper into virtual method. But for example, this
is the reason why physics process also ready, they come here with an
underscore because they are virtual methods
that we overwrite. Basically, the virtual method is the technical term for
built in functions, okay? So what is exactly then a
private and a public function. So let's see this.
First of all, public, these are meant to be
accessed in other script. If you declare a
function as public, that function is going to be
called in another script. But private, they aren't meant to be accessed
in other script. If you declare a function as
a private in, for example, the player script,
then I don't know, the vehicle script shouldn't be calling that function
or access in it. And as we have just seen, an underscore is added. For example, underscore
updates underscore animation, as we have seen a second ago. And why I am telling you here aren't meant to be
accessed in other script, because actually GODed, all functions can be accessed
in every single script. Even if you, let's say, declare a function as private, any other script or would be able to have access to that function that is
meant to be private. I am making sure that they understand this because in
other programming languages, if you declare a
function as private, you are not able to access
it outside of that script. But in GOD I GODOT let's say
that everything is public, and this is just a good practice to make the code a
little bit clearer. And now for variables, it is the exact same
thing as in functions. So basically, public variables are meant to be accessed
in other scripts, unlike private that aren't meant to be accessed
in other scripts. Once again, an
underscore is solid, for example, under score. And once again, why meant, I am telling you over here? Because all variables can be accessed in every single script. They are all public. So this difference
just has to do with clarity and in order to
write good clean code. And if we also take a look
at the code order again, here we can see some stuff. Besides what we have
already discussed about constants and already
variables that firstly, constants come and then
already variables. You can see here the order in which we should be
writing our methods. First of all, have an optional built in virtual it method. For example, we have a built in virtual ready method and the remaining built in
virtual method. Let's do not focus on
nits and Enter three. Let's say that just
for you to understand, they are quite similar to ready, but nits is the
first one called, then secondly Enter t is called, and lastly, ready is called. So let's say that
they are similar. And the remaining built
in virtual methods are the other ones that
are also built in, for example, a physics process. And below that, you should
write your public methods, and below your public methods, you should write
your private ones. So following this, yeah, you have physics process, but if I wanted to add
the ready function, I will not add it over here. I will have to add it over here. So I would do funk ready, and let me just do pass. Over here. So I first
have my ready, okay? So I am over here. Then the remaining built
in virtual method, this is my physics process. Then I will have any public
methods, if any, lastly, my private update animation function that is
with an underscore. And in reality, I could
add here another function. For example, I don't
know, player move player. I'm just doing here an example. And of course, as this
is a public function, I should not name it like this. If I want it to
actually be public, I had to write it without
the underscore that I have. So once again, to wrap it up, we have the ready method over here below
our ready method. We have the remaining
built embers on method, basically the physics process. And then we have here my move
a player that is public, last I have my updates, animation that is private. Now, let me just clean
up this to only have the code that I'm actually going to be using at least for now. Let me call now this
updates animation over here after moving. And here the god
is quite simple. If I am not in the floor, I am going to play. So animated sprint play
fall as simple as that. If I am not in the
floor, I will always be falling so I have to
play that animation. And then I need to play the walk animation
when I am moving. So I must have here the direction that is a
float, as we have seen. So I must have access
to this direction, so I can just pass it over here. And by doing this, I have
access to this variable that only used to exist inside
of this physics process. Because if I didn't do
it like this and I just wanted to access this
direction, okay? I would that direction
doesn't exist. Let me show you this. And also, let me delete this from here. And as you can see, it tells me that direction is
not declared in the current scope
because it is declared inside of the physics
process scope. So I will provide it once again. So what I will do over
here is F. Basically, if this isn't true and direction is different from zero, this means different. What I will do is to
play my work animation because if I am on the floor
and direction is not zero, which means that I am moving, I should play the
work animation. And if any of this is true, I should play my idle animation. And as you can see, this
is the result that we get
20. Flipping The Player: Hi there, and welcome
to a new lesson. In this one, we are going
to be flipping the player. Because right now, what
happens is that indeed, we do have the correct
animations playing. But you can see if I
am moving to the left, my player is not like flipping. It looks quite
weird. To do this, there is a pretty
handy option in the animated sprint
in the upset. That is basically flip
edge or flip horizontally. So this will
basically allow us to flip the player when
we actually need to. So to start with this, I will basically teach
you two approaches. One is, like, the easiest
one to understand, but it is a little bit longer. And the second one that I
would show is the shortest, but it may be it more complicated to understand
how it exactly works. So I will teach you both so
that you can understand them, and hopefully you can implement the second approach because it will make your code a
little bit shorter. So over here before actually
moving, okay, so over here, I also note how I am
dividing and leaving one empty line between different I wouldn't call
them sanctions in the code, but between functionalities,
because for cam here, okay, Mu and slide,
then animate. And over here, I
am doing something completely different
like clamping. And right here, I'm going
to be flipping my sprite. So I'm trying to get
things organized. So remember that everything here has to do with our direction. Remember, if direction is one, we are moving to the right. If direction is minus one, we are going to be
moving to the left. And when we flip when
we abl this option, it means that we are
moving to the left. So considering all this, we can simply do okay, if our
direction is equal to one, which basically means that
we are moving to the right, we shouldn't be with this option turned on because we are
moving to the right. So I should do animated sprint
dot Flipg equals false. Okay? By the way, I am using two symbols over here instead of one,
for example, here, because two of them are
used to do a comparison, and one of them is just to
assign something such as here, here, et cetera, just
for you to know that. And by the way, if you only use one it is going to return error because here you are telling
Godot I direction is one, but you are telling here good if and then assigned
direction equal to one. So that's not something
that makes sense. And then what we can do is
if direction is not one, or I believe that
maybe we should write is directly equal to minus one because different from
one would also be zero. Basically, if we are not moving. So if we are moving to the left, simply do flip it, okay? And this would technically work, and the code is clean is
something quite understandable, but there is a way of
writing this shorter. So let me delete all these, and I will write the following. I will make my
animated spread of flip H equals to direction. Equals minus one. So we'll basically just come
back to the previous code, okay, and I will comment it out using the hashtag so
that we can see it better. And I will write here
the exact same thing. So when I mean write up, flip H equals direction, equals equals minus one, so that we can understand
what is happening here. Um, basically, when are we
assigning flip H to be true? When direction is
equal to minus one? That is exactly what
we are doing here. This expression right
here is going to be evaluated as our
game is running. So here it will say, I direction equal to minus one? If it is, it's going
to return true. Okay? So this is
going to be flipped. Now, if our direction
is not minus one, it will basically return faults. To as you can see, it
is exact same way as writing four lines
of code in just one. So I will just erase this four. Our code is even shorter. And when we play,
you will see that the result that we get
is the exact same one, but just that now
it is much shorter.
21. Adding A Background: By there, in this lesson, we're going to be
adding a background. So I'm going to go to the environment and
add a new scene. In this case, we're
going to using a node that we
haven't seen before. That is the parallax
to the node. Right now, in the version
that I'm using that is 4.45. This is marked as experimental. If you are using 4.4
stable version or even 4.5 or even another version that has been
released after 4.45, it could be that now it is not anymore marked as experimental, but right now, it
works quite well, even if you are using
it just like this. So don't worry about that. And I'm going to rename
it to background. Let's save it to a
corresponding sins folder. And why have we added
this for a background? If we take a look at
our background image, I would just quickly drag
and drop it over here. Well, what I want to do is that instead of just
like scaling it in, I will lock its ratio so that
it is scaled in properly. I could do just
something like this, and this would definitely work as some kind of background. But not only do I want this, but also to create a
noto scroll effect. So that's why we had to
do some extra steps. So actually, I have
here my sprite, but I will delete it
and add it manually, Sprite today, and I will
quick load the background. There we have it.
So first of all, in order to do this, I want
to scale down a little bit the background because
I feel that it is a little bit too big. So I will make
something like 0.75. So now it is a
little bit smaller. And how this work is that I have the repeat
option over here. And I will firstly just
move it down a little bit. So I found that
something in the Y of 295 will just work fine. And also, we need over
here a repeat size. If I put here
something like 100, okay or male more 500, you will see indeed we have
now two backgrounds, okay? So this is how this
is usually done is that you put your sprite size over here so that it is infinitely repeated
repeated, sorry. So you may think that
you can use here the dimensions of
the sprite, 1024. So if we put this
inside of here, well, what happens here,
we have more space. Why? Because we have scaled
down our sprite. But if I put it back to one, as you can see,
it looks correct. But because we have
scaled it down a little bit to have to do some
extra calculations. So we basically need this
value minus one quarter of it. Why one quarter or 0.25 because that's the amount that we have subtracted
from the scale. So 124 -101,024 times 0.25. So there we have it. And now we can also set
an auto scroll speed. We only want to move in the X. That's why also, I
haven't put this in the Y because we are not
going to be needing this. So in the auto scroll speed, I will put something like -500. And if we were to run
this scene like this, it will not work exactly as expected because we only
have two backgrounds, so they are going to
scroll like something like this and then return
to the same place. But, well, we don't
have enough background. So we can increase repeats
times to something like three, so we will just have
more background. And then as you can see, it
is going to work as intended. As you can see,
like, the repetition is not even noticed by the player because we have done everything
mathematically exactly. Now, let's save the scene, go back to the main one, and I will instantiate it, basically, add it over
here. So there we have it. And now I will drag and drop it at the bottom
of everything. Because remember, Godot
first, in this case, we drop the background
on top of it, the rod and on top
of it, the player. If I put it right here, the Goats will draw Firstly, the rod, then the player,
then the background. We don't want that. So this
is how it should be working. And if we play the scene, this is what we currently see, well, it is quite, quite good the result that
we are getting. We can even just
maximize the screen, and indeed we can't
actually spot any weird thing that has to do with the background
being repeated infinitely.
22. Score UI: Hi there, and welcome
to a new lesson. In this one, we
are going to start creating the SCOR system. Firstly, in this lesson, we'll
create the user interface, and in the following, we'll actually create
the SCOR system. So to begin with this and to
keep everything organized, I will create a brand new scene. And in this case, the
node that I want to create as a root node
is a canvas layer. Why a canvas layer? Because usually user interfaces must be displayed on
top of everything. So it should be displayed
on top of the background on top of the layer on
top of anything else. So even though, as
we have learned, Godot draw things
from the top to the bottom in the
hierarchy, I mean, um, just basically,
with this canvas layer, we make sure that anything
that we put inside of here will always be on
top of anything else. So this is usually used for when we want to
create some kind of UI. So I will rename
this to just UI, which stands for user interface, and I will save it
inside of my sins. The score that I want to
display here is quite simple. I just want to I just
want it to be a number. So in order to display text, I will select the UI node, and here we add a label. That C is just used
for displaying text. I will rename it
to square label. And as an example,
I will just write here zero so that
we can at least, see the actual text font
and start modifying it. The first thing that I
will notice is that if I change the size of the box, its alignment doesn't change, so I'll make sure that it
is put in the exact center. Then it is, like, super small, so we have to create a new label settings over
here and we open it up. And this will basically allow
us to modify this label. We have the font, for example, so I will quick load
the font that we have downloaded at the
beginning of the course. And I will make it much bigger. Something like 75 pixels. Now, I will just make this
box a little bit smaller, something like this, because
it doesn't there is no use. There is no point in actually
making the box so big. And with the anchors
press, you can actually, position it wherever you want, but I will put it
in the center top. And from here, I want to
move it down a little bit. You can do it just using here the move tool and
with a green arrow, drag it down a little bit. But I want to go to layout
transform and in position, you can do this
exact same thing, but a little bit
more accurately. So something like 32 maybe. Um, so there we have exactly 32 pixels from the
top of the screen. Now, if we were to just
do this like this, and I will incentiate
here the UI, and you will see that
if it is here, here, or wherever it is, it is always going to be on
top of everything. As you can see, we can't really see the text, like,
super clearly. Clearly. So a great way of
making sure that we can see our text properly is using
outlines and shadows. Basically, the
outline if we were to know here a black outline and make it five pixels,
there we have the outline. And you can see now it
does look much better, but I tend to avoid using outlines because I don't like
the effect that they give. On the other hand, I tend to use shadow, it's a little more. So, for example, you
can give it here a size of five pixels. You can increase the opacity
to something like 130. And in the upset, you can give something like
three and three. Okay? So now there
are a nice shadow, and this looks
gorgeous in the game, as you can see,
because it's not like, super solid as the outline, and it does look quite, quite good and actually help us differentiate the
background from the UI. So that's what we
want after all. So with this, you have
learned something quite basic of how to create user
interfaces in GDA. We also create more user interfaces
throughout the course, but this is the first one,
so congratulations on that. And I will see you
in the next lesson in which we are
going to actually to actually be modifying our score. So I
will see you there.
23. Score System: Right there, and in this lesson, we're going to actually be
creating the score system. So to begin with this, I
will go to the main scene, and how I want this
to work is that basically every second
my score goes up. So the easiest and most straightforward of doing this
is to select my main node. And over here, I
will add a timer, and it basically a timer. So I will call it, in
this case, SCOR timer. And we have the wait
time that in this case, 1 second is correct. I have one shot this
basically determines if the timer will
only count once, and once it counted once, it will not count anymore. Another start will determine if the timer starts as soon
as the game is launched. So we want to start counting our score as
soon as we start playing. So that's why we're going
to be enabling that. Now, I'm going to be writing my score system inside
of my main scene. Why? Because then when I
have increased my score, I also want to modify this
score level text, of course. So the most straightful the ECS and most accessible way
of doing this is going to just write this
in the main node. So I will create this script
inside of my scripts folder. And here we have a
brand new script. In case if some kind of functions comments and
motaff was created, just delite that we are not
going to be using that. And then I'm going to select
my square timer, go to node. And here we can connect
the time out signal and make sure that we are
connecting it to the main node. So basically, when
every 1 second, this function is
going to be called, to give an example, I will
print scord actually, for example, and I will play. And we see that every 1 second, I'm getting here this
message in the console, so everything is working nice. And by the way, if
when you connected, this signal, you didn't
get this void over here, make sure that you add it. And, for example, when you
write the ready function, the physics process or more functions and you don't
get these auto completions, make sure that you go to Editor settings and you
look for type hint, and you should be able
to find this action, add type hints and that
it should be turned on. Make sure that if
you do not find it, make sure that you have
advanced settings on. So now that we have this, I must have a reference, a value that will determine how much score
do I have right now? And so I will create it
in a variable because, of course, its value is
going to be changing. It is not going to be constant. So that's why I
am defining it as a variable and not
as a constant. And it is also going
to be private. So it will only be
accessed in this script. That's why I will
start this name with underscorR and I
will call it SCR. This is going to be an integer, and initially, it will
just have a value of zero. Let's leave two empty lines over there to follow the
GDScript style guide. And then I will just
increase score by one. So score plus equal one means add one to the current score. And then I need to update
the text of this UI Canvas. But how do I access this node if it is in
a different scene? So I will right click here
and do Editable children. So now I have access to this, and I can drag it over
here, hold down Control. Drop it, and as
you can see there, I have the reference
to the score label. Now, you can technically just
turn off editable children. Okay, and this reference
would still work. But I believe that if
you're actually accessing a child in here, you should just leave the
editable children in case you need any other reference
because in the future, um we will have to have
more references to our inside of components of the UI scene, such
as, for example, when we create the coins label to know how many coins we
have collected so far, we'll have another quite
similar score label but called coins label. So we'll also have to drag
and drop it inside of here, and I can't drag and drop it if this is not said to
editable children. So that's why I encourage
you to leave this like this. It's not going to have any
kind of negative effect. So now that we have this, let's actually update its text. So to do this, you do
score label the text, and you set it to
whatever you want. So I will set it to score. And if I do this, I
would have one problem. And this is detected beforehand thanks to static typing
the score variable. If I put it like this,
it will not be detected because God is not able to tell what type of
variable this is. And in order to modify
the text of a label, in GoDa it must be a string, and here it is an integer. So that's why it is
returning here and error. So to convert an
integer into a string, we just write STR, and there we have this. So now when we start playing, there we have our square
timer working correctly.
24. Vehicle Scene: Hi there and welcome
to a new lesson. In this one, we are going to be creating the vehicle
scene because, well, so far we have added
the score system, the player itself,
and more staff. But, well, we don't really have an obstacle to dodge
or anything like that. So I think it's a
great moment for us to start creating this vehicle. So once again, let's
add a brand new scene. I will actually just
close these ones because it is getting
a little bit messy. And I will start off
with other type of node. In this case, I'm going to
use in an area two D. Why? Because let's super
quickly go over the different collision objects and physics bodies that we have. The static bodies can't be
moved by external forces. So for example, we
use this one for the road because it was
always on the same place. The character body,
we used it for the player because we were
moving it with the scripts, and it also provided us with
a template in order to move. The rigid body, we're
not going to be using it for our course. And this mostly has
to do with physics. And are we going to using
physics in our vehicle? No, we aren't so the absorption
here would be the area. And this type of
node is quite useful because it allows us to detect
collisions super easily. And let me show you
this. Quite similarly to what we have in
the timer of signals, remember that in order
to use the timer, we cancit its timeout signal. The area today has
area enter area exit, body enter, body exiting signals to allow us to
detect collisions. And in reality, if you take a look at the player scene
that has a character body, this doesn't have any
of that kind of method. So without the vehicles
being an area two, it would be a little bit more complicated to detect
the collisions. That's why we are using
this type of node. So let's rename it to vehicle, and I will save it over
there on my scenes. Now, let me over here a sprite and also
a collision shape. And if we take a
look at the sprites, we have a lot of them, but I will just
use, for example, this one, and then
we'll actually be changing them in a
second randomly, okay? First of all, you can see
that this is a blurry. This is something that we
have dealt with before. So we can basically go to
the sprites and on texture, we change the filter to nearest
and that error is gone. And also, it is a
little bit small, so I will scale it into
something like six. So now as you can see,
it is much, much bigger. Now, also, all these vehicles
are looking to the right, but actually our vehicles will move to right to left
exactly like this. And as you can see, it would
look a little bit weird. So that's why we have
to enable over here flip Ho so that it will always look correctly
as it should. Now, next, we have to add
a new collision shape. I will use just a rectangle
because I think that it will match most of our vehicle
sizes quite correctly. So maybe something like this, it will be enough. If you want, you can
quickly go and adjust it if you want it in order
to fit more vehicles. But I think that
with this shape, it is going to be more than
enough for most of them. Maybe we can make it
a little bit bigger. Okay? Maybe something
like this would work, because there are some of them that are a
little bit larger. But yeah, something
like this, it's going to be more than enough. Now, I want to randomly modify, as I was telling you the vehicle that is going to be spun. Because not having always
like the same, for example, the same borring green car, it wouldn't be like
the best thing, because if they are
always the same, it will be a little bit boring. So to avoid that, let's
add here a script. I will say it inside
of the scripts folder. And also by the
way, make sure that you just disable here template. We are not going to be
using them anymore, so that we just create
a brand new script. And for this, we are going
to be seeing firstly a new annotation that is called the export annotation, Export. This annotation will allow us to set the value of a variable
directly in the inspector. For example, I will create here a score variable
that is going to be an integer and this
will now when I save the script appear
in the inspector. So I can say it to No 40, and I am setting it
directly in the inspector. By the way, the value
that you set over here will override the value
that you have in the code. So if I play the
game and I check what the value of the score is, it is not going to be zero. It is going to be 40 because
I have overridden over here. So what I want to do
over here is to have a reference to all
these sprites, and then I will choose randomly. So this is going to
be a variable as well that we call vehicles. Vgles exactly like that, but this is going to be of type array and it's in square
brackets, texture two D. Let me explain this.
First, an array if we control and
click it over here. This is basically a data
structure that holds a sequence of elements of any
elements that we want that we specify here. In this case, texture
two D because it is the type that
here it is requested. Right here, there is a glitch in the version that I am using, but here you should be able to read texture two D. That is
the data type that we need. That's why I am putting the texture to the so
for example, here, they have an array with
some strings and integers, and if they print
the first index of it, first is printed. If they print index two, they print three because
the count starts at zero. So first is zero, two is one, three is two. Last is zero, one, two, three is a third one. So we are basically storing
all of our vehicles actually all of our textures
inside of just one place. So what I'm going
to do is to just select all of my vehicles. I will first select the
first one, hold down shift, and click on the last one, and I will drag and
drop them over there. And as well as I
have all of them. And now I just have to
select one of them randomly. In order to do this, I will need to have access
to my sprite so I will drag it and now
drop it over here holding down control, okay? And I will just call it sprite, not Sprite two D. If we follow
the GD Script style guide, first, we have export variables
and then ready variables. So that is correct. This
shouldn't be like this, like this is the correct way. And now I will
leave two emt lines and call my ready function, basically, the one
that is called as soon as we start playing. And I will need to
select a random texture for my vehicle from this array. So I will call it
random texture. This is going to be
a type texture duty because it is the same
type of my array. And this is a method
quite handy that arrays have that is basically
vehicles dot pick random. Okay? It will basically do that. We have an array
with eight items. I will pick one randomly. So once we have that, we can basically do
sprite dot texture that is basically this
parameter over here. Let me find it. Over here, this is this parameter, and I will basically
make this equal to the random texture that
we have just assigned. Now, what this will
do is that if I play, you will see that for example
here, have the red card. If I play again, I should have a different one, the green card. It could be that sometimes
they are repeats as you can see that we
have a green one again, green one again, but
well in the game, we're going to spawning a
lot of them there we have. This is the tax, I believe, yes. So, indeed, everything is
being randomized as it should.
25. Spawning Vehicle: Hi there and welcome
to a new video. In this one, we'll actually be spawning the vehicles, okay. So first of all, I will
go to the vehicle script, and I will leave it to
empty lines over here, and I will create the
process Delta function. I'm going to using the
process Delta function that is quite similar
to the physics process. But the difference is that well, physics process is meant to be used for when
you want to do some kind of physics related
calculations such as here. But, our vehicle is not
going to using physics. That's why just using
process is going to be the best choice. But they are quite,
quite similar. So in order to do this, the only thing that I
want to do in this case, is to just move my vehicle
basically to the right. So for example, I spawn
here a vehicle, okay, and we spa them outside of the screen
so the player is not able to see the
vehicle coming and I just want to continuously
move it to the left. So in order to do this,
it is quite simple. We just have to do
position dot X, and I'm going to subtract, Okay, to the current position
X. Delta times 500.0. This, once again, we
already discussed Delta. This will make sure that
our speed is constant. I will just write it like this. It is not a good practice
to put they are called magic numbers numbers that they come from
nowhere in the code. We should start
this in a constant. But for example, if we
go to the background, over here, we can see that the autoscroll
speed is also 500. The reality is that
in a future lesson, we're going to be making
sure that by code, all these values are the
exact same ones because if our vehicles are moving faster than the background
or the other way around, the effect that it will
cause is quite crazy. It is super confusing. It can even make people
feel list bit dizzy. So that's why at
least for this game, we will keep most of the
speeds quite constant, okay? But, just for you to know, you should always avoid
using magic numbers. I'm just going to be doing
this because it's something temporal that's going to
be changed quite soon. But well, when we do so, I will just manually instantiate here one vehicle so that
we can see it coming. And when we do so there
we have the effect. And for example, let
me make this vehicle, something I know, 100, so you can see what I mean. Now, if this is, as you can see, slower, it doesn't look correct. It looks quite weird. And if we are moving also, it looks even worse. So that's why I'm making
the exact same speed. Now, in order to
spa our vehicles, I am once again
going to be using a timer that I'm going
to add right over here, and I'm going to
call it spanerTr. I will select both nodes. Basically select this one, hold down Control and
select this one. Then I will right click here, and I will reparnt
to a new node. In this case, it will be just a white node, let's call it. And I will call
this node timers, so that everything
is nicely organized, and I will delete UI
this vehicle over there. And this spanner timer, I will spawn a new vehicle
every 2.5 seconds, and I will enable
other start as well. I am leaving one shot
disabled because I want to always be starting
this timer again. And with this, we do
have our timer setup. We are going to be
needing two more things. I will add a nod to the, and I will call it
via Hills container. Here, this is the
node in which we are going to be instantiating
the vehicles just to keep everything nicely organized and also
sorted correctly. Because this is going to be like over here on top of the player. We want to make sure that our vehicles are on
top of the player. But then, for example, we'll
also add some decorations, so we want to make sure that our decoration is span
on top of the vehicle. So we would have a different
container over here. And as this container would be on top of the
vehicle's container, it would be rendered on
top of the vehicles. But, that is
something that we'll worry about in the future. But for now, let's just
create this container. And lastly, I will create a marker This is basically
a node that has a gizmo, as you can see, and it's a
little bit easier to see. So I will basically position it. I actually have here the exact positioning
where I want it, so you can basically
copy here these values. So this is going to
be at the bottom. Okay, right over here
is where we're going to be spawning our vehicles, and I will call
this one spa point. And well, here, I will
just sort it over here. Also take a look at the
order that I'm having over here just to keep
things nice and clean. So let's connect here
in the spun timer, the timeout signal to
the main script. Okay. And here we have this.
So first of all, we need a reference to our vehicle scene in order
to actually instantiate it. So I will create here
the export variable. I am writing it over here because according to
JScript style guide, first, they go export variables, then private variables,
and then ready variable. So I am basically
following that rule. We have already seen
the export annotation. This basically allow us to set the value of a variable
through the inspector. And I'm going to
call it vehicle ten. And this is going to
be of type packed so basically a sin
that we are able to load in and then instantiate. And we also need a reference
to a vehicle's container. So we'll drag and
drop it over here, and when I drop it, remember
to hold down control. And I will also drag and drop a reference
to my spawn point. Now I will follow
here the code order. So the score label will come at the end and first the
vehicle's container, then spawn point and lastly
score label, so that is okay. And over here, I have
to instantiate this. So the first thing I have to do is to create the instance. So variable vehicle instance, this is going to type area two since our root node of the
vehicle is an area ti. This is going to be equal to
vehicle SN dot instantiate. So basically, now this
exists in the scene, but then we have to
add it as a child. So I will grab my vehicles
container dot a child, and I will add this
vehicles vehicle instance and make sure that
the writing here vehicle instance are
not vehicle seen. And lastly, we have to actually set the vehicle
incense position. So vehicle Iscens dot position, and I want to make
this sequel to the spawn points position
that I've just created. So to make things clear, when the sponer
timer is time out, I create the instance of
the vehicle instance. And to do this, I call vehicle
scene dot instantiate. This creates the actual instant. It is basically
added to the scene, but it is not yet added
inside of the scene. It's like, let's call it preloaded or existing
like in the air, but it doesn't have a parent. So in this case, we want to
make sure that it is added inside of this vehicle
container that we had created. And once it actually
exists in the game, we want to set its position
to spawn point position. Basically, a point that
the player can see. Now we also have to set
this vehicle scene. So we go to the main. We have vehicle
scene, quick load, vehicle, and there we have it. Now, here we have it.
There we have a red car. We should have here
another one blue. We have another one
blue, but I think that blue is actually different. We have the taxi,
another yellow car. But you go to see
like the jump is not working like as it
should because we have, I believe too much
gravity First of all, let me change here
the jump velocity, something like -900 and
here the speed to 500. Once again, I will
then change this 500 because it is the same speed that our vehicles have and the same speed that our
background has over here, and I will go to project project settings and
in physics study, I will also modify
the default gravity to something like 1,800. And now this is the
result that we get. As you can see, it is a much
smoother player movement. We are able to jump on top of the cars where everything
is working as it should.
26. Singletons (Autoload): Hi there and welcome
to a new lesson. In this one, we are going to
be talking about singletons. Why? Because what we need to
do is to have some kind of speed that can be shared by every single
node that has to move. For example, we have the
vehicle whose speed is 500. We have the player
whose speed is 500 and we'll also have more
stuff as the project grows that we need to
have some kind of speed, for example, the coin, the decorations, et cetera. So in reality, we
could definitely just in every single thing
that I've just mentioned, have the constant of speed, 500 and that would work. But the problem is that we want our game to have some kind
of progression, okay? So we are going to be modifying
the speed of our player, coins, background, et
cetera, as time goes by. So that's why we need, like, something like a
global reference to a speed variable that every single node in the
game can access globally. And this is when
singletons or or load take a vital role,
play a vital role. So its formal definition
is basically that it is a design pattern that is useful to store persistent
information between scenes. And I believe that the
key part is over here, store persistent
information between scenes. As I've just mentioned, the idea is that we have something like
a global reference, a global value in this case, speed that we can use wherever we need in
the background scene, in the going scene,
the vehicle scene, in the player scene, et cetera. So that's why it's going to store information
between scenes, okay, that's going
to be persistent. They are automatically loaded or insentiated as soon
as the game starts. So if you define
something as an oro load, it's going to be
insentiated, initialized, loaded as soon as the game
starts in the first scene. And they are pretty useful to exactly what we're going
to be doing right now. For example, to store
global variables that can be accessed
easily in any scene. We're going to seeing how
easy it is also to both implement this design
pattern and to also access the data that
we have inside of it. And they are also useful
to persist between scenes. This is something that
we're going to see at the end of the project,
in order to, for example, be able to play music
in every game scene without cutting
it in the middle. So we want to always be playing the music in spite of
changing the scene. But, that's something
that we'll have to worry about in a
couple of lessons. And they are also super useful for handling scene transitions. Of course, there are
much more usages, but these are the ones that
they are usually used for, and they are the ones that we are going to be
seeing in the course. Now, you can
autoload two things. You can autoload basically script what we're going
to be doing right now, which would be the first usage to store something globally. But you can also
autoload scenes. And this is useful, for example, when you want to persist
some stuff between scenes, for example, in disgrace
to play the music. Well, that music
note we want it to persist throughout
the different scenes. So let's actually
see this in GORE because it is even
easier than it seems. So for this, I'm going to create a new script on
my script folder, and I'm not going to
attach it to actually any node because I just want to overload this script itself. So I'm going to right click in the scripts folder,
create new script. This script tends to have
the name of global, okay? Because it's quite descriptive. So I'm just going
to name it Global. And now we have it, okay? By default, this is
going to extend node. And if we take a look at what
node is, as you can see, it is the node, the parent node of every
single node that we see, okay? So it's the parents
of everything. It's the base class
for all seen objects, actually, we can see
that the definition. And actually, when you
auto load a script, then in the hierarchy, it is just going to be
attached to a node. So when we actually
auto load this, what is going to happen is
that GoDa will add a node, and it will attach this global
script to that node, okay? But, that's just for you to
know how this exactly works. Now, for this node, I'm going to be having just
literally two lines. I'm going to have a constant that I will call default spill, and this is going
to be 260, okay? And then I will also
have the actual speed that is going to be a variable, and this one is the
one that will change as the game is played. So this is going to be a float, and this is going
to be initially equal to default speed, okay? Why am I doing this like this? This is going to make much
more sense in future lessons. But, for example, when
we reset the game, we need to reset the speed
because as I was telling you, the speed is going
to be changing. So when we restart the game, we have to make sure
that our speed is reset. So basically, we would make a speed equal to
the default speed, basically resetting its value. Now we have to actually start
using this speed value. So let's take a look at where
we were using this value. In the main, we weren't until right now and in the
player, we were. So for example
here, we were doing direction times speed
times this speed constant. But what I will
do is that I want my player to move a little bit faster than the speed that
I have defined over here. So I will call this constant
extra speed like this. And I believe that
I will move it right over here because
the jump velocity is a little more important than this extra speed because
it isn't the actual speed. It is the extra spear. So most important things
should come first, okay? And the extra spear,
I will make it 120. Now I want to access my global speed that I
have defined over here. So how do we do
so? First, we have to go to Project
Project Settings. And here we find this
section over here, globals and we have
here Auto load. So we can browse here, and we can auto load basically
here our global script. We click Add, Okay, and there we go. Now, once we have done this what we can
do here in direction, I can basically just multiply by global like this dot speed. And as you can see
that error is gone, and why Global
exactly like this? Because here the name is global. You can actually change it, but let's leave the default one. And I also want to
add this extra speed, so I will do some basic
math calculation, and I will add to this
speed the extra speed. Now, we don't have here anymore this speed when
we are deaccelerating, so let's just access
this speed once again. Now, another place
where we are using this speed is in the vehicle. So in this case,
let's just multiply this via global dot speed. Now this is a result that
we are going to be getting. Ac, it looks a little weird because the background
is moving a little bit faster because we haven't modified the auto scroll
spit that it has over here. So let's attach a script to it, and let's make sure that this is saved inside of the
scripts folder. And what I will do I will leave two empty lines
because remember that functions should always have two lines above,
two lines below. And what I will basically do
is to modify my auto scroll dot X. I would make it equal
to minus global dot speed. Why minus because we're
moving to the left, that is a negative value, and our speed is defined
as a positive value, so that's why we make it minus. So now let's play
again and we should see defect, working
as it should. As you can see, the player
does more a little faster. So that's the effect
that in my case, I want. That's why I added
that extra speed, but the rest works quite well. And also another advantage
of doing this is that you can at anytime
make this much faster. Let's say that now
your default speed, you want it to be an 0400. So let's make it 400. So now you can see,
everything is much faster or you can even go
crazier and do 4,000. And now it's going to
be even faster, okay? So there you have it. So but let's just make
sure that this is to 260. With this, this is done.
27. Game Over UI: Hello, there. In this lesson, we are going to be
creating the game over UI. So to start with this, I
will open up the UI scene. Okay? And I will add
new nodes over here. So first of all, I will
select the UI node, and I will add a control node. As you can see,
this is the parent for every single node that has to do with user
interfaces, because basically, I just want to be
a container for our game over because
we're going to be hiding this and we'll only show this game over node when
the game is actually over, so that's why I need to create, like, a division for it. And inside of this
game over is where I'm going to be adding
the different nodes. So first of all, by the way, remember that with Control A, you can quickly add a node to the current one
that you have selected. So first of all, I
will use here a color wrecked that is basically
a rectangle color. So I could change here the anchors present
to be full wrecked, so it should occupy
the entire screen. But as you can see,
that's not happening. That's because our
gamewareParent, doesn't have its
size set correctly. So let's just make
this also full wrecked so that now it
will cover all the screen. Let me call this one background, and I will change its color
to be completely black. And you can change the
Alpha that is basically the opacity to
something like 75. Okay, so there we have that
pretty interesting effect that probably you
have seen before. Now I also want to add a label that I'm going to be
calling game over label. And here in the text, I will
put something like game over let's add a
new level settings, and I will center all this
just in case I need it. Let's load in the font
that we have used before. And this is super small, so let's make it
something like 100. Then I will put it at
the center top and I will move it using the move
tool a couple of pixels down, maybe something like this, just below my score label. There we have it. And then what I want to do is
to add two buttons. So I will firstly add one. This is going to be
my restart button. And in the text, I
will also put restart. Over here, you know, to modify the font and
everything for this, you go to the bottom over
here and thin overwrites. And let's load in once again, the fonts that we have used. And it is super small. So make sure that you increase
it to something like 50. So that looks fine.
So, for example, I would to, like,
center it over here. I will duplicate it and
create the other one that would be the menu button. Okay. And I could
put it over here. Okay, and then select both and try to center
it as much as possible. But this is not correct. This is not a good practice. What you should
use is a container because this makes
the process much easier and also
much more expanded because even though they may
seem that they are center, mathematically,
probably they aren't. And if I wanted to add
a third button, well, then I will have to select
the three of them once again, see where the center is, everything is not
maybe the best thing. So I will just
select both nodes. I fairly select one by the way, hold down Control and then
press on this other one. Then right click reparnt to New Node and I will
use a VBox container. You also have the
H box container, but in this case, I want
to sort them vertically. Okay? Now, this VBox, I will center it, okay? And this is super simple. You go to them over,
constant, enable separation, and here you give any
separation that you want. For example, 25. Then I will also go
to layout transform. And here, I'm going to
set the size of this. I will put something
like 355 155, also think that
it looks correct. So let me center
this once again. And there we would
have our game over UI. Now, I will also
super quickly set up the script that we
are going to be using. Then we're going to modify it, but I just going to
at least add it. So I will add it to the game
over control node itself. So I will add it over here, and I will make sure that this is inside of the scripts folder. And here, what I
want to do is to know when I have
pressed these buttons. And for this, we
also use signals, so I will connect the pressed the button press
signal of the start button, and I will do the
same thing, but with the menu, well, this
is quite simple. In the restart, we want to
reload the current scene. So we're going to be doing get three dot reload current
scene as simple as that. And then for the menu scene, we want to change to the menu. But, well, we don't
currently have a menu scene. We will have with
the next lessons. But for now, I will
just leave here pass, and when we have the menu scene, I will go ahead and
replace this line. Oh, well, now we
do have the setup for our UI and our
game over system. If you receive here,
as you have seen here, any kind of warning,
this is perfect. This is what we should be expecting because
what is happening here is that this
Vivox container, if I go to Select Mode and
I change the size of this, as you can see, the width is
being set by the container. And in this case,
this is correct. So do not pay attention
to that warning. So now make sure that you
have saved your changes. And if you go to the mainstream,
well, you will see this. So we don't want to show the
game over screen by default because the game is not going to be over as soon as
we start playing. So let's just hide this note, and when we come back,
everything's going to be okay. Now in the next
lesson, we'll actually create the system
that will allow us to show the game over scene
the game over screen, sorry when we need to.
So I will see you there.
28. Game Over System: Hi there, and welcome
to a new lesson. In this one, we are going to actually be creating
our game over system. So first of all, we have
to think of which are the different conditions that
would make our game over. And in this case, we
only have one condition, and that is quite simple. Basically our vehicle
colliding with our player. So we have to take into account, you may think, Okay, I
have here the signal, so I just connect
the corresponding signal to the vehicle, and if it has collided
with the player somehow show the
game over scene. And that's the thing
because remember that when we instantiate
the vehicle, we do it inside of the
vehicle's container. Exactly right here. So if we were to detect the collision
inside of the vehicle, the vehicle doesn't have access
directly, as you can see, to the UI and to the game over Control node in
order to show it. This is something
that you can still do technically because there is a function here called
get parent, okay? And that would basically
do that return the parent. So we can get parent
and once again, from this parent,
get the parent. So we would be in the main node. And from there, we
can get the UI node. And inside of this UI node, we can get the game
over and show it. But this is a practice
that you should never do get parents is something that in most cases, you should avoid. So I will teach you a much better approach
because I really want you to learn how to write
clean and efficient code. Because, for example, with
this get parent thing, if the parents start
changing, if the vehicle, now you don't have it inside
of this vehicle's container, and then the UI organize the hierarchy differently and the game over is
not exactly here, then everything will break. So you always have to
make sure that you write clean and efficient code. And using get
parent, get parent, get node is not the best thing. So instead of calling the corresponding signal
to the collision, okay, just here and connecting it to the vehicle, we're
going to be doing that. But in the main script, when we are instantiating
the vehicle, First of all, as you
can see in the area, we have a lots of
signals that we can use. In this case, what we want to detect the collision
with is a body. Remember that our player
is a character body, body two D. So our vehicle should listen
to body entered, okay? So how exactly do we do so if we were to connect
this to the vehicle, this is what we would
get a function and body enter that would have the body
that it is colliding with, and it is of type node
two D. Basically, it can collide with
any kind of node two D. But how we do
so in code, okay? So I will just disconnect
this and erase this, and we'll come back over here. The good thing is that
we have a reference to the instance of the vehicle
that we are instancing. So this is quite simple. To do this, what we
do is the following. I'm just going to be
leaving there an empty line because we are not doing anything related
to the position. We are doing something
completely different from that. So just to get
everything organized. So I'm going to be calling
vehicle instance and then dot and then you
write the signal name. In this case, it
is body entered, and then you write connect. Okay? And this has,
like, lots of arguments. I'm going to hold on
Control and then click. And here we should see this, but I think that it
didn't work as expected. So let me do it
again. There we go. Sorry, I didn't
mean that it had, like, a lot of argument, but the argument that you
have to provide here, sometimes it can be
a little bit long. So for example here,
the documentation shows an example of
connecting a button signal, a press button signal, okay? So as you see, they do connect. First the press, that is
the signal dot connect. And here, they are putting
what you say callable Basically callable
is a function. So we need, let's say, a receiver function that we
are going to be calling. And that was the
function that was generated over here
on body enter. So that's exactly what we need. The best way of
naming this would be the following
underscore because this would be a private variable
a private function. I'm sorry, on because everything that is on
is usually a signal, Vicle because this is
the name of the node, basically vehicle,
then underscore and the signal
name, o body enter. So this is the pattern
that is usually followed. Now it gets an error
because this identifier on vehicle body entry
is not defined, so we will define it over here. So we'll paste it it
will return void, and I will just write
over here pass. But remember that this also
has a body parameter that I will create over
there that was of type node two D. Now, what I would do
in this function, at least by now is
for now sorry is just to print body dog name. So it would just
print the name of the body with which the
vehicle is colliding. So when we play, let me
collide with this one, for example, or with this one. Okay? And there we have
it. Okay, we have player, player, and there we have it. By the way, in the first
one, it wasn't detected because I got here this
vehicle that shouldn't be. But now every single vehicle would detect the
collision correctly. And there we have player,
player, et cetera. Now, just for you to teach
you the best practices, we have to know exactly
with which body our vehicle is colliding
because our vehicle right now, the only thing that
it can really collide with is the player. But then maybe when we
start adding things, the vehicles will collide with decorations and also the coins. And, of course, if the
vehicle collides with a coin, we don't want to end the game, it would mean nothing. So we only want to end the game to show this
game over screen. If the vehicle has
collided with the player, but how do we detect so? The best way of doing
this is using groups. So I will select the player, go to the group section. We have sync groups
and global groups. Basically, first of all, groups. They are a way of organizing nodes in different collections. So for example, in
the course, also, we are going to be seeing how we are going to be disabling these two buttons quite easily by adding them
to a buttons group. So that's one
functionality of groups, grouping similar nodes
together that we want to get easily because
maybe in another game, you may have 100 buttons. Okay, so it is easier to reference them if they are
just in the same group or the other functionality of groups is just
identifying a node. What I want to check over
here is that if I am colliding with a node that is
inside of the group player, then it must be a player, and therefore, the game is over. So we'll press here a new group and have to provide here a
name player in this case. This is usually a singular noun. You can make it global,
and if you make it global, you can add a description. But basically, syn groups, okay, are the ones that I can only assign in the scene in
which they were created. So if I go to a background,
I cannot access this group, and global groups,
you can access them personally node, global. I can access it here in
background anywhere that I want. So that is the difference, okay? Let me also delete it over here. Okay? So there we have it. So now in my main, I can simply do if
y dot is in group, player, I make sure that the spelling is the
exact same one. Then we do want to end the game. So I will have to reference
this game over, okay? So holding down Control, I will drop it over there. So I will do game
overver dot show. Do to show basically means
to do exactly this, okay? Now, when we collide
with the vehicle, we do see that the
game over screen is shown and we can't
even restart it, but well, the game was still being played
at the background. So not only do we
want to do this, but also to pose the game. So we do get three
dot post equals true. So now everything stops, but we can't anymore press the buttons over here because
indeed the game is post. So this is something
that actually I'm going to explain in the following lessons so that we keep the lessons
organized, okay? So I will see you in the next.
29. Process Modes: Hi there, and welcome
to a new lesson. In this one, we're going to be discussing process modes because right now
the problem that we have is that we are calling getredt post when we collide with a vehicle
to pause things. But when we do so, we also pause the input detection
here in the button, so we are not able
to click on them. So the easiest solution for this is to change the process
mode of these two nodes. If we go to the
bottom here process, we see this mode inherit, which basically
means that they will follow its parent, okay? And its parent is also inherit. So it will inherit the
ones from GameOver. And this is also inherit. So this will follow
the ones from UI, and this also is inherit. But well, if they do not
have anything different, but well, if
everything is inherit, it just means that
they are possible. So to quickly
explain them because they are quite simple,
with possible, these are nodes
that you can indeed pause when getredtPost is true. So this is what every
single node has by default. When post, we determine
that they will only be processed when the GTR dot
post is equal to true. If the game is
running as normal, they are not going
to be processed. Always will basically
mean that there will always be a process, even if they are
paused or if not, disabled means that
they will not process. They will never
actually process. And by process, we
understand that, for example, the scripts. Basically, if they
are processing, it means that their
script works, for example, to keep it simple. What happens is that our
two buttons over here, they are set to puzzle
because they are inheriting, this is inheriting,
inheriting, inheriting. And if everything
everything is inheriting, it means that they
are impossible. So, indeed, they
are possible nodes. So when we are posing the game, they are no longer
being processed. Here, there are two solutions. We can set them to when
post so that they are only processed when the game
is post or to always. Now, for this case, I
recommend that we just do when post because we will only actually process these buttons when the
game is post indeed. So you can still use other ways, but it will be even more
convenient to just we post because if the
game is not post, we don't need to use
these notes at all. So why would they be processing in the background if
we don't need them? So this is also to
keep into account in order to optimize
the game a little bit. And going to see when you do so, you also like the color
of the notes also change. By the way, another way
that I think it would do the exact same thing is to
have these two in inherit. And this one instead
of inheriting, you also put when post, okay? So that would work. But, I believe that
it is just better to keep this in when
post, okay, over here. So let's say this again, I'm
going to restart the game. Well, even though I was
able to press the button, now the game
continues to be post. So we have to make sure that
when we restart the game, actually we unpost the game. So over here before restarting
the scene or reloading it, we have to do Get once again. Do post equals false. And by the way, we don't
yet have a menu scene, but before changing
to the meno scene, we also have to disable
the pause because if not, the nodes in the meno scene
would not process as well. So we just make sure that we are not anymore
pausing the game. And with this, let me show you, I will collide with this car. I can restart and everything
works as expected. Right now, if I press the menu, it is going to unpause
and basically, it will not restart the game. Uh, but, well, this is because we don't yet have the
menu scene, okay? Because after posing, we should
change to the menu scene. We shouldn't stay
in the main scene. As well, that is something that we are going
to be addressing with the following lessons. So I will see you
in the next one.
30. Menu: Hi there, and welcome
to a new lesson. In this one, we are going
to creating the menu. So let's go ahead and
add a brand new scene. The user interface is
going to be quite simple, so I am not going to
be spending a lot of time explaining everything. I will still do
it here with you. But let's go a little bit faster so that
we don't waste our time. So I'll just add
over there my menu, control note and I will also instantiate here
the background, okay? I just want to have over
there the background. But remember that by default, this is moving, but I don't want it to be
moving over here. I just want it to be
completely static. I will here a label. This is going to
be my title label. And I will put here
the title of the game jump them but you can
write whatever you want. Let's center it, create
a new level settings, and I will just load the font. I will make it vigorous
something like 100. I will center top it, move it tele to the bottom, and
there we've got it. Now, as you can see, we can see quite clearly because
of the background. So as we have done before, let's use a shadow for this. So let's make it
something like ten. I will make it full opacity
this time, I believe. But I will also offset it a little bit more
so something like 44 so that we can see
something like this. And then I will
also add a button, a play button with
a text of play. In the theme overwrite, once again, this is super small, so let's load in the font, a font size of
something like 60. Let's make it a little bit wider in the select mode, okay? And I will put it
exactly like this. So what I also want to do here is a super
simple animation. So when I press
this play button, I just want to move the title to the top,
something like here. I also want to move
this right here. And as this happens, I want to decrease the opacity. So just a super
simple animation to some kind of juice to
the game game fill. So I will add what is
called an animation player. This is the node that
will allow us to do this. And I'm going to create a new animation that I
will just call Start game. As we have done in
our animated sprites, they are usually I mean, animation names
are usually verbs, start game, walk,
fall, et cetera. You can define here
the duration for it. I will make it quite
quick, something like 0.7, and I can even zoom in
using the mouse wheel. Okay? So something like
this will be okay. Now let's start with
the play button. So now, as soon as we see these keys over here
to the key frames, so I will go to transform, and I will basically key
its initial position. Okay. I will move to the 0.7, Okay, basically to the
end of the animation, and I will move this to the
bottom, something like this, outside of the viewport, and I will key that
value as well. So this is the
result that we get. Now, as that happens, I also want to
change the opacity. So in visibility,
this is the modulate. I go 2.7 once again, and I will make sure that I
have no more opacity, okay? So, sorry, here, this
is with full opacity. So this is at the beginning, but at the end, I want to
change this to no opacity. Exactly like this. Okay? So this is the
effects that we have. Now let's do something quite
similar, but with the title, I will key its position
its initial position, then I will go to the end of the animation and
I will move it up. I will keep this new position. I will come back
to the beginning, and I will modify its modulate. Okay. First of all, it
will be with full opacity, and at the end, it will
be with no opacity. Okay, I will make sure that
I have a key that value, and this is the
result that we get. Now, even though
it's not that ad, it's too linear, if we select this difference,
we see the easing. Okay. And indeed,
this is linear. So here we can try out different effects
if we right click. I believe that the
best one for this case is Is in out, okay? And I will select
also these ones, and I will do the same thing. Let's check that
everything should have this easing. There we have it. And now you will see
the result that we get. It is quite difficult maybe
to see the difference, but it's not a linear, okay? It is a little bit better the
final result that we get. So that's quite good. Now we actually have to
play this animation. So let's add a script, okay, into our scripts
folder right over there. We'll connect the
pressed signal. You can see it is something
that we have done before. So I am trying to do it quickly so that
we don't waste our time. And I will need a reference to my animation player and also a reference
to my play button. Remember, too when you drop
it to hold down Control. And let's also make
sure that firstly, we have our play button. You can change the order
holding down ls and pressing the arrows in your keyboard
because in a hierarchy, firstly, we have
the play button, and then we have the
animation player so that we follow that
exact same order. And what I want to do is
when I press in this button, I want to play this animation. So animation player
does play start game. And when the animation
is playing, okay, I don't want to be able to
press in this button anymore. So I want to disable
it. How do we do so? That's why we have the
reference to a play button. So we basically disable it. Now, I will leave
an empty space over here because we actually here, we are not changing the scene. So what we can do is we have to detect when
we have finished playing this scene playing this player
and when we have done so, we have to change the scene. So for this, we use the await
keyword and then we put animation player dot
Animation. Finished. Okay. When this happens, we do get three change scene to find main. So basically, we are
playing the animation, waiting until it finishes, and once it's finished, we change to the main scene. There is another
method of doing this. The animation player actually
has here another signal. Basically, we can search
here animation finished. So you could connect this,
and when this finished, you could basically call this. It will rule in the
exact same way, but I believe that this
way is even easier to do, but we just for you to know. So let's also make sure that we have our menu scene saved. And the first thing
that we notice is that when we click Play, we are starting in
the main scene, but that shouldn't happen. We should start in our
menu now that we have one. So in our settings, in run,
we have the main scene, and here let's basically select the menu. So there we have it. And here we have our menu, okay? We can press play. And once
the animation finished, we actually started the game. Now, when something
that you saw is that the game the auto scroll
of the ground was set. Because remember that we have
this script that already, it would set the
auto scroll speed. But we can actually just delete the script, detach the script. This is not going to modify
the background itself, okay? As this is remember
just an instance of it. We can do whatever we
want to this instance, and this would not affect
the background itself, because in our main
scene, for example, the background still
has the script, okay? So that was just a reminder.
So there we have this. As you can see, it
is quite good, okay? We still have to add
a scene transition, but it's not that bad. And now we also have to
do the proper function to change to the menu in the UI. So besides doing this, let's do Get change
into file menu. So here we are in the menu. I can play. And when
I collide with this, I can either restart the game or I can
also go to the menu. Okay, there we have this.
31. Starting To Code Progression: Hello there. And in this video, we are going to be creating
the progression for our game. So for this, let me just make the file system a
little bit smaller. We're going to using
another timer okay. So let's add it over here, and I will call it
progression timer, okay? The wait time, I will, basically be progressing
the game every 2.2 seconds, and I will enable
to start so that the countdown starts as
soon as the game starts. And now I will, of course, connect its timeout signal
into our main script. Now, first of all, in
terms of progression, progression actually is
never like infinite. You can progress a lot throughout these kind
of endless games, but it is not infinite. You have a limit and for this, I want to create, let's
say, a level system. So we're going to able to increase the level of
progression sometimes, but it's not going to infinite. We are going to able to
allow something like five changes in the progression. And if we are in the last
level that we have defined, we don't progress anymore. For this, I will create over here a constant
called max level. So in my case, I will
allow my player to progress five at most, okay? Now, also, I will
have a variable, a private variable because I will only access it over here, and it's going to be an integer, and at the beginning, the
level is going to be zero. This is a variable because
the level will change and the max level is
just a value that we want to store but not to modify. So here is going to be
happening is that we're going to actually be increasing
our level by one. And then we want to ask if
our level is vigor or equal, this is a vigor or equal
max level. Then we return. Basically returns
means do not do anything that we write
over here, okay? So we start off at level zero. The first time that we
progress, this is level one. Is one bigger or equal to five? No, it is and so
the code continues. The second time
level will be two. I two, bigger or equal to five? No, it isn't will
continue until, for example, level is now five. Is five bigger or equal
to five? Yes, it is. Then return. We don't
want to progress anymore. Then the next time
level would be six is six vigor or equal to five, it is, so we don't
progress anymore. Because if we didn't have this, it would be quite
complicated for the player sometime
because things would be so much so fast that they would not be
able to keep on playing. We would be literally
killing them. So that's not something
that we want. Now, in order to do this,
remember that we have a global variable
that is the speed. This control the speed
of the background, the speed of the vehicle,
the speed of the player. And then it will also contribute to the speed of the
coin and decorations. So what I will do is that I will have a progression amount, which is going to be a float. In this case, 1.15. So
the progression amount is going to be 15%. So what I mean by
this is that I will use this value in my speed, and I will multiply it by
the progression amount. So I will always be adding
15% to the global speed. That's why things are
going to be moving faster. Now, technically, this
could be a constant here, and I don't think we would
be having any kind of problem if we just play
this like this, okay? We would just have this exactly like this, and
there would be no problem. However, I've never
seen a constant being declared in the
middle of a function. Okay? So just to play safe, I will put this as a variable to avoid any kind of problem. This is not something stated in the G Script style guide or in any other place in
the documentation. In every single place
in the documentation, they use se variables basically in the
middle of functions. That's why I'm using a variable here just to follow
that rule, but well, know that yes,
baby, you could use a constant there
if you wanted to. Now, not only do I want
to do this, but also, I want to grab the sponer timer so I will put it over here. Remember to hold down
control when you drop it. And I want to spa things
a little bit faster. So sponer sponerTr wait time, in this case, I will
divide it to decrease it by progression amount. Now, something we
have to know is that we are modifying
the global speed. So as all vehicles
are in their process, basically every time they
are using this speed, we won't have any problem
with the vehicle. And with the player, something
quite similar happens, right here in physics process, we are using this global speed. So they always have
the updated value. However, in the background, we are only setting the out scroll velocity in
the ready function. So we are no longer
updating this value. We are just calling this at the beginning of the
game, and that's all. So for example, if we play what we're going
to see is that the varon speed will always
be the same one. Even though we are going to see how vehicles start
moving faster, the player will start
moving faster as well. I believe that you are noticing how things are going slightly faster and also
how we are getting more and more cars
being sensitd, but the varon always
stays the same. So that's something
that we must modify. Now, one solution that could
be the easiest one is just to put here process Delta, okay? So every time we're going to be updating the auto scroll speed
based on the global speed. And this would work. I'm
not going to lie to you. However, this is not the
best thing for performance. Right there, you can see how
the speed has just changed. This is not the best
thing for performance because we are calling
every time a process, and we are all the time
updating the velocity. And, of course, that
is something that we are not taking advantage of. We are just updating
the auto scroll speed when we need to when we update this global speed
basically over here, we should somehow
tell the background, Okay, now you should
update your speed. And to make this as
clean as possible, I'm going to use what
is called a signal, a signal as a button press body enter that we have worked on. But now we also have those
were built in signals. Now we have here
custom signals, okay? So I'll call Min Progress made, and I'm declaring it here
at the top because this is the order that Godot gives
in the DScript style guide, and they are usually
named with the past tens. That's why progress made. So basically what I
want to do is that whenever I am progressing
right over here, I want to call
progress Md dot MMIT. Now, this is indeed emitting, but no node is listening
to this emission. So we have to subscribe or listen to this signal.
And how do we do? So we can do it by
code or actually here, we can find this signal now, so I can double click it and I will connect it
to the background. So this will create
a brand new function that will be the
receiver for the signal. And I can just simply update
the auto scroll speed. Basically, I can do this, okay? But I also want to do this
on the ready function. So I could technically
just do this, and this would work
perfectly fine. Um but I will just wrap this into a new function that we call update audio scroll, which won't return anything. That's why I'm
writing here void. So I will just put it
over here and here, I will just call
update autoscroll and here auto scroll to keep
everything nice and clean. So now, when we play,
we are going to sing how everything is
working as expected. And for this, for the first part of creating the
progression, we are okay. But something I want
to do is to add some kind of extra speed and random speed to the
vehicles themselves because they are always moving at the exact same speed,
and I don't want that. I also here something
that you may have noticed is that the speed, goes crazy when, for example, let's play here for something
like 10 seconds or so. And when I restart,
the progression like brakes or things start
going even faster. So maybe something like this. And when I restart, as
you're going to see, I am still going
like, super fast. So what happens
is that the speed is not actually being reset, because this is an oro load, so the value is never reset unless we tell it to
actually be reset. So we'll go to the
GameOver screen, and before doing
anything of this, let's do Global dot speed equals global dot default speed. So this is where we
are actually using the default speed constant
that we defined over here.
32. Adding Extra Speed To Vehicles: Hi there, and welcome
to a new video. In this one, I want to
be adding some kind of extra speed to my vehicles because right now they are always
going to be moving at this constant speed
of the global of global. Well, maybe not constant because this global
speed will be changing. But the thing is that all vehicles are
going to be moving at this speed at Delta
times Global dot speed. So I just want to add some
uniqueness to each vehicle. I'm going to be achieving
this through an extra speed. So I'm going to create
a ran dw variable that I'm going to be
declaring over here between export and
unready because private variables and
also public variables are defined between the two, and they are named
with an underscore. So it's going to be
extra speed float. I am not going to assign
any kind of initial value because I am going
to actually be assigning this
variable in a second. I will actually create my own function for this to
keep everything organized. I'm going to call in it
update, extra speed. This is not going
to return anything. So for this, actually, I will have a minimum
and maximum extra speed, and then using that, I will create a random range. I know that sounded
like complicated, but it is simpler. So I will start with my
variable mean extra speed, which is going to be a float. And this will be equal to
global dot speed times 1.2. What I want to do is that
the extra speed that I add is a minimum of 20% of the current speed and
that the maximum of it is a maximum of 50%
of the current speed. So using this, I will
assign my extra speed. And I want to create an F range, basically, a float range
that is going to be random. And the minimum is
going to be mean extra speed and the
maximum max extra speed. So that's quite
simple to understand. Here we have our extra speed. And now, when we are using
or here our global speed, I'm going to add to it, basically, my extra speed. I actually have to update
my extra speed because right now the extra speed
is completely empty. I haven't assigned any value, and I want to assign it right when the vehicle is spawned. Now, as you can see,
every single vehicle will move a little bit faster
than the actual background. So that will give a pretty
interesting effect and we also add some
difficulty to the game. However, there is one problem. Remember that this relies
on global dot speed. And remember that our
global speed is going to be modified based on the
progression timer. So we also need a way of updating this extra speed because let's say that we
have spawned a vehicle, okay, and that vehicle has
already set an extra speed. That was actually set as
soon as it was insantiated. But, when the vehicle
was insantiated, maybe the game has progressed. So the extra speed that
we have set before actually used the
previous value of our speed and remember that
we have changed it over here. So to be fair, we should be updating this extra speed
when we are progressing. And this solution is
quite similar to what we have done in the background. We have to listen to the signal with a
progress made signal that is being emitted
in our main script. But the challenge here is
that remember that here we were connecting this
signal like this, and I have no vehicle
over here because the background we sentiated manually before
everything started, but vehicles Irvin
instantiated as time goes by. So it's not that
simple, but well, it is actually not super
complicated because it's going to be quite similar
to what we have done with its body enter
sign right over here. So in this case, what we
want to do is the following. We want to connect the
progress made signal, so I will do progress
made connect. And here we need a
co. Basically, Okay, we are connecting this signal, but we need the receiver method, would be the technical term. And this would exist inside of the vehicle instance that
we have just instantiated. And then we would need
the method itself. So I will create it
right over here. And I'm going to calling it
on parent progress made. Why exactly like this you
may be thinking about? Remember that we are using here an underscore because this
is a private function. By the way, here you
may think, Okay, yes, it is a private function, but
we are using it over here. We are not using it directly. We are not calling it directly. We are just putting
its name, okay? So it's not the same calling a function than just
referencing it. That's why it is still
a private variable, and therefore it is prefixed
with an underscore. And then signals always have
on here at the beginning. Then in this case, which
is the emitter of this, in this case, I put on parent, because this is basically
the object that is spawning the vehicle, but you could technically
call it on main progress Min. Well, it is more emphatic, but I just wanted to emphasize more that this is going to be a children of our main node. So that's why I put on parent
and then progress main because this is the name
of our signal, basically. So on parent progress made. And now I will actually
use this function here. So dot, okay? And I will put on
parent progress made. And now in our vehicle, we just have to do
update extra speed. And now, like this, everything should be working as expect. Maybe this difference of the last thing that we have done about connecting
the signal, it is not easy to
spot, but well, it is basically a
minor addition to the game to make sure that
everything works as it should. And also so that you
learn more about signals. So well, it was a win
win situation that I wanted to teach you how to do this because you can see the potential behind
signals, okay?
33. Coin Scene: Hi there, and welcome
to a new lesson. In this one, we are going to
be creating the coin scene. So let's get started
by creating new scene, and I will just close this one so that we don't get messy. I will make this
oselitle bigger. And I will create an area today as the roots
know because remember, this is the easiest way
to detect collisions. This is the same one
that we used for our vehicles. So
I'll call it coin. And also, let me
show you over here. We are not we don't
want it to be static. It is going to be moving around. It is not going to be a
character moved by script, and it is not going to be having any kind of
physics implemented. So the only option left is area, not because of just this
is the discarded option, but because it is
specialized for the text and conditions
quite easily. So that's the best option. Now, let's save it in the
corresponding folder. And in this case, I will use an animated spread because
if we check the assets, here in the coin, we have
a pretty simple animation. And I will also add a
collision shape, okay? So for the animated it spreads, we have already worked
with this, so we should be able to go at
least a bit quicker. Let me call this
animation idle, okay, because it is the
only one that I will have, and there we have it. Okay? Right now,
it is super small. So let's, of course, make it a little bit bigger, something like 4.5
that will work. It is blurry because it is pick lard and when working with piklard we have to make sure that we are using
the correct filter, so there everything looks fine. And for this, I will use
a circle, for example. So let's make this a little
bit bigger and with that, it's going to be enough. Now, the most basic setup
for the coin is completed. However, I also want to
have an animation that will be the collect
coin animation that's going to be
quite simple, okay? It is just the one that's going to be played
when we collect it. This is also meant to add a
little bit of game juice of game fill So I
want to create it. Remember that they are
usually named with lower cases and with verbs
collect coin in this case. The length for it is going to do quite fast,
something like 0.4. And in this case, make sure that you are
working when changing handle. In this case, what I
want to do is to create an animation that will
make the coin go up. So make sure that what
you're animating is, in this case, the animated
sprites and not the root node. Because if you actually
change the root node, you will see that it will
have a super weird defect in which the coin will
move wherever it wants. So I don't want to
dig any deeper, just take into account that when you want to
animate something, make sure that that
animation you apply it to the sprite itself and not to the
root node because if not, it is going to be quite
difficult to actually work. Um, so once that we do so, we need to start
modifying some stuff. So first of all, I want
to modify its position. So as a see, I don't see the kiss over here
to key my value. So I will go to animation. Okay, and right now, I will
see the kits that I need. So the initial position is
going to be zero, zero, okay? And the final position in 0.4, in the way, it's going to be
something like minus 250. So I'm going to go
up a little bit, and I will key that value. So it's going to do that. I also want to modify
the color of it. I just want to fade it out. So let's do it like that. And I will make it
completely transparent. So there we have lemons
so we can see it better. There we go. And I also want to
make it bigger, okay? So right here in the
scale, at the beginning, it's going to be
that, and at the end, it's going to be something
like, let's say, six. Okay. So this is the effect that we are
going to be having. Now, before continuing
with the animation, something that I
want you to note is that if I run
this current scene, you can see that
there is no animation playing in the animated sprite. This is because by default,
animations are not played unless we
tell it to play. So we can enable autoplay
with this button. And by the way, this is just
that the animations looping. So that is correct
that it is like that. And now we do see our animation. Our animated sprite actually playing the animation
that we need. So now we also need some
more stuff over here, because when we
collect the coin, we don't want to be
able to collide with this coin anymore because
it has been collected. Now, there are multiple ways
in which we could do this. We could make it so that
when we play this animation, we just access the collision
shape and disable it. Um, and also when the
animation finishes, we want to delete the coin. So once again, we could do something quite
similar to what we have done in our
menu, basically, use the weight until animation finishes,
and when it does, we do what I've just mentioned, access the collision
shape and the saved. And lastly, just basically
delete the coin. Now, that is one approach
that would definitely work. However, I want to show you
other way of doing this. And this other approach
would also work for you to modify this code, and you could make
it work differently. But I just wanted to
teach you both ways, and then you can decide on which one is the most
efficient for you. I personally like
also working with this other approach that
I will teach you because it is even simpler
and more direct. So what you can do
with this is that not only can you animate
scale positions, colors, but you can also animate other values such
as here, disabled. If you enable this, the collision is off, basically. So as soon as our
animation starts, okay, I'm going to keep this
value as disabled, okay, as simple as that. But I will make sure that
by default, this is off. And how can I also make
sure that by default, this is going to be off if
I go to the reset track. This is the one that is
going to be the default one, unless we change
to collect coin. So here, as you go to see
collision shape is disabled, and by default, collision
shape should not be disabled. So I disable that and
I will also come back here and make sure that this is not disabled because if not, we are not going to be able to detect collisions with the coin. Now, not only this, but also as I told you, I
wanted to delete the coin. So what I will do is to add track and here
called metal track. Here, I will select the coin. Okay, I will right
click Insert key, and I will look for u free. And here how it's Qu free. Okay? Now, I will put this at
the end, basically in 0.4. So what I've just done is that when the animation
finishes playing, I call Q free in my coin,
basically delete it. So I've done
literally everything without even having a script
attached to the coin. So that's the main
advantage, okay? And also, by the way,
if any other value in the reset track is
not set correctly, the position is not zero, zero, the modulate is not this, the scale is not 4.5, or the collision here is
set to not be disabled. Just make sure that
you have these exact values as I
have over here. And also, you may
have seen that I have not modified
here the easing. This is because I do really like defect as it
currently looks like. You would still
need to select this and apply easing
out, for example, and defect would look slightly similar or you could even use Io Ease out and there defect would be a
little bit different. But, I just want to make it linear because I believe
that it looks just fine. But just bear in mind that you can modify it if you want to. Now in our following lesson that we have everything
set up correctly, we're going to both be spawning this coin and
then collecting it. So see you in the next one.
34. Spawning And Colliding With Coins: Hi there, and welcome
to a new lesson. In this one, we are
going to be spawning and also detexting the
collisions with the coin. So first of all, let's attach
a new script to it and make sure that it is saved
in the corresponding folder. And the very thing
that I want to do is to just leave two
empty lines, okay, because I will put here the
process Delta function, and I just want to
move it to the left as I have been doing
with my other objects. So basically Delta
times global dot speed. This is the same thing
that we have done, for example, in
the vehicle, okay, the discussing code without the extra speed
because in the coins, we do not want any
kind of extra spill. So now let's get to actually
insantiate this coin. So I will duplicate here the
vehicle scene reference, and I will now create the
sorry, the coin scene. So coin sin anima Minsin I will just go ahead and assign
it. There we have it. And remember that here have
the spanner timer timeout. And here we are always
spawning vehicles, but I also want to
instantiate coins. So basically, based
in randomness, I'm going to to spa
one or the other. So basically, on top of this, making sure that I leave
the corresponding space, I want to define a
new function that I will just call spun, okay? It's going to be quite simple. I will have a random integer that is going to
be Run range 0-2. This will return either zero, one or two, as simple as that. Also check here uhmsen Rand E, which means a random
integer and not Rund F, as we have used before, okay? So those are
different functions. So I will do, for example, if random is less or equal to one, I will spawn a vehicle. And if not, if random
is equal to two, I will spawn a coin, okay? So let's say that I
should have 66% of a vehicle and only 33% of
getting a coin spawned, okay? So I will leave this like this. So now what I'm
going to be doing is that I will get
all this code. I will press Control
X to cut it. And here on spawner timeout
I will just call span, okay? Now, I will also
select these lines and I will move it on top, just over here, okay? And there we have it, okay? And now I will do a new
function, spun vehicle. And I will paste the
code over there, okay? So this is the function
for spawning a vehicle that I'm going to
be using over here. And now I need, let's
say, a similar function. But in this case, for
spawning the coin, okay? So I'll make sure
that all the spacing is correct. So yes, it is. And then below this because
it is related to a vehicle. So this is all related
to vehicle nine. So now we're going to create the code
related to the coin. This is going to be spun coin. Remember, I'm using
the underscore because all these are
private functions. By over there. And well,
we have to spun the coin. This is going to be quite
similar in some things. So I will read here the coin instance that is
going to be an area today. This is going to be for
the coin scene that Isentiate and now I am not going to have
a vehicles container, but a coins container. So I will select this
vehicle's container, and I will call it
coins container. I have duplicated
it with Control D, but you can also right
click and press duplicate. I will also reference
it over here below my vehicles,
exactly right there. So now over here, I will do coins
container dot A Child, but in this case,
the coin instance. Then as I have done over here, I want to change its
position to the spawn point. So coin Instance dot position equals to spawn
point dot position. And then I want
to use this spawn coin function over here. And in order to etect
collision with the coin, I will create a receiver method
as I have done over here. So I will actually copy this
line, past it over here. In this case, is on coin. By enter, this also
receives a body. Um, and in this case, I will just do I or
for now, if body, that is in group player check how I am just
doing the same thing, basically checking the
collision with the player. And if I have, I'm going to be doing some stuff in a second. For now, I will just
pass because here I should play the coin
animation and do more stuff, but there is something that I'm going to be doing in a second. But before I have to, as I have done over here, connect the body enter signal. Okay, so this is going to be my coin instance dot body
entered, dot connect. And in this case, the
receiver method is going to be coin, body entered. Exactly like this. Please make sure that I know it was
a little bit messy, but make sure that
you read around. And in vehicles, you have no reference to
to coin instance, coin scene or
anything like that. You shouldn't have any of that. Also, when you
connect the signals, make sure that you
are connecting it to the correct receiver method. The same thing over here, coin instance everywhere, coins container, here,
vehicles container. So we have no reference to
anything named vehicles. The receiver method is correct. So yes, everything should
be working as expected. And now that we have this, we have to come back
to this script. Basically, you have to
play this animation, okay? The collect coin animation. So I will drag and
drop a reference over here to the
animation player. And I will create here
a public function. So I am not going to prefix
it with an underscore. I would just call
it collect coin. Exactly like this.
And I will just do animation player
play collect coin. Okay, as simple as that. And now I have to call this function when I have
collided with a coin. How how am I supposed
to do this over here? Because in this function,
I do not have access to the coin that was insantiated. So I somehow need a
reference to that. So I will add a new argument. Is going to be coin
and remember that our coin is basically an area to d. And I need to pass the coin instance
when I am connecting this. So on body entered, I will do dot Vind to be
able to provide argument, and I will just pass
here the coin instance. Basically, nd, what is
allowing us to do over here, we can do Control click. This basically allow us to add one or more arguments
when we are using cobs. Remember, coable are basically a reference to a function that we want to
provide over here. So we are basically,
okay, to this function, the arguments that I'm
providing over here, and we don't have to
provide the body because that is something given
by the signal, okay? So the first argument
is, like, omitted, and then the argument that we provide here is
the second argument. And if I wanted a
third argument, I would just add it
right there, okay? There wouldn't be
any kind of problem. And now that I do have a reference to the coin
incense that I have, I can just do coin,
dodge, collect, coin. So, for example, over
here, oh, I couldn't. Here I have another
one. So there we have the animation, okay? Let's see if we can get another
one. So there we have it. And also, we can check
how in the remote, this basically shows
the current notes that exist in the game. So I only have one coin here, and we have collected, like, much more of them. Maybe this coin is
because it exists, like, over here, outside
of the road, okay? It could be. So that's
why we have the one coin. I basically wanted to show
you that because indeed coins were deleted when the
animation finished. We weren't getting
there thousands of coins that I have already collected because if I had all the coins that
I have just used, I would be wasting
resources, okay? But, well, optimization, I will cover it in just a
couple of lessons. So with this, this
lesson is completed.
35. Displaying Coins: Hi there, and welcome
to a new lesson. In this one, we are going to be displaying the number of
coins that we have collected. So, of course, we are going
to be adding this in our UI, and to in with this and to
keep everything organized, as we have done
with our GameOver, I'm going to add a
new control node, which I will call coins. Okay? I will put it
exactly right here, and I will change its
anchors to be full wrecked. Why am I putting it over here? I will for an example, just I will make this
maybe a little bigger. Okay? And I will put it right over there, change
the color, whatever. And if I show the
game over like this, as GNC is going to look correct. Okay, because it is
behind our buttons. But if I put it right here, it would cover the buttons. So that's why I am putting
the coins over there. We hide this. And in the coins, I just want to have
here a coins label. Okay. And I believe that we can just duplicate this
label with Control D, or you can rightly duplicate. I'll call it coins label. And I also want to add
a texture rect, okay. This is quite
similar to a sprite, but it allows us
to use anchors to position things a
little bit easier. And I will load in here
just the coin itself. It is going to look blurry, but we can modify its
texture once again. And as you can see everything
is going to work fine. Now, for this, I will make
it a little bit bigger, something like 85 by 85, okay? And I will also rename it to
something like coin icon, okay? Exactly like this. Now for the coins label, let me check if all sings here are the ones
that I'm looking for. I have the fonts, I have 75. I have the shadow. So yes, everything is fine. But now I want to see which is the Y position
of my score label. So in this case,
it is 32 in the Y. So I will copy this value, and I will give it
to both of these. So position 32 in the Y. But I think that this
one wasn't updated. So let's go ahead and set it. So what I will do is to just move the coin label to
something like here, and then the coin
icon to the right. Okay, maybe it was
a bit too much, so maybe let's position
this over here, coin label over here. Okay. So I think that like
this, it looks quite well. Um, now, if I write more
numbers, as you can see, this doesn't work as it
should because maybe we are able to collect ten coins as you're going to see it
doesn't look as it should. So for this, I will change each horizontal
alignment to be right. And now I also have to go to Selectmd and just make
this a little bit bigger. Something like this
will be enough. And as you can see now numbers
are displayed correctly. And also, you can check if
I turn on the game over, this is not shown on top, okay? So we have to make
sure that we are sorting things as they should. Now to implement this, because we know how to update this text based on how many
coins we have collected, I'm going to go to
the main script. And here are my score
and level variables. I want to add one in the middle
of them called the coins. And I'm going to start
off with zero coins. This is private because
I am not going to be accessing it outside
of my main script. And below my score level, I have my coins labeled, so I will reference
it over here. And now what I want
to do is to go to where I am collecting
the coin right over here, coin dot collect coin. And before doing that, I will increase the amount of
coins that I have collect, the number of coins
that I have collected. And then I will just
set it to my label. And we make sure that
I convert this into a string because if
I do not do that, I'm going to receive an
error because in order to in order to modify
the text of a label, the data that we provide
here must be a string. And our coins here
is an integer. And if I didn't
static type this, as I have already explained
sometimes in the course, go that we detected
that this is correct, but then in the game, it
would throw an error. So that's why static
typing is so, so important and it helps VAC errors without
even running the game. Once again, I am leaving
a space in between these because these two lines basically they are
updating the coins, and this line does something
completely different that is playing the animation or
collecting the coin itself. So that's why I'm
leaving that space. So now let's play
and let's see if everything is
working as expected. And now here I have
my first coin. I will jump over these vehicles
and see if we are able to at least get two coins.
There we have a second one. So even a third one, so everything is
working as expected. I'm not going to play until collecting ten because that
would really take a while, and I may lose before that. But I will try to cut
the video so you can see that the UI is indeed
being displayed correctly. So here I am about to
collect the ninth, and I just need to collect
the coin number ten. Let's see if we are
able to get it. So as you can see there, the UI displays everything
as it should.
36. Decorations: Hi there and welcome
to a new video. In this one, we are going to
be adding decorations, okay? Because right now in the assets, we do have some decorations
that we would be able to use. These are things that we
just add a little bit to the background of the
game because even though we do have the background
that is moving around and doesn't look that bad and actually adds
a lot to the game, I love it if we could actually like spawn
lights at the background. We also have some
signs over there. So, well, I really love it. Um, so we add a new scene. And the only thing that they have basically an image
that we want to display. But what happens is that
in a future lesson, okay, quite close to us, I'm going to be adding here another area today that will basically
destroy everything. Because what
currently happens is that every single
vehicle, for example, that we spawn or coins
that we don't collect, they basically all the
time, keep moving, keep moving to the
left infinitely, okay? And that's basically
waste these resources. Now, in this game,
even if you have if you are able to play
for 1 minute, 2 minutes, 3 minutes, probably, if
your PC is powerful enough, you're not going to
be facing any kind of errors because the game is
quite simple and small. But in the longer term, when you create bigger things, you will need to keep
an eye on performance. And a way of keeping an eye on performance is seeing is sorry, deleting objects that you
are not using anymore. So that's why we'll just
create here an area toy, and whatever it detects with that area is going
to be deleted. For example,
vehicles, coins that were collected and
decorations themselves. And sprites alone, okay, if I were to adjust
sprite like this, sprites alone are not able
to detect collisions, as you may already imagine, we must use, for example, an area two, okay? So once we know that, I'm going to add here the daria ti with its
corresponding name decoration, and I will add it
and I will save it in the sins folder, okay? So we should to find
it right there. Now, as usual, I'm going to add the sprite and also
a collision shape. For the sprite, I will
just drag and drop one to give an
example. So this one. And going to say,
it is super small, so let's make it much
bigger, something like 5.5. And it's also blurry. So let's make sure we change
this to nearest. And I will also create
here a rectangle shape. And as we have done
with our vehicles, I will set one side, and then we'll see if
they match more or less the others. So let's see this. Okay, so it's not
that bad, I believe, or we can even just
make this liti smaller because the only vague
decoration is the highway. So maybe I can make
this it smaller. We are not going to be
dejecting collisions with in other parts than
in the object destroyer. So we don't really mind if the collision is not that perfect. But, well, it matches
so so the shape, so it's not that d. So with this, we are
going to be okay. And as we have done
with our vehicles, I also want to
randomize its texture. So I'm going to do
something quite similar. As usual, first, I need
to attach a new script. And I will actually use the
vehicle code over here. So I will copy everything. You can press
Control A to select everything and then
Control C to copy it, and then I will
paste it over here. I will press, once again, Control A to select everything, Control B to basically
override everything. There is some stuff that we
are not going to be using, for example, extra speed, we are not going to be using it, updates extra speed, we are
not going to be using it. So we also delete
this over here, and we don't have this
receiver function for the progress made signal. And also here when
we are moving, we don't need to add
the extra speed. So we just want to
move to the left. If you check this line
these lines actually are the same ones that we
have in coin over here. Now, what we have to
do to modify this, so this is not vehicles. I will press Control
D so that I can also rename the other
reference that I have, so it's going to be decorations. So there you can check that I have modified both
at the same time. For the textures, I will
select all my decorations. Once again, I select
the first one, hold on shift, press
in the last one, and I drag and drop
it over there, and then I got the six of them. By the way, make
sure that they are dropping there where
it's a y texture to the. If you drop it anywhere else, they are not going to be added. And now I need to spa
these decoration. So I will create a
new timer, okay? We control the I
duplicated the other one. So decoration timer. The wait time is going
to something like 2.6. Auto starts on is okay. I will disconnect the signal, and I will create a new one to my main script right over there. Now I need a reference
to my decoration scene. So I will create it over here, Control C and Control
V to copy and paste. And it's going to be
decoration scene. I will also need a
decorations container, okay, decorations container. And in this case, I
want to show firstly the vehicle on top
of the vehicles, the decorations and on top of
the decorations, the coins. So that's the order that I want. So I will drop this
below the vehicles. So vehicles, decorations, coins is the same order
that we have over here. Then spawn points, core
label, coins labeled. So yes, everything makes sense. And when we do so, let's go over here. And I'm going to do things quite similar to what I've done over here in a coin
and spun vehicle. So in this case, this is not coin instance. I will once again,
press Control D to just reference all of this. Firstly, you double
click it to select the word or the words
that you want to modify. And over here, it's going
to be decoration instance. This is going to be an area
to this, so that's correct. I don't want to incentiate
the coin scene. I want to incentiate
the decoration scene. I want to add this inside of
the decorations container, and I want to add the
decoration instance. I want to set its position and I don't want to
connect its body entered. Let's also load in here in
the main decoration scene. And here we have them, okay? Now, I feel that
we can move them a little bit to the top, okay? I would like them to be a little bit more to the
top of the screen. So I will add an offset
over here to the position. So I would simply do bar y offset this is going to be a float and I will set
it to something like 40. So I will get this instance and I will move its
position dot Y up, so I have to decrease
it by the Y offset. Okay? So this will basically
make sure that I move up a little bit every
single decoration. So there we have. So
now the effect is, I believe in the way I
see, much, much better. Once again, you could
declare this as a constant, you would have to change its
name to be Y offset, okay? Wouldn't need actually static typing over there,
but you can leave it. And this will work in
the exact same way. But as I have
explained previously, I haven't seen ever in the documentation or in
any other place that they use a constant in the
middle of a function scope. So just to play safe, I
have used a variable. So, indeed, this
is working fine. Now, I quickly want to address this thing of
optimization, okay? I just want to tell you
what the problem is, and we're going to be solving
it in the next lesson. I will just play for a while. I will leave some vehicles there some decorations as well. Hopefully, one coin there. So I will go to the remote app. This shows the notes
that currently exist in our ongoing session. And, for example, we
have four vehicles that we are not
using most of them. We have decorations that
we can't see anymore. We only see two decorations,
and we have four. In the coins, we have, that one that is over here. But for example,
we have here four vehicles and we only see one. So this means indeed that there are a lot of
vehicles that are existing outside of our
screen that we don't need. So that's the issue
that we are going to be addressing in our
following lesson. So I will see you there.
37. Optimizing: Hi there and welcome
to a new video. In this one, we are going to be discussing
optimization, okay? Because right now the project
is quite well optimized, but there is one key thing
here that we must fix. And I have already explained
it in a previous lesson, so I am not going to
expending a lot of time. But basically, for example, when we are spawning vehicles, okay, also when we are spawning decorations
and coins as well. What happens is that,
for example, vehicles, they're going to respawn
somewhere like here, and they're going to
move to the left, and we are never deleting them. And with decorations, the
exact same thing happens. We are spawning them here
or something like here, and they are moving to the
left infinitely, okay? So what happens is that we
are going to have in here lots of objects that we
have already used, okay, but they are still
existing in our game, and they are consuming some resources in vain.
So we have to avoid that. And also the last thing that we have to take into
account are coins. Now, coins can be deleted, as we have seen with
the animation itself, when the animation finishes, we are calling you
free to delete them. But what happens, okay, if we have a coin that wasn't collected by the player because the player was not able to
collect it or whatever, but basically, it
will also continue moving to the left endlessly. So we have to find a way
of actually making sure that these objects are deleted when they exit
the screen, okay? Now, there are multiple ways
in which we can do that. One way, I will show you. For example, let me open
up here the vehicle scene. And one way that maybe you have seen in other courses
is or tutorials, basically using a visible
on screen notifier, okay? And as you can see, this
is quite similar to a collision shape in terms
that this is a tu space, but this is not for actually
the texting collisions, but the texting the
visibility of the object. So we have something similar
to a collision shape. Let me just hide it
so that we can see. In this case, it is as you can
see some kind of pink box. So we can also resize it and set it quite similar to
the collision shape, and also it has some signals screen enter and screen exitive. So you may think, okay, I just connect the screen
exiting signal, and when this is
called, I call Qure. That would work for
a lot of cases, but what happens
is that remember that our vehicles coins, decorations, they
are all spawned actually outside of the screen. So if we actually did this, what would happen is that as
soon as the vehicles, coins, decorations et cetera
are being spawned, as they are outside
of the screen, they would be instantly deleted. There would still be some ways
of avoiding this behavior, but I think it would be much
more complicated in vain. Okay? So I believe that there is a much more effective way of doing this and it's
still quite clean. And that is basically
creating an object destroyer. And I will create in
a brand new scene to keep everything organized, and this is going
to be an area two D. So I just want to
create here an area, and if anything collides
with that area, I want to basically destroy it. So I will create it over here. By the way, I am not using a
character body, rial body, static body because we do want to be able to detect
collisions and the easiest way, as I have explained is using the signals that
only the area has. I'll call this one
object destroyer, Okay, exactly like this. And I will save it in the
corresponding since folder. And the only thing that I
will need or here too is to have over there
my collision shape. And I will adhere
a rectangle, okay? You can either resize
collision shapes, by the way, using here these orange dots or you can also
manually set the size. I already found here a size that is going to
work quite well. That is 21 vi 648, okay? So it's going to be quite tall. I'm going to save these changes, and I will instantiate it in my main scene.
Exactly like this. In this case, I will put it over here just to keep
everything organized. As you can see, I
have, let's say, two the nodes over here. Then I have this is
a canvas layer node, and then I have a blank node
over there with all my time. So I'm trying to keep
everything organized. And now, what I will do
is basically position this object destroyer
somewhere like here, okay? I am moving at a it more to the left because we
have to take into account the vehicle
collision shape, size. So for example, if I had the objects ray like right over here where
the screen ends, what happens is that
the vehicle would move. And when it is still
inside of the screen, here you can see, we have a collision, and
it would be deleted. But as you can see, still the car is
inside of the screen. So that's why I'm basically
offsetting it a little bit. It doesn't have
to eat that much. So maybe something like this. As you can see, it's going
to be more than enough, we are just going to be
like wasting, let's say, this resource for a
couple of seconds until it collides with this, but it's not going
to be a big deal, so we can work with that. And of course, we need a script. And this is going to be quite
simple for us to implement. We just need to detect the so I will use here
the body enter signal. But for this, I
first need to attach a new script to my
object destroyer. So I will do it
right over there, and or heal connect the
body entered signal. And when a collision happens, the only thing that I'm going to be doing over here is body, which means the body
with which I am colliding, dot, he free. So I will basically delete it. Now, here I want to remark something that
could happen to you. And that's the
difference between a body and an area because here we have the same functions for area entered and body enter. And here we have
used body entered. But actually, if you take a look at the nodes that we have, bodies are actually
static bodies, character bodies to
the rigid body today, and area is a different
type of object. So body enter will not detect collision
with any other area, just with rigid body, static
body, and character body. And we should take a look
at the type of notes that we have in our objects. Vehicles are an area, so we wouldn't be
detecting this collision. Decorations are an area as well. Coin is an area as well. So actually, here we are not using the corresponding signal. I just did this on purpose
for you to show you this. If I were to play
the game like this, let me press here on the remote so that we see the current nodes and let me now open this up
again. I will press plain. And then I have my main scene, and I will open up
vehicles and decoration. So right now, I'm going
to press Restart, and let's try to dodge
here some vehicles. And I'm going to say,
Well, all those vehicles, all these decorations should be deleted, as
well as the coins. If I do not collect a coin, let me there, I am not
collecting that coin. So indeed now, I am going to
collide here with a vehicle. So we should only see here
something like one coin, one vehicle, and one decoration. But check this. We have
a lot of vehicles. We have a lot of decorations, and we have a lot of coins. Basically, this is
because this function is actually never been called. So instead of doing this, we have to connect area entered. Okay. And over here, we just do area dot Qu three, and we can delete this
function and make sure that we are living
there two lines. We can even over here print
a message, delete it, okay, because something
could have been deleted or even we could put area dot name so that we get the name of the node
that has just been deleted. So once again, I will
play for sometime. So that we have some vehicles, also we have some
decorations and also their names are being
printed, like over there. Sometimes you may not
see their exact name, but that's something that
we don't really care about. So right now, we should
see one vehicle, one decoration, one coin. We may have some
object over here that has just been spun
and we don't see, but we shouldn't be seen
like a lot of them. And when we see one vehicle, one decoration, and one coin. So everything is working fine. Now, we can delete this print
statement if you want to.
38. Autoloading Fade Scene: Hi there, and welcome
to a new lesson. In this one, we are going to be using SN transitions, okay? So as usual, in order to keep everything
nicely organized, let's add a new sN. And over here, the
root node that I'm going to use is
actually a canvas layer. If you remember this node
is the one that we use for our UI to
basically make sure that it was always displayed
on top of everything else. So, of course, our faith effect, our SN transition, we want it to be on top of everything else. I will show you actually
this in a second. So I will call this one fade, and I will save it
in the sins folder. Now, I'll be using the
color wrecked node to just have there my rectangle and
I will make it full wrecked. And by default, I will just make it black with no opacity. But I will make it with
opacity so that we see this thing of ordering
the canvas layers. Because what happens is that if I now instantiate
this fade over here, as you can see, it is going
to be on top of my UI. Why? Because of the drawing
order that God has. But if I change it, as you
can see over here, now, if I apply here the fade, it wouldn't be like
covering the UI and, of course, that is something
that doesn't look good. So how can we make
sure that this is always on top of
everything else? So the easiest way of
doing this is that canvas layer have
an actual layer. So, for example, if I set this fade to be on
the fifth layer, it will always make sure that it is actually
on top of everything. Now, of course, if I can put
this fade wherever I want, and it will always be
on top, as you can see, but we always have
to take into account that if I change my UI
layer to be an O in ten, it will now be displayed
on top, as well. With this, we are going to be making sure that this
is always on top. Now I will delete
this from here. That was just an example. And in order to be
creating this fade effect, we are going to be using
the animation player, and I will quickly set up the animation that we
are going to be using, and I will call it fade. I will make it last 4.7 seconds. Why? Because I wanted to make it equal to the animation
that I have already created here because
I want to be playing the fade at the same time that this animation
is happening. So if one animation
is faster or slower, the effect is going
to be a little bit different from the look
that I want my game to have. And it will also
look quite weird. So for our fade effect, now that we have it here in 0.7, I will also rename this
to black color rect, just to be more emphatic. And I will keep its initial
value with no opacity, okay? And then in the 0.7, I will key the value
but with full opacity. So this is the effect that
we're going to be having, as you can see, quite simple. Now, I go, that's what
we can do to avoid having multiple fade in, fade out animation is to just then play this
animation backwards. So then we would have fade out. Fade in is where the
opacity goes 0-1, and fade out is 1-0. Okay? Basically, from full to null or from null
to full opacity. I also check that in
your reset track, make sure that well, the
opacity is by default. The default value is zero, okay? Now, let's add over
here a script. And we are going to
be coding some stuff. First of all, I need a reference
to my animation player, so I will drop it there and remember that
when you drop it, you have to hold on control. So I just need to have
this reference in order to play to play it when I need to. But how do we know exactly? And this is when we're
going to using auto loads. Once again, remember we have already done this
with the Global, which was a little bit simpler. We only had, like, this variable that we were accessing,
basically the speed. But as I already mentioned
in the Singletons lesson, not only can you
auto load scripts, but also you can
auto load scenes. So I will auto load here
the fade scene. Okay. And I will add it. And
this will do two things. First of all, it will
give me access to all the notes that they exist over here and to also
the script itself. So basically, let me press here play so we can
see this in action. I don't know why that
happened. I just played it again and
everything fixed. I think this is because
of the dev update, but do not pay
attention to that. And if I go to the
remote over here, I find indeed the
fade scene itself. And here I can
basically open it up. You can see how every
single component of it. And we also can find
here the global node. The C has the global
script that we have or loaded in basically a base node. So that's how basically scripts and scenes are oro loaded, okay? And by the way,
even that we don't see here the script icon, at least in the version
that I am using, we can see here at the
bottom that, for example, global does have the
global script and fade does have here the
faded script, okay? So indeed, when you
auto load a scene, you are both auto loading the script and the scene itself. And, of course, we
need to auto load also the scene elements because we can have
here a function that will access the
animation player and the animation player will change the color of this color wrect. But because of that, we must have access to
the scene itself. By the way, if we were just about to auto load the script, this is just for you
to understand actually autoload because
it is so useful, I will just auto load
the script itself, okay? So there we have it. So now, when we play as you can see, I only have here
this fade over here. And for example, I am receiving here an error because
in this script, I am trying to access
the animation player. And where is the animation
player over here? It is not being auto loaded because the only
thing that is being auto loaded is the node to which the fade script
is being attached to, in this case, the Canvas layer. But we do not have access
to the animation player. So that's why we had to delete the reference
to this script and autoload the
scene itself, okay? So let me look for
faint and Alt, okay. So I hope that now
this is much clearer. And of course, if we
play it like this, we receive no errors over here, and we are able to access every single component
of the scene. So once that is clear, I'm going to define here a public function
because, of course, we are going to collin
it from other places, and I'm going to calling
it change scene. And this scene is going
to receive a parameter. Basically, the target sin, and this is going to be in
the form of a string, okay? And this won't return
anything, so boil. So basically in
every single change that we have in our game, we have to go ahead and
modify with this function. Every easy way of
doing this is to go to search and finding files. And in this case,
we're going to look for change scene to file. That was the function
that we were using. So I can click over here, and instead of doing Get
change scene to file, I will do fade dot change SN. And as you can see,
I am providing here the exact same scene
that I had before. Now, let's do it, but over here, so this is going to be
paint dot change scene. And just for now to check that everything is
working as expected, I will get three dot
change scene to foil, and I'm going to provide
here the target scene, okay? So the scene that we're
going to be changing to is going to be the
one that we provided, for example, over here, and where else did we use this? Let me check it once again. And also here, instead of
reloading the current scene, what we're going to be doing
is fade dot change Tin. And here to reload
the current scene, I will basically grab here. This was in the game
O, so I want to reload the actual main scene, so I can just drag
and drop it over here without having to hold down controller or
anything like that. So until now, everything should be working quite similarly. But you will note that now I am not able
to press the button. And this is basically the fade over here has this color rect, and this inside is able to
filter the mouse input. So as this is on top of
every single canvas layer, we have to make sure that it mouse input is
basically ignored. So we're going to
using here Ignore. And now you can see everything
will be working as before, but, well, now we
have to actually be implementing the fade.
39. Adding Scene Transitions: Hi there, and welcome
to this new lesson. In this one, we're
going to actually be coding the scene transitions. So to win with this, we now have this new
function that we are going to be using whenever
we are changing scene. And well, now we actually how to use the animation player. So first of all, what we have to do is that as
soon as we change a scene, we are going to be fading in. After fading in,
okay, basically, when this animation
has finished, we want to play this
exact same animation but backwards, okay? And basically when we
also do this animation, okay, we want to change
to the target scene. I know it may seem quite
complicated, but it is simpler. So first of all,
let me close this. What we're going to be
doing over here is to call animation player dot play fade. Okay? So first of all, we're
going to be fading in. So what we are doing is
basically this, okay? Then we're going to wait
until this fade finishes. And as we have done before, we have to use the await
keyword over here. So animation, player
dot animation finished. All right, so we're
going to wait until this animation stops playing. Now, when this animation
stops playing, which basically means that
the fade has been completed, it means that we should be
loading in the next scene. So this is okay. We had to
change to the next scene. And when we are on the
next scene, of course, we don't want to leave this
black rectangle like this. We want to fade out. So we're going to play this exact animation
but backwards. So we're going to be doing
animation player that play, but in this case, backwards
and once again, fade. Now, also, if we're
going to play, let's make sure that our
faith is in layer five. This is something that we have seen in the previous lesson. But actually, I did the
change in the main scene, but not in the actual scene. So let's just make sure that
that is set in layer five. And there we have our
scene transition. Let me now loose over there. I will go to a main menu. But there we saw something weird happening with our game being
posed when it shouldn't. So let's see it again. Let me collide here with the vehicle. I would press for restart. And I going to see, there
are some seconds that the game still plays. So let's check here in our game over script that is the one that
is handling this. And here we have the problem. As soon as the restart or menu
buttons are being pressed, basically, the posing is
not set to tread anymore. We're changing it to fold, so the game is continuing. But we only want to pose the game once the fade
has actually finished. So what we are going
to do instead of this, I'm just going to
be deleting those. I will come back
to fade over here, and I will add
here a validation. So what I will do is that
if Get dot post, basically, if our game is post when we
finish playing the animation, we're going to basically
unpost the game. Okay, we could basically say here always just pose the game, but there could be
some circumstances in which the animation
finish up playing, but the game would not be posed. For example, as soon as we start playing the game
when we press here, play, and this
animation finishes, the game was not actually post. So we would still be unposing the game when it was
actually posted. So just a small
optimization there. And for you to know this,
I will just print here. And post, okay? And this line is
going to be cold at the very beginning, okay? And if we weren't adding this, it would be cold, okay? So we wouldn't be wasting
a little bit of resources. And see there it was cold. So just for you
to know that now, also something that
you will know, this is that when I when
I collide with this, I am not able to restart
the game anymore. And that's because
our node over here, it's process as we have
seen isn't to inherit. So basically, this is possible. And in that situation in
which we are in game over, our game is set to be post. So this node is not
processed anymore. So there is no faith and
if there is no faith, there is no actual scene change. So that's why we're
going to change process mode,
actually, a always. And why not when post? As we have done, for example, with other notes throughout the game. So let me check here. For example, I believe that we have done this with these ones. Yes, with the restart
and menu buttons. Because remember that the
restarts and menu buttons, we only show them when
the game is sober. And if the game is so, it
means that the game is post. But actually, the fade can also happen when the
game is not posed. For example, at the
very beginning here, the game is not posed, so
here we should be fading. And if I actually said
this to only when post, here, the game is
not post, okay? So the fade here would not work. And once again, if the
fade doesn't work, if this animation is not played, then the scene is
not transitioned. So that's why here we
have to use always. Now this will work correctly, but we are going to be
finding other issue. And that is basically, when I am fading here
in the game over, I am able to press like
multiple times the buttons. And even though maybe there is no actual
change or no error, the player shouldn't
be able to, like, press a dozen times in the exact same button when there is happening a transition. They should be disabled as it
was happening in the menu. I see there, the button
was being disabled. We can even check it
here in the code. So we also have to disable the buttons,
basically these ones. And how do we do so. And here we want to see the other
functionality of groups. Remember that previously,
we were using groups to just identify the player. We're adding it here
to a player group. And then we were using this
to detect when we were colliding with a player here in the main script. Let me check. I body, for example, here, if the coin was colliding with
a varying group player, basically, if it was
colliding with a player, then we would do the logic. But there is also another
functionality for groups. Basically, I can group
these two buttons together, get all the nodes that
are inside of this group, and do whatever I
want with them. So I will firstly
create here the group. I will basically call it button. I will make it a
syn group because I only want to assign
it in this scene, and there I got them. And now what I have to do
is inside of the game over, I will add a new function, what we call the sav buttons. This is going to be
a private function. That's why it has
the underscore. And in order to get this, we're going to
using a four loop. So basically, here the syntax
is the following four. Then you put a number for the collection of items that
we are going to be getting. In this case, we are going
to be getting buttons, so I'll call four button in. And here we have to put here the collection of items
that we want to get. In this case, gett dot
Get nodes in group. And in this case, we
provide the name button. So this will basically provide every single button inside
of our buttons group. Okay, you can name whatever
you want this here. Now, here what we can do on that we actually have
our button is to just o, for all this button,
just do button that disabled equals true. This will work, but there is one tiny new thing that
I want to explain. As you can see, I wasn't
able to auto complete this. Go wasn't auto completing
the word disabled. So here, if we actually statically defined that this
button was of type button, okay, what's going to having is that we are going to be
having auto completion. So just the small tip for you to actually start using static
typing also in your projects. Because as we have mentioned
in that specific lesson, static typing improves
auto completion, and this is a case in which static typing
indeed improves it. So now, basically,
after doing the faint, let's do disabled buttons and also right here,
disabled buttons. So now, as you can see there, the buttons were disabled. You can know that because their sprite is
changing a little bit, they become a
little bit lighter. So there we have it, and I am not able to click
them once again. Now, I just want
to fix something quite simple about
the first fade, because as soon as
the game starts, I do want to have
some kind of fade, and I also want to play
the fade animation as my this start game
animation is being played. I don't want it to
be played after. So we're going to be fixing
this in our following lesson.
40. First Fade: Hi there. And in this lesson, we're going to
implement and also here a fade as soon as
the game starts. So for this, this is going
to be quite quite simple. So as you may understand, we will have to create this in the fades great because, well, this has access to the
actual animation player, and this is an load, so we can quickly
call a function here. So this is the easiest
way of doing this. And we'll basically call
this one first fade. Once again, without
the underscore over here because this function, then we're going to be calling
it outside of this script. And this is not going to
return anything, so void. And by the way, I am declaring this below the change scene because usually when you are sorting your public
or private methods, you can choose your own order, but usually the most
important functions, the functions that
you are calling the most number of times go on the top and the
others on the bottom. So first phase, we are
only going to equaling it one time in the entire game, and the change
scene, we're going to equaling it more times. That's why it is on the top
and this one on the bottom. So first of all, let's think of the exact animation that
we have to be playing. Do we want a fade
in or fade out? Remember, fade in is this
and fade out is this. We fade in by just
playing the animation, and we fade out by playing
backwards the animation. So, of course, what we want over here is not to fade
in because if not, we would have a black screen, but to play it backwards. So considering this
in our first fail, what we want to do is
to play the animation backwards just as we
have done over here. So now from any scene, I can go ahead and
play this first fade. So I want this to happen
actually in the menu. So here, I'm going
to be adding this, so make sure to live there
the corresponding lines. And over here, basically
do fade dot first fade. And if you can't
see the completion, it is because you haven't
saved here your changes. So make sure to save them. And when we come back, we should be able to see there
we go, first fade. So now when we press play, we do see our initial fade, and there also the
fade is working fine. However, there's
something I want to modify that I've also mentioned, and that is that I want
to play the fade at the exact same time that the Star game animation
is being played. The Star game
animation is this one, the one that moves things
outside of the screen. Okay, so as this happens, I also want to be fading. So I don't want to equal in it after this
animation finishes. This happens because of the
code that we have here. When the play button is
pressed, we disable it. We play the start
game animation, we wait until it finishes, and once it finishes, only
then we start fading. So in this case, I don't want to wait until
this animation finishes. I want to play it right away. So now here we are, I can press play. Okay, and we have the
exact effect that I want. Now also with this initial
fade, we have a problem. And that is that if I press
here play, as you can see, I can actually press play while the fade
is happening, okay? And that shouldn't be possible. We should only be
able to fade out when we are not anymore fading. Okay. So as we have done
with the game over, we have to disable this button. So we have to go to the
play button, disable it. But now, of course,
what is going to be happening is that it will
no longer be clickable. So when do we exactly
want this button to be to not be disabled anymore to basically become interactal once again. When our first
fade has finished. So how do exactly connect this? Because remember that the
fade here is an auto load. We have no direct access to it. We only have access to
the auto load pattern to a Singleton pattern here. So actually, here we are
playing this first fade, but how can we make
it so that here, okay, when this
animation finished, as we have done over here, we magically, let's say, connect to the menu scene, we take the play button and we make it
interactable once again. And this is another
amazing usage for signals. Remember that we
have previously used signals that we were meeting
here on progress made. In order to communicate
our main scene with every single vehicle instance
that we were spawning. So signals indeed make communication between
scenes and scripts that are completely
unrelated and getting a reference to
them would be complicated. And they make the code super, super clean and efficient. So in order to start with this, I will over here
define the signal. And they are name with
past tense verbs. So first, fade, finish. This is clear enough. So basically, when we finish
up here playing fade, our first fade, actually, we'll make sure that this
signal is being emitted. Now, of course, remember that this itself is not
going to do anything. Yes, we are emitting
this signal, but there are, let's say, no listeners, no scripts that are listening to this event and reacting it to the signal. Sorry. So we have to listen
to them, connect to them, subscribe for them, whatever
word makes sense for you. So over here, let's
come back to the menu. And okay yes, we are playing
here the first fade, but here we should also be
listening to this signal. So first of all, I will create
here the receiver method. Always remember
that this is with an underscore on because it's
usually used for signals. Then you use the node
name or the scripts name, in this case, fade and then
the actual signal name. First, fade finished.
Just like this. You can also go ahead here, copy the signal
lane to make sure that everything is
spelled correctly. So basically, when the
first fade is finished, we basically want to
enable the button. So we'll copy this line, but I don't want
it to be disabled, so I will make it fold. And now we actually
have to listen to connect to the signal
that was emitted. So we do fade dot first pay. Let me save the
changes so that I get the auto
completion over there, first finish, dot connect. Here we just provide
the function, the receiver function name. So that we have it, we
should have no errors. Now as you can see,
when I start playing, this button is not
clickable and now it is. I can go here to the game,
play whatever I want. I can come back to
a menu. It is not clickable and now it is. This is how we are now
able to transition between scenes with some
amazing fade effects.
41. Vehicle Engine Particles: Hi there and welcome
to a new lesson. In this one, we're
going to be adding some particles to our vehicle that we basically
try to simulate the engine smoke that is
emitted in real life. And for this, if we try to add no something
called particles, we'll find two particles. And well, here, the description
is not quite accurate. Basically, they say
that CPU particles, CPU based to the
particle cemeter and GPU particles to the
particle e meter. So which of these should
you actually be using? So according to the latest
information until today, I'm going to be leaving
a link to this article, by the way, that is from
the official Goto website, as you can see. And basically, it's
all about particles. And here's explained that they
always try to keep parity between CPU and GPU particles. In reality, you can
basically convert from one type to the other
with just a few clicks. But as you can see,
keeping this parity, it is becoming a little
bit complicated because of all the changes that
have been doing with the new version good
at four with changes in the GPUs and CPUs that have been released in the past
years, et cetera. So to avoid falling in
more complicated topics, here they clarify exactly
here what's recommended. First of all, no more
features will be addted to CPU particles because
of different reasons. So to always keep up
with the latest things, they basically recommend
using directly GPU particles. So that's why we're going
to be using exactly this. Now, in terms of particles, I already have created
here this effect. But the best way of learning particles is basically
creating lots of effects because
there are a lot of things that have to
do with particles. So we have here some options
that have to do with time. You can also have some
collision, or more stuff. But here, you tend to have a process material of type of
particle process material. So this will allow
you to actually customize the particle itself. This is the process material, and then you have
the e meter itself that we determine
for some of the lifetime of these particles, the speed, explosive
naps, et cetera. So first of all, we can't
barely see these particles, as you can see, they
are super tiny. So first of all, let's start off going to our
process material. I will just make this it bit
bigger, so we can see it. And here under this play, we can see scale, okay? So let's start
basically over here. In this case, I'm
going to provide a minimum scale of 15
and a maximum of 18. So now you can see
it is much bigger. But as you can see, they
are always the same size. But what I want to do is
to add a new texture, a new curve over here, okay? And in this curve, I can
basically do the following. I can make them
start at full size. And as time goes
by, as you can see, I am just going to be
reducing its size. Also here in display, you have color curves. Okay, so this will allow you to actually modify the color. And what I want here
is a color ramp ok so it creates new gradients. And this, as you can see, creates a gradients
that is going to be applied throughout the particle. So I can open it up these gradients and at
different points. I can have here a point, I know, let's make it violet and
there it is changing. And with the right
click, you can delete some of the points. I actually have here the
colors that I want to use for this particle. So I want to have one
color here at the end, in this case, of the particle. And this is going
to be a dark gray. In this case, the color
code is 58, 58, 58. Okay, it is a dark gray, then I will put another point, something like over here, and this one is going
to be 907-90-7907. There we have it is a
slightly lighter color. And finally, something
like over here, I will put another color. And in this case, the code
is going to be E two, E two, E two. And that would be all. And lastly, here at the end, I will basically just
fade out the particle. So there I have effect
that more or less, I think that looks quite well. I mean, in terms of
scale and color. Now, also going to
say, our particles have gravity because they are moving down and we
don't really want that. So here in
accelerations, gravity, you can turn this off basically set them to
have zero gravity. But then well, we are not
actually moving our particles because the only force that was being applied was gravity. So basically, to fix this, what we're going to be doing is that in animated velocity. Sorry, in spun, here I can
set the actual velocity. So I will give it over here initial velocity of something like 300
and a maximum of 400. Okay, so there we
start to see something a little bit that we want. Now also I want to
change the angle because as you can see,
they are all squares. So just to add some
variety, some variety, I can basically increase the
angle here to something like -700 -722, 720 positive. So now, as you can see, I have different rotations for
every single square. Now, what I want to do is
list a little more particles. So something like ten
is going to be fine. Of course, the more
particles you have, well, you can see
the differences, but ten is going to be enough. The lifetime determines how long the particles live for
so something like 0.2, in this case, is going to be
better because as I can see, we do see some kind of engine. I know, of course, the engine
is at the back of the car. So first of all, let me
move it tilt to the right. And I believe that
something like 98 in the X, and also I will move
it little on the Y, literally to the bottom,
something like eight. So there we have it. But now, as you can see, our particles
are on top of our sprite. So basically drag and drop them over there so that
they are behind our sprite. And also something that
I want to do is in position in spun
actually position. I will change the spa position. Basically, the mission shape. I don't want to be just
one point because they are all being born in the
exact same point, and I don't want that so I want to use, for
example, a box. And for example, if you made
this box like super big or something like I
don't know, 1,000. Okay, so this is the
effect that you have. Of course, we don't want this, but just for you
to understand what this does, I could
give it, I don't know, 15th and 15 in X and Y, and this would change
slightly the effect. But, well, in this case,
I want to get zero in the X and five in the Y. So it's going to much little bit more spread around and not everything
in the same point. As you can see now, you have
particles in more points than in just one
exact same point. And you can even just
increase this elitit if you want to do
something like ten, so you will have
even more height, but I believe that five is
just the correct value. I also want to rename
these particles. I don't care if they
are GPU or CPU, so I will just call
them particles. So now let's play and
let's see what we end up having Okay, so we should have our
vehicles with the particles. And I was going to see
that looks amazing. But when I collide,
as you can see, well, we have this thing
that everything is glitching because we
have post our game, and the particles are
still being processed. And maybe you have
thought of changing the process mold from
inherit to possible, so the particles should not be processed anymore when
the game is posed. But this wouldn't actually, like, fix the issue cells. Let me show you
how the particles will continue being emitted. Or well, not emitted, but the game would not look correct. And if you set process
mode to always process, what would happen is that basically they
would always be emitted. So that's not something that you want because the game
is supposed to be actually bused so
these particles should stop being emitted. So we'll just basically set this to inherit so that
we can puse them. And in our following lesson, we'll actually get
to stop emitting these particles when
the game is over.
42. Stopping Vehicle Particles: Hi there, and welcome
to a new lesson. In this one, we're
going to actually be stopping these particles
when the game is over. So for this in our
vehicle script, I will need to reference
here the particles, so I will drop the reference while holding down control so that it is
automatically created. I don't want to have here
particles to as the name. I just want particles
that's correct. And what I simply want here is a public function
that then I will call the main from the main script once the vehicle collides
with the player, I will just stop the
particles from being emitted. And for this, below my process, I will create the
public function. I will call it DsablePicles,
just like this. Okay? Why over here? Because remember the code order, firstly they come
virtual methods, basically these built in
methods, ready process, physics process, et cetera, then public functions, and
then private functions, okay? So here what we simply
want to do is to call our particles and here
set meeting to be false. Now what we want to
do in our main scene, we have to actually
call this function in the vehicle that has
collided with the player. And here we have to do something quite similar as we have
done here with the coin. Basically, when we
are sentiating it, we need to pass the reference of the coin
instance or in this case, the vehicle instance
because here we don't have access to the vehicle that has
collided with the player. We only have access. So we only have access the body with which the
vehicle has collided, in this case, the player, but we don't have access
to the vehicle. So you have to do something
quite similar here. So when connecting this
function, the signal, sorry, we have to use divine
keyword and provide the vehicle instance
and also add it as a parameter in the
receiver method. So over here, I will add a COA. I will call the second
parameter Via two, which is going to
be a type area two. And then over here, what I will do is basically
Vhicle Disable articles. Now I actually need to provide
this argument over here, so I am connecting
it right over here, and I will put dot bind
to provide the arguments. In this case, as I have
already explained, the body is
automatically passed, so we omit it, and we have
provide the second argument. In this case, the
vehicle that is going to be the
vehicle instance. I remember that the vehicle
instance is the one that we have just spawned
a second ago here. But this keeps not
working as it should. Why? Because in the particles, its process mode
is set to inherit, so it will be possible. And when the game is over,
remember that it is posed. So we actually need to
process this node for a little bit more time so that it actually
can stop emitting. Because what happens
over here is that we are disabling
the particles, and right away, we
are pausing the game. So the particles actually
do not have enough time in order to stop being emitted. So we will basically select this process mode of the
particles to be always, and that will allow us to
actually stop emitting them. Okay, so let's give it a second until we can collide
with a vehicle. Here we have coin, and there we go. They have stopped being
emitted and we can restart the game and everything is going to work just fine.
43. Player Trail: Hi there and welcome
to a new lesson. In this one, we're going to be creating a player trail, okay. I'm talking about the player, something that I don't really like is that when
the game starts, the pay starts at
the top left corner. So I just want to
move it slightly to the left, maybe
something like this. So basically, I want to
add a trail behind it. And, you know, to keep
everything organized, as usual, let's add a new scene. And here, the type of node that we are going
to be using for this is a line two D, okay? Now I will call it trail. And I will save it, okay? Now, what we have
to consider for this is that this
has points, okay? So we can add, basically, if we go to select mode
and we adhere a point, I can add different points. I will adhere in ten, ten. So there we have two
different points, and I can add as many
of them as I want. But of course, we
have to do this, but as the game is running, just for you to understand that. So I will attach a
new script to it. Okay. And what we have to do over here is that
first we have a constant. As you see over here we had different points that
we were able to add. So we have to define a
max number of points. So basically, this
is going to be the length of our trail. So in my case, a max point is going to
be something like ten. I found that this number of points is going to be just fine. Now, as we have to be adding this point in the exact
same player's position, you may think that you would
do the same process delta. Now, if you did this
in process Delta, at least in the version that I'm using, everything breaks. So what we're going to do is that you just use
physics process Delta. Maybe if you're using a stable
release, you can try both. You can try it in physics and
in process Delta as well. And what we want
to do here is to add the corresponding points. So for this use the
A points method, and here we need to
provide a position. Just for testing, I will put here the get global
mouse position, so I will basically have
a trail in my mouse. I will use this button
to run this current and here I will have
this trail, okay. But as you can see, we still
have to slice it titled, and also a brand that
we have is that well, the points are not
being deleted, so the length is
endless for trail. As we receive here a warning because we are not using Delta, so let's underscore it, and as soon as we do so,
the warning disappears. By the way, you can
run the current scene with a shortcut F six, and you can actually run
the project with F five. So what we want to check
over here is that if points, basically, this refers to
this or here to the points. And if their size is
bigger than max points, then it means that we have
reached the maximum length. If that is the case, I want to co remove points zero, okay? So this will basically make sure that we get the length
of trail that we want. This is the length of
trail that I want, okay? Now, also as it
desists a little bit, we need to modify its width, okay, because it is too thin. So let's put a width of
something like 55, okay? So now we see it, okay. I'll show you what happens if I actually use process over here. It is the exact same code
that I'm using their process. Well, as you can see, everything
starts to break, okay? So for this, I will just
be using physics process. And I also want to
create a gradient. So in gradients, I will
create a new gradient, and I will basically
make all this white. But at the beginning, it's going to have no opacity, and at the end, it will
have full opacity. So this will create this pretty
interesting effect, okay? Now, in order to start
using this, of course, we have to add points inside
of the player position. So let's instantiate this
trail in our main scene. Right over there, and
also let's drag it below our play because
we want this to be displayed under our player. So now we don't want
to be doing this with adding points in the
global most position. We want to be doing this
in the player position. So we can basically drag here and drop this while
holding down control, and we'll automatically create a reference to the player node. I will leave here
one empty space. And here we basically add points in the player
dot position. Okay, now as you can
see, when I move, I do get the effect
that I want, okay? Now, also something that I
don't like is that when I collide with a vehicle and
the trail is not deleted, you can leave it like
this if you really want to pause everything. But as the trail is only drawn when there is
player movement here, there is no player movement. A quick solution for this is to just go to the trail
and here in process, make sure that this
is set to always. Let's save the
changes, play again. And now as this is always
going to be processed, even if the game is
indeed post, well, then the player the trail
would just disappear, okay? Now also an effect that is quite interesting is the width curve. So I will add this curve and add a point there and a
point at the bottom, and I will show you what
happens if I do this. So I press over here play, and there it is our effect, but actually, I
wanted to do it in the opposite way,
just like this. So basically, our trail is now, shrinking as the time goes by, and it looks for me at
least a little bit better. But as you can
see, we're getting like, lots of fares here. And as far as I have
been investigating, this is something
that has to do with this Dev version over here. That basically when you add a width curve, like,
everything breaks. Because if I open the
exact same project in 4.3, you may see here some stuff
related to the audio itself, but we are not going to be
paying attention to that. Um and I will go
basically to the trail. As soon as here, I do not have
already set a width curve, but let me add one, okay, in the exact same way
that we have done in the other version,
and I will press here, play, but let me open
up the menu scene, and then press here, play. You may see some things
a little bit different, okay, but do not mind them. But you can see the
With curve here. Let's play for a
couple of seconds, and you will see that there is actually no error
that this return. You will also see that the
other score background, kind of breaks, this
is an error that is actually fixed in
the Dev update. That's why I'm using that for
this course because if not, we will have this awful effect over there in the background. So now, as you can see, I'm getting here, no errors. Okay, so this is indeed a bug from the version that I'm using. So here, feel free for you
to actually use the trail, okay, with a width car
of something like this. If the version that you have doesn't have
any kind of error. And if it is a table version, you shouldn't be having
any kinds of problem. But I just wanted
to point that out. Because in the actual project, I am not going to us
with curve because, well, basically, it
breaks everything. And in reality, if I
just play the game like this without any
kind of with curve, it is quite interesting, but you can see nothing happened. But, just a small detail for
you to take into account. I would play for something
like 10 seconds to make sure for you to know that
there are no errors. I'm just going to say
there are no errors, okay?
44. Sound Effects And Music: Hi there, welcome to
this new lesson in which we are going to be
adding audio tour game. Basically, sound
effects and music. So as I see, this guys
we have four audios. We have one music and
four sound effects. So let's start
implementing them. So for this, I will start
off in my main scene, and I will add just a note here to be able to organize
things a little bit better. And I will call the
first one just audio. You could technically play everything from the main script, but to keep things a
little bit organized, I will just play some of them in the main
scene and others, for example, in the
player because we have, for example, the jump. So in the player itself, we already have
access to the lining which we are jumping that
is basically over here. So, indeed, I'm just going to be dividing audios in the best way possible so that playing them is the easiest way possible. So here, I believe
the two audios that we have to
are the following. But in order to
play these audios, we must use an audio
stream player. Any, we find three types. We find Oil stream
player, two D, and three D. Basically,
these two and three D, they are meant to be used
for positional sound, basically sound whose intensity changes based on the position. And, of course, here we
don't care about that. We just want to play audio, so this audio will make sure
that all audio is being played at the exact same
intensity in spite of position. So I will add that one. Then I will call
this one di audio. By the way, audios usually
named as in animations, basically with the verbs, collect coin, die,
jump, et cetera. And I will also just
duplicate this audio, and I will also do the
colect coin audio. Why I have chosen to, um, actually integrate
these two audios in the main scene because
in the main script, I have easy access
to these two events. Basically, the die audios going
to be when I collide with a vehicle and they collect coin audio when the player
collides with a coin. So the access is much
simpler to play this audios. So these two, they
are already covered. And for example, the jump, as I have explained, we can play it directly from
the players scene. The music, we are going to
be seeing this in a second, as well as the UI, okay? So then we have to
load in the audio. So die this one and collect
coin is then this one. You can drag and drop
them or go to here. Quick load and load
them in, it's the same. And now we also how
to reference this to be played in order to be
played in our script. So I will basically select both select
one, hold on control, select this one,
drag them over here, press down control,
and drop them. So both references are created. So now I will go with
the collision over here. So what I will do is that
after disabling the particles, for example, I will
play the audio. Now we also live here in empty
space because here we are handling things that happen when the game over
is meant to happen, and here I am actually
doing the game over, so just to keep everything
nice and organized. And then here in the coins
over here, for example, after doing this, I will
be playing this sound. Sorry, after actually
collecting the coin, so collect coin ado dot
play because firstly, I'm doing everything
that has to do with the coins themselves,
for example, updating the UI,
playing the animation, and lastly, I am
playing the sound. And with this, these
two would be working. Now, remember that's, for
example, the die audio. After it is played, the game would be posed. So the audio would just play for like a
fraction of seconds, and then the game
would be posed and it would not be playing anymore. So we have to make sure that
it is always processed. We could just select these two, go to process and make them
to always be processed. But you can also go
to the audio node and we always will want our
audio to always be processed. So an easier way could
be doing this always, and as these two are inheriting, okay, they are going to inherit the audio and
the audio set to always. So they will always process. This is basically the
other approach that is available for when, for example, if you
remember in our UI, when we were setting the
restart the menu buttons to only process when post and
we set this for both nodes. But you could also just set these two to inherit and
set this one to when post. But, two different approaches, you can use whatever you want. In this case, we
only have two nodes, so it's not a big deal. But of course, if you
had a dozen audios here, this would be the best approach. Now, um for the music, what we want to do is
to play the music in every single scene in the
menu in the main, et cetera. So for this, I will
create another auto load scene
because remember that auto load scenes exist
in every single scene, something quite similar
to what happened with our faith that basically
exists in every single scene. So the only thing
that I need here is another audio stream player. I can call this one music audio, and I will quick load
the music, okay? I will just lower the intensity is a bit to something
like minus eight, and I will set this
to autoplay so that it starts being played as
soon as the game starts, and I will just save it. Then I will convert
it into an auto load. Right where it sits music audio. Okay. So there we have
it and we can add it. So as soon as the game starts, this music audio is going to be created and it's
going to be playing. Not only that, but also
in the music file, okay, make sure that
you have loop enable. So that's as soon
as it finishes, it should start once again. So make sure that
loop is enabled. Click Rinport and there
it should be looping. Lastly, we have a one
sound effect that is only meant to be played
when any button is pressed. Or, well, before
getting to that, let's finish up implementing
here the jump audio. So let me go to the
player over here. I will add this or string
player, jump audio. Let me quick load it. Jump. Now I will have to
reference it over here. And here when I am
jumping right over here, I will do jump audio dot play. So now, yes, we can
start with a UI. Once again, this is going to be an auto load because I want to play this sound
in different scenes. I want to because I have
buttons in the menu, Okay, how they play
button in the menu. And in the game over screen
that is in the main scene, we also have some buttons. So I have to make
sure that this node exists in all these scenes, and the easiest and
most efficient way is with another auto load. So audioStrm player
in this case, we called UI audio. Let me save it right over here. UI. Let's make sure that
we have all our scenes in the same folder and
that the scripts are also organized.
Well, yes, they are. So now, as we have
done with our fail, we just have to play this
audio wherever we need. So in the menu here on
the play button pressed, what I will do I will
leave here some lines, and I will do UI, but firstly, let's auto load it. So let's first select here
this UI audio scene, add it. And here I will be
able to call UI. Audio dot play. In this case, UI audio, is basically referring to this node itself to
the audioStrem player. So that's why I can
play it quite easily. And then also in the
game over screen, right over here, I can
get to play it over here, UI Aulio dots play. And when I press
the menu button, also I can play it. So UI audio dot play. What? So, there we have it. And with this, our
game is complete.
45. Building Your Game: Hi there. So now our
game is complete, and I will teach you how you can build your game so that you can share it with friends or do whatever you want with it. First of all, I want to clarify that I've muted the
audio in the recording, so that is not disturbing. Basically, the sounds,
the music and everything. So first of all,
something that I want to change is that here, when the game is opened, we want it to actually
be maximized. So this is something
quite easy to change. In the project settings, we basically go to
Window and inside mode, instead of window, we
basically choose maximized. Okay? So when doing this,
it will start maximized as a real game and to actually
export, this is quite simple. You just go to Project Export. And here in press
it, you press Add. And here you select
Windows desktop. Now, you have here a lot
of red lines over here, but do not worry
about them because everything is as
simple as pressing. Manage export templates,
download and install. And then here you will have
to wait a couple of seconds, a couple of minutes until
everything downloads. Take into account as
this is something like 1 gigabyte in sine, so it may take some time. And after waiting a
couple of minutes, here you have export templates are installed and
ready to be used. So when you do so, all
errors have disappeared. You just have a warning here that basically you
should configure the RCE dit tool in order to modify the icon or
up information data. Or basically this, for example, would allow you to set a
custom icon for your game. So now, what I recommend
you do is that you enable Embed PCK Because if not, you're going to having two or even three files once
you build your game. And well, you can
do it if you want, but how to send multiple
files to your friends or you how to store multiple files instead of just one executable. So I really encourage
you to turn this on. And also, when you press
here on Export project, this will actually allow
you to build your game in an executable format. You would select
your project path. In my case, I would say
it's in the downloads. We should have you should provide here
the name for a file. In my case, game is
going to be just fine. And also disable
export with Diva. This is once again to just have one file
instead of various. So click Save, we the
same warning about rec dit because we have
not set this tool, and therefore we
are not able to, for example, modify
the icon of the game. And as you can see right
here on my Donads, I have the game only
in an executable. Now, I have built
the game using 4.45. I will actually building in this version doesn't
work, as you can see. But, well, I will
now build it in 4.3, basically the latest
stable version at the moment of recording, and it will build perfectly. By the way, you may see
some warnings over here, but don't pay attention to them. They are usually generated when you change the version
of the project. So I will go to
Export over here. I already have the
template that is the exact same one with MBL, P CK turned on. I will press export projects. I will not export with Divog. I will press Save let's
give it a second. So there it is doing
everything that we need. And I believe that
everything is set. And I don't see now I have, once again, a game dot X file. I discarded the one
that we generated in the other version
to avoid having the same file with the same name that could lead to some errors. And when I open it
up, here I have the game working perfectly fine. And with this, you technically have your game working
perfectly fine. Once again, as you can
see the background, sometimes it doesn't
work as it should. This is basically an
error in 4.3 stable. But in Dev versions,
it was fixed. That's why I was
using a Dev version in the same place
because if not, the oscrob background would
not work as intended. Now, if you want to change the application
icon for Windows. Actually, the process in Goo
is a little bit complex. As you can see the documentation
actually explained this. I will be linking this
in the resources. But it is, like,
too much process for something that
is quite simple. It is not impossible to do this, but you do how to install
this tool over here. You also need an ICO file. So there are just
too many things that will need to
be explained and covered in a completely separate lesson or
even two lessons. So I don't think it's
worth it because you can already follow
the recommendation if you really want to do this. But I don't think that this is worth the extra time
for the course. Because the idea of this
course is that you are able to use GDT to create
your first game. And even as it was
quite easy to show you how to build your game for
Windows, that will be all. And then if you go to
actually go the extra mile, I am linking the
resource if you want to, you can follow it along. For example, here, they
explain this thing of cE dit to change the
icons and everything. So well, now you know how to
correctly build your game.
46. Congratulations!: Congratulations on successfully
completing this course. Indeed, you have
been able to learn actually a lot of
the Godot engine, and now you're actually
ready to start creating your own
stuff in the engine. However, before the course
ends, in the following lesson, I will show you some
ways in which you can continue on developing
this project. It really has a lot of potential in order to add some features. So I will see you
in the next one.
47. Develop The Game Further: By there. So yes, indeed, you have successfully
completed the game. But, well, this is not enough. Of course, you've made
amazing progress, but you still have to
continue learning, creating more stuff, et cetera. So here, I have put together some ideas that I have thought of and that are
probably going to be quite interesting if you want
to implement in your game. So the first one is to add
more difficulty changes. For example, you can add different vehicles
with different speeds. If you remember, we
had, like, five, six, seven vehicles that we were randomly choosing basically as the texture for our vehicle. So you could add something
that, for example, if the vehicle is the taxi, well, then it could go
a little bit faster. If it is, you know,
the green car, maybe it could go a little
bit slower, you get the idea. Basically, vehicles, different vehicles with
different speeds because right now all vehicles go with the exact same
speed or quite similar. So that is one addition
that you could do. You could implement
more decorations. For example, birds
flying across the sky. I think that the
decorations that we have, on the ground are enough. But maybe the sky that there
is is a little it empty. So you could look for some kind of sprites out there on the Internet with
a bird flying around. And you can basically
insentiate that bird flying from end to
end of the sky. And that would be quite
quite interesting as well. Then if you want to add
more player customization, you can create some kind
of player sprite selector. For this, you can look for more pixelar characters
online on the Internet. There are actually a lot
that you can find for free. So that is something that
would really encourage you to add because it is something that you
sometimes have in video games that you can
select your own skin. And also you can create
settings menu to, for example, enable and disable the music and also
the sound effects. Once again, this is a feature
that tends to be inside of video games because some
people may not like to be playing with music
or with sound effects, and others may like to
play without music, but with sound effects. So they are more
player customization.
48. Thanks So Much!: So yes, this is the
end of the course. But for the last lesson, if we can even call it a lesson, I just wanted to tell you, thank you so much. Out there, there are just too many go to courses
that you have taken, and you have chosen this one. So I really appreciate that, and I really hope that you were able to learn
a lot of things. My two passions are creating
games and also teaching. So this thing of
creating courses is something that I
sincerely enjoy a lot. So I hope that I
was able to show this passion and that was actually helpful for
you in order to learn. Oh, I hope we can
see each other in the next one and see you bye.