Cover image for Converting my Prototype  into a Game

Converting my Prototype into a Game

rcarlson profile image Robert Carlson ・4 min read

So it has been about 2 weeks since my last update on this game. Since that time, I have taken the prototype and created the beginnings of a framework for level design.

The Framework

In order to make level design easier, I needed to take the single script file I had in my proof and create re-usable objects. Here are the objects I've created so far:

The Ship

The ship object consists of a sprite, an animation player and a collider. I suspect I may need to expand on this in the future, but for now this covers everything I need. Right now you can't collide with anything, but I plan on having the ship explode on contact with the planet.

Alt Text

I decided to move the gravity code to a different part of the game (the map). The ship itself can alter its "desired vector" based on the rotation and thrust of the ship. This vector gets altered in a different part of the game that actually simulates the gravitational forces.

extends Area2D

const TURN_SPEED = 180 # how fast the ship will turn
const MOVE_SPEED = 150 # how fast the ship will move
const ACC = 0.01 # acceleration %
const DEC = 0.01 # deceleration %

var motion = Vector2(0,0) # ship's actual move direction (not the desired move direction)
onready var animation = get_node("AnimationPlayer")
export var fuel = 100.00

func _process(delta):
    var rotating = false
    if Input.is_action_pressed("ui_left") && fuel > 0: # if the left arrow key is pressed...
        rotation_degrees -= TURN_SPEED * delta # turn left by TURN_SPEED (* delta, for uniform timing)
        fuel -= 1 * delta;
        rotating = true
    elif Input.is_action_pressed("ui_right") && fuel > 0:
        rotating = true
        fuel -= 1 * delta;
        rotation_degrees += TURN_SPEED * delta

    var movedir = Vector2(0,-1).rotated(rotation) # desired move direction

    if Input.is_action_pressed("ui_up") && !rotating && fuel > 0:
        fuel -= 1 * delta;
        motion = motion.linear_interpolate(movedir, ACC) # lerp towards desired move direction
    elif Input.is_action_pressed("ui_down") && !rotating  && fuel > 0:
        fuel -= 1 * delta;
        motion = motion.linear_interpolate(-movedir, DEC) # lerp towards stillness
    elif !rotating :
        #motion = motion

    position += motion * MOVE_SPEED * delta # move using actual move direction * speed

Animating the Ship

You can also see at this point I've implemented the animations for Forward, Backwards and Left/Right rotation! I also stopped the ship from shaking when idling. Not really sure what I was thinking when I originally created that animation. Needless to say it looks better now.

Alt Text

Adjusting Movement Controls

I decided to go with an Asteroids like movement style where you can only go forward and backwards with the ability to rotate for a full 360 freedom of motion. This just ended up feeling a lot better once I added the animations.

Adding Fuel

I still don't know what the exact gameplay is going to be, however I decided to experiment with the concept of fuel. Each thrust reduces your overall fuel until you reach 0. At that point you cannot move the ship at all. I plan on adding fuel stations or canisters to refill when you are low.

Alt Text

The Planets

The planet object right now only consists of a 2d node and a collider. Each planet has a mass property that I use to determine the size and gravitational force the planet has on the ship.

Alt Text

I still need to figure out how to give planets a scalable texture that looks like pixel art.

Alt Text

The Gravity

I created a script for the overall map that loops through all planets and applies a force to the ship.

Right now I'm still not happy with how the gravity feels. It's difficult to establish a clean orbit around a planet and I can't seem to find a good balance between the ship's thrust and the gravity from the planets. I imagine I will be tweaking this code for a while.

extends Node2D

var orbitalBodies = []

onready var ship = find_node("Ship")

func _ready():

    for body in find_node("Planets", true, false).get_children():

    #initiate gravity physics

#determines the appropriate acceleration based on relative position and object mass
func acceleration(pos1, pos2, mass):
    var gravity = mass * GRAVITY_MULTIPLIER
    var direction = pos1 - pos2
    var length = direction.length()
    var normal = direction.normalized()

    var acc = normal * (gravity / pow(length, 2))

    return acc

#apply orbital vector to body
func step_euler(ship, object):
    var step = 16
    for i in range(step):
        var dt = ship.ACC/step
        var acc = acceleration(object.position, ship.position, object.mass)

        ship.motion = ship.motion + acc * dt
        ship.position  = ship.position + ship.motion * dt

#event handler for physics engine
func _process(delta):
    for object in orbitalBodies:
        step_euler(ship, object)

Next Steps

Now that I have a couple mechanics and objects that I can easily use, the next step is for me to figure out the "fun" of the game. I'll be sharing my results (and failures) in the next article.

Posted on by:

rcarlson profile

Robert Carlson


Husband, Father, Coder, Gamer, Co-Founder LetsBuild.gg


markdown guide

Thanks for sharing.
I loved the "Animating the ship", that gif of the ship movement is inspiring!
On the "Next Steps" section you mentioned "for me to figure out the fun of the game" and it reminds me of this video Jan Willem Nijman - Vlambeer - "The art of screenshake" , it's an inspiring source and reference about how to implement small changes and tweaks that turns a prototype into something greater.


I could just look at that animation in the background all night long! I just wish it was on a more continuous loop. πŸ˜†


I'm only 5 minutes into the video and I already love the guy! His breakdown of the feedback loop players have on the game makes a ton of sense. Thanks for sharing this!


This is dope! Those ship animations are looking good.


Looking great so far Robert!