HomeVideos

Godot 4.5 Beginner Tutorial: Game Over, Upgrades & Combat Polish (Part 5)

Now Playing

Godot 4.5 Beginner Tutorial: Game Over, Upgrades & Combat Polish (Part 5)

Transcript

872 segments

0:02

Right now, our game is broken. We level

0:05

up and the game freezes forever. Today,

0:07

we're going to fix that. We're going to

0:08

build the upgrade system, give our

0:10

player a health bar, and finally let the

0:12

enemies fight back. Welcome back. We're

0:15

at the final step. In the last video, we

0:17

left our hero frozen in time on the

0:19

level up screen. Now, in this video,

0:21

we're going to add buttons and give

0:22

those buttons functionality so you can

0:24

choose your power. Then we're going to

0:26

raise the stakes by adding a health bar,

0:28

invincibility frames, and a game over

0:30

screen.

0:32

First, let's get the game moving again.

0:34

We need to add buttons to our level up

0:35

panel so we can choose a reward and

0:37

unpause the tree. Now, back in our game,

0:40

before we do anything, go to our scripts

0:43

and our UI script. We're going to add

0:44

something, a function called resume game

0:48

function. Resume game underneath our

0:51

level up function here. And what we're

0:53

going to do here is we're going to take

0:54

our level up panel. So once again, this

0:57

has to match. So this should populate

0:59

automatically as soon as you get that

1:00

money symbol. Level up panel. And then

1:02

we're going to set the visibility

1:05

to false. Visible. Visibility. There.

1:09

Visible equals false. Well, helps if I

1:12

spell it right. Ble. There we go. False.

1:14

Great. So when we resume game, we want

1:16

to hide the level up window. And then

1:18

well, we want to unpause the game. get

1:21

tree and pause needs to equal false.

1:25

Now, this is crucial because this

1:26

unfreezes the game after we've selected

1:29

which power up we want. Unfreezes the

1:32

game. Perfect. Go and save that. I'm

1:36

back in our main game here in our 2D

1:38

section so we can see what's happening.

1:40

We're going to unhide our level up

1:42

panel. Perfect. And in this panel, we're

1:46

going to actually rightclick, add child

1:49

node to our main panel node. We're going

1:51

to look for something called a vbox.

1:54

Vbox container. There we go. And then

1:57

we're actually going to drag our label

2:00

into our VBox like this. And our VBox

2:04

container, we want it to be anchored at

2:06

a full wctck. So it takes up the whole

2:09

level up panel. Great. Now in this Vbox,

2:13

we're going to right click and add three

2:15

buttons. So button, enter,

2:19

we have one button. We're going to

2:21

duplicate it twice. Once, twice. Just

2:23

hold down control D. Great. Now we take

2:27

one button and button three. We're going

2:29

to highlight all three of them. Now in

2:32

our anchor here, our size settings,

2:35

we're going to expand the vertical

2:37

alignment on all three of them. Now they

2:40

take up our whole spots or rate. Now

2:43

this first button, well, we're going to

2:44

call this the heal button.

2:47

And we're going to set the text to heal

2:50

plus 20. Perfect.

2:54

And this button too, well, we're going

2:56

to call that the speed button.

2:59

Great. And the text in there, it's just

3:01

going to be speed plus 50. And the third

3:06

one, we're going to call that our damage

3:08

button.

3:10

All right. And the text in there is just

3:12

for now be ammo plus one.

3:16

Great. Now we have that. Now we can hide

3:19

our level up panel again. We don't want

3:21

to see it unless we level up. We're

3:23

going to open up our script and our UI

3:26

script here. And then we're going to

3:28

click on our heal button first off. And

3:31

we're going to go into the right by

3:32

inspector. going to go to the node

3:34

section.

3:36

All right. And then with our heel button

3:38

selected and double click on the pressed

3:41

signal and not in the UI, we want it in

3:44

the I mean not in the player. We want it

3:47

in the UI on the heel button. Pressed.

3:50

Connect. That should populate. I want to

3:52

do that for the next two buttons as

3:54

well. Speed button pressed. Double click

3:56

in the UI. Connect. Populate. Damage.

4:00

Double click in the UI connect.

4:05

Now we have all three connected. All

4:07

right. Now the first thing we're going

4:09

to do our heel button pressed here. I'll

4:12

expand this out. Make it bigger. Now

4:14

we're going to

4:17

one pressed the heel button. We want to

