Author Archives: fornclake

Godot 3.2 Player Skin Changer Tutorial

insert intro here

Here are the steps we will take to achieve this:

  1. Create a main scene with a character selection menu. This menu will have two buttons to go forwards and backwards, a small preview of the character you are selecting, and a name for the character.
  2. Use an autoload singleton to store the path to the skin texture for use in-game.
  3. Replace the player’s default texture with the one stored in the singleton.

Included below is a zip file containing a starting template for the tutorial. All it contains is a folder with a base Zelda-like player controller and three player sprite sheets. You can still follow along using your own game, but if you get lost, I recommend following along with the template so you see how everything fits.

playerskin-tutorial-start

MainMenu.tscn

First, open up the game. If you are not following the template, you should at least already have a player set up with a sprite sheet and an AnimationPlayer. Create a new scene. This will be our menu scene, so you can select User Interface in the Create Root Node menu. I am going to call it “MainMenu”. Save this into the root directory of the project as “MainMenu.tscn”. You should also go to Project>Project Settings, select Run, and set the Main Scene to this new scene.

Add a Panel node as a child and name it SkinSelect. Size it as so in the center of the screen:This panel is going to hold all of the skin selection UI, along with its script. This tutorial is going to use the default Godot theme, and the template has a low screen resolution making this theme somewhat blurry. If you would like to see how to make your own themes, you can check out this page in the docs.

Next add two Button nodes and name them “Back” and “Next”. Place them on the left and right ends of the panel. Now add a Sprite node and put it in the center. Name it “Preview”. Set its Texture to the sprite sheet of your default skin, and adjust the Vframes and Hframes as necessary. If you are using the template, the Texture would be “res://player/player1.png” and Vframes and Hframes are 7 and 6, respectively.

We can also optionally add a short animation to this preview. Create a new AnimationPlayer node, make a short animation of the preview’s first two frames, and set it to loop and autoplay.

Finally, we’re going to add a Label node to show the character’s name for each skin. Call it “Name” give it some default text, and center it underneath the preview. I also increased the size of the preview sprite in this next screenshot.

SkinSelect.gd

Now let’s move onto the SkinSelect script. Right-click SkinSelect and add a new script. I will be saving mine to “res://SkinSelect.gd”. We will start by making two variables: one that will keep track of the currently selected skin, and one that will store all of the names and paths to skins in a dictionary.

extends Panel

var selected = 0

var skins = {
	"Chain": "res://player/player1.png",
	"Knot": "res://player/player2.png",
	"Tie": "res://player/player3.png"
}

skins is where you will add all of the alternate png files the player can choose from. The keys are the names and their values are the paths. You can add as many skins as you want.

Next we’ll make our update_skin function. We will pass a parameter to go back and forth through the dictionary using the buttons.

func update_skin(new_selection):
	selected = wrapi(selected + new_selection, 0, skins.size())
	$Preview.texture = load(skins.values()[selected])
	$Name.text = skins.keys()[selected]

Let me break this down. The parameter we pass will be the direction we will move through the dictionary; if it receives -1 it will go back, if it receives 1 it will go forwards. The first line in the function will wrap the selection from 0 to the size of the skins dictionary, so if you are at 0 and try to go back it will bring you to the end, and if you’re at the end and go forward it will bring you to 0. The next line updates the preview to the texture of the selected skin. The last line updates the label to the name of the selected skin. Just remember that the keys are the names and their values are the paths.

Now we just need to run this function when the Back and Next buttons are pressed. We will do this with signals. Add this _ready function.

func _ready():
	$Back.connect("pressed", self, "update_skin", [-1])
	$Next.connect("pressed", self, "update_skin", [1])
	update_skin(0)

All this does is connect the pressed signal to this script’s update_skin function. The last parameter there is an array of parameters we will pass to the function. In this case, it’s the -1 and 1 I was talking about that will move through the list backwards or forwards. The Back button being pressed runs update_skin(-1) and chooses the previous skin, and the Next button being pressed runs update_skin(1) and chooses the next skin. We also run update_skin(0) so that the label and preview always starts off with the first skin in that list. The default texture and label text we set earlier was just to make sure everything looks correct.

You can run the game now and have a nice little skin selection. However, we still need two things: a button to start the game, and a way for the player in another scene to know which skin it should be using. We will come back to this script in a minute.

Settings.gd

Still in the script editor, hit File>New Script. Name it “Settings.gd” and save it to the root directory. This is going to be an AutoLoad singleton, which means it will be accessible by any script in any scene and its state will stay the same even if the root scene is changed. This will let us save the current skin to this script, and when we change to the main game scene, the player will know what skin to use. I am calling this Settings, but if you already have some sort of global script in your project you can throw this next part in there and use that.

All this script needs is one variable: skin_path. Set it to the path to the default skin png.

extends Node

var skin_path = "res://player/player1.png"

