Posted December 03, 2019 by Jon Topielski
I wanted to share the animation process for creating Harley the Hare, the main character from my latest game Hops and Harmony
Harley, along with all the characters in the game are just primitive shapes drawn onto the screen
You can especially see this in the aptly named Sheepa below when a light is cast from above
I used the Godot Engine but you can use any engine or tool as long as there is a way to do custom drawing in 2D
export var body_radius = 40
func _draw():
var screen_center = get_viewport().size / 2
draw_circle(screen_center, body_radius, Color.pink)
Drawing a circle is great and all but what we really want is 2 adjustable semicircles. We can use this arc function to help us define our own custom method for creating semicircles supported by custom parameters such as radius, angle, and curviness. The white circles are the points that the circular arc function generates (the nb_points parameter determines how many points each arc should take)
export var body_radius = 40
func _draw():
var screen_center = get_viewport().size / 2
draw_circular_arc(screen_center, body_radius, 0, 180, Color.pink, 1.0, 6)
draw_circular_arc(Vector2(screen_center.x - 20, screen_center.y), body_radius, 180, 360, Color.pink, 1.0, 6)
#
func draw_circular_arc(center, radius, angle_from, angle_to, color, curviness, nb_points):
var points_arc = PoolVector2Array()
for i in range(nb_points + 1):
var angle_point = deg2rad(angle_from + i * (angle_to-angle_from) / nb_points - 90)
var next_point = Vector2(cos(angle_point) * 1 / curviness, \
sin(angle_point) * curviness) * radius
points_arc.push_back(center + next_point)
draw_circle(center + next_point, 5, Color.white)
draw_colored_polygon(points_arc, color)
By modifying the curviness parameter, we can alter the curviness of the circle
I created curviness, curviness_rate, and is_curving_up variables to facilitate the curviness variable oscillating from 0.8 - 1.2
It's breathing!
var curviness = 1.0
var curviness_rate = .1
var is_curving_up = true
func _process(delta):
if is_curving_up:
curviness += curviness_rate * delta
else:
curviness -= curviness_rate * delta
if curviness < .9:
is_curving_up = true
elif curviness > 1.1:
is_curving_up = false
update()
For the head, we'll just bob it up and down using the same curviness parameter
func draw_head():
var screen_center = get_viewport().size / 2
var head_offset_y = 50 * curviness
var head_center = Vector2(screen_center.x, screen_center.y - head_offset_y)
draw_circular_arc(head_center, head_radius, \
0, 180, Color('c06c84'), 1.0, 8)
draw_circular_arc(head_center, head_radius, \
180, 360, Color('6c5b7b'), 1.0, 8)
The eyes and nose are just circles with offsets. Use the head center position as a base for drawing the eyes and nose
func draw_face(head_vec, head_offset_x):
var eye_height := 5.0
var eye_between_width := 9.0
var eye_radius := 3.5
var left_eye = Vector2(head_vec.x - eye_between_width + head_offset_x, head_vec.y - eye_height)
var right_eye = Vector2(head_vec.x + eye_between_width + head_offset_x, head_vec.y - eye_height)
draw_circle_custom(left_eye, eye_radius, eye_color)
draw_circle_custom(right_eye, eye_radius, eye_color)
var nose_radius := 4.0
var nose_offset_y := 2.0
draw_circle_custom(Vector2(head_vec.x + head_offset_x, head_vec.y + nose_offset_y), nose_radius, pink_color)
Since we have a good understanding of the semicircles, let's go back to just pink
var face_offset_x = 0
func draw_head():
var screen_center = get_viewport().size / 2
var head_offset_y = 50 * curviness
var head_center = Vector2(screen_center.x + face_offset_x / 2, screen_center.y - head_offset_y)
draw_circular_arc(head_center, head_radius, \
0, 180, primary_color, 1.0, 8)
draw_circular_arc(head_center, head_radius, \
180, 360, primary_color, 1.0, 8)
if is_walking_right():
face_offset_x = 5
if is_walking_left():
face_offset_x = -5
draw_face(head_center, face_offset_x)
There are circles for the outer ear, smaller circles for the pink inner ear, and a primitive shape from the radius of the outer ear down to a little above the eyes
To finish up, just add a collider for physics and stretch the body whenever you jump/land. I added some little particle effects on landing as well
For more devlogs, updates, and tutorials feel free to follow me on itch.io or twitter
Cheers!
---
You can check out Hops and Harmony at https://pyrecraft.itch.io/hops-and-harmony