Enemy at the Gates

Blackout182 · 12/02/2021

Hello again travellers!

Antitype have been busy this month bringing a wide array of new features to your favourite up-and-coming platformer.

One of the first things you might notice is the new and improved visuals. The forest background has been completely redrawn. Let us know what you think in the comments.

We thought adversaries for our heroes to face might make the game more interesting, so Justin, the programmer, drew one. As you can see, its beauty is striking.

To make this bad boy work, we implemented some simple components to generalise two of the most basic features for any actor in this type of game: the ability to hurt and to be hurt. Justin got the idea from a tutorial series by HeartBeast, which is good for learning the Godot fundamentals. In the video, he implements a `hurtbox` and a `hitbox` to handle these types of interactions. The hurtbox detects collisions with hitboxes and then fires a signal that we can respond to on a case by case basis. This method allows for easy customisation of responses to hit events.

We gave Alan the ability to shoot basic fireballs. After doing so, we realised it was difficult to tell when the enemy was taking damage, so Justin got to work learning how to do shaders in Godot. For those code savvy among you:

shader_type canvas_item;

uniform float intensity;

void fragment(){
	vec4 previous_colour = texture(TEXTURE, UV);
	vec4 white_colour = vec4(
		previous_colour.r + ((1.0 - previous_colour.r) * intensity),
		previous_colour.g + ((1.0 - previous_colour.g) * intensity),
		previous_colour.b + ((1.0 - previous_colour.b) * intensity),
		previous_colour.a);
	COLOR = white_colour;
}

Beautiful, no? It takes a float between 0 and 1 and uses it to vary the intensity of the white shading over any material it is attached to. In the game code, we were then able to create a coroutine that lifted this value up and down at a given rate. Modulating from 0 to 1 then back to 0 again proved to be a bit trickier than expected. Here is the solution we came up with:

func modulate_over_time(current_time: float, total_time: float):
				
	var fraction : float = current_time/total_time * 2
						
	return fraction if fraction <= 0.5 else 2 - fraction

This is probably basic to you fancy maths wizards. If you have a more efficient method, please let us know. This works just fine, but we are almost certain that it could be improved.

As you can see, the player is becoming quite a complex beast. We were able to refactor a lot of our existing code into a node-based state machine. This takes a lot of complexity out of working with it. Sure, it’s not perfect, but we need to get out of the habit of making it perfect because this is what kills development.

That’s it for this month, kids. Have a good one and we will see you next time! For loot & glory!