So earlier, I talked about why you should have one script do one thing. So, does this mean we need to animate the player with the animated sprite?

Yes, of course! That would be an easy start in the right direction.

So, what might our animations for this maze game be?

Idle Walk.

Simple enough. Now, how do we animate something when the player moves? Signals?

Not exactly, there is an easier way to do this. =)

If you look back at the player, under get_input(), it shows what inputs cause the player to move. We can use those exact same inputs for our code in the animation player.

Let's add a script to the Animated Sprite, and copy/paste get_input. We also need to use func _process(delta) for this.

Now, we can remove everything about velocity, and move_and_slide, the animated sprite is not detecting collision. What do we need the code?

play("whatever_animation), like this:

Now... what about if we want it to stop?

Let's look back at the player's get_input(). What else does it have on it?

velocity = Vector2()...

What is that?

If you remember from our test, it kept the player from constantly moving. How?

Vector2() means Vector2(0, 0). If we are not pressing any buttons, velocity will always be 0, 0. This is why the character stops.

So, can we use it? I mean, the Animated sprite is the child, not the parent...

Normally, you would use a signal to get to a parent, but there is another way. Since I want to show you whatever I can, the other method is to write get_node(), and with the Player selected, drag it into those parentheses and see what you get.

Ignore the error for now. This is the child calling its parent directly through ode. Yes, they often use signals for this instead, but this was to show you that you can do it.

Now, how to check the velocity?

Every node grabbed in code can have all of their variables, functions, and whatever else used. You could add .velocity == Vector2(0, 0) right in.

Now we need to finish the if statement with play("idle_animation_name").

And you're done!

However, there is an even easier way to do this! :o

Here's my challenge for you in this round: You have all of the information on how to do this in this post. What can you do to basically turn all of this into two simple if statements?

I will see you in the next one.

Hello, world!

...

I wasn't saying it because it was some intro video.

So, anyways, one thing that I wanted to share with you this time was lighting. I mean, the games look great, don't they? With all the sound and graphics?

However, it's a maze, and the player right now can see through walls and such- it's just a bit weird.

So let's change that.

For this, you will need some light masks. I made some a while back for one game and put them under the CC0 license, so here you go, use them however you want.

https://godotforums.org/discussion/29891/light-masks#latest

Now, what are light masks? Well, let's go into the player and add a Light2D node. In the inspector, you will see something called texture. That is where you put your light mask.

Now, I am only going to use the round one, but you can use either or both.

Now if you save and press play, you will notice things are not lit in your game! However, the walls shouldn't glow. Can we keep certain things from lighting up?

Yes, using the LightOccluder2D.

(And yes, I know I haven't done much to my game yet, I've been busy explaining things to you guys. :) )

So, what we need to do is go into whatever nodes you don't want to light up, in my case, the walls. Now, we only have to do this to the main Wall node, the rest of the copies will gain this ability automatically. So let's add a LightOcclude2D.

Nothing happened.

Of course not, we didn't tell it how it is shaped yet.

In the inspector panel, go to the empty box next to Occluder and click on new OccluderPolygon2D, and then select it.

Next, make sure that you are using this cursor-shaped tool before proceeding, otherwise it will not work:

Now, click on the edge of the sprite of the object you want occluded, and carefully work your way around the shape. You might want to use the snapping tools, which are at the top of the editor.

After that's done, save all and hit the play button!

Wait, you say you everything is still bright?

In the Light2D of the player, there is a tab called Shadows. Click on that, and toggle shadows on.

There, that looks better!

So now, my challenge for you is to add lights to your game. Note that the light2D has a color property- you can change the color of your light! Have fun, and I will see you in the next one.

Hello, everyone. I don't know about you, but... isn't the maze still sort of bright, even with the occlusion?

So very quickly, I am going to tell you about a node that you can use to change that, and that is the CanvasModulate. So, let's go into, say, your first maze, and add one in.

And, the most obvious thing you will see in the inspector is called Color, and it is currently white.

It's not really a challenge, but I would like you to just play with it and have a feel for how it changes your game. :)

Alright. At this point... I'm not going to give you something new to learn, at least in this post- and there will be more learning ones to come.

Right now, I just want you to step back, and look at everything we have already gone over...

For a little maze game.