4:20

call a health update. We're going to

4:23

write this function in a second. So

4:25

we're going to trigger the health update

4:27

and it's going to be a function called

4:28

heal. I'm going to send in how much we

4:31

want to heal for, which is going to be

4:33

20. Once going to write this function in

4:35

a second. Now, after we heal, well, we

4:38

want to resume the game. Resume game.

4:42

Just like that. Perfect. And save that.

4:46

Now, we're going to do the speed button

4:48

here. Replace this placeholder. Now,

4:50

we're going to up the player speed. So,

4:52

we're just going to do player speed.

4:54

Access the speed variable in the player.

4:56

And we're just going to up it by 50.

4:58

That works for now. And then after that,

5:00

of course, we want to resume our game.

5:03

All right, go and save that. Now, this

5:05

ammo one's going to be a little more

5:07

tricky. So, when we want to up our ammo,

5:10

we're have to update a couple functions

5:12

here. But what we want to do is we want

5:14

to add one to the projectile count.

5:18

Projectile count. But we want to stop if

5:22

we hit three. We don't want too many.

5:24

Gets a little crazy. So what we're going

5:26

to do is access the player.p projectile

5:30

count

5:32

and we're going to equal that to a

5:34

minimum.

5:35

So min what this going to do

5:38

control-click on that just returns a

5:40

minimum of the given numeric values. So

5:42

say we have a list of all these numbers

5:45

and return the lowest one. Back in our

5:47

UI script there, our minimum is going to

5:50

be the player projectile

5:55

count

5:57

plus one, but we don't want it greater

6:01

than three.

6:04

Oh, this needs to be a period. There we

6:07

go. And we're going to add this

6:08

projectile count into our player after

6:11

we finish this function because we need

6:14

to resume the game. Perfect. So, after

6:17

we add a projectile, add one plus one,

6:22

but no greater than three to our player

6:25

projectile count, then we can resume the

6:27

game.

6:28

Great. And now, back in our player

6:30

script here, click there or scroll up to

6:33

the top.

6:35

And there are signals here. We're going

6:36

to add a signal called health changed.

6:41

And what this is going to have with

6:42

parameter is the current health.

6:45

When the health changes, we're going to

6:47

set the current health to that. Right?

6:49

Now, we need to write the heal function.

6:51

Scroll down to the bottom after our

6:53

level up stuff is function heal. And for

6:59

what? For the amount we send it into.

7:01

So, the health we're going to plus

7:02

equals the amount that we send in

7:07

type. There we go.

7:09

And then after that we want to check the

7:11

cap. So if our health cap is which is

7:13

100 right now is greater than our health

7:17

goes over 100. Well we want to set the

7:19

health to 100 which is going to cap our

7:21

health at max. There we go.

7:25

And then we want to emit that signal

7:28

that our health has changed. So the

7:30

health changed signal we want to admit.

7:33

We want to emit what we want to emit the

7:34

health our health is currently. to our

7:38

card health. And what this is, this

7:40

triggers the UI update. Triggers the UI

7:42

update.

7:43

Perfect. All right. Now, we need to

7:45

handle the projectile count. So, we go

7:48

up to the top. We're going to add that

7:50

variable in our exports. So, at export

7:54

variable projectile count,

7:57

and we're going to set that first to

7:58

one. So, that just starts the uh

8:01

projectiles at one, which is start with

8:04

one projectile.

8:06

what that means. Perfect.

8:09

And then we need to update our holster

8:11

here. So go to our holster. Save that.

8:14

Holster GDScript and our timer timeout

8:17

function. We need to rewrite a couple

8:19

things. We need to add a loop. So at the

8:23

beginning here, we'll enter down. So

8:24

we're going to loop through our

8:27

projectile counts.

8:29

Our projectile count. One, two, or

8:32

three. Great. And that we do that by

8:35

saying for i in range of player

8:40

projectile count.

8:43

There we go. So in the range of our

8:45

current projectile count, we're going to

8:48

go into the body here.

8:51

And then we're going to take all this

8:53

info here. Let's highlight

8:55

all this underneath the loop. We need to

8:59

indent it so it gets inside the loop.

9:01

Just like that.

9:03

Then we need to define our player too as

9:05

well. And we can do that easily by

9:08

saying

9:09

on ready

9:11

var

9:13

player since our holster is a child of

9:17

the player simply we just have to say

9:20

equals get parent.

9:23

