Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
9. July 2015

 

In this part we are going to explore using Particles in the Godot Engine.  Particles are generally sprites, either provided by you or generated programmatically, that are controlled by a unified system.  Think of a rain storm, each drop of rain would represent a particle, but the entire storm itself would be the particle system.  You would not control each drop individually, instead you would simply say “rain here” and the system takes care of the rest.  Particles are often used for special effects such as smoke, fire or sparks.  The Godot game engine makes working with particles quite simple.

 

There is an HD video version of this tutorial available here or embedded below.

 

This particular tutorial isn’t going to go into a great deal of detail over the effects of each setting, as there is already an excellent illustrated guide right here.  Instead I will focus on using particles in a hands example.  As I mentioned earlier, particle systems are often used to create fire effects, and that’s exactly what we are going to do here, create a flaming/smoking torch.

 

Creating a particle system is as simple as creating a Particles2D node:

image

Creating one will create a simple system for you:

part1

 

As always, the properties are controlled in the Inspector.  In this case we are creating 32 particles with a lifespan of 2 seconds aimed down and affected by gravity:

image

 

Now let’s suit it to our needs.  First we want to change the direction of our particles to up instead of down. This is set by setting the direction property, this is a value in degrees for the particles to be emitted in.

image

 

Here is the result:

part2

Next, since this is a torch, we don’t want the particles to be affected by gravity.  Under Params, simply set Gravity Strength to 0:

image

And the result:

part3

Now white dots are exactly convincing flames… so lets add a bit of color.  This can be done using Color Phases.  These are the colors the a particle will go through during it’s lifetime.  For a torch, we will start with a brilliant white, then orange and finally red, like so:

image

Be sure to set the Count to 3.  You can have up to 4 phases if needed.  Now our results look like:

part4

A bit better.  Now we want to work on the size a bit.  Let’s start our particles off bigger and shrink as they move away from the source of the flame.

image

Resulting in:

part5

 

Finally we slow it down slightly and decrease the spread:

image

 

And voila:

part6

 

A fairly passable torch.  You could play with it a bit, use an image instead of a square particle, change the alpha value of each color phase or add another overlapping particle system to provide smoke.  Keep in mind though, more particles, more processing.

 

Here is a simple layer of smoke added as a separate particle system and the alpha lowered on the final two color phases:

part7

 

Particles are as much an art to create as a texture or 3D model.  Play around until you achieve the effect you want.  Be sure to read that link I post earlier for the effects various settings have on your particle system.  One other area I never touch on was randomization.  In addition to numerous settings for controlling how particles are created, you can also randomize each of those values so your particles end up being less consistent.

 

As mentioned earlier, a particle can also be created from a texture or series of textures.  To set a texture, simply set it’s texture property:

image

 

In this example I am going to use this spritesheet to create a flock of animated birds:

robincropped

 

Set H and V to correspond to the number of rows and columns in your TextureAtlas:

image

 

I am unsure of how to deal with TextureAtlases with empty squares, there doesn’t seem to be a way to set a total count, but I may have overlooked it.  Next you are going to want to specify the speed you want it to jump between frames of animation using Anim Speed Scale

image

I tweaked a few more settings:

image

And my final results are a fairly nice flock of birds:

part8

 

One other feature available is the particle attractor ParticleAttractor2D, which can be used to attract particles, to either fling them out the other side or absorb them.  Think of it like a black hole that either sucks in or spits out the particles in it’s radius of influence:

image

part9

Keep in mind that particles all have a lifespan, and once that lifespan has elapsed, it will fade away.

 

Particles provide a powerful way of implementing tons of graphically similar effects ( like fire, fog, flocking etc ) with a single controlling system.  They are as much art as programming though, so will take some time playing around to get the effect just right.

 

The Video

 

Programming


18. June 2015

 

So I decided to take a look at the process of extending the Godot Engine, and to my horror I discovered there is no solution file!  UGH…  Yeah, you can compile from the command line, but that’s not that pleasant of a development experience to an IDE warrior like myself.  I thought I found a solution that I posted about here and I almost did, but it still left me unable to debug and with mostly broken Intellisense support… so, yeah, not great.  Then I found this post, which although it didn’t work, it did fill in the missing pieces.  So, if you want to work with Godot using Visual Studio, here’s how you do it.

 

First you need to have a properly configured development environment… meaning Visual Studio, git and python, all in your PATH.  Next launch a Visual Studio command line, this guy…

image 

 

Make and change to the directory you want to install Godot.  Keep in mind this process will make a godot folder, so if you want c:\godot\ run the following from c:\.

 

git clone https://github.com/okamstudio/godot.git

This will download the latest source for Godot Engine.  Next we want to build it for the first time and generate a Visual Studio solution file.  cd into the Godot directory and run:

