Transcripts
1. Introduction: Creating a space shooter is a classic way to get introduced into
creating video games. In this course, we're
gonna go ahead and take a look at a few
different mechanics, including a scrolling
background. Classic for games like this, having different pickups
that we can get an activate, we're going to create our
own little explosions using the particle system. We're going to create
a multi shot system to go ahead and join and learn how to make a
space shooter today.
2. Where To Download Godot: All right, welcome everyone.
And if you do not have the engine in order to
create our game here today, then you can head on over to Godot Engine.org and you
can pick up directly from the website by selecting the Download
tab here at the top. You only need the
standard version to follow along
with this course. The mono version does
support C-sharp. However, we will not
be using C-sharp, though you can pick it up. There's no need to use it. Wouldn't use the standard
version, just fine. This engine is available
on Linux, Mac, and Windows, as well as available directly inside
of the web browser. If you know, how did you scoop? We can see, we can just
scroll down here a little bit and you've got your scoop
instructions there. On picking that up. You can also build this directly from the GitHub repository. And as you can see there, there is also a page that
you can pick it up on, as well as the steam page
that you can pick it up on. Wherever you decide to get
it is completely up to you. Either way. Just make
sure you pick it up. And I'll see you in the next one where we can get started.
3. Project Setup: Alright, so once you've opened up the engine for
the first time, you'll be met with this screen. Of course, you won't
have anything inside of local projects unless you've already done stuff
in here before. But we're going to do is hit this New Project button here. You can go ahead and
give your project a name and browse wherever
you want it to go. And when you do, you can go ahead and just hit the
Create Folder button. And a new directory
will be created. For example, my demo game. If I hit Create Folder,
it'll be traded. You can use either GL ES 3 or 2. It shouldn't make any difference in this specific project. And if you're watching
this in the future, you're going to have to
Vulcan options here. Neither of what she's
really going to make any difference as to what
which one we select here. So for the purposes of this, I'm just going to leave it on OpenGL three-point. Oh, I see. No reason to change it. And I'm just going to
hit Cancel already. Have an empty one created here. So we can open that up. Alright, so now that we
have a project open, now that we have
our project open, we can go ahead and we
can head on up to project tab here at the top and we
can get our project setup. So what we're gonna
do is we're gonna go ahead and inside of the Config, inside of application, we're going to select
to use custom dare. And that way we can
have our logs go out to a folder that
has our game name, which will look a little
more professional. If a user needs to access
the logs for any reason, if you want to give
it a custom name, you can do that here. I'm not going to bother. I'm fine with just leaving
it as my project name. Now if we scroll down, we can look for
the section called display and go inside of window. Now for this background
that I've got here, that we'll be using it
as T2 and T4 by 400. So that's what I'm going
to set our window to. Now we'll adjust the
actual size of this later. But for now, this is what we're setting our window
into, 224 by 400. We're going to set, make sure
it's on our handheld or set it to portrait and
infrastructure. We can set it to 2D and
the aspect to keep. And now our project
is ready to go and we can jump in to the next video and start
actually getting things done.
4. Scrolling Background: Alright, so the first
thing we're gonna do is we're going to set up our scrolling background
for our space shooter. Since our player
is not going to do any actual movement as far
as like traversing around, like you would see in
like a platformer. In a space shooter, the background actually
moves and the player stays stationary and moves around
on the visible screen. So to do this,
you're going to take the textures that I've
included in this course. And you can go ahead and
bring them into your project. For the time being, I just
have a sprites folder here. And I have my
background, Brendan. And I have a folder here called
scenes where I'm going to keep all of my individual
scenes that we create here. The first one we're going to
create will be called World. That was going to hit 2D scene here at the top or root node. And I'm gonna go ahead
and rename mine world. And then you can go ahead up to scene or up here and Save. Or you can hit
Control C or sorry, Control S or Control Shift
S to save your scene, I'm going to close this one because I have an empty
one created here. And there we go. You should
have it looking like this. This is how our
project should look. And you can see this
faint blue outline here. That is basically our Canvas. This is what it's going to
be rendered in our window. So anything inside of this blue rectangle
will be visible. Anything outside of it will not. So I'm gonna go ahead and bring
in my background dot PNG. Now we can just drag it in and we can just
drop it in like that. In our case, since it's
going to work as a sprite, is perfectly fine that
we just drag it in. In some cases, you may want
to hit the plus button up here and add in whatever it is that
you want to look for. In this case, it was a scrape. And then you can just drag the image right into the
texture slot here on the right. Now I'm going to
make sure that this is setup properties here. I'm going to move mine over
to the left, one down one. That way it fills
up my whole screen. And now when I hit this
Play button up here, the play scene button on Windows shortcut is
F. As you can see, I'm going to hit that
and I should now have my own little window and see this background
taken up the entire thing. Now I did say that we will adjust this window size
later because again, depending on your monitor, this may look huge or this
may look extremely tiny. We go, I brought my window
up here on the screen. So what you see right over
here in our little red box, sorry, it's not a
little red box view. Which she here, this is now exactly what we
see in our games. This off to the
right-hand side there. So as you see for you, this might be super small or this might be extremely large depending on your
monitors resolution. I'm not going to know that. But when we change
our window size, you'll be able to tweak
the values in there. But for now we can see it
covers our whole window. And it looks fine. It's just it's not moving. So what we're gonna do
is we need to actually create our movement for this. And all it's gonna do
is just move down. So we're going to
create a script. Now you can right-click
on our background here and select where, where's our task one right
there, attached script. Or with it selected, you can just hit the attached script button up
here at the top, which is the way
I normally do it. Either way you'll be brought
up with this menu here. We're going to use the
GD script language. As you see by default, we have visual script, kiddies
script and native. And if you have the mono versus, you would also have a
C-sharp option in there. But for this course, again, we're just using GD
script that selected, it inherits from a sprite
because that is the type that our background
is, the template. We can just leave it on default. We don't need any
built-in script. And our path inside of our
scenes, we don't want that. We want to keep
things organized. So we're going to create a
new folder called scripts. And that's where we're going
to stick our background script and hit Create. Alright, so we have
our variables here. And we'll go ahead and
create one for scroll speed. Now we'll use colon equals and we can set that to a number. I'm going to set this to ten for now and we'll see
how well that works out. We're not going
to need the ready function that we see here. And as you see what
the note here, this is called as soon as are the note enters into the
scene for the first time. That's not what we want to do. That'll do something.
Just a onetime. We're actually going to
use the process function. So that's something can happen continuously with both
lines selected here. I'm just going to hit Control
K to uncomment those out. And we can remove the
pass function here. And we can call
self dot position. Got y. Because y is gonna
be the up and down. And we can set that to. Now I always get this
confused on whether positive it's up or down or
minuses up and down, right? So let's see, let's do plus equals and we'll
see how that works out. I will set that plus
equals our scroll speed. Alright, we'll go ahead
and test out our scene. And that moves down for, that is moving super fast. So the first thing I'm gonna
do is multiply or scroll speed here times delta. And this will help our game
be frame independent as well. So regardless of how many
frames our player has, which should we find with this being a really old
school type of game? And the graphics not being
all too demanding here. But either way we're doing this, this should keep it scrolling
at a nice smooth amount. Regardless. If we take
a look, as we can see, this can move a lot
slower as well, which is why I'm going to tweak this option before
touching my screen. Now, how fast you want
it to move is gonna be completely up to you. It's gonna be completely up
to you and your preferences. I think I want to slow
mine down a little bit. Let's try nine or a
little more extreme. Let's try cutting,
cutting it in half. See me here to five. Alright, I think, I
think I like five. So I think that's what
I'm gonna go with. And now what we need
is we need our image. You actually resect. You see when it goes all
the way down, it's gone. So what we need to
do is we need to, after we set our
position, we can do. And if check here, we could check if self
dot session dot y. We could check if it is
greater than a set number. In this case, the
number would be 400. Say greater than
or equal to 400. However, if we take note here, notes close that off
to remove the error. If we take note, we noticed that our position is actually in
the center of our image. So if that's going
to be passed 400, then we're still going
to see half part image. So we need to add
in half of that in or half of our
image into that. So in this case it's
going to be 600. And all we're gonna do
is we're going to set the position of y back
to what it currently is, that you can click on
background and you can get that right
in the inspector. But since I know that's
in the middle of that should be 200. And if I come in and
take a look transform, my y is definitely at 200. So for purely for checking
that this is working, I'm going to change
my sweet to 15. If we take a look, scrolls
down just a little too slow, Let's double that up
to 30 for testing. And we can see it moves down and as soon as it gets to the
complete bottom of the screen, it should be right
back at the top. And just continue
scrolling on down. Here we go. Here we go. So now the problem that we
have here is obviously we can see the image or the lack
of an image behind it. And we could obviously
see that this image ends. So this is most
certainly a problem. So we need to tweak
some of these options. And what we're gonna do is
we're going to set this to, we're going to create
a new variable called Let's set this to reset. What did we call it? Reset? Let's call it reset scroll. I'll say minus
equals, set it to 0. Now notice I'm using
export var here. And if you are watching
this in the future, maybe using version 4.01 of
the changes that you will need to do here is actually put this at sign before export. But if you using version three, you're not going to need that. What's that? What that is going to do is
wet background selected. You can see over on
the right-hand side, we can change the
number of this. Now for our specifics. We need 600 for
this specific one. So we can set this, our position y if it's
greater than or equal to. Reset scroll. This way since its
x-coordinate here, we can use the same script on another one that can have
completely different numbers. So we can do another one for
export bar, start scroll. And with this we can set
the starting position, which is 200 for us here. And fill this in
replacing into our code. Alright, there we go. If you have, do you have any error that pops
up about a node? Let's go ahead and hit the
stop button at the top and open it back up,
or replay the scene. And you should see that
it works perfectly fine still. Which is great. Because now we can add completely different numbers
with a second one in here. So I'm gonna go ahead and select my background hit Control
D to duplicate it. And I'm moving my second
one right on up top. I'll just make sure this is set perfectly so we don't have
anything showing in-between. And now we can just tweak
what our numbers are here. So our starting position
should be minus 200. And our reset scroll, we should have a minus there. Would that be positive
200 possibly. But now if we go
ahead and run this, we should see just look
like one continuous image. And when it resets, we're not even going
to notice it because everything is going to
be perfectly lined up. So it's going to always look
like one constant scroll. There we go. We now have our
scrolling background. Again, just go on in there and weaker speed to whatever
you would like. And if you're
wondering why we're not exporting our speed, simply because we
don't need to change the speed value for both
of our backgrounds. We can just leave this as
being the same number. So we can come down here and we can change it to five now. Or if you wanted to use and, or 20, whatever you want
to use for your game. You see me come in and
everything works perfectly fine. We now have a scrolling
background for our space shooter.
5. Window Multiplier: Alright, in this video, it should only take us a bone which has to be a pretty short. We're just going to tweak our window size
now so that we can have get that out of the way now rather than coming back
and addressing it later. So what we're gonna do
is we're going to put this inside of a global script. Now, this may also be referred to as an auto
load or a singleton. All depends on the
environment that you're in and who it is that
you're talking to. But they're all generally
considered the same thing. We're just, it all
really depends, really like the singleton
will be in a design pattern. A global is something
that's referred to a lot. And in here they're
called auto loans. But what I'm gonna do
is I'm going to come down into my biosystem here. Select scripts, right-click it, and select New Script. And since this is
a global script, I'm just gonna go ahead
and call mine global. Hit Create. I'm going to come up here to project,
project settings. Go into the auto load tab, rouse or open file path. Let's select our global script. Press the Add button, and now you can see the
script that's being loaded. It's enabled,
meaning it's active. And the name that we see here, you can come in here and you can change that if you would like. I'm going to leave mine
as disagreed the word global and that word, that name is how we're going
to access this script later. If we ever needed to access
anything within this, whether it's variables
are other functions. So what we're gonna do is we're just going to use
the ready function here. And we can go ahead and set OS dot window screen a window size. Our window size is equal
to our OS dot window size. And we can set this to
whatever our multiplier is. If you want, you can
come up here and create a variable for size multiplier. And the reason why we're setting this with a colon equals. If you are wondering, rather than just using an equal sign, like you see here,
which is also valid. But using just the equals here, it's going to set it to two. However, if we with
the colon equals here, it's also setting it to the tight on that two is an integer. So it'd be the same as
if we went like this. Only it's where would they do this by writing
lesson with an int, it's not terrible, but sometimes you may have something really long
like dictionary. And this is really
shortens that whole, shortens that whole thing up into just start two
characters here. We're setting it to two, as well as declaring the
type as whatever two is. So with this, if we run this, we'll see now that
our window opens. And now I have to
resize this on here. But I see now it opens up. Our window is double the size, which depending on
your screen again, this might be a lot easier to see what's going on and be a
lot more playable for you. But now you can come in
and he's just change that size of multiplier,
whatever you want. So if you want to make it
smaller, you Doug 0.75. If you wanted to, if
you're on like maybe it's 720 P screen. Or if you're on a
Fourier screens, you can increase this multiplier
to maybe a four times multiplier to get
something much larger. And we're also maintaining this, the resolution and seeing
exactly what's in here and not moving
outside of our box. Remember, due to
our setting here, stretch mode by having
the mode to 2D, setting our aspect
to keep. Alright. So now that we have that
running at all times, our windows set and we move on to some more
interesting things.
6. Player Setup: Alright, let's go ahead and
get our player's setup. So the first thing
we need to do is create a brand new scene. So you can do that
by hitting the plus button up top here. And instead of creating a normal node to D like
we did for the world, since this is going
to be a player, we want to be a
kinematic body 2D, so we can hit the
other node here. And we could just type in kinematic and we
can share it there. Kinematic body TD. Go ahead and select that. And I went ahead and I renamed
my player and saved it. Once you do that, it should
look like the following. Hear the word mother's
yellow triangle. We'll go ahead and solve
that in just a moment. Let's just telling us
that we don't have any, we don't have our
collision area setup yet. So as a player doesn't know
how to apply any physics. The first thing I
want you to do is if our player is blurry and the supplies again to
your background as well. So I bring it in here. You can see that
mine is not blurry. I turned my filters
off, but if it is, you can go ahead and select it down here in the file system. Go up here to the import
tab in the top left. And you'll notice filter here, check and turned on you on, turn it off and import. Otherwise, if it is on, it'll bleed blurry like this. Which for some games
could be fine. But for pixel art,
this is terrible. And you'll see the difference
here again as I turn it off and hit the
re-import button again. It makes a huge
difference in pixel art. So make sure you have
that turned off or every texture that we
use in this project. So I'm just going to
delete that out of here, since that's not how we're
actually going to use this. And that's it. I don't want have to worry about placing it in the correct spot. So what I'm gonna do now
is I'll select my player. I'm going to hit this Plus
button and get the sprite. And now it is going to be locked right here in the middle
where it should be. I'm going to grab
my sprite sheet and drag it right into the
texture slot of my screen. Now there are many ways that
you can do an animation. And in this case, I have a broken
up for each line. So we can see in the
first line there, we have our idle animation where we're just kinda
like flying straight. And then our next
two lines there, next two rows were
turning left and right. So in order for
us to use this in a normal sprite
for a spreadsheet. We're gonna go into this
animation tab here. And we're going to
set eight frames, which is the horizontal to two because we have two columns. And then vertical frames
we have three rows. So I said that three. And now we have our first one and you'd be able to
change between them using the brain button
here, as you see. And that's basically how
we're going to work with creating an animation
layer. Later. For now, we still have
our yellow triangle here. So let's go ahead and
select our player again. The plus, bring in a
collision polygon, sorry, I collision shape. A basic shape will do
just fine for us here. And we can just use a rectangle. You can go ahead and fit this however you would
like to your player. I'm gonna go ahead
and just extend my notes a little bit like so. And I'll leave the tip
off the tip me just fine. Alrighty. So the last thing
we're going to use here is where we need, we will need it.
So let's go ahead. We'll add another thing
into our player here. And this will be the
animation player. What is going to,
where we're going to end up creating animations and playing them from during certain instances
that we need them. All right, so that'll do it for the player creation and
the player's setup here. Next, we'll go ahead and jump into getting the
movements setup.
7. Player Movement: Alrighty, Let's
go ahead and jump into getting our
player to move around. Because if we were
to play this scene here, it's pretty boring. You just kinda sits up there. And if we go into
our world scene, and if we hit this
chain icon here, we see we can have access to our other scenes
and we're going to grab our player scene. We just go ahead and move into position of where you
want your player to be. I'm going to set
mine right there. And again, if we'll open
it up and take a look, when you see it's
not very exciting. It's moving, but our player, it's just kinda sitting
there as a stationary image. So we can go ahead and fix that and get
that moving around. We're gonna go into our player. On our player scene.
We're going to hit this Add Script button
and we're going to add a player script to it. Now, remember to go ahead
and put this inside of your scripts folder
to keep things nice and clean and organized. And go ahead and create it.
And this is what we have. So we're going to need a
couple of variables here. One of which It's
gonna be our velocity, and this is the main one. We're going to
need, var velocity. And we can set this to colon
equals to a vector, chew. And you can either open up the parentheses and
put in 0 comma 0. Or you could do vector two dot and then the word
is 0 in all caps. Both of these are
the exact same thing and produce the same result. The reading function here
we're not going to need. And let's go ahead and create one more variable for our speed. And I'll go ahead and
go ahead and set mine to set mine to 100, and we'll see how that looks. Next up. We have our
process function. We can uncomment that out again just by selecting
and using Control K. And inside of here is
where we're going to have our functions here. And the first one we're going
to need is moving slide, move underscore and
underscore slide. And we have to pass in at least one argument
for this to work. And that argument is just
gonna be our velocity. Now with that and the problem, we're going to see an error. Now, if we go ahead
and start this up, and you see an R T
bugger down here. We have two issues that pop up. Now these issues, if we
go ahead and click on them and go inside
the Errors tab, we can see delta has never
used in the function process. So we can simply put an underscore at
the beginning of delta. And that'll tell the
entrant to ignore this. Ignore the fact that
we're not using this. And our second one says
that returns a value that is never used and we
never need to use it. So what we can do here is we can actually
put in a comment. And that comment is
just to click over. Sex spot we need is additional. So we're going to use a
comment I called warning, dash, ignore, colon, return, underscore value,
underscore discarded. And that's going to ignore the discarded value
of the next line. It's essentially
put on line nine. It's going to ignore
that the value on ten, or second error here from moving slide that gets
returned is discarded. And if we wanted to, we
could do the same thing for delta as well. So we could do this
with, if we would like. We could go above the process function and
we could use warning dash, ignore, colon, unused argument, and get rid of this
underscore before delta. And we should see both of
these completely be ignored. And it's only going to
be for those two lines. This is just a very
temporary thing that's created or that
tell us the answer and to ignore the following error
that precedes this comment. So you can do that,
have those either way. But that, those are two different ways stuff to you, which way you want
to go about it. Now for the movement itself, we're gonna go ahead
and create a function called movement. And we're going to call
movement above moving slide. We're gonna do here is we're
gonna go ahead and check if our button is pressed. So we're say if input. And for now let's use is. Dot is underscore,
underscore breast. And the scan code
we can put in here if you know the number,
you can put it in, but odds are you don t.
So we're just going to type in key underscore
d in all caps. And we can put a colon. And then the next line
we'll do a velocity dot x. So we just wanted to access
the x value of the velocity. So the first number and the D key is typically associated with
moving to the right. So what we're gonna do
here is we need to set this going to the right
on the x-axis here, and we're going to the right. It's going to increase a number. So this is gonna be
a positive number. What's this equal to? Speed? Now if we run this
and we hit the D key, and she, we're
moving to the right and we just keep on moving. If you want to create a a button in the form of
the name of an action. So if you don't
want to do is keep pressing and put it
into key like that. We can actually hit
up two projects, project settings called
the input, input mapper. And this allows us to create controls for our game
extremely easily. Or the action here, I'll
just do turn, right? Add. And now I can hit
this plus button. And I could do a key. And any key I put in here, I'll put it in the D key here. I can hit okay, but
I can also come in. And if I wanted, I
could go Command key and we could do the
right arrow if I wanted to. So if I want to
support both WASD and arrow keys, I can
certainly do that. And I only need to
make the one command. We're doing this.
And how we would use this as instead of
using his key pressed, we're going to do
is action breast. And you'll see your action
pops up and bills in here. So we can select turn right. And if we were to run that, Oh, we need the colon on
the end. There we go. Now if we run that and
we hit the same thing, we had our D key that we assigned to the
turn right action. We're gonna go ahead and
move on to the right. And of course we move into the world and take
a look at that. There we go. So what I want
you to do is I want you to go ahead and take a shot at having yourself be able to
turn to the left now. And as an extra challenge, I want you to see if you
can figure out how to make herself stopped moving when you're not pressing either
of those buttons? Right? Go ahead and take a moment,
pause the video and give that a shot and a moment. You can unpause
it. And we'll take a look and I'll show you how
I went about doing this. All right, welcome back. So here we're gonna go with the first thing we're gonna do is we're going to say else. So also, if we're not
pressing the right button, our velocity dot x
is going to equal 0, which got to stop
us from moving. So you see if we now hit
the D key, we move right? And if I stopped,
we stopped moving. Okay, so if our
buttons are not being pressed, we stopped moving. Great. Now something that you might try is you might have
come in and said, if input is action
pressed, then turn left. Which at the moment
does not exist. I'm gonna have to go
created here in a second. Then you would access
velocity dot x. And if you remember what I
said is going to the right, we're going to
increase in value. So going to the left, we're going to
decrease in value. So it's gonna be
a negative speed. Now let me just go create
this button real quick. Turn left. And I set this to my achy. There we go. It's now
you might see if we hit D, nothing happens anymore. We can't turn right. But if we use a, we can certainly turn left and we stopped, but
we can't go right. Now all we have to
do to fix this is actually set this to an LFO, also called an else-if. So if we do E, L, I, F on R turned left
instead of a regular, if those two letters will fix everything in this code and everything in the now
work the way it should. Because we're, we're
checking if one of these bugs or press
what I'm looking for. All these different
requirements. Although I will agree
that it is a little French at two F's don't
really work here. And this aspect, but when coming to
doing movements anyway, you're usually just want one
direction being pressed. So if we run that now
and take a look at it, we can go right, left, and we stop every time. Alright, so next we can take a look at animating our layer. And we also need
to take a look at stopping our player from going
off the screen like this. And there's multiple
ways that we can go about doing that as well. All right. I'll see you
guys in the next one.
8. Player Animation: All right, so let's go ahead and animate our player. In this one. We're going to need to create
some animations for it. So let's head on over
to our players team. I'm going to hit a to D
at the top here so I can take a look at what's going on. And we can select our
animation player. Now this is what
holds our animations and our sprite up here. As everything inside of it. We just need to trigger it to look like it is a,
an animating image. So we can go into our
animation player, hit the animation of what
down here at the bottom. Select New. We'll call this
idle. For this animation. I'm just going to make
it 0.3 seconds long. I'm going to set it to loop down here in the bottom right. Again, still we haven't
gotten anywhere with chains. Arc length is 0.3. We hit the looping
button here to make sure it's turned on. And what we're gonna do is we're going to now select our sprite. We can take a look
at our frame here. And we notice we have these keys that show up now
in the inspector. Now what this does is this
allows us to make a key frame inside of our animation
for anything we have here. And what we're going to keep
rhyme is our frames here. So if I hit this key, we don't need a reset track, but if you want to leave that
on, it doesn't hurt any. And I'm going to
use Bezier curves. And this case is, again, it's not really going
to matter with the, with the spreadsheet, but
I'll go ahead and hit Create. So you see we have our
low time frame here. Just make sure that
your little marker here is at the very beginning. And we can go ahead and
create that keyframe 0. And then 0.2, I'm
going to create the keyframe for changing
it to frame one. If I just play that
back while loops, we can see we have what
looks like our flame activating and having
a little flicker here. And we can go ahead and do that for her and left and turn right. Of course, we're not
going to use frame 01 and we're going to use the, the next set of rings. I want you to go ahead
and try creating the turn left and turn right
animations for yourself. And pause this video,
give it a try. Come back, and I'll go ahead and step through it
and if you had any problems, hopefully, we clear
some things up for you. All right, welcome
back. So we're gonna go into animation and
create a new one. We're going to do turn left. And let's see which
ones do we have that we indeed have
turned left first. So I'm gonna come down here, change my length is 0.3. Turn looping on, go
to the beginning of my track with frame set to two, I'm going to create a keyframe. It create. I'm going
to move to SharePoint to do the next frame, which is frame three. Great, Another key point. And I'll hit Play to loop that. It seems to my first
frame got messed up. So I'm just gonna go back
to the beginning here. Kinda suck to chew and hit
the keyframe button again. And there we go. If I hit play,
everything looks fine. I'm going to do the same
thing for turn right. Create new animation. Turn right. Set this to 0.3 loop and turned on
will go to the beginning, go up to frame four. And I'm just going to frame
that again just to be safe. Jump up to 0 to go to
frame five. Hit the key. That was already on
five, so I need to teach six and hit the key. There we go. Let's
try that again. My numbers are weird again, so I'm gonna change
that back to four. Jump up to 25. Here we go. For some reason we're
holding the animation. The first frame there always
seems to be a little weird. In some situations. We will go ahead
and play that and there we go, random mating. So now we need this to
actually work inside of our script anytime
we're moving. So for this, we're going
to create a new function. Animation or animate rather, just keep it slow
or keep it small. And we're going to call
this animate function up here inside of our process, just like we did with movement. And all we need to
check for is if our velocity on our x-axis is larger or smaller than 0, because if it's 0,
we're not moving. If it's smaller,
we're going left. If it's larger,
we're going right. So we can go ahead
and we could check if velocity x is larger than 0. Yeah, okay. So if
that's larger than 0, we're gonna go ahead and we can use the dollar sign to access any property early on
or to get our node. But what I'm gonna
do is I'm gonna make this a little cleaner. Look at here. So I'm just gonna go back
up to my variables here. I'm going to do on ready, var, say an M layer, Excel and set that equal to
dollar sign animation player. Now again, if you're in 4, I believe with an already here, you will need the at sign. Let's see. I guess we're in three. That's just going to
throw us an error. So now we can come back down
to our animate function. We could just type
in and in player. And it will reference that
animation player node here. And we told it to get. And we could do dot play. And we'll be turning
right when x is larger. So if we go ahead and try that, we can see that now animate. Only now of course,
we get stuck. Same situation that we
had with our movement is our animation turns to the right and then we're
stuck there on the right. We don't change back to being back to our little
idle situation here. So if you would like,
go ahead and take a moment here and see if you can figure out to get
our turn left and have us return back
to normal when we're not pressing
either button. Alright, welcome
back. Let's go ahead and tackle this situation. We're going to do just like
we did before with LLF. We are going to get
our velocity dot x. We're going to check
if it's lower than, if our X is lower than 0, meaning we're
moving to the left. And we're going to go ahead
and set the animation player, so Anime player, play. Turn left. Now we have to get the other situation on the case that we're not pressing
either of these buttons. And just like before
we can use else. And in player dot way Idle. Now if we take a look
at that, here we go, We're turning both
left and right, and we return back to normal and we're not pressing
either of them. We can take a look
at that inside of our world and how we have
ourselves a moving player. And that's all we need for
animations for a player. So if you wanna go ahead and add movement to move
forward and back, That's gonna be on the y-axis. So if you want to set that up to be able to move
forward and back, you can certainly do that. And I think we can go
ahead and you can add, add that just for the
specific use case. Now remember if
you're turning right, we're going to set
our velocity to 0, just like we're going
to do one else. What you would do that for the y to see if we do velocity
dot y equals 0. And of course going to set
them on Alice as well. And we will do the same thing l, if only we could do
something like forward. Now of course we just
influence our velocity. Not why? We are speed, whether that's
positive or negative, is going to determine whether
or not you're going up or down or when you're doing that. We're not going to be
moving left or right. Now. I don't have my button setup, but that's essentially what you're gonna do and you gonna do the same thing for
backwards only of course, is make sure that you've got
your speed setup properly, whether that's positive
or negative on the Y. So you can move forward
and back if you want to add that functionality
into your game.
9. Diagonal Movement: Alright, in this video, I'm just going to show
you quickly how you can create 8-way movement. So if you want to move on a diagonal, you're
going to be seen. If we take a look here, we
can move left or right. Extremely quick. Oh, that's because
I have changed. Here we go. So you'll see here you
can move left or right, or you can move up and down. If you don't really move. At the same time, we see if I move up and I press right.
Now, Let go over it. I'm still moving on
that weird angle that we have going on there. So all I'm gonna do is
I'm going to remove the all of our zeros sets here. So our buttons are
only going to change the one access, the extra Y. We're going to take
our else block here that sets everything to 0. We can remove that completely, change our ellipse or else if statements into
just an if statement. And at the top of movement, we can go ahead and set velocity
equals vector two dot 0. And that's all we need to do to have proper diagonal movement. That works properly and we
don't have any weird issues. So if you want to
have 8-way movement, that's how you can go
ahead and do that. Again, that's why we're
moving our zeros. So if you remember here, I wouldn't return, right? We also set velocity y to 0. And when we went up and down, we set velocity x to 0. Well what this, by
removing those and putting velocity equals vector two dots here at the
top of our movement. We can go ahead and have some good 8-way
movement in our game. So if that's something that
you want to have in there, That's how you can go ahead
and go about adding that in. Now, if you notice there is
one thing there in rats, when you move on a diagonal, you're actually moving faster than if you move left or right. So all I'm gonna do there
is we can set the velocity equals velocity dot
normalized times speed. Were to try that. Now, you see we keep a consistent speed regardless
of if we're going straight, sideways, or on an angle. Right? So that'll do it for this video. That's why throw
the end real quick. So I know some of you will
probably want 8-way movement. Asks you, in a way, kind of like modernize your game a little bit
and not be stuck so far in the past where we only had the two separate directions
and we add one or the other. So that's how you
add in movement. And in the next
one we'll go ahead and take a look at how we can stop the player from
going outside of our screen.
10. Game Barriers: Alright, so welcome. In this video we're going to take a look at how we can stop the user from going
outside of the screen. As you see, we go left to right. We're going to completely
go past the screen, which is not what we
want for our player, same with going backwards and forwards will completely
leave the screen. So to accomplish this, we have two methods
of doing this. We can go with the
invisible barrier method, or we can go with checking the player's position
relative to you, of course, the size
of our project here. So if we want to go to
the barrier method, we can go ahead and create a static body
here in the world. Create a collision shape. Assign that shape,
have a rectangle. If I just grab that static body, I'm going to lock
the collision shape here so I don't grab
a hold of that. So I grabbed the static body
and just move it down here. I can now lock this. And if I extend the felt like so that's it. That's all
we would have to do. And of course, we can apply
that to all four sides. And we could block the user from going outside
of the screen. So of course we can
go at the bottom because we don't have
a barrier down there. But that's one way that you
can set that restriction. Now for going over here
to the right-hand side, we're gonna go ahead and
use the second method that we could use for that. When we turn right, we are going to check
for a second condition. And not position dot x
greater than roughly why 92. And how I got that
is our witness to 24 and I'm just subtracting
off our sprite. Now if we move to the right, you see we have that
barrier there that gets put in the game or
not. Let us turn that way. And then the left
side, of course, you can see we still have
our turn animation going. We just can't go any
further to the left. So there are two completely
different methods. It's fully up to you. Which method you want
to go about doing this? Two to 08. You go. So we have the exact same, we're right up against
the corner. Now. You can see it with one method. We're still playing our
animation and trying to turn. And with the other
one, we just come to a dead stop and we
don't move at all. So we're not turning. So which method you want to go for is completely up to you. Just keep in mind that if
you'd want to do the barriers, you have to set it
to four barriers around all four sides. If you have the full movement, a forward, back left Android. And the same with
your code here. If you wanna go the code route
here and do your checks, you're going to
check it positioned on X on your left as well. I didn't check your
position dot y for your forward and back. And of course forward is 0 is going to be at the top
of the screen here. So 0 would look
something like that. And then of course,
if except 400, which is the bottom
of our screen, we would have
something like this. So you have to do your
own calculations as well. So I would say do
16 for the top, do 384 for the bottom. And then of course the
left-hand side over here, we can just do 16 and features. How I got that, the
origin of our player. Remember if we take a
look at our player scene is in the middle and
the sprite is 32 by 32. So I just took half of that, which will be 16. So that's how I
got those numbers. So which method you use to block your player off
is completely up to you. The benefit of doing the
invisible barriers, of course, means that you can always
just take it and adjust it at any point and visually
without having an issue. Of course. The other one, the benefit of the other
one is we don't have that stuck animation look while we're trying to go to
the end, whatever direction. In this case, our occurrence
completely up to you. Personally, I'm going to
apply the code method here. I'm checking my position
into my check shear. But if you want to use
the invisible barrier or approach with
the static body, that is completely okay.
11. Shooting Ability: All right, In today's video, we're going to go
over on how to create a shooting mechanic
or our player. And whether you shoot one
reject out to projectiles. However you want to manage,
that will be up to you. But I'll be using I think, two projectiles or at least
to shooting points in here. So if you want to use one, you'll need to apply to one. If you want to use multiple, you'll see how we can apply
it to multiple locations. I also have multiple
projectiles here. We have three different versions with and without
the black outline. It is up to you which versions
you want to use for this. And if you want to see how they look with different colors, as he wouldn't go into
the visibility tab here on the visibility
section on the inspector. With them selected, we can access modulate and we can
change the colors here. So if you have a
specific color in mind, you can certainly change that to whatever you want to use. And that should give you an idea of what all of these look like in the various
different hues. So for myself, I think I'm
going to go ahead and use, again project out to Alt, so without the black outline. So this can be my
default default shots. So I'll go ahead and now that I know which
one I want to use, I'll go ahead and
get rid of all of those points and we can
create our projectile, seen someone create a new scene. We're going to go ahead
and create our projectile. And I'm going to set that as a kinematic body 2D so we can have our
physics applied to it. I'm going to add a sprite to it. For our laser darlings,
our projectile. I'll bring the one
I want to use it to the texture slot
here on my screen. We can get rid of this
little triangle by adding in our collision shape. And in my case, since I'm using this one, I can use a circle shape
and shrink that down. Now if you're using
a different shape, if you're using the
laser boy standard shot, then you can make, you can use the rectangle. Of course, if you're
using the other ones, you can also use a
sphere or a rectangle, or a circle or a rectangle, depending which route
you want to go on, you can cover the whole thing or coverage is the one end of it. And I'll go ahead and save
this, this projectile. Save it, put this
inside of my scenes. Save that. Now
that we have that. In order to shoot a projectile, we're going to need
a shooting function. So I'll go to my input map
and create a shoot action. And I will set this
to big my space bar. Alright, now we need
our projected out to actually move, right? It's no good if we shoot it
and it doesn't go anywhere, it doesn't do us any
good at that point. So let's go ahead and
we can add in a script. Make sure to place that
in the correct location to keep things nice and clean. Scripts project
down normal dot GD. And much like our player, and we're going to
need a velocity. And I can start out as
an empty vector two. We're also going
to need a speed. And let's go with, I'll say a 100 for now, we'll see how that
changes later. We're not going to need
the ready function. Actually, we can use
the ready function. So that's a hold up on that. Keep that here, and let's
add the move and slide. You can also use move in class, but I tend to always
use move inside myself. I never I haven't
needed to move and Clyde and in this situation it's not gonna make
any difference anyway. The collider slides is pretty
much what happens when two, when the two bodies
run into each other. So with moving slides set
there and are ready function, we can take the velocity and we can grab the
y property of it, and we want it to go up. So we're going to set
it to a negative speed. Now if that works, it should
completely disappear off our screen here when we try
it and we don't see it. So it's either gone
or it's too small. Either way, we can
take a look at that. And you can see in our debugger
we have 22 issues there. They are the same things
that we had in our player. Just now on our projectile
are two comments back in. I do also want to know if you do want to get rid of these. Off from showing up
and you don't want to use these comments consistently, you can either ignore them, which I personally wouldn't
necessarily recommend, or you can head up into I
believe it's in the Rajah. Yes. And just search warning. And under GD script you'll find the unused
argument right here. As well as you should
find one for the return, return value dish got
it right here as well. So you can just turn
both of those off if you don't want to be
putting these comments in that alternate
way at it in there. We've now hit over
to our player. And I'm going to add
in a position to d. Little hard to see here. There it is. And you can set this to wherever you want your
projectile's to spawn. So in my case, I'm
just going to set mine I'll set mine Ray,
right about there. That's fine. Of course. You can make it as close
as far away as possible. I'm going to name this left
left projectile position. Spelled that wrong. There we go. And I'll just duplicate
that and add a second one. On the right-hand side. I'll make that right
project Alpha position. And those who are
gonna be my two points that I'm going to shoot from. So now going into our player, we can create a variable
that has our normal shot. We can set that to a preload. And that'll take an argument of our projectile
seen that we created. If we take a look in scenes, we have our projectile normal. Go ahead. You can copy the
path or you can drag it in. Like so. And what
that's gonna do is when our player gets
brought into the scene, it's also going to load up that projectile normal seen
for when we need it. Instead of loading it on the
spot, will already have it. Alright, so let's go ahead and we can create a
function for shooting. And what we're going to put
it in here is we need to create an instance
of our normal shot. And then we need to
put it into the world. So we'll say Create new
variable that's temporary. Got shot in the
Stanford shot instance. And this will be
equal to our normal shot variable that we just created up top dot instance. Now, all we have to do
is set the position. And the, well, we don't
have to set the velocity. We already said that we just
have to set the position to shoot up on our own
or on its own rather. So to make this easier,
we'll go ahead and create another on ready bar at the top. For our left. We'll call it left
shoe position. And would create one for the
right-hand side as well. Position. Here we go. Sam would come down here
and we do get our shocked. And do dot position to access the position property of it. And we'll set that equal to, we'll say our left
shoe position. Position. Now, we want this to only happen when we
shoot our projectile. So I'm just going to highlight
those two lines and hit the Tab to move it in. And I'm going to
stick out inside of an if statement saying if input is action, just press or you can go with just
released, it's up to you. I'm gonna go with just
pressed and we're doing it. So this happens
the onetime and it doesn't continuously happen
while we have it down. That's the difference between
just crashed and action. Press. Action pressed
means we can hold, hold the button down while
the button's pressed down. This is going to
happen consistently. Just press means it's going
to happen the onetime. When we push the key
down, it'll happen once. And then that's it. Make sure to call shooting
inside of our process. And if we go ahead
and run this now, we should be able to
hit our shoot button. Oh, my mistake, I forgot
one crucial thing. We set its position,
but we never actually added it
into the scene. So something to take note of here is we don't want
to add it to the player. If we add it to the player,
then it's going to move. When we move their
player left and right. Then our projectile is
going to move in the air, which isn't going
to make much sense. Since we're not creating
like a laser for our normal, we need to add this as
a child to its parents, so we're going to add
it into the world. So in our scripture,
we're going to yet, which will be the world. And if you're wondering how I know that if you
take a look here, you see we have this
like a tree function. We have this line coming out of the player and then it goes up and the first thing
it hits its world here. So that's get parents. And it's the same
thing with these, that these positions here are
the parents of our player. But our script is being
accessed from the player. So we're going to run the player off one, which is the world. We do get parent dot, add child. And it will pass in that shot. And now we should
be able to see it. Alright, so one small change their note that
instead of position, even though it says positioned
in the inspector here, and if we hover over
it, it says Position. What we actually
want to use this, want to set it to
left shoe position dot global underscore position. And that'll actually you place
it where we want it to go. So now if we go
into our world and play this, you see
when we shoot, it goes there and it's just pushing us back just
because it's a little vague from doing a little
bit of testing to try and figure out why
we reset the scale to one on our projectile. And we'll be back to
normal. So you go. So now we have our
projectile going, obviously we only have one going and that is
still pushing us back. Just a little bit. Little oddly. So I'm gonna go ahead
and grab both of my positions and pushed
them up a little bit. You could tell it to
completely ignore player, which we can take a look
at doing at a future date. But for now, let's move forward a little bit and
you can see are shooting. It's not working perfectly fine. So again, to just go over that, go over our shooting
or shooting function, we check if our shooting
action is just press. So that only happens once when
you press the button down. Then we create a new
variable that will hold an instance of our shot. What's a normal
shot dot instance? And then we set the
position of that. So if that instance, the shot instance, we get the
position property of that. We set that equal to
our left shoe position, which is a position to D that we brought
in on our player. And we set that to the
left shoe position, duck global underscore position. And then we're not going
to see anything unless we actually add it into the name. And we want to add it
to our players parent, which is our world. Note they're gonna
wanna get that node, get his parents, and then add child and add our shot instance. As a child of that. We're going to come
on in here and since we have two positions, I'm just going to
create a second one. So I have a shot in-situ. Now we'll set the second
one to our other position, which is our right shoot. And make sure we're accessing
shot in number two, this. And then we have to
make sure we also add that one into
our scene as well. So we're gonna get parenting
and child shot into. And when we play this,
we should now be shooting both of our
projectile's at once. Now, as you can see, if we
were to expand the button, we can get a lot of these cell. Now whether you want that
to be intentional in your game or not is
completely up to you. If you want to add some
type of cool down to that, can easily add that in as well, just by checking if
the player can shoot. And if not, then we don't
allow them to shoot. There we go. We now have a inability to
shoot some projectiles. And again, you can make
this whatever color you want and your projectile seen just by changing the modularity to
wherever you want. So if we change it to the screen and we come in here
and shoot books, we have to come into
here and shoot. We now have a green projectile. So you can make that
whatever color you want. You can make them two different
colors if you wanted. That's completely up to
you and what you wanna do. But that's how we can add a shooting mechanic into
our little space shooter.
12. Creating Power Ups: All right, Welcome. In this
video we're gonna go over creating our power ups and get those spawning
into the world. And the reason we're
going to tackle this first before we
get to the enemy, is simply because the
enemies are going to use effectively the
same system that we can introduce with power-ups without confusing it with any
AI or behaviors hernia, that the first thing we
need to do with the power, of course, is create our power. Let's create a new scene. We're going to select Other
and make it a kinematic body. I'll rename it to our up. It's going to need a sprite, of course, because we need
to show what the images. We're going to have
an animation player. What else can we do? We can set it to, we're
going to need an area. And that area will have
its own collision. Now I know we have this yellow
triangle on the powerup, but we don't have to worry
about that because we don't need that to have
a collision shape. What we need is for the area to have a collision shape that
way you can detect from our player enters it
or interacts with it. And for the collision shape, I'm just going to set
it to a rectangle. Okay, for our sprite, we can go ahead and drag
in our spreadsheet. Sprites, power up, bring it on in AUC we have health
shields, speed, animal t. Now, we can set this of course eight frames
and it's going across. We have six across, and we have four vertical. And now we can just use
the Animation player to create our frames. And if you only wanted to
have one of these colors showing, you, certainly can't. Otherwise, we're going
to animate it to have it loop between all these colors and sounds like a little
rainbow flash going on. It's going to be up to you how
you want to go about that. But that's all we have to
do nor to set up our power. Go ahead and save that scene. And then in the next video, we'll go ahead and we'll tackle the creating the animations. And I guess setting up
our setting up our code. Since the majority of her at this moment is just
gonna be the animation.
13. Animating Power Ups: Alright, let's go ahead and jump into animating our power-ups. Let's go ahead and select
the animation player. Am going to select New
from my animation. I'm going to select Health. And now with it
being 1 second long, I'm going to set this to loop. I'm going to set
my snap to 0.15. Now you could always set
this to whatever you want. How VR app asks you want
things to move for you. For me, I'm going to
use 0.15 and I'm going to use frame 0 for my first
frame here. Hit Create. I'm going to staff up
to 0.15 0s frame one. As you see, it's
going to advance, booked the frame on the snap, as well as the frame and
my number here so I can just keep hitting keys. And now we've got
our health setup. So if I go ahead and play that, we've got this
health with a bit of a rainbow flash on the text. Again, if you don't want this, you can just set it to being one frame for the
entire animation. But that's up to you. I personally like the rainbow, the rainbow RGB switching. That happens. But of course if you don't
or you don't want that, you don't have to have that. And we're gonna go ahead and
create the same thing for our other animations.
I'm going to stop that. Go into animation new, and we have shields. It. Okay? And our frame
will start on six, back here at 0. Insert this key. Devin will be our 0.15. Makes sure that it's looping. And it will set this
again, 67891011. And if we play that, we
have our shield animations. Fantastic. So we just have
two more to create here. This will be our speed, is 0.15. Loop it, go back to
0, cetera, animation. Frame 12. Move up for 13. There we go. We can
play it to review. It. Looks great. And our last one is
a multi Snap, 0.15. Luke the animation. Go back to the beginning. Started on animation 18. Delete that last frame
real quick and play that. Here we go. We have a nice
animation going with that. And just like that,
we have all of our animations created
for our power-ups. Now of course, if you add more to this sprite sheet
and create your own, by all means, more animations. Use more, make more power-ups. I'm just gonna go
ahead and save that. And we can head into
our powerup script. Now, what we're
gonna do to get this to work as far as
the future goes, is we're going to
create a new function called create power up. And that's going to
take one argument. That argument we're
going to call tight. And we can catch
that as a string. Now again, we don't have to put this colon string in here. You could just have tight. However, we should get
used to it because in larger projects this is gonna give us a slight
increase in performance. Casting all of our
different variables here, variables,
arguments, parameters. So it is something that we
should get used to doing. So what we're gonna do here in create power-ups
is we're going to set our variable from tight. So we're going to
have a, our type. We're going to set our type
is equal too tight. That way. This specific power will know what kind of power
but is which will come in handy when we pick up our powers later and
interact with it. And the only other
thing we're gonna do is set our animation. You're going to get
the animation player. We're going to call play on it. And we're just going
to pass in tight. And that's all we need to do
for animations to work here. So whenever we pass in whatever our type is, that's
what's going to work. So for example, just for
demonstration purposes here, we'll go ahead and
we'll do create power up and we'll call it. We'll pass it and say health. And if we test this scene, we can see it's animating and it's our health
power-up up there. And if we were to
change this to, let's say speed, try this again. We have our speed
power-up up there in the corner and that's animating. So everything's
working as intended. As far as the
animation to go in. The next video, we'll go
ahead and give our power, some movement and create a spotter for it to appear
in our world randomly.
14. Power Up Spawner: In this video, we're
gonna go ahead and create the movement of
our Power of Habit coming from the top of the screen and come
towards the player. So to do this, we're going to need a few of our
standard things here. The first one being velocity
added into our power up. So far, velocity colon
equals vector two dot 0. We're also going
to need a speed. We can set that to,
I'm going to use 200 for this process, we have to pass in our move and slide with velocity as
our first argument. And for our ready, we can say velocity dot x dot y because we're moving
vertical equals speed. Now we're using a positive
because we are coming down. If we're doing negative
would be going up unless I got those backwards. We'll see in a second and
let's test our scene. And there it goes,
moving down our screen. So I do have those in the,
the correct orientation. Alright, so now we
have those going. I'm gonna go ahead and
grab my two comments again from my player. And I'm going to pass them
into my Power Apps here. Avoid any confusion. We go. And now we have
movement for power up, and we have our
power of animating. We need to actually
spawned it into the world. So for this, I'm going
to create a new scene, select other for my node. And I'm just going to
use the basic node that you'll find
at the very top. And this will be by spawner. I'm gonna go ahead and
rename it spawner. This spotter will
have a timer on it. Now the amount of time
that you want to set it to is gonna be
completely up to you. For this purpose. I'm just going to set it
to three seconds and turn autostart on my scene. Spider.js CAN add a new
script, my spawner. Make sure it's in
the correct folder. And now we can actually create the bonding application
of our power-ups. We don't want power-ups to appear placed all
over the map, right? We don't want to hand place
all of our power ups. And you'll maybe going
like 4 thousand pixels above our actual
scene or any of that. We want to actually
spawn it into the world. We want them to be randomized. So it's different what
powers will get every time. It's never the same.
It's actually do this. We're going to create
a few variables. We're going to create one
that holds our power-up list. Say power ups list. That's gonna be an array, a pool string array
specifically, that's just going
to hold health. Shields. Our speed, and multi the exact
same names and spellings of the animations
that we used earlier. We don't need to worry about
the process function at all or the ready function. The only function we
need to worry about right now is our timer. And when our thing times L. So I'm going to
select the timer, the node tab here at the top. Double-click on timeout
makes sure spawner is selected and hit
the connect button. Now we could have connected
this through code. This is true, but this is also
the simplest way to do it. If you are new to doing some
of this code on timeout. And the first thing we need
to do is call randomize. And it's going to
randomize the seed and prevent us from having the same outcome
every single time. Because if we don't do that, our seed will remain the same. And for example, we
might get shield speed, multi health shield speed, multi health shield speed, etc. And that's not very random. It's also not very exciting. So we're going to
randomize it every time the timer times out. And we're going to
need a variable that holds our power obscene. Say r equals reload. And we will pull our
power obscene in. Now that we have that
right after we randomize, we can create an instance
of arsine bar power. Equals our up dot instance. So now that we have an
instance of our scene, we can set we set the position of where
you want it to span. Now, if we go across the top, we want it to be anywhere
random up here, random above. Now if we take a look at our
project and if you remember, you come down to our display. Our width is only 224. So that's what we
have to work with. So we're going to say
var position underscore x is equal to Randy, which is a random integer. And if we do a
percent sign followed by a number such as seven, this is going to give us a
random number between 06. So if we do 224, this will give us a random
number between 0223. Now, we can always change this. For example,
something we could do is we could do between 0201, but then we can also add
on an additional 23. So this will now give us
a number between 23224. And the reason is we're
gonna get our number. So let's say for example, we get 0, they get selected. We're then going to
add 23 onto that. So the lowest number
we can get as 23. And the highest
number we can get is since 200 is at
the top of our list, is 200 plus 23. So however, you want to decide where your spawns
work will be up to you. For the current time. I'm just going to go
ahead and use to 24. Now that we have a position, we need to get our random
power up that gets created. So we're going to work
this in the same way. We're going to say var
hour equals Randy. And we're going to
pass in another number using the percent. Only. This time we're going to use the size of our Power Apps list. Now what size is going to do is that's going to provide us with a number of how
long our array is, how many items are in here. So 1234, which means we're going to get a
number between 03, which works out for us because when we're
talking about an index, we have 0123, right? We started at 0. So size will
give us the perfect number. And if we were to add
other things in here, such as, I don't know, let's go with
explosion, right? Then. We don't have to change
our code at all. We can just change
or we can just add a new item to
our Power App List. Go to our power-up scene
and created new animation, and we will be good. We won't have to touch
our code at all. Now that we have the position
we want it to spawn it. And the power or the power that we want to be
shown and displayed in game would need to
actually set both of these two things and add it into our scene to be able to be seen. So to do this, we can get our power right or instance
of our power up here. We're going to set the position. We want the x property of that. So we want to set the exposition
of that to our position. Underscore x, whatever
that random number is. Now if we take a look at
our power-up script here, remember we created, made a function called
create power up, and we pass in a type. This type is gonna be the
power that we pass in. So the power type will
be one of these here, which is also the same
name as our animations. So we're also going to play an animation based off
of whatever we pass in. So we can go to power. In our instance here, we're going to
call create power. And that takes one argument. And that argument is
going to be our power. And those should not be
a capital B lowercase. We go, alright. So now we have our
position being set. We have the power type being set and our animation
should be getting played. All we have to do now is
add this into our scene. And since our spawner
doesn't move or anything, we just added directly
to our spawner. We say add child power. And now if we were
to play our scene of our spawner here and take a look. Oh, my mistake. It's creep power up,
not creep power. Alright, let's just save that and go back to testing
the scene again. Every time this times
out, we should see. All right, Once
smallest you here, I forgot how it
gives us a number. We still have to
access what that is. So we have to go into our, our, our x list. And the index we're going
to pass in as our power. My mistake there. I was jumping
ahead of myself a little. Now if we go ahead and test it, we should now see our powers
spawning in an animating. These are shield. And we wait for the timer
again, their speed. It's another speed. And we see it's
completely random. Every time we got
three heads in a row, That's a lot of speed for our character. There's
another shield. Speed, got a lot, a lot in the middle there, there's there's a
multi shot speed. We're not getting
too much in the way of health at the moment. There's a ship, we're getting
lots of shields though, which could be nice. There's a Swede. That's another speed we're
getting a lot of speak. Can we get one health in here, foreclosing? What
do we get an x? We got a multi. Alright, so apparently
we're not gonna get any health passed in
here for our power-ups, which is unfortunate,
but it is random. It will appear, trust me, it's just all up to
orangey at that point. Now all we have to do is go into our world and our little
chain icon up here and just add our spawner into
the scene. And there we go. We now have power-ups
spawning in our game. They don't do
anything right now, but they do appear. And we can always adjust our timer as to how we want
this to go in the future. There's a health we
got for ourselves. Now, one issue that we're
going to have here. One issue here is our power up. Sometimes we don't want it to
always spawn up, power up. We don't want it to be
on every 20 seconds, for example, or
every two seconds. Wanted to sometimes we don't get a power up and
sometimes we do. So for something like that, if you want to have that
random chance in there, just to add a little more
randomness into your game. Then we can create
another variable here called let's go. Let's
call it a chance. And we'll set it equal to
a random integer again. And we can pass in a number
a percentage of two. And now this is going
to say 0 or one. So we can say 0, it does not
spend anything, and it does. So for that we can match chance. I'll say 0. This will pass and
on one will actually spawn the power of what we need to tap this in
one more. Here we go. There we go. So now
we don't always have a power-up coming in. So to show this Wassup
rent under the 0, I will say no power. Let's go ahead and run into our world and we can
take a look at this. You see we got to power up
that time and if we watch our output sooner or
later, we should hit a 0. There we go. No power. No power again. Three no powers in a row cases. So you can see already even
though we have a short timer, since it is a 5050 chance here, we are really reducing
the potential. But at the same time, you can see we're also
getting a lot of powers. So if you wanted
to change this to, I say a 10% chance, then we can come in here
and we can say ten, right? We can set this to ten numbers, so 0 through nine. And all we have to do
is we can come up here. You can set this
to whatever number we want. It doesn't matter. So we set it to 0. For example. We could just pass in
the others as being a wildcard and say, no power. So now every however
long our timer is, I think it's 1 second. I don't
think it would change it. We only have a 10% chance
of a power up spawning. So however you want to do that, what do you wanna go
with the 5050 route? Or if you want to go with a
percentage chance like this. So this is 10%. If we change this to
a five and run it, we now have a
one-in-five chance. So one in five would be 20% chance of our
power up spawning. Which is a fairly decent, you can always modify
this as your levels go. If you have levels or you can
just make it one infinite scroller and maybe
adjust the number. So you can change the five there to maybe increase get overtime. But anyway, I'm
sure this video is getting fairly long
at this point, but there's how we
create power-ups. There's how we can
do the 5050 chance of whether it's
spawns or it doesn't. There's how we can do
a percentage chance of a power-up spawning. And remember, you can go
in and you could change the timer on our spawner. Here. You can select the timer and we haven't got
three seconds. You can adjust this to however, however long you want yours to be in-between
potential power ups. So with that, I hope you
have a pretty good idea. How do you create a power-up? How to spot them into the world? I'm gonna go ahead
and save that again. So you now know how
to create power-ups, add them into your list, create the animations for him, and spawn them into your
world for us to use. Audits left for the
Power Apps now is to actually be able
to interact with them and have them act accordingly based
on what they are.
15. Power Activation: All right, Let's go ahead
and create our power-ups and make them functional. That they can actually do things and interact with the
player wouldn't pick it up. Alright, so let's go
into our power-up scene. And we can select our area 2D. And we're actually
going to pass in a signal of body entered. Could pass that right on
up to our power up here. And now the first thing we
want to do is want to make sure that this is the player. So I'm going to check if player and body
and body dot name. And I can double-check. Yep, I do have my kinematic body here called
player with a capital P. So this should work. Sorry,
if player in and body dot name when come down here and we can have whatever
happened accordingly. Now of course we want this to be dependent on the type of power. But for now, we can
go ahead and print. And we can say power obtained. And if we were to play this now, when we run into our power, when one of them spawns, we should see that printed
out into the console. Boom, there we go. Power obtained. So the real question becomes, what do we want these
to do with each power? Well, we can use speed
as an example here. But what I want you
to do is I want you to try and figure
out how we can get the speed power-up to increase
the speed of our player. Alright, so go ahead, pause the video and
take a moment to do that. Alright, welcome back. I'm gonna, I'm gonna go through, and what I'm gonna do
is I'm going to use a math statement and I'm going
to match my power uptakes. So max power tight. And I'm going to say, if
the type is equal to speed, what I'm gonna do is
I'm going to access the body, which is our player. Remember, I'm gonna, I'm
gonna get the speed value, the body dot speed, and I'm going to
set that to 200. So whatever our speed is,
we're going to multiply it. And to avoid any errors for now, we're just gonna call him
the wildcard and hit past. So let's see how
that happens now. Of course, we have
to wait until we get a speed power-up to appear. If we're lucky, we'll
get one right away. You can see how slow
we're moving around here. And that should
double as soon as we get a speed power-up, that is Health, nothing happens. That's fine. Same with shield because this
falls under our wildcard, which at the moment is
not doing anything. That's more health. Their speed. We hit it and you can see
we're going much faster. Ready? Now of course shield,
we're going to miss that. If we get another speed
that should multiply. So I get, it's not even
going to multiply us because we were setting
it through hard to 100. We're not multiplying
the sweet at all. So this is all fine and dandy, but we also need to take a look at reducing our speed back
to normal at some point. So what we're gonna
do is first off, we're going to create
a new variable called speed multiplier. And we're going to
set that to two. That way we can multiply this
With Ease in the future. So we're going to set
this two times equals, which means we're going
to set speed equal to speed times whatever we put
on the right-hand side here, which in this case is gonna
be our speed multiplier. So we're saying speed is equal
to speed times multiplier, so speak Tom steel. And that'll give us
the same outcome is just a little more
modular because that would come up here and we
can just adjust this to whatever we want it to be. At the moment. I'm just going
to leave it at two times. Alright? So now we need a way for
the speed to wear off. So for my player, what I want is I want my speed. I want all my power-ups to last. I would say ten seconds. So I'm going to
create a timer on my player and call
it our app timer. I'm going to set the
wait time for it to ten seconds because that's how long I want my
power-up slash. I'm going to connect the
timeout signal to my player. And now when the
timeout happens, we're going to do depending on the power up that's active. So we're going to
create a new variable called active power. And that will just be a string. And we're going to say
match active power. So when our timer times l. So at the end of
our ten seconds, we're going to be what
our active power is. In this case, we're working
with speed as our example. So we're going to say
when our timer runs out, we're going to set our
speed back to normal. So we're gonna get our speed variable and set it back to 100. And for the time being, if we have anything
else, we'll just pass. Alright, so if we were
to run this, now, you'll notice there is, there is an issue here. Now if we go ahead
and we wait for this shield and you know what? I'm gonna go ahead and
print down here just to make sure that we're
not counting wrong. Speed normal. Let's try that
again. Nepali. Okay. Come in here with the
speed to show up anytime. Apparently which getting
really unlucky and not getting any power ups while we're
trying to test them here. As a super unfortunate. But it can happen, of course, because
it's all random. So it looks like
we're getting quite a dry season into our power-ups. Their speed, we got it. Okay. You can see we're
speeding along. If we look at the output, we can see any
second hour speeds have returned to normal. But it doesn't. And
why doesn't it? Because we never actually
start the timer. And that, of course,
it's gonna be a problem. We can't return our speech
normal at the end of the time if we never start the timer. So what we need to do back in our power up is when it's speed. Not only do we have to change
the multiplier or sorry, chase the sweet value. But we need to also
do body dot get node. Let's take a look.
What did we call it? We call it a power-up timer. So we're going to
have a string in here called power Tyrone. Make sure it's spelled exactly the same or you
will have an error. So power-up timer and
we'll say dot start. So we're going to
start the timer. And now if we play it, not only shutter speed increase, but the timer will start. And so when the timer ends or speed should
return to normal. But if you think about
it, we're still missing one crucial thing as to why our timer won't actually
return this back to normal. Can you think about
what that is? That's right inside
of our player. We're basing this off
of the active power, but we never set what
that active power is. So inside of our
power-up script, we also need to
set that as well. So body dot active power. Sure, I spelled that right. Active underscore power. We can set that equal to speed. Or if we don't want
to set it there. We can also set it up here when we know we don't want to set it. When we create the Power App, we only wanna do it,
wouldn't pick it up. So we have to do it down
here inside of our match. Alright? So if we try it now, or speed should increase. As we had before, the act
of power should be set. So we know what to do
when the timer runs out. And we should be starting at the timer so that
it can run out. Nothing happens. And we just wait
on for the speed. I had a typo in my name. Here's the problem. I have a capital I and my timer. I need to fix that. There we go. I Aaron
out due to a typo. That's why it's important
to make sure that you spell things exactly the way
that you had it before. Because when we're
comparing strings, and uppercase and lowercase are two very
different characters. So let's go ahead
and wait again for another speed
power-up to appear. This is why we always
test the code as we go. We don't want to. A bunch of things in and
then test it and have like 30 different errors from all these different
locations appearing. We want to make sure that
we catch the error when it happens so that we can
fix it immediately. So we just wait for that
speed power-up to appear. It's another health.
Boom, boom, boom, boom. Shooting. That still works. We get a screen that's shield. There's a speed. There we go. You
can see where much quicker and assumes
the time runs out. Let's see it printed
out returns to normal. And we're slowed down again. So now we have a
speed power-up that functions the way it's intended, as well as reverting
us back to normal. So the last thing
that we need to do is actually adjust
things for memory, because at the moment we do have a memory leak in our game. And that is because
our Power Apps never disappeared though
they're off-screen. There's still existing
within our world. So what we wanna do is we can get rid of our
print statement there. And on our power when we
interact with the player, we want to free ourself. Now remember, self is optional, so you could just
type q for each, just like we do with that child. Personally, I prefer
typing in self, but you don't have to queue free when the player
touches the power up. But also we want to take
a look at in the process if our position as disappears. So we want to say if
that's all capitals. So we say if self dot session
dot y is greater than, and if we remember 400 long. So let's say if it's
greater than 400, but we got to factor
in the extra time because the point is gonna be in the middle
of verse, right? So we're saying for 20. So if our position
is greater than 420, then again we're just going to tell our power up
to delete itself. And if we were to not have that, you could see it
in the remote tab, which I'll show you
here in a second. We'll go ahead and
play, and you'll see remote in on the
left-hand side here, according to hit that this
is our game as it's running. So if we open up our spawner, you see the Power Apps come in. And you'll see once
they leave screen, they will delete themselves. Now previously they
weren't doing this. If you would like, you can go and you can
comment those out. And there you go. You saw that power-up disappear. And if you want,
you can go back, comment that out and
you can take a look at it that disappeared. When I speak shows up. We should run into
it and we should see how that disappear swap. And we could actually optimize
this R code slightly. But let's just make
sure that this works. Alright, so there's
our speed there. We got speed boost. A power-up disappeared. Timer should be running out any secondary returns to normal. So everything's still looks like it's working
perfectly fine. So what I was talking
to and we could refer or get our code back
to normal as well, or rather optimize a little more as we don't want to
write self dot Q every, for every single power,
because we want to do that every time regardless. So what we're gonna do is we're actually going to come down and outside of our
match statement, as long as the
player interaction, so we're still inside
the if statement. We're going to free it. So what you can
do now is you can now go in here and
you can create more power up so you can
replace our wildcard there. So we can say
health, for example. And now you come in
here and to create a health variable on your
player if you would like, if you wanted to jump
ahead and do that now. And you could add one to
the health of your player. We can take a look at the multi and you can activate that and have it so that if you're on
a shooting one now you can shoot two, for example. Or maybe you change the
projectile altogether. When did you get the multi, whatever you wanna do this
completely up to you, but you can now create different effects for every power that would pick up. And I'll see you guys
in the next one.
16. Shields: Alright, so let's
go ahead and add the shield power up into our players so that we
can avoid getting hit. So we're going to have a
visual representation of this. I will deal with it, disappear once we get to the damaged portion
of this course. So I'm gonna go ahead and stop that preview or test
play from going. And you should see in inside
of your sprites that we have another spreadsheet
here for our shields, and we know how this works. Now we can go ahead
and create a sprite at an animation player to
it. We can go ahead. Td seen, all we
need is a sprites. We don't need any
animation for this. So we can go straight for a
sprite for our root here. Call it shields. We're going to need
an animation player. Because of course we need
our shadows to be animated. You can leave them
dyadic if you wanted, but I'm not a bad. What do we need? We need shields,
there's our texture. Bring that in animation. We got horizontal frames, three vertical. And
there's our shield. We can go ahead and set some
animation for that scene. We can create our animation. Animation knew. That ends at thereof.
What is his 0.75? So 0.9, I can leave that would tell us to loop and
we'll see how that looks. Okay, so that's
looking a little. It looks okay. It
might be a little slow or fast for some people,
It's completely up to you. The first thing I
noticed is mine is blurry from gonna go ahead and
re-import that real quick. And turn my filter off. Very important, there we go. And play that. Now we go. Let's see. Don't want
to speed that up. What happens if we
do speed that up? I'm just gonna go. Now, let's
change this to 0.1 instead. And everything's moving
to lead or functionally. Snap it down there. Three, these see how that looks. I think that's looking better. I'll adjust my
length here to 0.6. Alright, so I think these are the numbers that I
want to go with. I'm gonna go with
0.05 on my snap. Their total length of 0.3. I think I'm happy with
this speed per my shield. You might want your slower
to my watchers faster. But I think this is what
I want to go save that. And now that we
have this crater, I'm gonna go ahead and
stop the animation. And the animation here. If we set our current animation
to being shields active, that should automatically be playing whenever
it's in the scene. And we're going to
need an area of detection or when our
shields get hit later. So I'm going to
create an area to D. And that needs a
collision shape. For the shape, I'm
just going to give it a circle, something like that. And we can take a look at
that with our player to make sure that it is going to cover our player and blocker
player from getting hit. Let's see, let's, let's
open up our player. And for now let's go ahead
and add in our shield. Take a look at it so we can see our finished sticking
out player a little bit. So what I'm gonna do is
I'm actually going to increase the size
of my shields here. I'm going to come down
here to transform and I'm going to
increase my scale. That might be a little
too, maybe 1.25. Let me take a look at that is definitely locking
out everything, all of our other hits here. Save that and take a look
at that in game now. What we got now, not animating like I expected
it works, so that's fine. We can just set it
to automatically animate within the
shield script itself. We'll go into our field. It's script in the
correct location. Scripts shield. Great. I'm ready. Did the animation player
dot play shields active. And that's it. Here we go. Now we
know what it's, what it would be like to have
shields around our player. Now, of course, we don't
want this all the time. We want this all
into B when we pick up our shield are up there. So we can go now go
into our player. We can load in our
shields, say var, shield, scene equals reload, and we'll bring our shield seen in air it is. We'll
bring that in. And for detection of this, we can set shields
to being true. Bar shielded, true. And we also of course want
to cast that as well, which you want us to separate. This will be a Boolean. So now we can come
down here and create a function shield, activate. And we're going to need
an instance field n equals shield seen instance. And now we just need to add this to our players. Self-doubt. And child shield should be all we need to do here. So let's head on to
our Power Apps Script. And when we hit shields,
when this gets picked up, we're going to call it
body shield activate. We're going to double-check
your spelling on that layer. And just to be safe,
I'm going to copy the function and just
paste it in there. Okay? It's correct. And we could delete
it from our layer. Now I can go ahead
and test and when we pick up a show power up, the shield should appear on us. And this is gonna
be of course, RNG as to when this
actually pops up. Alright, so we've got ourselves
a shield and there we go. Two seats activating
everything just fine. Now all we need to do is setup
the shield to disappear. Which again, we can tackle
that when we get into the damaged portion
or the player taking damage section of the course. Alright, so if you've been
following along thus far, you haven't steered
off on your own. You should now have a
shield power-up working. And we just appeared
to have a bug there because we picked up a second shield and
now we have three. So we can fit our two
rather, but we can fix that. We can check if
body dot shielded. Make sure I got that right. Yeah, shielded. We're going to set to false by
default not true. Say if body dot shielded. So we're gonna say
if shielded is true, so if our player shielded,
we won't do anything. So we want the opposite of this. So we could do exclamation point here at the beginning and say, if not body dot shielded, which would get us a false. Or we can type out the
word if not bodied, not shielded, whichever way
is more comfortable for you. I'm going to type out the word, not just to make it
clearer at glance. If not body not shielded. So if our shielded
variable here is false, then we'll do that. Otherwise, we won't
do any of that. So now if we were to run it and run into multiple shields, it should only work for The
her shield that we get. We need to come into
one more thing. We need to come into
our shields here. We need to remember
to set body got shielded to true. Alright. Now for our testing, you can see that our shields are
not going to stack up one shield and that's all the shows
that we should get. And there we go. So we have
our shields working and we patched small bug that
came up. Alright. So with I'm just gonna
go back to my spotter and remove this since we no longer need to test that and just set this back
to saying no power. So with that, we now have a shield power up,
fully functional. Well, as far as getting into
the game and being used.
17. Multi Shot: Alright, in this video
we're going to take a look at adding a multi shot. So instead of shooting
one from each side, we're going to shoot to
protect Alice from each side. And they're going to come
out on a bit of an angle. Alright? So the first thing we need
to do is we're going to head on into our layer script. And we're going to
create a variable here. For the multi shot. To false by default. We can go into a fight or
shooting location here. That in, and we're
going to say if multi shot or say if not multi shot. And do that. And then we can
basically do a copy of this. And coming on down there, but then will be repeating code. But we need the extra us anyway. So kinda hear someone say lf to say else-if,
else-if multi shot. And we're going to
need four of these, in our case, three or so
now we have four spawning, but they're going to be
overlapping at this point. We're going to head on over to, let's see, add these children. Here are scenes of
three and forestry. She mostly, most of
what we've done is just a copy paste of
what we had up top. But what we also
need to change here is the velocity property. So we need to change
the x of that. So we're going to change
shot dot velocity dot x. We can set that to, let's see. First one have wanted to go to the left
and 34 to the right. So we wanted to do
was say negative 50. And we can copy this for crimes around
it three more times. 34. So 34 are going
to be positive, 512 will be negative 50. And we'll go ahead and run that. That's actually never
going to change and we have to go to a power. When multi gets it
will do its body. Multi shot, right? Copy that multi shot, true. Alright, so you can now
see with our multi shot, we got this cross
action going on. Now of course, you can
tweak your numbers here to whatever you see fit. And we just have to decide when to turn this multi shot off. You see we're no
longer shooting too. We're shooting projectiles. And if I restart
that real quick, you see will be back
to shooting two. For now, all you need to do is decide how or when
this turns off. And then come over
here to our player and active power speed. So I think I'm going to
redo this section as well, or disabling our powers. But we can save that
for another time. But for now, we can see
this turns on, it works. And let's see how can
we enable multi shot, who were function doesn't
come down here to really enable multi shot. This will turn multi shot true. Then what we can do
from here is we can do, we can use a yield. Now this is going
to work differently in 4, slightly differently. You don't need
these parentheses. So you might have to take a look and see what
the difference is for the x. I'm not a 100% sure on that. But we have yield
and then we want to get tree dot create timer. Inside of here is how
long we want it to last. We'll say five seconds, get the timeouts, and then
we'll set multi shot to false. Now this might be using, this method might be the way I redo our Power
Apps here, right? That the speed as well
as we move forward. So we're going to
come in and instead of enabling multi shot, we're going to say body
dot enable multi shot. And we'll take a look,
see how that works, make sure that that functions. So we're shooting two out of
the gate, which is great. We've got a multi shot, was shooting four of them. At the end of our timer. We're back to you going
with two. So there we go. We have a multi shot
that works beautifully. Alright, so we have a shield that activates
and enables for us, and we have a multi shot
that turns on and it gives us our power and ability. Again, you can just
change this number to whatever you want for however
long you want it to last. And if you have different shooting Power Apps that you enable in the future, this is all you have to do. Change whatever your ability is, and change whatever it is that
you shoot or how however, however you go about doing that. So if you have a laser, you're going to bring it in. You're going to
have an instance of a completely different scene. For example, in the
case of a laser, you would just add to the
player because we want the laser to stay
with the player. Typically if you're
going to have like a traditional like laser beam, rather, rather than shooting
lasers like a blaster. But there you go. Here's how multi shot works. And like I said,
I'm probably going to change the code
here for the speed. And instead of using
a power-up timer, just use a small function like this activator,
bittersweet.
18. Small Changes: Alright, this is her
stay. A short video. Just want to show you
that I did re redo the speed just created in the same format that we did
for our multi shot here. So we have a function
called enable speed. It added a parameter in there that we can
pass in a multiplier. I said my speed to just be
speed times y multiplier. We wait our five seconds. Once that's up, we decrease our speed again by
our multiplier. And on the power append or
just calling enable speed. And we pass in that
multiplier that we were using beforehand. So that's the only thing that's changed there for the speed, shields in the multi shot
has remained the same. But what we can do is
one can do as well. If we open up our
projectile scene, we could get rid of
our collision shape. It is going to bring up, we will have a yellow triangle if you delete the
collision shape here. But if we just remove it, that is perfectly fine. And if we were to do that, you'll see here and the
multi shot that the two in the middle that are
right up against each other, they're now going to
shoot through each other rather than colliding with
each other and going straight. Now those are two completely
different outcomes, are two different results. So it'll be up to you whether
or not you want to have your collision shape
on your projectile here, enabled or disabled. And as you can see,
the speed is activated 54321 and we're back to normal. There's a multi shot.
So now you can see our middle pieces crossover
each other eventually. So if you don't want
to have them smacking against each other and
going perfectly straight. That's all you have to just turn that collision shape off. And we could just completely disable it there because
we don't need to see it. There you go. You can see
they're crossing over each other and we're getting almost
like a toString shoot now. But there we go. It's up to you if
you want to have your collision on your
project out disabled. Or if you want to
leave that enabled for that screen appearance, or if you want them
crossover up to you completely developer
and design choice. But I figured I'd throw that in just to let you know as well.
19. Enemy Setup: All right, In today's video, we're going to go
ahead and take a look at creating our enemy. We're gonna get our enemy
created now and then next we'll move on
to getting our enemy to shoot and getting our basic vertical scrolling in with our enemy, the motions. Alright, so first
up, we're going to have to of course
credit a new scene. This just like our player, will be a kinematic body, of
course is going to be a TD. We're going to need a
right for our enemy. Ross, going to need a lot of things that we
have on our player here. So we could add a
collision shape, which is why we have
our triangle here. So we got our kinematic body
at a collision polygon. Want the shape go. And if we take a
look at our player, what else do we need? We could use an animation
player later if you want to create
animations that way, specifically for your enemies. But for this specific setting our enemy up, we're
not going to need it, but we aren't going
to use a position here so that we have
a location of where our enemy is shooting from
a position to D. Alright, so starting from the top, we can rename this as enemy. I'll call it the enemy ship. Wouldn't call. You can call it whatever
type of entity that you want this one specifically to
be. Go to our sprite. We can bring in our
enemy and we notice it's just a normal sprite here. It's not a sprite sheets, so we don't have to worry about
painting the animation or anything because this spray just going to be moving
around and shooting. We don't have all of these
different animations on it. You could, of course, use the
spreadsheet if you want it. This is where I can introduce to you the alternate way that
I mentioned previously. And that is what the animation, I'm sorry, not the
animation player, the animation animated,
animated sprite. So let's say you wanted to do an animation using
the animated sprite. We would come in,
we would do frames. Could say if you don't have any, you're not using a sprite sheet. You just had individual PNGs. You come in here and do
a new sprite frames. You click on that again. And now we have our
animations here, right? And it wouldn't come
in here and go idle. Right, left, right.
And you get the idea, we can do them this way. And instead of messing with a timeline and positioning
your keyframes, you have a speed here that determines how close each
of those keys would be, then all you would do is just bring each frame in
here one by one like this. And as it plays, it would loop through it. And to take a look at that,
we'll just go back to our animated sprite again
and we have playing. We would be able to
take a look at it, which of course in this
case the stuff in there. So if we go to idle,
when you see there's our ship and it's playing through our frame
CC the specter. So that's the alternative. If you just have PNGs
and you don't have a spreadsheet for your enemies. That's how you would
go about that. What again, this
is, in our case, the enemy is just a static ENG. There's just gonna
be moving around based on coordinates
on the screen. But for future reference, if all you have are
PNGs and you don't have spreadsheets or you don't want to use spreadsheets
and you want to cut up my player and the power ups
all into their own sheets. This is how you would do it and it would be the
same thing though. Instead of calling
an animation player, we call the animated sprite
and play the animation now. So like I said, we don't need that for ours, our case. I'll get rid of that. And I'll show the
regular Sprite again. Collision box. This is
just a simple rectangle. That's all we need
for. This will come up and we'll cover it. And you can decide how much of your ship you want to cover. So I think I'm just going
to cover that part and not covered the weapon portion. And my position to d. I can make sure that I get the reflection that's
in red, that down. There we go. I just move that just
a little ahead of the canon, an AAC. If we were to take this
in, move it around. We have our position and that's where it's
going to be shooting from. Men Lizzie, or 0. There we go. So we have our enemy.
Save our scene. And it'll be shipped.
That we have our basic enemy set up and
ready to start shooting, moving, and being
spawned into our world.
20. Enemy Shooting: Alright, we're gonna
go ahead and tackle the enemy shooting
ability in here. Now, you could use didn't go off just like
we did with our player. Create a custom scene
with its own shot, give it its color. I give it its own direction. You don't have to do
the code in that. You're just going
to make it go down the screen instead
of up the screen. But for purposes of this, I'm going to show you how we can use the players projectile. So we're going to use that same, that same scene
that we had here. If we open up our
scenes, There we go. So I'm going to show
you how we can use the same scene here. But tweak it for the enemy
to be able to use it, as well as continuing to
allow our player to use it. So to do this, we're going to head on into our enemy ship. We're going to add
the script onto it. Makes sure we place it
in the correct location of our scripts. Hit Create. And there we go. We have this created. So to start off for our enemy, we're going to need
them to be able to do. So what we're gonna
do is we're going to add a variable here. Time or enemy ship. We're going to add a timer
into our scene here. And we can use the one to
have any spaces in there. We want to avoid that, to
avoid any potential issues. And back in our script, now that we have
a time variable, we can actually set this
to a random number. And to do this, we're
actually going to leave this, have a default up there. And inside of our ready function is where we're
going to tweak it. Should we're going
to call randomize. What's going to
randomize our c. So we can have true randomization. This way. We don't get
a repetitive mouth. So every time we started up the game, we're
not going to get saved. 510131211. We're not going to get
those same sequence of numbers every single time
when we randomize the seed, that's going to change, effectively change
that up every time. So what we're gonna do here
is we're going to call randomized just a
onetime because we just want to change
up the time that we get. So we're going to
set time equal to, and then we're going to
set it to a random float. And if we take a
look here with this, we go ahead and we put in with Randolph will get a random
number between 0, between 01. Okay? That's kinda useful. But between 01, I think
that's gonna be really short. And in case of this enemy, we don't want to have
something like a machine gun. So what we can do is
we can do a random, we can round off a float if
we go ahead and use those. But instead what we're, what I think we're gonna
do is we're just going to use where is it here? We've used it before. We could just use rant. There it is, down there at the bottom with our percentages. But again, we want to, want to mix this
up a little more. So we're going to use
rand range this time. So we can get float numbers. Just to shake things
up a little bit. If you want to use
the regular random, just have increments of whole
numbers. You can do that. But for this, I think
I'm going to use rand range. Like you see here. That way we can get a float and we have to pass
in two arguments, the smallest number and
the largest number. So I'm going to say
it's going to be at least 1 second between
shooting. At most. I'm gonna give it five
seconds between shooting. Now we're gonna get some time
between 15 seconds timer. We can then go ahead
and get our shot timer. And we'll just set the time. We can see here in the properties
it's called wait time. Wait underscore, fine. And we can set that equal to
time that we just created. So now we have a
random amount of time. With this, we can connect
our signal for my timer, which this is going to be a
bit different in 4 as well. If you wanted to do
it through code. If you want to keep this as easy as possible
to follow along with me, just come up here to node
and double-click timeout. It's like our enemy
ship and hit connect. That way is going to go
across both versions. Whether you're using
version three or version for the engine. But if you wanted to
connect this new code or you're curious how to do it. Then in, in the
current version here, we're going to do this. That self-doubt connect
much they were gonna, you're gonna get what
you want to connect. What's your shot timer? They would want to
connect something. What we want to connect
is the signal follows up. And that signal, if we take a look at it,
it's called timeout. So we would type
in timeout here. And the target, which is what
you want to connect it to. Remember when we
select our enemy ship, when we went like this
and we select our ship. What you select here, in
this case our enemy ship. This is what we
want to connect to. And since the script
is on our enemy ship, we just have to say self. That leaves us with
a third argument, basically just being whatever you want the method name to be. So if we go like this, that this command here is essentially what the engine just did when we went like this and selected the enemy
ship and hit Connect. Now, on version four, this is going to be
slightly different. And I'm not a 100% sure what that's gonna look like
off the top of my head. But like I said, the easiest way is
just to go into that node tab and just connect the timeout
signal that way. So when our timer runs out, what we're gonna do
is we're gonna shoot. So obviously for this, we're
going to need our scene. So we're gonna say,
we're gonna load this as our wouldn't want to call this, would just want to
call it a shot. And pre-loaded in Sweden, get our projectile normal seen, bring that in. On time out. We'll make our shot instance equal to or shot dot instance. Now we have it and we're ready
to add it into the scene. Horse, this is going to be
added to doubt ourselves. But in this case, if we do one got one good parent to be added to our spawner, what's our spotter
never moves anyway. So that's not too big of a deal, but if you want to go all
the way up to the world, like we do with our player. Then we can just do
get parent twice. Now in most cases, you want to try to avoid
using multiple get parents just to avoid potential
issues in the future. And that's where creating our own signals like this
would come in to play. Whenever you go up the tree, it's better practice
to use signals. And when you go down the tree, you just get the node. But in this case, specifically for
this type of game, this is not going to
cause any issue source. So we can do to skip parents, don't get parent and child. And we can add in our
instance shot here. So that's going to add
this into the game. The problem is, at this point, is we know our shot is
gonna go up the screen. So what this are shot
is going to be going out where our enemies
essentially going to shoot themselves. And
that's not what we want. So what we need to
do is we need to modify parts of that projectile. So if we come here, we
can take a look at, we're setting the y velocity
to a negative speed. So we can change that. Now that it's been
added to our scene. We can change that immediately so that we can overwrite that. So let's go ahead and set. We can get our shot. Access the velocity
y variable of it. The y property of our
velocity variable, and set our shot
set to our speed. Now remember our
speed is positive. So we're not going
to subtract it here. I want to go positive, which will send it
down the screen and to differentiate
it from our player. If I open up that scene, if you remember
here in our sprite, we can go ahead and we can change the
color down here in visibility and modulate. It seems like we did that
on the kinematic body, which will make this
a little easier. This is all we're gonna do. We're gonna change the
modulate so that it looks different when it's
shot by our enemy. Gonna get shocked moduli. And we're going to set that
equal to a different color. So if we just type
in the word color, you can see that the word color is going to change into a color. And we just do. If you do
parentheses like this, you can pass in an RGB value. If you use double quotes, you can pass in a hex
code if you wanted. What I'm gonna do is I'm
going to take advantage of the built-in colors because
there are a lot of them. I'm just going to color, period. And now you see we have tons of different colors here that we can pick from that's
already built in. And a lot of times this is
all I need to I need to do. And it usually works
out well enough for me. I think I'm going
to try. Let's see. Let's go with a medium purple. Alright, so we save that. Let's head over to our world
and create an enemy ship. We just bring them into our
world here and we hit play. We should be able to
shoot within within five seconds based off of
whatever his rent numbers. Except he is not. And the reason for that is because we
actually did not start the timer at any
point. Set it up. We set up our current, but
we didn't start the timer. We're gonna get our shot timer and just call it the
start function on it. And when our timer runs out, we will also do this again. So let's get our shot timer and columns Start. Here we go. If we just take a look, we can see my project officer going up and his project out. We see it there on the left-hand
side. It's moving down. And the reason for that is why same issue that we
had with with our player. We need to fix the
position of it. So if we move on in and we
take a look at our player as a reference because we did use
the player position there. We can see we get
a shot position. And we set that equal
to our position 2D and equal to the
global position, head down into our enemy. And we can do this anywhere. We knew it before we add
as a child or after. It doesn't really matter in this case because
we're not overriding anything inside of the
project Alex self. So we'll do shot into
position and we'll set that equal to we have
this disposition to D, Let's call it pause
shot position. Set that equal to
our shot pause. Mobile position. Here we go. And we run it now. It should now be shooting
from his bedroom. We see mater yellow
and his or purple. Now that purple in this
case is a little dark, it might be hard for
the player to see. So I'm gonna go ahead
and change this color. And this way you can make
tweaks to it and decide what looks best view
against your backgrounds. Now, using a lime, this would be very, that is very, very bright and
easy to see from our enemy. So that is fantastic. At this point, you can
just go ahead and tweak the colors that
you want for that. And just as a side note, if you want to just
use this one sprite, but you want to have
different ships are different colored chips or maybe you just don't
want this glue. We can actually do the
same thing that we do with our shot come
into modulate here. And since it's not white, we're actually going to add
different colors into it. As you can see here, that we can get different colors here if I just turn the
collision shape off there. And you can go ahead and
take a look at that. So you can make slightly,
slightly different variations. If you wanted to. I'm just going to reset mine
back to normal. And there we go. Alright, so with that we
have our enemy set up. And we now have our enemy able to shoot us at a random time. And to show you
that it is random, I'm just going to add
another and being to our scene here, just going to use Control D
to duplicate. There we go. We have three different ones
and they're all going to shoot at three completely
different times. You go. Oh, as you can see, the two on the left look like
they were fairly in sync, but they're actually
fairly off in their time. A little more coincidental. There we go. So now we have the setup. They're shooting and they're
shooting at random time. So they're not all
going to be the same when they come out or
when they get spawned in. So next we'll go ahead
and set up an enemy, the enemy spawner or
the enemy movement that I'm thinking we should probably do the
basic enemy movements. Think well handled that next. That way when we spot it, we can actually
tell that the being spawned instead of them
staying off screen.
21. Memory Leak: All right, So something
that I wanted, I want to tackle first before
I forget about it, is we are going to
run into issues. Eventually longer a game goes on because we do
have a memory leak. What this is, is what we're continuously creating all these items
that are causing it. And we're not dealing with them when we don't
need them anymore. So we're just going
to continue stack up more and more and more and more until eventually
the user's computer slows down and starts lagging, or maybe even crashes. And we take a look at the
right-hand side here. I've gone ahead and pause this test that you
see on the side. And if we just take
a look at this and the remote section, take a look at all
of these projectiles that have been spawned in,
but they don't go away. So even though we don't
see them on screen anymore and they're completely
irrelevant to our game. They're still moving. There's still a
part of our game. So what we need to do is
we need to now handle this for when it leaves our screen at the bottom and when it leaves our
screen at the top. So we're gonna go ahead,
go ahead and go into our projectile script here. I'm going to create a
function for check. What a chat with
a check position. It's not the best name for it, but it'll work for this. We'll say self. We can check
if self dot position dot y. I will say if it's less
than 0, because remember, 0 is gonna be at the very
top left-hand corner or top of our screen will
be 0 on the y-direction. So if it's less than 0, then we're going to tell
it to Q3 itself. Now, we also have
to check for when the enemy shoots is going past
the bottom of our screen. And if you forget the
number of your screen, we can come on in again
to your project settings, go to our display window. And remember it isn't 400 tall, so we want to look for
anything larger than 400. Remember our sprites,
32.5 of that is 16. So we want to check LF,
LF, self-doubt position. Don't Y is greater than. Now, remember we said
400, like this for now. Remember we said 400. But if we take a look and
remember the projectile, the point is in the middle. So we have half, half. This will be sticking out still, which in this case is fine, but look nicer if we wait until it pulling
leaves the screen. Since these are 32 by 32 sprites that we're using an all these. We can actually check. We can add that onto this. So we could add 16
just to get a bit. We do 32 to get the whole thing. I'm just going to use for 50, give it a nice round number. And to fully insure that there's no possible way that there'll
be left on our screen. And then I'm going to tell
it to cue for you if it is. Now if we take a look
this remote section, when we play our game, and we take a look at all
these projectile's come in, they get spawned and did not
delete it themselves. Easy. That's just because we
never actually call it our check position with the
gradient but didn't call it. I'm just going to
call this inside of our process function. Now if you wanted, you
could create a timer that will check this. Instead of calling this
every frame and the Tiber, putting a timer
on projectile and checking when that
time is out will probably be a little more
performance friendly. But that's all going to
depend on how far you go with your game as to whether or not that ends
up being a better option. If we come in and take
a look and again, we'll look at the
remote we should protect house gets spawned in and they get deleted
when they leave the screen. And same with the ones
we shoot as well. Those are all get deleted
and there they go. We have now fixed
the memory leak that we created inside of our game. So it's just that simple. It makes sure that once you
don't need something anymore, you go ahead and get rid of it. And if we take a look at our power-ups inside
of our spawner here, we see we're not, we
don't have any of these issues with our
power-ups appearing. And the reason for that is we actually addressed
that right here. If you are curious,
I will reject if the position was greater
than 420 and we deleted it. If it's greater than, of course that number is passed. Our player has passed up or 100. Then we know it's not
onscreen anymore. We don't need it and
we get rid of it. So we did address this with
our with our power-up. And now you just saw
with our projectile, why we need to do that with
the remote tab over there. With just the sheer
amount of things that we're creating
that still exist within our game and
how quickly that will build up with projectiles. For example. Again, if we have some
going with a rapid-fire, we have a rapid firing weapons. For example. You can see how quickly those can really start building up. So we've tackled
that, we fixed that, and we'll move into adding vertical
movement to our enemy. If you just want to have the enemy scrolling
towards the player.
22. Vertical Movement: Let's go ahead and address our nice being able
to move vertically. If that's all you
want in your game, then this is all the movement
that you're going to need. Now this is, of course, hyper dependent on what
you want out of your game. Of course, what we're
gonna do here is we're just going to find
our enemy ship here. And we're gonna do
a similar thing that we did with our projectile. So we have our velocity and our speed that we
want to ship to move. Inside of our process, we're going to need
a move and slide. We need a, some type
of velocity passed in. So of course we're
just going to use our velocity as the
velocity argument. And all we're gonna do is
just like a ready now again, if you wanted to randomize
speed between two numbers, you can certainly
do that as well. Just make sure to do that under the randomized color here. And you can do the same thing
just like we did with time. They're using Rand. Well, I want to present a number or if you want to
do a rank range, you can certainly
do that as well. You can randomize the speeds. If you want all your ships
to have different speeds, you can certainly.
I just add as well. For me, I'm just going to
use the normal speed here. And I'm going to
set mine to a 100. So I'm just going to say
velocity dot y equals speed. Now remember we're
having this go positive. So our ship is moving down. And if that's all the
movement that we want, That's all that
we're going to need. I'm going to go ahead
and just move these up. And go. I said if
they've all been spawned at different points
and we can see that they go, become moving towards
us and we can adjust. We can go ahead and adjust
those speeds however we see. And you can see how they're all kinda like moving
in a line there. So I'm going to show you
what that would look like if we change this to
being a random amount. So say speed equals. And let's go with, just to show you even
just a small change, we're going to use rand range. We're going to set this
between, let's say 9110. So that's a small gap, that's a 20 difference. We take a look and we can
see that they started close. But then they have differences. Now this one is
falling behind because the middle one is
actually moving quicker. And of course, you can make
this as large of a gap as as you want it to be. If you want to go this
route, there we go. The middle was just cruising on in and the one on the far right, which just kinda
chill and relax. And if we were to pause
this and go to remote, we actually come down
and see our enemy ship. And we see one ship has
187, the other ship has 95. And our third one
has one-to-one. So if you want to have
a random speed for your ships in that
vertical range, That's how you can go ahead
and adjust that are set that. So that's gonna be
completely up to you. I think for now I'm just
going to leave mine like that and we can move on to
adjusting our spawner.
23. Enemy Spawner: Alright, for the enemy spawner, we're gonna go with
the same thing here, using a basic node as
a root Enemy Spawner. Go ahead and save
that to our scenes. And we're gonna do a lot of what we did here with
our regular spawner. So let's add a timer to it. And if we take a look at
the code that we use here, we have our enemy here. Now, if you want to have
multiple our UPS or not, in this case, just
like our powers, we have multiple enemies. So you can have a random, random variety of enemies
like it spawned in. You can certainly do that. And I'll show you how
to do it that way. Because you know
how to do it with a single item like this. Now, what we're gonna do is
something similar to this. So we're going to go
into our enemy spawner. I'm going to add a script, put it in the right location. What we would do is we can do var enemies equals and
then our square brackets. But then for each of these, we're going to go like this
and get our enemy ship. So if we were to have
multiples of these, would then just look like this. And you would just
continue on with however many varieties
you had in there. In this case, I
only have the one. And of course, the benefit of
doing it this way is if you add more of the smaller
enemies in any way. In the future, it'll
be self-contained, like you won't have
to edit your code. You can just add them into
the top here and move on. Alright, so if we referenced
back to our power-ups that we had our spawner, not open that code. We did. It's right down there.
I didn't even see it. So you can see we're doing
everything on timeout. So that means we need to connect our timer into our
enemy spawner. And now we have that
setup as well on time, or we can call randomize. Because again, we want things to be random just like
we do with our power. And we can see here we create
an instance of our scene. In this case, we're having, we're calling an
instance of our power, but we want these to
be a random number. Then we need to actually
get a random ship first. So say selected enemy
equals enemies. And inside of our
square brackets, we're going to say Randy. And we're going to use
percent of our enemies dot size to new variable.
There we go. So what that, no matter how
many enemies we add in or remove up at the top here, our code was never
going to change. We're always going to have a, an enemy that can be selected. So we come on down and then we can create an instance
of our enemy. So let's say enemy n equals
I put that wrong way. Let's say selected
enemy instance. So whatever enemy gets picked, that's the one that we're going
to create a new variable. And then all we have to do, it is one is added into. So I'm going to take a
look at our spawner here. And you can see all we
did was just add it in, which is perfectly fine
with our spawner because the spawner itself
isn't going to move. So let's go ahead
add child enemy. And at this point it
is now in the game. But what we want, remember one, a variety on the x. So it's not all just in
the top-left corner. Let's say rand position x. And we'll set that
to be random number. We can use rand range. That's perfectly fine. Did we use that here to go
a different route with it? We just use Randy. So let's go ahead and
stick with that just for consistency
consistency standards. But if you did want to
use these in-betweens, again, 02 to four. Here we go. So we have our
random number within our 224. I can, you can tweak this if you don't want your
ship to be hanging out a bit. So for example,
I'm gonna go with, I'm going to say 200. Then at 20, which
will make my numbers my Min and max 20 to 20. We just add them into the scene. So let's head on into our world. And in our enemy spawner. And I'm just going to
move that up there. And if we play this now, that's not going to go
because we actually did not trigger our timer. So let's go back to that, set it to auto start, and try that again. There we go. So we see they're going there and they're actually
running into each other. And they're staying up there. You gotta position,
but we did not set it. Just get our enemy
position dot x. So the good thing is we know
that our script is working. Bad news is it is
colliding with itself. So when new position
dot x equals our rand, rand position, I can
spell here ran position. And that'll sort that out. Or sips are still going
to run into each other. If they get the chance
to. There we go. We see it there on
the right-hand side. I have three of them
all stacked up. So we often spawning, we have the position
and they're shooting, looking great, except for the fact that they're
crashing into each other. So at this point is where
I'm going to introduce to you the Mac and
layer feature. So if we go into our
enemy ship, there we go. And our kinematic
body 2D, safe margin. And then here we go under
collision object td. Here in our Inspector, we have Coalition, and here
we have layers and masks. So the layer is, if you view something
like Photoshop, you know what layers are,
works in a similar fashion. Where you can have a
player layer are up layer, the enemy layer,
project out layer. And however many wanna go
ahead and split up with that. You can see if I open this up, you have 32 different
layers to work with. And both your layer
and in your masks. Layer is where your object is and mask is what
it can interact with. So if you don't, your ship to be able
to crash into each other or crash into the
player or any of that, we could turn mask off. Now the problem that we have
here is our projectile is also on layer one. So since we turned mask one-off, we're not going to be able
to shoot the enemy at all. So what I'm gonna do
instead is I'm going to move our enemy
over to layer two. Nothing is, has a mask of
layer two at the current time. So if we go ahead
and play that now, you can see our enemies
don't run into each other. They completely
ignore each other. But they are running
into the player because remember our player
is on mask one, or is our players on layer one? So with mask been detected, we are running into it. Now, depending on if you want the enemy to
be able to run into the player or not and blow the player up with
deal of damage to the player. This may or may not
be ideal to you. Remember, if we're dealing
damage to a player, then we can just disable the player's
collision temporarily to avoid that from happening. So what we can do then is go to we can leave
our player on one. We have our enemy on to. And if we use three
for our projectile. And we take a look at that
three for the projectile. And the projectile
can interact with both the player and the enemy. So we have mask 12 both
set and we try that. We see bone and now the
enemy's go right over us. And they can no longer
interact with us. So there we go. That's wow. How we can go ahead and
accomplish that are shifts and no longer
running into each other. They're not getting
stuck on our player and our projectile. Since it interact
with both layers. With our mask selected 12. We should be able
to deal damage to our enemy and our Amy should be able to deal damage to us
still once we add that in. So that's also a
small introduction into layers and masks there. So remember, layer is where
your objectives and the mask, what layers it can
interact with. So again, if we're on
mask one and layer one, layer one will be
interacted with it. Since we have mask selected. If we're on layer two
with mask one selected, then we can interact with
anything that is on layer one, layer one side
interacting with us. Hopefully that's not, that didn't get too
confusing for you. But just know we have
everything working. If you have any questions
about layer masks, you can always ask them. And I'll try and clarify whatever it is that you're
confused about with them. And we can move
on to next video. At this point, we have spawning shooting movement and we have
no memory leaks going on. So what I'm gonna do is
I'm actually just going to remove these three starter
ships out of my scene here. There we go. Now, we don't have them when you start and they can spawn in. Now if you want to create a
random timer for your ships, you know how to do
random timers at this point or get
random numbers. You can certainly do that.
Replaced the wait time. Alright, there you go. We have everything
set up, going to go. We have enemies,
power up, shooting. Aside from health and GameOver was destroying
and all that. We have. At this point. The basic, the basics of standard
space shooter.
24. Bullet Hit: Today we're going to tackle
having our projectile actually shoot and destroy
our enemy and our player. And depending on how much health you want the player
or the enemy to have, you will either
be dealing damage or outright killing them. So the first thing we should do is rather than first
thing I want you to make sure that you've
done is make sure that your enemy ship is
not causing any, isn't causing a memory leak. By checking your position, like we do with the
projectiles that we did recently, one
of the last videos. And with that, once you've
made sure you've got that, let's head on over
to our projectile. And you're going to
go ahead and add an area to D that's got a collision shape and make the collision shape
just a little bigger. What are clicking shape was
so you can see here for me it's just one-click bigger. Alright, so go
ahead and do that. And then in order
to make this work, Let's go to our shot area or area to be equal
to the collision. Mature layer is set
to layer three. And we're going to
set our mask 212 so we can interact
with layers 12, which star player
and enemy ship. We can head over to
the notes section here so we can take a look
at the signals and we can connect the body entered signal into our
projectile script. And this is what we
should see here. This function automatically
created for us. So the easiest way to do this and to get this up
and running and testing is for our player, I'm going to show you two
ways that you can check this. One using names and
one using groups. So for the player I'm
going to use names. So I'm gonna say if
player and body Name, body dot Q free. So what this is saying
is this saying, if the physics body
that enters this area, if its name pass player
with a capital P. And then we're gonna
tell that body now entered our area,
DQ free itself. So if we go back to
our player scene and we take a look at
our kinematic body. It is a player with a capital P. So this is going to work. The enemy should be able
to effectively kill us, will get shot and
mode disappear out of the scene. There we go. If we shoot, we move. Nothing happens because
we are completely healed. Alright, now for our enemy, now I'm going to show you
how to do it with groups. So if you want to create
multiple different enemy ships, you can just tuck them all
under the group enemy, and this will just work. You won't have to add
any code to project. So let's go to our enemy ship seen with our kinematic
body 2D here. Because remember we're working
off of the body entered. Let's go over to the group
section. On the right. We're going to go into our
text box and we're going to say enemy and hit
the Add button. So if we were to manage our
groups now we see we have the enemy group and that
consists of our enemy ship. As you see their notes
in group enemy ship. And you could easily add
or remove from there. But now that we
have that in there, we can have this
work with all of our enemies as long as we
just add them into the group. So all we would have to do
is if body is in group. And this will take an argument in the form of a string if I'm not
mistaken of the group name. So in this case it would be
a string of enemy capital Y. Let's go ahead and
give this a shot. Run our world. And we should now be able
to kill off our enemy. And we cannot. Oh, never mind. We
told it to pass here. Obviously we wanted to do free, just like we do with our player. So if our bodies and
the enemy group, we just tell it to keep free. Selected the wrong
scene there, of course. And you can see if we shoot now, Aereo, our enemy
and it gets killed. Now, as you can
see, our object is going directly through
anything we shoot. So if you don't want
that to happen, you want to have your
shots to be minimal. Here. What we're gonna do is outside of any
of these conditions. Now you could do
this at the bottom, or you can do this at
the top, doesn't matter. We're just going to
say self dot Q free. This way, our projectile
discourse itself. There we go. We have a shooting working in
our game and we're able to destroy our anatomy
and our player. Alright, the next video, we'll go ahead and we'll
set up health speaking up. There's power right there. Set up health and our
damage multiplier. Make sure that our shield
is working to protect us. There we go. Alright, I'll
see you in the next video.
25. Health and Shield Damage: In this video, we're going
to go ahead and tackle the player and our enemy, having health and damage
being done to them. So let's go ahead and go on in. Let's go to stack
our enemy ship. Be a little easier, but some spacing in there. And we'll create a new
function called damage. We want to call it hit. I pass in my
parameter of damage. And we'll just hit pass for now. We're going to go up to
the top two are variables. And I'm going to create
a variable for our, for this specific enemy ship. I'll call it Health. And I'll set that to three. So the ship has three health, it's not very strong. And what we're gonna
do is we're gonna say health inside of our function, Health minus equals damage. Then we'll say if health as
less than or equal to 0, then self dot Q free. Now the reason we're
going to say less than or equal to 0, because if it's equal to 0, then our enemy should be
dead and it should read. So. But if there is somehow, in some way a glitch that happens and our enemy
ends up with negative health. This is acting as
that barrier check to make sure that the enemy does get destroyed
like it's supposed to, even if it's somehow
glitches below 0. Now at our projectile, where we have our
enemy group here, we're just going to
call body dot hits. And remember this takes
in a parameter essence are this enemy has three health. We're going to say
this project analysis, we can shoot it really fast. We're gonna say this
checked out only does one damage to the enemy. So if we were to run that
now we should see that the enemy takes shots to kill. Here we go, 123. And if our player gets shot, you see our players still
gets destroyed instantly. So our ship now has health, and our player needs
to have health, but also factor in other
parameters such as, of course, our shields in that. So let's go on over
to our layer script. Let's give our player some
health if you haven't already. My player has three health. We're going to come on down
to Where should I put this? I'll put this right
underneath of my shooting before we get into
our power-ups. I'm going to create a
new function called hit. This will take a
parameter of damage. And we're gonna do the
similar thing here, health minus equals damage. And we would say if l
less than or equal to 0, self.view gray, just like
we did with our anatomy. Now the problem here,
so we need to take a look at our shield, right? So we need to take a look
if our shield is active. So we take a look, we have a variable that we
created called shielded. And when shield is active, we can go ahead and add
in shielded equals true. Let's make sure that we
have that on our function. And now when we get hit, before we do any of
those calculations, we can say if the old did. And we want to make sure it
says if not, she had a C, You can do the exclamation point before the word shielded, or you can type in the word not. Either way. It was out doing the same thing. And I'm just going
to highlight these three lines and hit Tab. So if we're not shielded, we're going to lose health. And if our health is below
0, we delete ourselves. So now we can have an
else statement here. So if we are shielded, we can then delete our shield entered shielded, set to false. Now if we take a look,
shield against Israel is our child of our player, we going to have one of those. So if we open up
our shields scene, we can see we just called
this great shields. So we should be able to do inside of our
players seen here. We should be able to just
get the node shields, make sure you spell it correctly
or you will end up with an error once we run the game
and get to this portion. So say shields dot Kubrick. Now this should delete our shield and set our
shielded to false. And if we don't have a shield, then we should get
damaged out to us. So for this, I'm
going to also print our health just so we can see that visually in our console. Let's go ahead and run
this and see how this works. Without any shields. We get shot. We did not
call it on our projectile. Want to call it body dot, hit. And again, I'm just gonna deal one damage to our
player as well. It's going to keep it even
between the two of them. We see over in the
side here we go on to health One Health and 0, which of course we died with. Now if we can live
long enough to get ourselves a shield,
we can test that. It's gonna be a little
bit of a random test. Who knows? When we're
gonna get a power? If we're gonna get one as well. Let's go ahead and
oh, there's a shield. Fantastic. So we have one. When we get hit, our health should not get lower and our
shield should disappear. Our shield disappeared. And of course we didn't
print our health because we never took damage. Now we take damage to one. And then our shields and our our health is all decreasing
just as we expect it to. Now if you have an explosion or death animation that you add into this for your
player or your enemy. You simply just
play the animation. And then once that's finished, I set it to.
26. Health Gain: Alright, let's go ahead and
tackle in our health up. So too, do I have
anything in here? So let's take a look. What do? Take a look at our
Power Apps Script. And we can create our power up. Buddy entered. Okay,
So here we go. When we get healthier, that's the section that we
want to take a look at here. So when area 2D body entered and the power up we're
looking for is our health. And that's when we're
going to work with here. We're going to go ahead and
create our function for it. We're gonna say,
well, health will say health up amount and redo
health plus equals amount. And that's as simple as we have to make our health
power-up to work. If you want to have a
maximum amount of health, then you can say, all we have to do is then go in up top here and we'll
say var max health. I will set that to maybe five is the maximum
health we can never get. Will come in and we go if
health less than r max shelf. And then we just
have this line in. And there we go. That's all we would
have to do if we want to make sure that we have a maximum health
that the player does not go above or below. That's all we have
to do for that. But now we can see that our
health is going to work. And if I print out healthier, and I'm just going to
go into our world. And let's go ahead and play it and see what
happens when we get a health our Hold on. I do remember, I
did not call it. So let's go into our
our power-ups health. And we're actually called
the body dot health. And pass in the amount that we wanted to up,
which is my one. Make sure I did that right. Yep. Alright. Now we can go into
our world and we can test our health property. So we have three by default, if you remember, we picked up a Health and you can see in the console
there on the left, or health is now four. When we started at three. And with our check
for the Mac health, we should never go
above for any reason. Whatever our back
south is set to. All right, so there we
go. Our health power-up is now functioning
the way it should. Our shields are
not only working, but being taken into
account when he gets shot. And when we get shot
we have damaged. We dealt appropriately to
our enemies and our player. That covers all
of our power ups, that covers our power, our shots, dealing damage. If you create different shots, you could then of course
you could use the same the same type of script for
the projectile only have different values put in
here for your damage. All right, so we have
all that working and for the most part, we have just what
everything we need to Call this completed
space shooter.
27. Stop Shoot Each other: Alright, in this video,
we're going to go ahead and make sure that our enemy cannot shoot
each other in the back. And how we're going to do that is heading over to
our enemy ship. We're going to add a ray cast to D. And for some reason
it's disabled by default. So we want to go over
to the Enabled section in the inspector
and turn that on. Now, arrow is effectively how far our cast is gonna
go, how far we're checking. So what we're gonna do is I'm gonna go ahead and set cache to let's say, maybe a 100. That do it extra, do
most of your screen. If you want to get a
little crazy with it, you could do something
like 400 to make sure that you cover the
entire screen. That's completely up to you. Or collision mask, we want
to interact with layer two. So I'm going to turn one off because we only want to check if we're hitting our enemy, or in this case
our enemies ally. So in our script, when
we shoot, Let's see. Where do we shoot it here, we should write here
when our timer times L. So we're gonna
do a little check. I'm going to say
if we're gonna get our ray cast 2D so F ray
can study dot is colliding. And that's all we
should have to check. Cd there is colliding or isn't. So we're going to say
change this to if not, re-cast TD is colliding. We're going to do
this, which is going to essentially olives to shoot. And notice I left the
starting of the timer out of there because whether
it's colliding or not, we want to restart the timer. So if we were to run this now, and just for pure testing
purposes and showing you, I'm going to set
my velocity out y to 0 again on my enemy. I'm going to turn, go into our world here. And I'm going to set to enemies. I'm going to set one right in
front of our players here. Or rather, let's set it
off to the side here. And let's go ahead and get
ourselves another enemy ship. And we'll set it
behind him like this. So now if our code works there, yep, in the back
here should not, because it knows it would shoot a friendly an ally for it. Whereas the one
in the front here should be able to just
continue shooting like normal. And there we go. We
can see in the front and all of these ones that are
spawning and are shooting. But the one that the one that's right here in our top
left are our upper left? No, since the enemy in
front and did not shoot. If we take a look, only
the first one is shooting because the others are hitting at least one other ship
that'll be in front of it. An app Our to say grab this
ship and pull it over. You can see now that would have shooting because there's
nothing in front of it. And the one at the very
top is not shooting. Because if you take a
look right in this area, you can see it's barely hitting the collision box that
we have of our ship. So if we were to just take
that and just over a bit, you can see down here it goes ahead and he starts shooting. Now he is hitting
our enemy there. And that's for the body. Alright, so we didn't go.
We can see that they only shoot when we have enemies
in front of them directly. So you can see what this, we have some fairly decent
connection going on here with knowing whether or not an enemy is
in front of us. So with that logic, we
should be all fine. Now, I'm gonna go ahead and add my spawners back into the
world. Enemy spawner. If we go ahead and
take a look at it now. Oh, that's right.
I set them to 0. Test that. Set this back
to speed. There we go. So we can see that
they're not shooting when they have another ship
directly in front of them. And we go. So now our ships
are a little more self-aware.
28. Spawn animations: Now all you have to do if you
want more complex patterns, instead of moving directly down. You can just use
something like a random, something like our
random that we use. Let's pull that back. For example, just like
we're doing here when Randy we can do
something like that. And then based off of
the number that you get, you can play a
specific animation that you create British ships. So if you want to have unique, maybe you want to ship
to do a couple of loops. You can go ahead and you
can set it to doing that. Obviously, you would need
to set its y velocity to 0. If you want that. Otherwise, you're
going to keep moving vertically even though you're
playing your animation. So you can take advantage of the animation of player to make your ships do all
kinds of things. And you can take
advantage of using Randy to create different or
play different scenarios. And the place you
would do that would be right here inside
of your enemies spawn. So based off of
whatever you get. So we're saying, let's
say, for example, if I will say var equals randy, Alright, let's say
Randy five, like so. And then we'll say like F
and M equals, equals 0. What did the default here? And here, and m equals one. And of course you can use match like we did before
with the player. When it comes to power ups. Right here, you can
see a match here. You don't want to
use if statements. Obviously, we can go
ahead and take a look. If anime knife animate. If Adam one. Play this animation, set
velocity know pi to 0. And that's all you
would have to do. Now, our shape is going
to continuously to shoot. That's logic is all on its own. But this is how you
can do it, right? And then we can, of
course do another check if we were all and M2. And we can play this animation
and set the velocity is 0, who rolling a three
per cent that. So up to there, it's
really up to you. And the animation is
that you want to create for the ships to use or
have when they spawn in. And if you want to
take it further, say animation one comes
in from the left. I'm Sam from the
left. You can do. You can come in and you can, you can check position
x is less than, maybe your animation has
gotta be less than 300. So you can check that, right? So just using these
simple text and creating different kinds of animations
with a bond flow like this. I should also add in here. Just in case some people
don't realize add enemy as child. Child. I go to just add that in for a little bit
of emphasis there. But this is essentially
all you have to do is just follow this
path thing with, and you can go into
the Animation player and you can create all
the different animation, all the different
animations you want for your ship to take as
far as path and goes. Alright, that, that handles it. We have, you have an idea of
how to create unique having. If you want to have
a special animation or your ship, when it spawns in. And of course, it'll be a random chance whether
it does that or if it just comes straight
down. If you want. We have gone ahead and
addressed our enemies, not shooting each
other in the back. Right? At this point, I'm not
going to use any of these, but you certainly can,
if you would like. I don't I don't
think I'm going to, I'm okay with it
just coming straight down like some of the classics. But we don't really have much
left to do here aside from tackling what our GUI is gonna look like and having it updated.
29. UI Creation: Alright everyone, In this video, we're gonna go ahead and
we're going to create the user interface
part of our game. So if I just zoom in here, you can see that
we're going to have our health displayed on our
left in the form of hearts. And we have both an
empty and a fill. As just as we did with
our other power-ups here, but we're going to
have our power-ups displayed on the
right-hand side. When they're empty, they
will be grayed out. When they're
visible. There'll be all lit up like you see here. Now. We could just leave them
individually in like this. And then just toggle
which ones are being shown through the visibility. But there's a much easier
way for us to do this. So I'm going to
delete all of those. And the easiest way to
accomplish something like this. First of all, use
a canvas layer. Now the canvas layer, anything that's put on that, on that will be
drawn on top of or in front of everything
else on the screen. So I'm going to create a new
scene, go to my other node. My canvas layer helps if we spell it correctly.
There we go. I'm going to rename
this to my duty. That's what it's going to
be and give it a save. Scenes. Save. There we go. So now we
have our scene safe. And gooey, if you don't know, it just stands for
graphical user interface. What I'm going to use for these is I'm actually going
to use a progress bar. But we don't want
to normal progress. We want to have our textures and we're going to use
a texture progress. Now, this is basically
going to allow us to fill up and empty a bar. And now he could
think of this as a typical rectangle health
bar or a loading bar. However, we're going to
do this with our sprites. And we'll go ahead, we'll start with the Health
Bar, what we named this one. And let's go ahead
and take a look. We're going to fill it
from left to right. You can see we have all these
different options here, depending on how you want to. Goal belt your Bartok's. We have left to
right, right to left. We have top to bottom. Which can be interesting or bottom to top paying on how you want to go
about doing that. We got clockwise bar, so I'm not mistaken.
Breath of the Wild. That new Zelda game
that's on the switch has used a clockwise stamina bar,
if I remember correctly. But what we're going to use
is left to right for this. Now if we open up textures you, we have an under and
over and a progress. Now I do mix up these threads exactly
what, which is which. But I'm going to go ahead
and bring in my health. Empty I believe goes to the under full either
goes on over or progress. I believe I believe
over would be like the decorations with a
border around your bar. Under is the
underside every bar. So if you have a health
bar might be a darker red or it might just be
empty and have nothing. And then progress is
what we're going to show as we make progress. So if I put my health
bar filled up one in progress and the
empty one and under, if I come down here to my
value and I set this to 50, which is halfway because the
Min is 0, max is hungry. So I said valued at 50 share health gets
filled up halfway. Now you can display this
however, you would like. I'm gonna go ahead and set
my maximum value to five. Which means if I set my value to five will
be at full health. If I set it to one, we've got one health left. And if you want to take
this another step, you can see our steps will
go up by being set to one. For example, we can't do 1.5, just round this out to two. But if you want to have
half a heart in there, then change our step 2.50, and now we'll be able to do 1.5 without rounding off on us. So those are just some
options that you can think of for what we're gonna
do or what you wanna do. Well, that's essentially all
we're going to need for. For doing these bars are essentially all going
to work the same. Our health and our multi
shot shields and speed. No, The only have one image. That just means
we're going to have a maximum value of one
than say there's 0 or one. It's either on or off,
enabled or disabled. Before a healthier, you can
see take a little liberty. So if you want, you can
do half damage marks on here or you can stick
with the standard one, which is what I'll
be using here. The standard 12345. And I'll just go ahead and
create our other marks here. So lab have two more texture. Progress bars will have one
for our multi shot bar. We have our speed bar. And lastly, a progress
bar. We don't lock that. But since I have that open, you can see a progress
bar is usually what you're going to see for
something like a loading screen. It's just a simple
bar that fills up. And that's it really all
you really have to that. Whereas the texture
one, as you saw, we can apply our own
custom textures to it, make it look more unique. So go ahead and get a
texture progress again. And that leaves just want
to be our shield bar. Alright, so moving on to
that one out of the way, our multi shot bar of it's
gonna get shrunk down. Let's take a look. We'll
put our under she's empty. Our progress, which is our
full bring our little bar. And so we have our minimum. And this is either going to
be 0 or one. Set that to one. To take a look at maxed out, we can bring our speed over, which would be roughly
the same size. Alright, so now we can
take a look at how far we want our positions
to be on these. So where do I want this go? Let's see, Let's take
wreck and position. And might be a little much. I think five would
be a good number. These along the go along the y position down, wrecked position y five. And same with our help. Keep everything on an
even field or an overall nicer look to it will also
pull five away from the x. Grab all three of these. Move on over. And
let's take a look. We have that. I'm going to start by taking us or all the way to the edge. And then I'm just going to
subtract five off of these. So say 208 minus five. Then we'll say 125 minus five, that'd be one eighty, one sixty three minus
five leaves us with 158. Alright, so now we have
an even distribution between all these
and if we run this, let me see, That's how our
UI is going to look here. With our UI now created. We can then move
on to implementing the bill ops and not
into our scripts.
30. Updating UI: Alright, so let's
go ahead and start adding into our code. And I think the easiest way
to do that is if we create one overall function that could handle changing any of our bars. So this will be a function
that we can use over and over. So I'm gonna go
ahead and create a new script onto arguing. Place it in the
correct location. Inside of our scripts. Not going to be any variables. They're ready function. We couldn't use that. I'm not going to get
rid of it just yet. And inside of our process
function, sorry, not process. And get rid of that. We're going to have our own functions here. I'm going to come in to the
function update, update bar. And that's going to take
in two arguments of a bar in the form of string. And that's going to take in a value in the form of an inch. Now, if you're doing
a half values, then of course you would
have to be able to accept loads as well, which means how you
can set it like this. Why do a whole number,
you of course do like 1, for example. Since I'm dealing
with whole numbers, I'm just gonna go
straight in with. And what we're gonna do is
we're going to use bar. So when we call this, we're going to pass in a
string such as health bar, multi shot bar, C
bar, shield bar. So we're going to tell it which these bars that we bought. After that, we can go
ahead and do yet node. And we can just pass in the
bar that we want in there. We set dot value equals
whatever value we pass it. And that's all we
have to do that. Battle now, add or set
our vars to whatever, whatever we want the current
values of them to be. In our ready function. I'm gonna go ahead
and do self dot, add, add, add to group. And I'm gonna go ahead and
just add this to a group called gooey in all caps. Now, what we just
did right here in the code AC equivalent
of coming over here to our node groups and adding our Dewey into a gooey
group here and hitting Add. This is the exact same thing. It's just going to happen
once our game loads. That's a second way that you
can go about doing that. It's really up to you
which Rocks Gogo to do that doesn't really hurt any or matter which
way you go about it. And I'll save that created. We should now be able to
start implementing these. So I'm gonna go ahead
and go to, let's go to, go to our power up, I'll add or do we into the
world at an art GUI scene. So now that we have our
Dewey in the world, you could see whether we have it at the top or at the bottom. It doesn't it's not
going to matter. Because again, it's an
a canvas layer which is always gonna be drawn
on top of everything else. Now you could change
this, of course, with layers, as
you can see there, but there's no real,
no real point. Especially in the
maturity of games here. And layers should only really come into
play when you have, if you have multiple
Canvas lazy, I'm going to keep
everything super organized as being displayed. Alright, so let's jump
into our scripts. Let's start with what did I say? Power-ups. Here we go. So we're jumping in,
so we're going to innate call and
they will speed up, shield activate, and enable
multi shot all on our player. Let's say. Alright,
so this gives us health is gonna be
what have we sit here? So we can go ahead and
we can set that to five. Now, going to set that to five successive maximum
amount that we can have. We're going to find
our health here. Alright, so in here what we're gonna do
is we're going to, we're going to call
the group DUE, which means everything
that's inside of that group. And you're going to tell
all of those things to perform a specific function. Now if it doesn't have,
have that function, of course, you might end up
with an error or a problem. In our case, we only have one item in there,
and that's our GUI. So we know the function
is going to exist. So we're going to say call, get, tree dot col group. So the first item
here is what group? Which is going to be
the GUI. We group. The second argument is the
function you want to call it. I'm just going to go ahead and select that to make
sure it's spelled right. These are all added as
strings, so update bar. And then the next are gonna be the arguments
that you pass in. So first up we need the
bar, which is health. Bar. And the second is gonna be the value that we
want to update it to. So in our case,
we're going to use health because health
is going to be set to whatever, right? And that's gonna be set to 123 or five by the end of this. So we'll go ahead and use
that to update our health. Now when we get
hit, you remember, you also have to
update our health. The health minus damage
go and we'll call that. So now if we run this, our health should update. And it's set to one
just because we are tetramer testing things. And because that's not
set to full on default, I'm going to come into my
health bar and update that. Where are my values there? So I'll set that to five. I asked my default and we go ahead and run that
so we have full health. And you see we've got shot,
we're loosing health. It's updating. And if we
can find a health power-up, that should also increase. If we can get so lucky. There's one, We got it and you see our health updated to now. Four out of five. There's a multi shot
which we haven't got any of those things
working as of yet. We're arguing for these are default values
should be set to 0. Are these virus. And there we go. Alright, so now we
can use the same code here to get our other value. So enables speed. For example, here. We can come in here,
we can enable it. I'm going to call the GUI group. We're going to call update bar. And this time we're going
to call the speed bar. And we're not going
to pass in health. We're going to pass in one. This time. We're actually
going to set our number. And when our speed
returns to normal, we'll pass in a 0. Alright, we can go ahead and address this for our
shield activate as well. Though shield activate
will set it to one. And we set it back to
0 when we get hit. So we come back up
here to hit when shielded turns false and
we keep rear shields. We update our bar. Notice that we actually
need to update that and we go shield bar. And then that leaves
our multi shot. Come on in. We said true. Multi shop are set to one. And after our timer, when we turn multi shot off, we set the value back to 0. So now our power-ups
should all be running. And who's got to wait
until they show up to test them? Their speed. Boom, it's on. We've got our boost. I should disable
here in a moment. There we go. To our speed works. Now we've got to make
sure our multi shot. There we go. We
ran into an issue. I put back instead of bar. There we go. That is why we go ahead and do our testing so we
know our speed works. We have to test our multi
shot now which should work. We just had a typo in there. And then we can
test our shields. And if both of those work,
then our Power Apps are all functioning as they should. Be. Fantastic. Always great to hear. It says go ahead and wait. There's a shield, pick
it up or shield lit up. Fantastic. When we get shot, disappears with her
shield. Beautiful. Now we just got to make sure
our multi shot is working. Alright. We went
ahead and got multi shots lit up working. And as soon as it's
done, it should. We go back to an empty icon. Alright, so all of our
abilities and power ups are working perfectly fine as
well as our health update. We kept it all contained
into a one simple function. We can call from anywhere
without happened to hookup signals and
making things any more confusing than they might
be for some people.
31. Particle Explosion: Alright, in this video, we're gonna go
ahead and I'm going to show you how you can make an explosion using particles. Now, you can use particles for all different kinds
of different things. In this case, we're
going to use it to make a little bit
of an explosion. This way instead of
animating an explosion, I'm going to show you
how you can create one. I'm going to show you
how you can create one using the built-in particles. Now, when creating
your particles, obviously we're going
to create a new scene. We're going to make a timer. I'm a child of it. Just so it knows when
to delete itself, who afford our memory issue. But when doing particles, CSI type this in here. Articles. We have CPU particles
and particles. There's not a huge
difference between the two, except CPU particles is going
to be powered by your CPU, whereas particles TD is gonna
get powered by your GPU. So depending on your project, you may want to side with
one side over the other, completely up to you, but we're gonna be using
the GPU particles here. Alright, so with that selected
and renamed to explosion, I've gone ahead and
saved my seen already. When Go ahead. We can leave lifetime at one. And we're gonna go
ahead and come on down to process material. Now this is what the
yellow triangle is telling us is that we have
no material for our, we have no material for our
particles here to go off of. So let's go ahead and create
a new particle material. Now, shader would
be going into code, and that's a whole
different language and a whole different
beast on its own. Keep things simple. And because we really don't
need to use shader code here, we're just going to create
a new particle material. And you can already
see that our particle is already active and
it's going straight down. Come on down, we
can take a look. We want our emission shape. One moment. There we go. So our emission shape,
this changes greatly. Should we say sphere node
go in a circle area? We've got a box was going
to be more of a rectangle. So this is pretty much telling
it how to create itself. We're gonna be using a ring. And an example here, if we
increase the ring radius, you can see we're getting different results compared
to this basic point. So if we were to use say, a box, say ten on the x. Why? You can see we're going
into that in ten by ten space that these
particles are spawning in. So depending on what
you're going forward, you might want to experiment
with different shapes, might find something
that you like. I'm going to go with a
ring for this explosion. Hand reset this back down to one, I believe was a default. So moving on, we can go to we've got direction and
we've got gravity. These are the two
things that are going to affect how your, your particles are moving. And for these, I'm going to
go ahead and set my gravity. It's going to be 0 on the y, and I'm going to
put one on the x so that it's moving
out to the right. Now. It's not going
very far at all. And it's not
spreading out at all, like you would expect
from an explosion. But what we can do
is we can move down to the initial velocity. And we can crank that
up, let's say 180. There we go, flying off
into the x-direction. And reason why we have it going all over there
because of our spread. So we had our spread
down to one degree. It's going to almost look like it's going perfectly straight. If we do 0, it will go straight. But since we haven't explosion, we need to actually flip
this all the way round. We want 180 degrees, right? We want to all the
way around us here. And I think 180 on the velocity might be a
little too fast for this. So I'm going to change it to 50. Now. This is, this
is looking great. But as you see, we're
getting like boop, boop, boop, boop, boop, boop. You can see all these
different directions. Now, Warren explosion, we want this to be like
an explosion, right? We just want a big boom
and there's everything. Well, before jumping up there, I'm going to tweak my
velocity randomness year. And this is just going to
put a variety in this. So if my velocity is at 50, my redness some 0.45. This means that my
velocity can be anywhere from 49.4 or five, sorry, 49.55 as a minimum
and as high as 50.45. And you can go ahead
and tweak this is much easier why we got a whole
one difference in there. But again, I'm just
gonna go with any 0.45. It's not a huge difference, but it'll add a little
bit of variety. So nor to get that
explosiveness that we want, we actually want to scroll
all the way up under, under the time section. We have explosiveness here. Go ahead and just
set that to a one. And boom, there we go. We have our explosion. Now, that's not a whole lot of particles that
we have going on. There's only eight of them. Well, we can go ahead and
tweak the amount here. And everybody system
is gonna be different. Remember, the more particles, the more resources it's going to take for the computer
to render those particles. We can go up to,
let's say, a 100. Boom, there we go. Now, if you wanted to use
a lower number, of course, 5050 looks alright
per pixel game as well. But I think I'm gonna go
with a 100 personally. And that's obviously going to be everyone's own
personal choices here. Now, looking at this, we can see it's all white. Now, this isn't gonna be
like a snow **** going on. We want, we want
some color in there. Let's move on down to
the color section. And we're going to
do a color ramp. So a new gradient texture. And just clicking on that, we can create a new gradient. Open that up. And here we go. So what I'm gonna do is
for my first color here, I'm gonna go ahead
and do a yellow. I'm now going to
have another color, a little under halfway,
create an orange. And on this one I'm just
going to go with a dark gray. And I've clicked off of that. There we go. So that's what
I've got for an explosive. You could tweak and
movie little bars here, which will affect the
the gradient change. So see if I move orange
further to the right, they're going to
have that yellow to orange transition
time a lot longer. We're asked to graph and
move it to the left. It's gonna be just one incident. So you can move these sliders
around to something that you feel comfortable with
that you think looks good. I think I'm gonna go
with that right there. And with that we have an explosion that's
created and ready. Now, we just wanted to
go off the onetime. Promise. If we hit one shot, our particles are not going to emit when they're
loaded into the scene. I don't know if this is a
bug or an issue or what, but we can toggle one shot
after it's been spawned in. And again, your amount here is gonna be all the way up to, but
I'm going to show you, what if we had something like a thousand C are
explosions get why? Why did a lot different?
Because responding all of these mount all at one time. You see we're getting a
very clear ring shape here. So like this might be
a little too much. In this case. Which is why for something like smoke supposed to exist
in a pickup game, I like going with
these smaller numbers, like 50 to 100. Alright, so now that
we have that created, make sure to save your scene. We're going to jump into, take a look at our
little script here. I'm going to create
the for the timer. I'm going to send the timeout
signal, my explosion. And I'm just going to
set that to self dot. Now the important thing
I want to set here is I want to make
sure the wait time on my timer is the same
amount as the life at the very least matches our lifetime on our
particles here. Because we don't want it
to get cut off early. And then we can make
sure to set our timer to one shot and auto start. Alright, so next, all
we have to do is move in and set this up
on our enemy ships. Alright, so on our
enemy ship here, I've gone ahead and created
a variable called explosion that freeloading in our particles here,
explosion particle. And I'm gonna go down to when our enemy gets HIT inside of the tape function is
less than or equal to 0. We want to delete it, but
of course we want to, we want to spawn
or particles in. So I'm going to create
a new variable conn EX p underscore. Set that equal to
explosion dot instance. Here we have a new
instance of this. And we of course want to
add it into our scene with get parent and child EXP. Okay. So that's great. We have it in the scene now. There's two problems
in this case. Well, one problem and
one partial problem. The first one is the problem that it's going to be heading
up in the corner still. So we need to set its
position EXP underscore dot position equals self
dot position. To now. The explosion particles
should now be in the same place as our
enemy ship when it died. And we can go ahead and we
can set one shot. To be true. You shouldn't have to do
this with the timer setup. But if you want to
be extra safe than a dozen loop or any
of that on its own. Just a little extra precaution. Then you can go ahead and set
one shot equals true here. Now if we go ahead and run
this, you can take a look. There we go. We have
an explosion and it disappears. There we go. Now you can go ahead and
you can do the same thing and add it to the
player if you wanted. When the player gets killed. There we go. We created
our own little explosion. Purely made from particles.
32. Game Over: All right, For this video, we're going to go ahead and make a little game over scene so
that when the player dies, we can prompt the user with an option to restart the game. And I think I'm gonna do
this inside of my order. I wanted to make a
separate sheet for this. You know what? Let's go ahead and I'll
add it into my Dewey. Yeah, let's go
ahead and do that. So I'm gonna go
ahead and for this, I'm gonna do a color wreck. And I'm just going extend it. Make sure it covers
all of my blue area. And I'm going to
change the color to be let's see what dark
mode will look like. Twenty one, twenty
one, twenty one. And lower my alpha
to a round halfway. If we take a look at that now, there's where we can look at. Now this game over
scene is going to be really simple for us to do. I'll call this GO, GO BG for game over background. Going to create a control node here and just call it game over. So I can make this
easy to access later. Move my background inside of it. And then what we're
gonna be able to do is just show or hide the
entire game over screen. Alright, so what we need here, so we need a label so
we can show some text. This text is just going
to say M over sure, labels on top of our background. And let's see. So anything we can
override in here. No, everything seems as good as we can do
it without bringing custom fonts into it. So say GameOver, say geo tax. And the last thing we're going
to bring in is a button. And this button will say retry. Alright, so now we
have our books. We have all of our
elements, you, we have a little
background to show that something is different. We have our text telling you
that the players game over and we have a retry
button. Now we can put in. So now all we have to
do is just show or hide this from view. And for this, we can go
into, go to our GUI. And what's gonna be very important for us is
pause mode here. Now this is set to inherit, which means if
everything else stops or GUI is going to stop
and if our Dewey stops, or game over screen
is not going to work. So we want to set
this to process so that when we pause the tree, arguably and all of
his children here, We're going to continue working. Alright, so let's take a
look at our script and we'll say write a
function called him over. And for this, we're
gonna get our GameOver. Note here. Is that
visible equal to true? And when our player dies, see where this is right here. Free. Ross going to
call the GUI group. Obviously we don't need
any arguments for this. We're gonna call group gooey. And I've already forgotten game over with an
underscore. Copy that. So there's no typos. You go. It's actually now trigger
our GameOver when we lose. Let's go ahead and take a look. Citizen ship sponsoring. Apparently they're all
taking the same pathing. We go. Okay. Alright, we
now have two health. One. This next one should
trigger our game. Over. Here we go. So if you don't want to pause the scene and you want to keep seeing your enemies
spawn and shooting. You can certainly stop
this portion right here. What I'm going to
show you how you can pause the screen as well. So inside of our player script, just before we do free it, after we've called
the game overseen, we're going to say
tree equals true. And if we were to
try that now we will see that everything pauses. When we die. There we go. So if you want to have
everything paused, if you want to have
the screen pause when we hit a game over like so. That's how we can do that. If you don't want to have that, just omit that screen altogether
or that line of code. And now we need our retry
button here to work. So let's go ahead and hook up our retry button with the
breast signal onto our GUI. And when that gets crashed, we're going to say get
three reload currency. Now what's that going
to do is that's going to definitely reload
missing justice. If we were to SF, we hit the play button
like we just did. Let's see, 1231 more shot
and we'll be hit with it. See GameOver,
everything's paused. And we hit retry. And we see it reloads, but everything's still paused. We need to unpause the tree now, now that it's been reloaded. So after we reload, the scene would do same thing
that we just did get tree. And pause, and we'll
set that to false. So now not only
will it be reset, but I'll be reset and we'll be able to start
playing immediately. Again. We're not going to have everything's not
going to be frozen. Go ahead and take a look. We need one more hit. Here we go. Came over. Can you retry? And now we can keep playing
some more. There we go. We now have a game over
scene, game over screen. Now we can that gives us
the option to restart a game without having to
close and reopen our program.