There we go. And that's going to be our

9:25

player. Save.

9:27

Now we have that settled. The only thing

9:30

we have to do here is after we fire,

9:32

well, we want to have a little delay if

9:35

we have any shots left. So, delay for

9:38

extra shots.

9:41

But we also want to wait, we're going to

9:43

wait 0.1 seconds before the shot, but

9:48

only if we have shots left. And we do

9:53

that by simply saying if I, which is

9:57

where we're at in the loop. So that's

9:59

where the I comes from here. So this

10:01

current index of the player projectile

10:05

count, projectile count

10:09

minus one. So we know we're still in

10:13

the count and not out of bounds. So we

10:15

want to say that.

10:18

And if that's true, if that I is less

10:20

than that, well, we're going to do a

10:21

thing called await and get tree and

10:25

create timer.

10:27

the timer. We want to wait for 0.1

10:29

seconds. And we're gonna time out. So

10:32

that creates a timer that waits for 0.1

10:35

if there's an extra shot. And then to go

10:38

back through the loop and shoot again at

10:40

a new enemy if the other one's dead. Now

10:42

that the game can resume, let's make the

10:45

player mortal. We need to track health

10:47

and tell the UI when it changes. So

10:50

first going to open up the player GD

10:52

script.

10:54

Save the ones we have. We're going to

10:56

add a signal up at the top here. Call

10:58

signal health depleted.

11:04

So that way we know when our health

11:05

depletes. And scroll down the bottom.

11:07

We're going to add the take damage

11:09

function. Enter down a couple times.

11:11

Function take damage.

11:15

Great. Now we're going to add some I

11:17

frames in a second, but first we'll do

11:19

the health. So, the health minus equals

11:23

10

11:25

minus 10 health when we get it. For now,

11:28

we'll we'll update per enemy if you want

11:31

to do that in the polish section. For

11:34

now, we'll just do hard code health

11:36

changed. We're going to emit that the

11:39

health has changed. So, that'll be able

11:41

to update our UI. So, this just tells

11:44

the UI to update.

11:48

All right. And then after that we need

11:50

to see if the health is zero. So if the

11:52

health is less than or equal to zero

11:55

well a health deplete emit again so it

11:59

can change the change the UI. We also

12:01

need to

12:03

need to fix this expression less than or

12:06

equal to zero. And now our health has

12:08

been depleted all the way. So then we're

12:11

going to disable the collision first.

12:13

disable our collision

12:15

so the enemies stop pushing the corpse.

12:20

Right. So then we need to get with the

12:22

money symbol our collision shape 2D. As

12:25

long as it's named the default, you'll

12:27

be able to access it like that. If not,

12:29

just set it to the one you change it to.

12:31

And we're do a thing called set

12:32

deferred.

12:34

Okay? And that's going to just like call

12:37

deferred. Set deferred is also going to

12:39

wait till the end of the frame. So set

12:40

deferred to disabled.

12:44

True.

12:46

Perfect. All right. Now, optionally, you

12:49

can hide the player. And so, it's more

12:52

like they don't exist anymore. So,

12:54

optional is going to be hide the player.

12:58

You don't have to do this, but if you

13:00

don't have a death animation, then this

13:02

suffices. So, we just hide. Easy enough.

13:06

Now, printing health to the console is

13:08

boring. Let's add a red health bar so we

13:10

can see our impending doom. So, back in

13:13

here, we're going to go to our going to

13:15

reduce this size here. Make sure I save

13:17

those scripts and our main game. I'm

13:20

going to select this UI here. Go to 2D

13:22

so you see what's happening. And UI

13:25

canvas here. I'm going to right click,

13:28

add a child node. I'm going to add

13:29

another progress bar right here. Just

13:33

create. I'm going to change the name on

13:35

this one to health bar.

13:39

Perfect. And for the style for this one,

13:42

we're going to set the sizing

13:46

uh sizing to the anchor anchor. We're

13:49

going to anchor our health bar. Make

13:51

sure it's health bar selected. Anchor to

13:54

bottom wide. There we go. And for this

13:57

one, the health bar, we're going to set

13:58

the

14:01

percent the value here. We're going to

14:03

set it to 100. So, we start off as a

14:06

full bar.

14:08

There we go. So, it's all nice and

14:09

filled up. And then we want to change

14:11

the color a little bit. So, let's go

14:12

down to theme overrides. Then we'll

14:15