scons vsproj=yes platform=windows

If you get an error here, first be sure you are using a Visual Studio command prompt, next be certain you are in the correct directory.  Otherwise your computer should churn away for a few minutes while godot libraries and tools are built.

After several minutes, in an ideal world you should see:

image

 

This means Godot successfully built and it created your Visual Studio project files.  Woot.  Now time to get Visual Studio to actually work.

 

First in the root of your project directory ( C:\Godot\ in my case ), create a file named build.bat, with the following contents:

set vc_path=%1
call %vc_path% & scons platform=windows

 

Next load the generated sln file in Visual Studio.  Give it a minute or two to parse all the files.  You will notice massive amounts of Intellisense errors, don’t worry, we will fix those next.

In Solution Explorer, right click your Project ( not solution, Project! ) and select Properties.

image

Select VC++ Directories then double click Include Directories:

image

Append the following to the value in Include Directories:

$(ProjectDir);$(ProjectDir)/core;$(ProjectDir)/core/math;$(ProjectDir)/tools;$(ProjectDir)/drivers;$(ProjectDir)/platform/windows;

This adds the include directories Godot depends on.

 

Next click NMake on the left hand side.  We now want to replace the contents of Build Command Line and Output to:

image

Then click Apply then OK.

 

You should now be able to hit Build->Build Solution.  If all went right, you should see build progress in the Output panel:

image

 

You can now run and debug as normal, set breakpoints within the code, hit F5 and Godot editor will run.  Keep in mind, it’s the Godot Editor you are debugging, not the library, although since you have full source you should easily be able to step into Godot core code, you just may not be able to set breakpoints there.

 

You are now ready to extend or contribute to Godot using the full power and comfort of Visual Studio.

 

The following is a video showing exactly this process, just in case I missed a step.

 

Programming


16. June 2015

 

Now we are going to talk about two important concepts in AI development in 2D games, path following and navigation meshes.  Path following is exactly what you think it is, you create paths and follow them.  This is useful for creating predefined paths in your game.  When you are looking for a bit more dynamic path finding for your characters, Navigation Mesh ( or NavMesh ) come to the rescue.  A NavMesh is simply a polygon mesh that defines where a character can and cannot travel.

 

As always there is an HD video of this tutorial available here.

Let’s start with simple path following.  For both of these examples, we are going to want a simple level to navigate.  I am going to create one simply using a single sprite background that may look somewhat familiar…

image

 

So, we have a game canvas to work with, let’s get a character sprite to follow a predefined path.

 

Path2D and PathFollow2D

 

First we need to start off by creating and defining a path to follow.  Create a new Path2D node:

image

 

This will add additional editing tools to the 2D view:

image

 

Click the Add Point button and start drawing your path, like so:

image

 

Now add a PathFollow2D node, and a Sprite attached to that node, like so:

image

 

There are the following properties on the PathFollow2D node:

image

 

You may find that you start rotated for some reason.  The primary setting of concern though is the Offset property.  This is the distance along the path to travel, we will see it in action shortly.  The Loop value is also important, as this will cause the path to go back to offset 0 once it reaches the end and start the travel all over again.  Finally I clicked Rotate off, as I don’t want the sprite to rotate as it follows the path.

 

Now, create and add a script to your player sprite, like so:

extends Sprite


func _ready():
   set_fixed_process(true)

func _fixed_process(delta):
   get_parent().set_offset(get_parent().get_offset() + (50*delta))

 

This code simply gets the sprites parent ( the PathFollow2D Node ), and increments it’s offset by 50 pixels per second.  You can see the results below:

PathFollow

 

You could have course have controlled the offset value using keyframes and an animation player as described in the previous chapter.

 

So that’s how you can define movement across a predefined path… what about doing things a bit more dynamic?

 

Navigation2D and NavigationPolygon

 

Now let’s create a slightly different node hierarchy.  This time we need to create a Navigation2D Node, either as the root, or attached to the root of the scene.  I just made it the root node.  I also loaded in our level background sprite.  FYI, the sprite doesn’t have to be parented to the Navigation2D node.

image

 

Now we need to add a Nav Mesh to the scene, this is done by creating a NavigationPolygonInstance, as a child node of Navigation2D:

image

 

This changes the menu available in the 2D view again, now we can start drawing the NavMesh.  Start by outlining the entire level.  Keep in mind, the nav mesh is where the character can walk, not where they can’t, so make the outer bounds of your initial polygon the same as the furthest extent the character can walk.  To start, click the Pen icon.  One first click you will be presented this dialog:

image

 

Click create.  Then define the boundary polygon, like so:

image

 

Now using the Pen button again, start defining polygons around the areas the character cant travel.  This will cut those spaces out of the navigation polygon.  After some time, I ended up with something like this:

image

 