On the top of the editor, select Project>Project Settings. Go to the AutoLoad tab. Press the folder next to Path and select “Settings.gd”. Add it. You should end up with a screen like this:

Return to “SkinSelect.gd”. Add a line to update_skin that will set Settings.skin_path to the selected skin’s value.

func update_skin(new_selection):
	selected = wrapi(selected + new_selection, 0, skins.size())
	$Preview.texture = load(skins.values()[selected])
	$Name.text = skins.keys()[selected]
	Settings.skin_path = skins.values()[selected]

Now we need the player to actually pull from this file. Head into your player script. If you are following the template, this is “res://player/Player.gd”. Add a _ready function, and set $Sprite‘s Texture to load(Settings.skin_path).

func _ready():
	$Sprite.texture = load(Settings.skin_path)

The last thing we need to do is add a button to our MainMenu that will go into our game scene. When I say game scene, I mean whatever initial scene that contains your player that all of your actual gameplay takes place, like a Level 1 or a first town. For this tutorial, I am not going to make a game scene. Instead, I will just change the scene to the player’s scene, since that is enough to show off the skin changing.

Add a Button node to MainMenu. Name it “Play”, and change its Text to “Play”. Center it above the skin selection panel. I am just going to add the script to the button itself as “res://Play.gd”. All we’re going to do here is change the root scene to “res://player/Player.tscn”.

extends Button

func _ready():
	connect("pressed", self, "play")

func play():
	get_tree().change_scene("res://player/Player.tscn")

Now if you run the game, you can choose a skin, hit play, and it will appear in-game.

insert gif here

insert conclusion here

playerskin-tutorial-finish

Godot 3.2 New Zelda-like Tutorial [1] Movement and Collision

This content is currently Patreon-only! All tutorials will be free and public eventually. In the case of the Zelda-like 3.2 tutorials, they will be public shortly after 3.2 stable drops.
To view this content, you must be a member of fornclakedev Patreon at "Bronze" or higher tier
Already a Patreon member? Refresh to access this post.

Godot Engine 3.1 Grid-based Movement

Introduction

Hey everyone! Welcome to my first Godot Engine tutorial since the release of 3.1 stable. Today we’re going to be covering grid-based movement, or RPG-styled movement. This means the player won’t simply snap to the next space but instead keep moving smoothly in a specified interval. We’ll also cover collision using a RayCast2D and the new TileSet editor from 3.1.

We’ll just be using the built in icon.png that comes with every new Godot project so don’t worry about any downloads. If you want to see the source, however, that can be found below.

Source code (Github link)

Creating the player scene

First we’re going to start with a regular Node as our root. Under it we’ll create a new Sprite using the icon.png that comes with every new project. Just drag it from the FileSystem tab into the middle of the screen and rename it to “player”. We will be handling our collisions manually so we’re using a Sprite over the usual body nodes. In the Inspector, turn Centered off (under Offset). Save the scene as “test.tscn”.

Player script

Next add a script to our player node. Give it an empty template and save it as “player.gd”. We’ll start the script with a few variables.

extends Sprite

var speed = 256 # big number because it's multiplied by delta
var tile_size = 64 # size in pixels of tiles on the grid

var last_position = Vector2() # last idle position
var target_position = Vector2() # desired position to move towards
var movedir = Vector2() # move direction

speed and tile_size are pretty self explanatory. Just make sure you set tile_size to whatever the width and height your player sprite is. When the player is moving, last_position is where he’ll be moving from and target_position is where he’ll end up. movedir is the direction he’ll go based off of our input (that we’ll set in a bit).

Our _ready() function is just going to have a few that makes sure the player is already snapped to the grid when the game starts. You could do this manually when creating your scene but it’s nice to have a backup.

func _ready():
	position = position.snapped(Vector2(tile_size, tile_size)) # make sure player is snapped to grid
	last_position = position
	target_position = position

Now we need a function that will set our movedir based on our currently held keys. Create a new function called get_movedir() and add the following:

# GET DIRECTION THE PLAYER WANTS TO MOVE
func get_movedir():
	var LEFT = Input.is_action_pressed("ui_left")
	var RIGHT = Input.is_action_pressed("ui_right")
	var UP = Input.is_action_pressed("ui_up")
	var DOWN = Input.is_action_pressed("ui_down")
	
	movedir.x = -int(LEFT) + int(RIGHT) # if pressing both directions this will return 0
	movedir.y = -int(UP) + int(DOWN)
	
	if movedir.x != 0 && movedir.y != 0: # prevent diagonals
		movedir = Vector2.ZERO

If you’ve seen my Zelda-like tutorials you know what’s up. First we create four variables for the four directions we can move. These are made as booleans. In the line after that we take LEFT and RIGHT and turn them into integers, make LEFT negative, and set movedir.x to that. That way if only the left arrow key is being held, we get movedir.x = -1 or Vector2(-1,0) which goes left. If both left and right are held, they add together to make 0 so the player does not move. It’s the same deal with UP and DOWN. The last two lines just check if you’re holding diagonal directions and set movedir to Vector2(0,0). As you can see I’m using some of Godot 3.1’s new Vector2 constants.