change our fonts. Our colors. There we

14:18

go. Our font colors. Not our fonts.

14:22

Our styles. My apologies. Styles. You

14:26

want to go to the fill. Right click on

14:29

there. A new style box. Flat. Then click

14:32

in there. Open it up. And then our BG

14:35

color. We want to change that to red. So

14:38

I go to linear here. I can just pump red

14:41

all the way up and all the other colors

14:42

all the way down. I have a nice red

14:44

health bar. Perfect.

14:47

Great. Now we have that. I can save

14:49

that. I go back to our scripts. Go to

14:51

our UI script. I'll make this bigger.

14:55

Before we make it bigger, I want to add

14:57

the health bar.

14:59

Oh no, we're going to do that way. Yeah,

15:01

I'll make it bigger. I go to the ready

15:04

function here in the UI script. In our

15:08

ready one, we're going to

15:11

Oh, before we connect that, well, let's

15:12

scroll down to the bottom. We're going

15:14

to add a new function. It's going to be

15:17

called

15:19

so we can update the health bar.

15:20

Function on player

15:23

health changed. There we go. Be new

15:27

health. So, our new health is what we

15:29

want to change the player health bar.

15:32

So we get that by since we renamed it

15:35

health bar money symbol and health bar

15:37

should pop up. So we get select that and

15:40

we're going to change the value to start

15:43

with 100. No to new health. There we go.

15:48

New health is going to be our new value

15:51

when the player health changes. Perfect.

15:53

Now back in the ready function. That's

15:56

where we're going to set the initial bar

15:58

value to 100.

16:00

So, initialize bar. I'm going to do the

16:03

money symbol again, health bar value.

16:08

This is where we'll set it to 100. So,

16:10

now that's when we start the game, it'll

16:12

be 100. Then when we change the health

16:16

in

16:18

the onchange player health function,

16:20

which we're going to connect here. So,

16:22

after our other signals, player.health

16:26

changed. So when the health changed, so

16:29

in our player script, our signal at the

16:31

top here health changed, we're going to

16:34

connect that to our UI. So player health

16:39

changed. And then we're going to connect

16:41

that to our on player health changed

16:45

function, which we do not need the

16:47

parenthesis for. Perfect. Going to save

16:50

that.

16:51

Now we need some I frames, invincibility

16:54

frames. It's a moment of invincibility

16:56

after getting hit. So, we don't die in

16:58

60 frames, which is a snap of a fingers.

17:02

So, let's get that implemented.

17:04

Back in our player scene here, right

17:07

there, we go to our 2D section, make

17:09

this smaller. We see our hierarchy. So,

17:12

we're going to add a timer child to the

17:16

player.

17:18

Add child node timer. And we're going to

17:21

call this timer the damage timer.

17:24

Perfect. I'm going set the wait time to

17:27

half a second. It's not bad for a

17:30

invincibility. And one shot is true so

17:32

it doesn't keep cycling. All right. Now,

17:36

back in our scripts, our player script,

17:39

we'll make this bigger.

17:41

Now, back down in our take damage script

17:44

here in our filter methods. You can

17:46

click there.

17:47

The first thing we want to do before we

17:48

take damage, well, we want to see if the

17:50

timer is running. So check if timer is

17:53

running if I invincibility vint or call

17:57

damage timer is running. So if the money

18:02

symbol damage timer

18:05

time left is greater than zero well

18:08

return that means we are invincible.

18:12

Invincible

18:14

I spell that right? No good enough. So

18:17

the second thing we want to do is well

18:19

then we want to take damage after that

18:23

and then after we take damage well now

18:26

we want to start the timer. We go back

18:29

up and then money symbol damage timer

18:33

and we want to start it again if it has

18:35

started already. So start and then it's

18:39

nice to be able to see when we got hit.

18:41

So we're going to add some feedback.

18:43

Start here. do the start I frames here.

18:48

Then after that, let's get some visual

18:50

feedback.

18:52

It's always good to have we do that by

18:55

calling modulate. So this modulate is

18:58

going to access the sprite itself. So we

19:00

go back to make this smaller to our

19:03

sprite 2D. What it's going to do, it's

19:05

going to access this visibility section

19:08

and our modulate. So, this is going to

19:11

change the color of our sprite or the

19:12

alpha. And then we can change it to a

19:15

right, a red, or a white flash.

19:19

We're just going to do a transparent

19:20

flash. We'll make this bigger. So, we're