This is why I said that I wouldn't show you how to make some huge game. This was a lot of effort that you have put into the game we are making already- and a big game will be worse.

With all that being said, we are still not done.

The good news? All that's left is a few finishing touches, and you will finally be able to release your game into the wild.

Give yourselves a pat on the back. You're doing amazing if you were able to come this far! =)

Hello, again, indies!

Really quick, I wanted to talk about how to rotate the player. Maybe you don't have a character that needs this, but mine does unless I want him to look this way while he's going left or right:

I don't want that. How can we fix this issue?

Let's look at the player's animated sprite, as that's what is in charge of player animation.

FlipH and FlipV? What does that do? Let's try one.

Okay, all that really did was flip his hair the other way. What else do we have?

We have the values under Transform... and in that list, we have Position, Rotation Degrees, and Scale...

Rotation Degrees? What's that?

Let's move its slider and find out.

Nice!

Now, can we use the rotation degrees in code?

If you actually barely type rotation_degrees in the code, you will see it pop up.

Go ahead, and play with it!

Now, this works fine if we use, say 0, 90, 180, and -90 when we go left, right, up, and down... How do we set the character to look sideways for diagonals?

Let's look back at the code.

Input.is_action_pressed allows them to move in any of the four main directions... Is there a way to use that knowledge to make the player look at an angle while moving in a diagonal?

That's my challenge for you this time. I will see you in the next one.

As I was working on my game, I couldn't help but notice the gray background. I mean, it looks as "Blah" as my old project name. :p

How do we fix this?

If you go to Project -> Project Settings, there is a tab called Rendering. Almost at the very bottom of that, there is a button titled Environment. The first thing that pops up is Default Clear Color.

I have changed the color to black:

Finally, you can now get rid of that boring, gray color! =)

I know I said that my last few videos are going to finish up this game, but very quickly, there is something else I should show you.

I just saw a question on the forums, asking how to change the text in the editor. How do you change the editor, and customize it? In case you haven't noticed, mine is not blue and white.

So, how do you do that?

Under Editor -> Editor Settings, there is a tab called Interface. Under that, there is a tab called Theme. If you click on that, you will see Settings for Base Color, and Accent Color. You can change those around to suit your needs/wants.

Now, for the crazy part.

If you want to change the text, go farther down. There is a Text Editor button. If you click on Highlighting, you will find a massive selection of different things you can change.

So go ahead, and customize your game engine to your heart's content.

Remember when I said order of operation matters? Here is another example of that.

In case somebody hasn't figured out how to shorten the script on the animated sprite, it's surprisingly easy.

in func _process(delta): in the player, we have this code:

So what?

So, what the code is doing when you use one of those inputs, it changes the value of velocity.

For this, you might want to add comments to remind you which direction you need to go in the script.. You could get lost very easily. :)

Now, we could do something like this for each diagonal:

	if Input.is_action_pressed("ui_down") and Input.is_action_pressed("ui_left"):
		rotation_degrees = -45

However, who wants to write all that out four more times?

Let's look back at the player code again. From this code, we can see that velocity.x is equal to 1 when we go right, and -1 when we go left. Additionally, velocity is set to 1 when going down, and -1 when going up.

This seems a bit backwards, doesn't it? This means that the positive numbers do not go right and up as in a grid in math, but right and down.

However, we can still use that information.

However, you have to be a little careful here. if you check if velocity.x or velocity.y is 1, it will never happen.

Why?

Because you will only get the velocity after it has been normalized().

Instead, let's us a new Vector2() in the player script called dir to represent direction.

Next, to check if we are moving in a direction, we can pass code like this into the animated sprite:

And it works!

This will also work for diagonals!

Now here's my next challenge- set the player to move in a certain direction based on diagonals.

Now, before you get all irritated and say things like, "I don't know what numbers I need to use for my diagonals, and I told you I hate math, and blah, blah, blah--"

Yeah, before all that... :)

I have already done your math homework for you!

The numbers you need are -135, -45, 45, and 135.

I will see you in the next one.

Okay, now for some real stuff that involves the game.

Now, this part is totally optional, you can skip this entire challenge if you want, but I'm going to go over the Timer node.

Now, as you can see here, I have already set up a very basic UI system, and I actually already attached it to the player, here is how it is set up, it is nothing fancy.