Our _process(delta) will have one section for idle and one section for moving.

func _process(delta):
	# MOVEMENT
	position += speed * movedir * delta
	
	if position.distance_to(last_position) >= tile_size: # if we've moved further than one space
		position = target_position # snap the player to the intended position
	
	# IDLE
	if position == target_position:
		get_movedir()
		last_position = position # record the player's current idle position
		target_position += movedir * tile_size # if key is pressed, get new target (also shifts to moving state)

The idle code has to be below the movement code (so that variables are only updated after any movement has taken place) but for the sake of simplicity I’ll explain it first. The if statement if position == target_position checks to see if the player is where they intended to go. We only want the player to be able to move if they are already in the middle of the tile. Otherwise you’d be able to change directions mid-movement which breaks the entire grid effect. We also set our last_position here which will be used in the movement code. Finally, we set our target_position based off of any keys we were just pressing. If no keys are pressed, that will remain the same.

Above all that is the movement code. We add speed * movedir * delta to our position in order to actually move the player.  If movedir is Vector2(0,0) no movement will happen. Multiplying by delta (the time since the last frame) keeps our movement consistent with different frame rates. You can read more about delta timing here. The if statement underneath takes the distance between our current position and our last idle position. If it’s more than one tile, we snap to the grid. When we hold down the key the player will move smoothly, but if we just tap it they’ll move until they’re locked to the grid.

If we run the game now we should be snapped to the grid and be able to move around with the arrow keys. The only thing left to add is collisions, so hop onto the next page and we’ll do that.

Zelda-like Engine Progress [2] Basic level editor

Today I put in the “Maker” part of “Zelda Maker.” You can place the three tiles that are in the game, set the boundaries of the room, and run the game. The room boundaries were by far the hardest part, but they’re working pretty well right now. Those are what tells the camera to snap to the corners (instead of always being centered on the player).

In the future I’d like to have a visual indicator on what your room selection looks like. It’ll probably just be a square that snaps to the grid, and maybe becomes different colors depending on if the room is smaller than the camera or something.

There’s a bug you can see with the player not going back to the default state and instead strafing around. Maybe I can get back to working on the actual gameplay tomorrow 😉

Zelda-like Engine Progress [1] Variable room sizes

Hey everyone! Last year I made a series on how to create your own Zelda-like game in Godot Engine 3.0. After a while I got a bit tired of doing that and took a few months off to work on a game called Terra Labyrinth. That game is still in progress, but I found myself wanting to continue what I started with the Zelda project. Because of the release of Godot 3.1 making some of the previous videos outdated, and not wanting to remake the series not even a year after the original one started, I decided to do something else.

The plan is to create a sort of “Zelda Maker.” It will be kinda like the Level Editor test that’s been sitting on this website for months except actually polished. You will be able to create Zelda dungeons and share them with other people. For the first few demo releases it will be closed-source, but once I reach a version I am happy with (or if I get bored of what I have) I will upload the source. For those of you who are only here for the tutorials, I will take any cool features that deserve tutorials and make videos on them.

This first progress update shows a few major changes between the old Zelda-like project and this new one.

  1. It’s widescreen now.
  2. Rooms can be different sizes, and the camera will properly lock itself to the room.
  3. For rooms that are too small for the camera to fit, it will zoom into the room so that the edge of the camera touch the sides of the screen.
  4. There is a lot less content than the tutorials (I’ll get there!)

Basically each room has its own Area2D node that are stretched to the boundaries of the room. When the player enters the area, it takes the camera and sets the limits to the size of the area’s collision shape. On small rooms, it sets the camera’s zoom to the smallest margin of the room.

I hope you’re interested in seeing more. Subscribe to my YouTube for updates and join the Discord for discussion!

Godot 3.1 Asteroids Tutorial for Beginners [1] Ship Movement

Introduction

Hello everybody! Welcome to my brand new Asteroids tutorial for Godot Engine 3.1! This series is meant as an introduction to the Godot Engine. It is good for people who are new to game development or just want to learn the engine. We will be using Godot’s GDScript for this tutorial, a very robust and easy to learn language. If you have any experience with Python, it shares a lot of the same syntax.

In this tutorial, we will be recreating the classic game Asteroids. We will have a ship that can turn, accelerate, and wrap around the screen when on the edge. In the next tutorial we will allow it to shoot asteroids that will split into smaller asteroids.

I will be explaining the Godot Editor as thoroughly as I can. As for programming with GDScript itself, I will be explaining what each important line does but not anything like what a variable or function is. You should be able to follow even as a beginner though.

Make sure to follow my Twitter and subscribe to my YouTube. If you really liked it, please consider pledging to my Patreon.

This tutorial was made with Godot Engine 3.1 alpha 5. It will function exactly the same when stable is released.