19:22

going to access the alpha. So, modulate

19:25

alpha, which is a we're going to equal

19:28

that to 0.5. So, when we get hit, it's

19:30

going to lower our alpha by half. And

19:33

then this is just check if we're dead.

19:35

Check if we have health. Check if we

19:37

have our player has health left.

19:43

So now we're still only at half

19:45

transparency. We want that to go back to

19:48

full transparency. We need to make this

19:50

smaller. And we're going to take this

19:52

damage timer. We're go into its node and

19:55

we're going to go into its timeout

19:57

function. And we're going to connect

19:58

that to our player script. Double click

20:01

it to timeout. Double click connect. Now

20:04

we have this populated here. And then

20:07

simply when this is done

20:10

timing, well, we're going to turn our

20:12

modulate alpha back to one. That way

20:16

we're not transparent anymore. Then Crl

20:20

S to save.

20:22

Now we enable enemies. But first, a

20:25

quick physics fix. In top-own games, we

20:28

don't want enemies to act like solid

20:30

walls that block our movement. We want

20:32

them to glide over us.

20:35

Now, we have a sticky problem we need to

20:37

get rid of. Go to our main game here and

20:40

run it. In the current scene, you see

20:43

when we get surrounded by enemies, what

20:46

we have here is a way Well, I guess I

20:49

got to stop killing them all so fast.

20:51

Here, let's take down the projectile. go

20:53

to my player scene in my holster.

20:58

Open that up in my timer for my

21:01

shooting. I'm going to put this just at

21:03

10 seconds for now because I want to

21:05

show you something.

21:07

And then we'll go back to our main game

21:09

after we save that. Run the current

21:12

scene.

21:14

And with a bunch of enemies, we'll start

21:16

walking with the enemies. You can see

21:18

how these enemies kind of stick to us

21:21

like this.

21:23

We don't want that. We want to make sure

21:25

we can walk through these guys without

21:27

them sticking to us. We're going to open

21:30

our enemy scene here. Go to our 2D.

21:34

We're going to select our main enemy

21:35

node here. The root node in our

21:38

inspector. Make this a little wider. We

21:41

want to find a motion mode here is what

21:44

we're looking for. We want to set this

21:46

motion mode to floating. And why do we

21:49

want to do that? Well, if you hover over

21:51

motion mode, the grounded applies

21:53

notions of walls, ceilings, and floors,

21:56

which is fine for if you have those, but

21:58

we don't. Not right now. We have the

22:01

floating when there's no notion of a

22:03

floor or a ceiling. All collisions

22:05

reported as on the wall. Now, this mode

22:08

is suitable for top down games like it

22:10

says right there.

22:13

What we also want to do is remove the in

22:16

the mask of the collision section, we

22:20

want to remove the player mask or

22:22

uncheck it. Now, this is going to stop

22:25

physical collision but keeps them moving

22:29

without us sticking to them.

22:32

Now, before we forget, I'm going to go

22:33

to the player scene and the player root

22:36

node. I'm also going to change the

22:38

motion mode to floating. Go and save

22:41

that. Then I'm go back to the enemy

22:44

scene. We're going to add a damage

22:46

hitbox. So on the root node, we're going

22:48

to right click, add child node, area 2D.

22:52

Enter. I'm going to rename this to

22:55

hitbox

22:57

small B. Then to this we're going to add

22:59

a collision shape 2D. Enter. And then

23:04

for this we need a in the shape in the

23:07

inspector we're going to use a circle.

23:10

We're going to make this centered here.

23:13

Make it slightly bigger than the body.

23:16

Now, this is going to allow us to damage

23:18

the player. So, we need to actually go

23:20

to the hit box and the collision, and we

23:23

make sure we are on the player layer or

23:26

the enemy, but only the mask for the

23:30

player. That's all this needs to do.

23:33

Right. Now, we have that, we can go and

23:35

save it. Go to scripts, open up our

23:38

enemy GD script. We'll make this bigger,

23:41

get rid of this output,

23:43

and we go into our physics process

23:46

method. And after our movement code, we

23:50

go under our move and slide. What we

23:52

want to do is add some attack logic.

23:56

So, first we need the target. So, for

23:58

the target or targets, we're going to

24:00

get our hitbox with our money symbol.

24:03

Hitbox. And then we're going to get

24:06

overlapping bodies.

24:10

So if our player is in our hitbox that

24:14

we just made, then we're going to save