So, basically, a I have it doing right now is displaying "Time Left: 60". However, I need it to subtract 1 from the time left after each real second.

How do we do that?

With Timeout!

Connect the signal from the timer called Timeout to the Control script, and inside the script add this line of code to it.

Now let's press play...

...And the words are huge, and hidden by the CanvasModulate!

Don't worry.

To fix the problem with the big CM, we go into the player and select the Control node. From there, we go into the label, and then the inspector.

Visibility... What does that do?

It doesn't look like it would be helpful. All the colors are set to white, and the visible toggle is enabled.

Huh.

What about... Material?

It has two things on it, what do they mean? What is CanvasItemMaterial vs... Shader?

A shader is something we have to code... Let's see if CanvasItemMaterial spares us of that. Let's create a new Material, and see what it is.

The only thing here that says anything about light is the Light Mode. Let's see...

It has Normal, Unshaded, and Only Light settings.

We have no light, so let's try unshaded.

Okay, so now, I will resize my letters and put them in the top-left corner of the screen, and then see if the timer is doing its thing, after I toggle the Autoplay button on.

Okay, so, if you want your game to be timed, go ahead, and make your own timer, and set it up however you like. I will see you in the next one.

Hello, indie devs! Who's ready to do some more coding!

I know this is getting long, so I will try to make the last few sections quick. :)

I have re-vamped my game with new graphics and a better player. Additionally, I swapped out the label with a progress bar which will serve as the oxygen level, as the game now has you exploring a space craft that was on a mission which went horribly wrong:

However, how do we make progress bars?

First off, this one was from Itch.io and was free, but use whatever health bar you want. I set it up exactly as I did with the label for the canvas shader so we can see it.

I have also changed the code on the Control node which is in charge of the countdown:

However, if one set this up exactly as I did, like so:

The oxygen sprite, which is the blue one in the middle, is not lining up with the scale- everything is shrinking from the center.

This is because, if you go into the inspector for the sprite, under Offset, we see a toggle called centered. Turn that off. You will have to re-position the sprite, but now it should work just fine.

So, my challenge for you is to add a progress bar- it could be an XP system, a health system, whatever, and play with it to see how you can make it do what you want.

Wait, XP system? Why?

This is because we are also going to implement taps and enemies. The enemies will have a basic AI system using a very simple state machine (a special thanks to @fire7side for this concept). State machines are not that complex, unless you need them to be. However, we have to set up a few more things before that. So, I will see you in the next one.

Alright, who enjoys adding the exact same music to every single level you make?

... Crickets?

Okay, so how do we fix that?

If you go to Project -> Project Settings, you will notice a tab called Autoload. Click on that, and then click on the little file tab, and select your music. Then click on add. It should look something like this when you're done:

Now you can sefely remove/not add the music/ambience into the levels.

Hello once again, indie devs!

Now that we have our games almost done, and we want to release them into the world, there is a huge feature that we may need in order to say they are completed- and that is the ability to save and load things.

Now, in my game, I currently only have one variable that gets saved which is the level number. It started as a variable that did not change, and would make you always start at level 1. However, what if you want to load an old game without starting over?

So, what I did was I removed the level = 1 line of code, and inside the Player, I added a Node2D called SaveData, and all it has is a script.

It's pretty much straightforward. Now, if I ever need to go to the door at the end of the level to go to the next one, I set up the door script like this:

And, as the player is the parent of the SaveData, I connected the signal to the player and added these lines of code under the signal-created function:

Now, whenever I start the game, it will automatically start on the level which I left off.

Edit: so I will admit it, I have just gotten into some issues with saving and loading, but fear not- the community here has helped me with the issue.

https://godotforums.org/d/30199-resolving-save-and-load/37

Hey, we all make mistakes, right? However, I'm glad I came across this bug so I can tell you about it.

However, the method I've been shown by the community here works very well- thank you, Godot forums! You guys and gals are incredibly helpful!

Now, after you examine the way to save multiple things at once- and we'll cover the for loop that we saw in this later on- what if you want to, say, save your current data for a scene- like, say you started with ten bullets in the first level, but you want to keep those ten bullets for each time you restart that level?

Instead of saving the bullets just in SaveData, you can save the bullets as an integer in the player script. If the scene you load is not your main menu, have your player bullets set to the amount of bullets in SaveData:

Now we change the script for shooting:

Almost done. Now, suppose we go to a new scene and want to save the amount of bullets from that one?

It's as simple as changing your scene loading script to something like this:

And, by the way, I know this method does work. 😉

Now, why did I add the part where I made a mistake in? I feel there is another thing you can take away from this.

The forums here are incredibly helpful. Do not hesitate to ask for help. So long as you don't spam the forums, the members here are willing to help you out. I don't know where you're coming from, but in my experience, building games is never about getting the first project done. I mean, it is, but there is a greater purpose here- and that is to learn how to code- finishing projects will come after this. If you are stuck on one tutorial- even this one- feel free to admit it. Others may direct you to other tuts that you can follow.

Also, if you get overwhelmed by all the variables, and signals, and whatever, it does not mean you are a bad programmer. It only means you are in need of help, or perhaps just need a break. I've been there. All that you shouldn't do in this state is let it make you quit. Programming is not easy, but it is rewarding and gives you a skill that not everyone has.

So, hopefully, I didn't just bore you to death with me rambling. I will see you in the next one.

Hello, indie devs! Who's ready to code?

Actually, we're not coding in this section, but it's coming.

I just got done with my main menu for Maze Escape, and I wanted to show you how I did some of this in case you ever need to use these techniques. Yeah, it has some blood on it- but give me a break, this is a zombie game.

First off, how do you make the buttons have a different appearance?

For that, you use the node called a texture button.

If you grab one of them, you will see its settings in the inspector. The main properties to change its looks can be found here:

I also added a Label over the buttons so I could type in what I want on them.

The other thing is, I actually saved my font to reuse it, but the font on the buttons are a different size than the one used at the top of the screen.

To give you the ability to change features on the font being used on one thing and not the other, inside the label, go to your font, and click on the little drop-down arrow beside it, and you should see something called Make Unique:

After selecting that, you can change the features on that font however you want, and even save it as its own font so you can reuse the modified version as you see fit.

And, as I mentioned zombies, very soon, we will be dealing with enemies in the game. We have to set up a few things on the character first, but eventually, I will show you how to make and spawn basic enemies.

Hello, indie devs! Now, let's get into the coding that I promised earlier.

Today, we are covering the state machine for the enemies, I'm currently using a kinematic body as I want the player to be able to collide with it, but I don't need the enemy to respond to physics like a rigidbody- and the enemy has to move, so it can't be a static body.

Here is the code I have for the enemy so far- but all it does right now is it changes the number that will trigger different states. (Thank you, @fire7side for this)

Now, first off, what in the world is export var? Actually, the answer is visible from this shot. The variables with export var in front of them are visible in the inspector, which means you can change them from there. In a later section, I will show you that you can actually change these variables for each enemy.

As for this very small starting point of a state machine, how is that a state machine? All it does is spits out numbers. What good is that? Well, you can then use another function that checks the states- if state == 1, the character is idle, if it's state 2, the character is moving, state 3 is turning, and so on. However, there is an easier way to do this, and that is by using match.

Now we have a decent, easy-to-read, and very simple state machine!

Now what is the rest of the stuff on the code? new_dir, and all that? I'll talk more about this later, but long story short, if you want to randomize a variable, you have to initialize it inside of a function. The problem with this is that, since you are putting it in a function, other functions may not have access to it. To keep the needed variables available for use in other areas, simply set a variable that is outside of the functions to have the same value as the variable within the function that you need. This isn't always necessary, as you can pass a variable as a parameter, but it's easier this way if you need that variable in multiple functions.

So now, my challenge for you is to create your state machines, for your enemy AI, and check to make sure your code does in fact can randomly pick any of the states you need. I will see you in the next one.

Alright, let's make these enemies move. Note that I changed the velocities for the different directions and the max speed into their own variables for ease of use.

So, how do you make characters move in seemingly random directions at random times? Actually, it's pretty simple.

A new state machine checks which number was randomly generated for the direction, and chooses a direction based on the chosen number.

Now it's your turn.

Hi, indie devs!

Now, for the enemies, chances are, that you want to animate them, correct? You could use the animation player, but there is another way to do this. It's not a better method, per se, if you only have very basic animations- but for more advanced animations, you may want to use an animation player. I have added a light to the scene that will serve as our example here in the lower right corner:

So, if we add an animation player, we will see a panel at the bottom. Select the animation tab, and select new and then name the new animation. Now, in that same panel, under edit, we see something that looks like a little clock. You can use the number beside it t adjust how long you want this animation to be.

After that, go to the point in the animation in the timeline where you want something to happen. After that, adjust whatever you need animated to be how you want it animated, and then click on the key next to the property(s) that you changed. I want the light to flicker and change colors, so I will go to my light2D and change the settings, and then select the keys on the properties:

Now my animation player looks like this in its panel.

I am currently playing the animation, which is why the red line has moved. To see an animation play, select your animation from the Current Animation tab.

Also, if you want the animation to loop, there is an icon right next to the time setting, just click on that and it will loop.

Now, if you press play, we have one little issue- the animation doesn't play.

To fix this, add a script to the animation player, and simply type play("whatever_animation"). This script is also going to be responsible for your enemy animations as well, assuming its used for your enemies. Again, do it how you see fit.

Since I am already here babbling, I'll tell you a little about how to make something translucent or change color. I will use this victim for this:

Within a sprite, we go under visibility -> Self Modulate, and then change the settings however we want. This could be useful for if you want to show an enemy has damage. Then you might change the a (for alpha) setting:

Or you could turn the player's skin red when it takes damage by turning the visibility color to straight-up red. And, as we saw with the light, we can animate this in the animation player.

So, enjoy animating your enemies. I will see you in the next one.

Hello, indie devs!

The next thing on the list is having the enemy chase the player. Now, first, the enemy has to determine what the player is. However, the player is not the parent, or the child, of the enemy- so how can we have the enemy determine what the player is?

Assuming you have things set up where the parent is the world, and the children of that are the zombie and the player, you could call the parent by typing in "..".get_node("name_of_node). However, that's a bit sloppy. Instead, you could get the parent, and from there, get the target, as I did here.

Now, what is the rest of this stuff?

The function hostile needs delta to work, but it won't be able to access it on its own, so instead we give it a parameter, and then in _process, pass delta as that argument.

Now, this enemy will chase the player no matter what while set like this- if you don't have the states changed and only have hostile, it will chase the player forever. How do we fix it so that the player is only chased when it is in range, and how do we stop the change_state function?

For the trigger, we could add an area2D, and check if the body entering it is the player, and then switch over to the hostile function.

As for the change_state(), it goes off based on a timer, so you could simply add the name of the timer responsible for state changing, and after that type .stop().

Now, this enemy doesn't move around obstacles, but doing so would be beyond the scope of this tutorial. However, I encourage you to research ways to make the enemies travel in this manner- for a hint, search for information on path finding. For the purposes of this tut, all you're trying to learn is how to build very basic mechanics. Besides, zombies are usually pretty stupid- it wouldn't surprise me if they decide to slam into walls. 😛

Now let's see if you can make your enemies chase the player. I will see you in the next one.

Hello, indie devs!

Has anyone noticed if one enemy detects the player, the entire gang of them from that level comes charging? Let's fix that next. This will also help export var become a lot more helpful. 😃

An easy way to do this is to put somewhere above _ready(), type var enemy_name = self.name. Now, why do that? If you would then have a print function in _ready() for your enemies, you will notice that each enemy has its own name. This means that we can determine which enemy we need to do something. If zombie1 notices the player in its area, it will check if its own name is the one being called while the player is in that collision. This means, even though zombie2 gets the same message, since his name isn't zombie1, he will not go charging after the player.

Alright, we are almost ready to wrap up. We still need a pause menu and a system to interact with our small inventory system, and then we can go through the steps of beta testing and releasing. I will see you in the next one.

Hello, indie devs!

Now, before we get deeper into things and I lose this idea to show you another node.... well, you guessed it- I'm going to show you another node. 😃

This time, it is the particles2D.

It's not much, but, say you are building a game that has a dripping faucet, or a leaky grate in a sewer, this could come in handy. This could also serve as another method to represent damage.

Let's grab a Particles2D, and in the inspector, under Process Material, select New ParticlesMaterial. Now, it will not be very big when you first see it.

From there, what you do with it is up to you. Just have some fun with it and see what all you can do with it. I will see you in the next one.