So we now have a NavMesh, let’s put it to use.  Godot is now able to calculate the most efficient path between two locations.

For debug reasons, I quickly import a TTF font, you can read this process in Chapter 5 on UI, Widgets and Themes.  Next attach a script to your Navigation2D node.  Then enter the following code:

extends Navigation2D
var path = []
var font = null
var drawTouch = false
var touchPos = Vector2(0,0)
var closestPos = Vector2(0,0)

func _ready():
   font = load("res://arial.fnt")
   set_process_input(true)

func _draw():
   if(path.size()):
      for i in range(path.size()):
         draw_string(font,Vector2(path[i].x,path[i].y - 20),str(i+1))
         draw_circle(path[i],10,Color(1,1,1))
      
      if(drawTouch):
         draw_circle(touchPos,10,Color(0,1,0))  
         draw_circle(closestPos,10,Color(0,1,0))
   

func _input(event):
   if(event.type == InputEvent.MOUSE_BUTTON):
      if(event.button_index == 1):
         if(path.size()):
            touchPos = Vector2(event.x,event.y)
            drawTouch = true
            closestPos = get_closest_point(touchPos)
            print("Drawing touch")
            update()
            
      if(event.button_index == 2):
         path = get_simple_path(get_node("Sprite").get_pos(),Vector2(
                event.x,event.y))
         update()

 

This code has two tasks.  First when the user clicks right, it calculates the closest path between the character sprite and the clicked location.  This is done using the critical function get_simple_path() which returns a Vector2Array of points between the two locations.  Once you’ve calculated at least one path ( the path array needs to be populated ), left clicking outside of the navmesh will then show two circles, one where you clicked, the other representing the closest navigable location, as returned by get_closest_point().

 

Here is our code in action:

PacNav

As you right click, a new path is established drawn in white dots.  Then left clicking marks the location of the click and the nearest walk-able location in the nav polygon.  You may notice the first left click resulted in it drawing a location to the left of the screen.  This is because my navmesh wasn’t water tight, lets look:

image

 

Although miniscule in size, this small spot of polygons is a valid path to the computer.  When setting your nav mesh’s up, be sure to make sure you don’t leave gaps like this!

 

There are a couple things you might notice.  The path returned is the minimum direct navigable line between two points.  It however does not take into account the size of the item you want to move.   This is logic that you need to provide yourself.  In the example of something like PacMan, you are probably better off using a cell based navigation system, based on an algorithm like a*star.  I really wish get_closest_path() allowed you to specify the radius of your sprites bounding circle to determine if the path is actually large enough to travel.  As it stands now, you are going to have to make areas that are too small for your sprite as completely filled.  This renders Navigation2D of little use to nodes of varying sizes.

 

Regardless of the limations, Navigation2D and Path2D provide a great template for 2D based AI development.

 

The Video

Programming


14. June 2015

 

As mentioned recently, I am in the process of compiling the Godot Game Engine Tutorial Series into an e-book format.  Today I just published the 10 chapter, 150 page first draft of the Godot Engine book.

 

BookCover

It can currently be downloaded by Patreon backers right here.

 

It is currently available in the following formats:

  • PDF
  • epub
  • mobi

 

Due to the large file size (@15mb) to install on a Kindle you will need to install via side-loading, the file is beyond the limits for emailing to Kindle.

 

Right now, this is mostly just a straight compilation of content available here on GameFromScratch.com.  I will need to do an editorial pass to make sure text makes sense in book format, as well as replacing now static animated gifs with more meaningful images.  If you prefer to read offline, wish to print or want to reader on an e-reader, this book should be perfect for you.

 

If you are interested in checking it out, Chapter 8: Using Tilemaps can be downloaded here. Of course, if you’ve already read the Godot tutorial series, this is going to be incredibly familiar.

Programming News


7. June 2015

 

In the previous tutorial we covered Sprite Animation, although to be honest it was more about creating animation ready sprites.  The actual way we performed animation wasn’t ideal.  Fortunately we are about to cover a way that is very much ideal… and capable of a great deal more than just animating sprites!

 

As always, there is an HD video of the this tutorial available right here or embedded below.  It’s important to have followed the previous tutorial, as we will be building directly on top of it.

 

Keyframes Explained

 

Before we get to far into this tutorial I think it’s pretty critical to cover a key concept in animation, keyframing.  Essentially you animate by setting a number of “key” frames in the animations timeline, then let the computer take care of the rest.  You can set a keyframe on just about any property available in Godot as we will soon see.  For example you can create a key on the position value of a sprite.  Then advance the timeline, set another key at a different position.  The computer will then interpolate the position over time between those two keys.  This interpolation between key frames is often referred to as a “tweening” as in “inbetween”.  Don’t worry, it will make a lot more sense when we jump in shortly.

 