24:15

that into the targets and make sure it's

24:18

the player first of all. So for all the

24:20

targets

24:22

in for target in targets

24:26

we're going to loop through that and say

24:28

if the target

24:30

name equals equals

24:32

well player

24:35

because we named it player

24:37

well we are going to take damage. So

24:39

targetake

24:40

damage.

24:44

So, actually there's a better way to do

24:46

this because this player string here,

24:50

let's say that I minimize this in our

24:52

player scene here. If you rename this

24:55

player to anything else, this string

24:58

will not work. Let's use a more robust

25:01

way here. We're going to use a class

25:03

name. Let's go into our player script,

25:06

player GDScript. Make this bigger. We're

25:10

going to scroll up to the top here. and

25:12

how we can make this a type.

25:15

We're going to go above our extends and

25:18

what we're going to do is call it a

25:20

class name

25:22

player. So now we know that this script,

25:25

whatever it's attached to, is a player.

25:28

So now minimize this. Doesn't matter

25:31

what you name this, we're going to be

25:34

able to access it because it's a player.

25:36

Because in our code, make this bigger

25:38

again. I'm going go to my enemy GD

25:41

script again. Now, instead of using a

25:44

string, what we can do now, instead of

25:47

accessing the name, we can say if target

25:51

is

25:52

player. Now, you see how it pops up

25:55

right there, and that's our player we're

25:57

looking for. So, if that's true, then

26:00

we're going to say target has a take

26:02

damage function, and we can use it. It's

26:04

safer. It autocompletes.

26:07

is considered more robust. So, we'll

26:09

stick to that way. But now, you know,

26:12

both ways, whichever way you want to do

26:13

it. Finally, the end game. Now, when the

26:17

health hits zero, we show the restart

26:19

screen.

26:22

Now, back in our main game here, I'm

26:24

going to switch this to smaller.

26:26

And in our UI here, what we're going to

26:29

do is a right click, add child node, a

26:32

panel,

26:34

just a normal one here. Create. We're

26:37

going to rename this to game over panel.

26:41

Great. Now, I'm going to go back to my

26:43

2D screen here. See what's happening.

26:46

And for this game over panel, I want the

26:48

anchor to be full wctck. So, it takes up

26:51

the whole screen. Just like that.

26:54

And in this game over panel, I'm going

26:56

to rightclick, add child node, a label.

27:01

And in the label, I'm just going to have

27:02

it say game over.

27:04

What we're going to do here for the

27:06

anchor, I'm gonna make it uh top center

27:10

and or top wide. There we go. Then I'm

27:13

going to actually horizontal alignment

27:15

the text to center. Great. I'm going

27:19

scroll down to make it a little more

27:23

legible. Our theme overrides our font

27:26

sizes. I'm just going to make this oh

27:29

60.

27:31

Now, let's go

27:34

100. There we go. And lastly, what we

27:38

need is a button. So, our game over

27:41

panel selected, add child node, a

27:44

button.

27:45

And this is going to be called the

27:47

restart

27:49

button.

27:51

And simply it's going to say

27:53

restart.

27:56

All right. We also want to go to the

27:59

anchor and center it. Just like that.

28:02

Now we have a button in the center and a

28:03

game over up top. And we need to hide

28:06

it. We want to see it all the time only

28:08

when we die. All right. Now we have

28:10

that. We can save it. And we need to go

28:12

to our UI script. We can click on here

28:15

to go directly to it. And I'll make this

28:17

bigger. Now I made a new function. We

28:21

need a new function here. I'll scroll

28:23

down to the bottom. going to write a

28:25

function here called on game over.

28:31

Now when we have a game over, we'll use

28:34

the money symbol and we'll access our

28:36

game over panel. And what we want to do

28:38

is well, we want to be able to see it.

28:41

So visible. We want to make that true.

28:45

And we also well, we want to pause the

28:47

game. So we're going to get tree. So we

28:49

make paused true.

28:52

Great. Now, we need to be able to access

28:54

this function. We need to connect it to

28:57

our players here.

29:00

We need to connect it to our players

29:01

health depleted signal, which means

29:04

we're dead. So, back in the UI GDScript,

29:07

we're going to go to the ready function,

29:09

use the filter methods here, and once

29:12

again, in our player connections here,

29:14

we're going to do player

29:16

health depleted.

29:19

We're going to connect to that signal

29:21

with our on game over that we just wrote

29:24

without the parenthesis

29:27

but with the one on the end. Okay. And

29:29

go and save that.

29:31

Lastly, we need to connect our restart

29:33

button. So, we'll make this smaller. Go

29:37

to our restart button. Then the node and

29:41

we need the pressed. Double click on

29:43

that. And we want to connect it to the

29:45

UI, not the player. Connect.

29:48

I'll make this bigger. Scroll down. We

29:50

can see it's connected now. So when we

29:53

press the restart button. Well, for now,

29:56

we just want to restart the level. So we

29:59

need to get the tree. And we need to

30:01

make paused equal false. So we don't

30:04

unpause. Well, we won't be able to play

30:07

after that. We need to get the tree. And

30:09

we just want to simply call reload

30:11

current scene for now.

30:14

When you polish it up, you can add a

30:15

game over screen or go back to the main

30:17

menu. But for now, we're just going to

30:19

reload this scene and play again. All

30:22

right, go ahead and save that.

30:25

Now, for the final polish, hit flashes.

30:27

We want instant feedback when we shoot

30:29

something.

30:31

All right, now back in our enemy GD

30:33

script, we want to access the take

30:35

damage function here. Before we spawn

30:38

anything, well, we're going to add some

30:41

feedback so we know we got hit.

30:43

So visual feedback is going to be the

30:45

first thing we do. Visual feedback and

30:48

we're going to use the modulate setting.

30:50

Now modulate setting in GDO4 create a

30:53

glow effect actually. So it's pretty

30:55

cool. It's like an HDR without accessing

30:57

any shaders or any of that. So we use

31:00

our money symbol and access our sprite

31:04

2D. Now we need to add the modulate

31:08

right there. Now, if you're curious

31:09

where this is, if you actually I'll make

31:11

this smaller. We go to our enemy scene

31:15

and our sprite 2D here and go to our

31:18

inspector. What we're accessing here is

31:20

the visibility

31:22

modulate. Now, once we get this, we can

31:25

change this however we want. All right.

31:29

Now that we know where we're going, make

31:31

this bigger. Sprite 2D modulate. We're

31:34

going to modulate it to kind of a a

31:38

flash white kind of effect. So, we're

31:41

going to change the color of the sprite

31:43

to 10 10 10.

31:46

And you can see it actually gives you a

31:48

preview of the color there. Now, the

31:51

next thing we need to do is something

31:52

called a tween. So, we need to create

31:56

a tween to fade back to normal color

32:01

after we've flashed to the white.

32:04

So tween's pretty cool. The only way the

32:06

way you can create one now in GDAU 5 or

32:10

GDO 4.5 is just create tween. Super

32:14

easy.

32:16

Now that we've created that tween, we

32:18

can access its properties by saying

32:20

tween. We go tween property

32:24

right there. And in the property, we can

32:27

edit our sprite back to normal by just

32:30

saying our sprite 2D again. And then

32:32

we're going to access the modulate.

32:35

And then in the modulate, we're going to

32:36

just turn the color back to how the

32:39

default is with 111. That's default. And

32:42

then we want to say how long we want to

32:44

take to get there. Well, really quick,

32:46

0.1. So it's like a flash. Now, before

32:50

we spawn the gem or get rid of our

32:52

enemy, we want to wait for this to be

32:54

finished. So you want to wait for the

32:56

tween for the tween to finish.

33:02

And then how do we do that? Well, it's

33:04

an await function. So we used the wait

33:07

and then tween.fin finished. Super

33:10

straightforward.

33:12

So once this flash is finished, well now

33:16

we just want to drop the loot. So we

33:18

spawn the gem and then we die or the

33:21

enemy does. Perfect.

33:24

With all that, go and minimize this and

33:27

go back to our main game scene, our 2D.

33:30

Let's go and give it a final test here.

33:33

The moment of truth and run current

33:35

scene. And we're going to run around.

33:39

Oh, we forgot to set our projectile back

33:41

to

33:42

actual shooting.

33:44

So, our player back to our holster

33:47

timer. We're going to go back to We'll

33:49

do zero. We're going to actually make it

33:51

a little longer. Make it a little

33:53

tougher. Do 0.6. I'm going go and save

33:56

that. All right. Now, I'm going to go

33:58

back to the main game.

34:00

run current scene and let's see how we

34:03

get along here.

34:05

Let's try to get surrounded by some

34:06

enemies.

34:09