AnimationPlayer

 

In the previous tutorial, we created a simple animation using code to increment the current frame at a fixed play rate.  Now we are going to accomplish the same thing using the built in animation system in Godot. 

Start by opening up the previous project and remove the code from our AnimatedSprite.  Now add a AnimationPlayer node under the root of your scene, like so:

image

 

With the AnimationPlayer selected, you will notice a new editor across the bottom of the 2D window:

image

 

This is your animation timeline control.  Let’s create a new animation named “walkcycle”

Click the New Animation icon

image

 

Name your animation and click Ok

image

 

Click the Edit icon

image

 

This will extend the animation options even more.

image

 

First let’s set the duration of our animation to 2 seconds:

image

 

You can then adjust the resolution of the animation timeline using the Zoom slider:

image

 

Here we’ve zoomed in slightly to show just over 2 seconds:

image

 

Now that we are in edit mode with our AnimationPlayer selected, in the 2D view, you will notice there are new options available across the top

image

 

This is a quick way to set keys for a nodes positioning information.  You can toggle on or off whether the key will store location, rotation and/or scale data.  You set a key by pressing the Key icon.  The first time you press the key icon you will be prompted if you want to create a new track of animation.

Select your sprite, make sure the timeline is at 0 and create a key. Advance the timeline to 2secconds, then move the sprite to the right slighly, then hit the key icon again to create another key frame.

g1

 

Press the play icon in the AnimationPlayer to see the animation you just created:

g2

 

Well that’s certainly movement, but pretty crap as far as animations go eh?  How about we add some frame animation to our mix.  Here is where you start to see the power of animation in Godot.

 

With the AnimationPlayer selected, rewind the timeline back to zero, make sure you select your AnimatedSprite, then in the Details panel you will notice that all of the properties have a little key beside them:

image

 

This is because you can keyframe just about any value in Godot.  We are now going to do it with the Frame value.  This is the value we programmatically increased to create our animation before.  Now we will instead do it using keyframes.  With the timeline at 0, set Frame to 0 then click the Key icon to it’s right.  Click Create when it prompts you if you wish to create a new track.  Then move the timeline to the end, increase Frame to the final frame (21 in my case), then click the Key again.  This will create a new track of animation:

image

 

You can see the different track names across the left.  The blue dots represent each key frame in the animation.  There is one final change we have to make.  Drop down the icon to the right of the animation track and change the type to Continuous, like so:

image

 

Now when you press play, you should see:

g3

 

Playing Your Animation

 

While your animation appears properly if you press Play in the AnimationPlayer interface, if you press Play on your game, nothing happens.  Why is this?

 

Well simply put, you need to start your animation.  There are two approaches to starting an animation.

 

Play Animation Automatically

You can set the animation to play automatically.  This means when the animation player is created it will automatically start the selected animation.  You can toggle if an animation will play automatically using this icon in the Animation Player controls.

image

 

Play an Animation Using Code

Of course, AnimationPlayer also has a programmatic interface.  The following code can be used from the scene root to play an animation:

extends Node

func _ready():
   get_node("AnimationPlayer").play("walkcycle")

 

Scripting the AnimationPlayer

 

Say you want to add a bit of logic to your keyframed animation…  with AnimationPlayer you have a couple options we can explore.

 

First there are the events that are built into the AnimationPlayer itself:

image

For simple actions like running a script when an animation changes or ends, using AnimationPlayer connections should be more than enough.

 

What about if you wanted to execute some code as part of your animation sequence?  Well that is possible too.  In your Animation editor window, click the Tracks button to add a new animation track:

image

 

Select Add Call Func Track:

image

 

Another track will appear in your animation.  Click the green + to add a new keyframe.

image

 

Now left click and drag the new key to about the halfway (1 second) mark.  Switch to edit mode by clicking the pen over a dot icon, then click your keyframe to edit it.  In the name field enter halfway.  This is the name of the method we are going to call:

g4

 

Add a method to your root scene named halfway:

extends Node

func _ready():
   get_node("AnimationPlayer").play("walkcycle")

func halfway():
   print("Halfway there")

 

When the keyframe is hit, the halfway method will be called.  Adding more function calls is as simple as adding more keys, or complete Call Func tracks.  As you may have noticed in the video above, you have the ability to pass parameters to the called function:

image

 

Finally, you can also access animations, tracks and even keys directly using code.  The following example changes the destination of our pos track.  This script was attached to the AnimationPlayer object:

extends AnimationPlayer


func _ready():
   var animation = self.get_animation("walkcycle")
   animation.track_set_key_value(animation.find_track("AnimatedSprite:transform/pos"),1,Vector2(400,400))

 

Now when you run the code you should see:

g5

 

The Video

Programming


GFS On YouTube

See More Tutorials on DevGa.me!

Month List