See how they're flashing white. That's

34:11

cool. Look there. Now see if we can take

34:13

some damage. Oh, we take some damage.

34:15

Then we turn our eye frames. We turn

34:20

transparent a little bit there. Oh, now

34:22

we have a level up. So now we could test

34:24

the heal. So we're at 30. We should go

34:27

to 50. Yep. To 50. Perfect.

34:31

Try to level up again.

34:34

Collect a couple more. All right. Now,

34:37

let's check the ammo. We should have two

34:39

bullets after this. Oh, we have a error.

34:43

Oh, look at this non-existent function

34:45

create time. We know create time does

34:48

not exist. You want to know why? Because

34:50

it's called create timer. Whoops. All

34:54

right. A little misspelling can really

34:57

screw up your whole game. Let's try this

34:59

again. Run current scene.

35:03

Now, let's get some

35:05

enemies down. First thing we'll do this

35:08

time is update the

35:11

weapon.

35:13

Let's get these guys.

35:15

All right, there we go. Ammo. All right.

35:18

Yep. One, two, one, two. One, two.

35:20

Perfect. Now, let's test it all the way

35:22

to max. Let's do three.

35:27

Then add and one, two, three. One, two,

35:30

three. One, two, three. One, two, three.

35:31

Perfect. Now we want to test the cap.

35:34

Make sure if we hit plus ammo after

35:38

three, it doesn't crash our game.

35:42

All right. Ammo one. One, two, three.

35:45

One, two, three. Perfect. Stuck at

35:46

three. So that's something you can add

35:48

in a polish and what you want to have

35:50

happen after that or have a completely

35:51

different upgrade. Great. Now, let's try

35:54

the speed to give it a final test. We

35:57

tested the health. That works. Now, our

36:00

speed, a little hard to see, but we go

36:03

to our remote section and our main game

36:06

and our player. We have our speed here

36:08

at 300. So, if we go back to our game,

36:11

now if we click speed, this should go to

36:13

350. And it does 350. Perfect. Now,

36:16

we're a little faster. Now, there's

36:18

currently no cap on speed. So

36:20

technically, you can get this speed up

36:23

to infinite, which would completely

36:26

break the game clearly. So that's

36:29

something you'd want to add yourself. A

36:32

nice little cap so it doesn't get too

36:34

fast, too crazy.

36:39

The last thing we want to test is our

36:40

game over screen. So let's go ahead and

36:43

get beat up here. Look at that. All

36:45

right, game over is popped up. And when

36:47

we click this restart button, it should

36:49

just restart from the beginning. Restart

36:51

from the beginning. Zero. And we have

36:54

one shot. So everything is reset.

36:58

You did it. You built a survivor like

37:00

from scratch. You have infinite terrain,

37:02

endless hordes, XP systems, upgrades,

37:05

and a complete game loop. From here, the

37:07

sky really is the limit. You can add

37:09

sound, new weapons, boss fights. I can't

37:12

wait to see what you make. And if you

37:14

enjoyed this series, please share your

37:16

projects in the comments or on our

37:18

Patreon or coffee. I really do love

37:20

seeing what you build. If you found this

37:23

helpful at all or fun, leave a comment

37:25

on what your GDO gamedev goals are.

37:28

Please like, subscribe, and hit that

37:29

notification bell. It really helps out

37:31

the channel. And thank you to all our

37:32

current and past Patreon and coffee

37:34

members. Your generous support keeps the

37:36

channel moving. If you want source code

37:38

suggesting future tutorials or full

37:41

access to tutorials the day they are

37:42

launched instead of waiting for the

37:44

YouTube scheduled videos, please

37:46

consider becoming a member yourself. The

37:49

links are in the description. I'm

37:51

Spaghetti Syntax and remember, finished,

37:54

not perfect. Fail fast, fail often.

37:56

Always stay curious and I'll see you at

37:59

the next checkpoint.

Interactive Summary

This video tutorial focuses on enhancing a game by implementing several key features: an upgrade system with buttons for health, speed, and ammo; a health bar with invincibility frames; a game over screen with a restart option; and improved enemy AI with 'floating' motion and visual feedback on hit. The tutorial walks through the coding process in Godot, explaining how to connect signals, manage game state (like pausing and unpausing), and add visual elements to improve player experience and game feedback. It concludes with a comprehensive test of all implemented features and encourages viewers to expand upon the game.

Suggested questions

6 ready-made prompts