loading...
Cover image for Building a game using 2D gravity in Godot

Building a game using 2D gravity in Godot

rcarlson profile image Robert Carlson Updated on ・3 min read

2D Space Game in Godot (5 Part Series)

1) Building a game using 2D gravity in Godot 2) Converting my Prototype into a Game 3) Removing my Game's Core Mechanic 4) Adding Health & Fuel Resources to my Game 5) Power-ups, Sound Effects and Level Progression!

Background

After creating my first 2d game using Godot, I got an itch to make something using some physics I'm quite fond of.. Gravity! I plan on keeping a devlog here going over my progress and also getting some much needed input from the community. This article will be the first in a long running series.

Simulating Gravity in 2D

Throwing some static objects with mass into the orbitalBodies variable, I then loop through step_euler(object,body) for every record in orbitalBodies which in turn adjusts the velocity and vector of spaceship each frame.

extends Node2D

var spaceship = {position = Vector2(50, 75), velocity = Vector2(0,0)}

var orbitalBodies = []
var THRUST = .5
var GRAVITY_MULTIPLIER = 175

func _ready():
    #initialize all orbtial bodies on the screen
    orbitalBodies.push_back({position = Vector2(200,200), mass = 5.0})

    #initiate gravity physics
    set_process(true)

#determines the appropriate acceleration based on relative position and object mass
func acceleration(pos1, pos2, mass):
    ...

#apply orbital vector to body
func step_euler(object,body):
    ...

#event handler for drawing screen each frame
func _draw():
    draw_circle(spaceship.position,4,Color(0,1,0.7))

    for object in orbitalBodies:
        draw_circle(object.position,object.mass*3,Color(1,9.7,0))

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

The gravity simulation is not 100% accurate, however I find this represents a nice balance of playability and realistic effect. For example, the orbital bodies effect a force on the ship, but the ship does impact the position of the orbital bodies. I tried using real physics for a while but I found it too difficult to control.

I also implemented some global variables for GRAVITY_MULTIPLIER and THRUST to allow for tweaks down the road. I will most likely change these as I add more gameplay elements.

#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()

    return normal * (gravity / pow(length, 2))

#apply orbital vector to body
func step_euler(object,body):
    var input_vector = Vector2.ZERO

    if Input.is_action_just_pressed("ui_right") || Input.is_action_just_pressed("ui_left") || Input.is_action_just_pressed("ui_up") || Input.is_action_just_pressed("ui_down"):
        input_vector.x = Input.get_action_strength("ui_right") * THRUST - Input.get_action_strength("ui_left") * THRUST
        input_vector.y = Input.get_action_strength("ui_down") * THRUST - Input.get_action_strength("ui_up") * THRUST

        print(input_vector)

        body.velocity += input_vector

    var step = 8
    for i in range(step):
        var dt = THRUST/step
        var acc = acceleration(object.position, body.position, object.mass)

        body.velocity = body.velocity + acc * dt
        body.position = body.position + body.velocity * dt

You can see the result below. Notice how the speed and trajectory of the ship changes relative to its position to the sun. I should point out at this point the ship can be controlled using direction keys.

Alt Text

The Art

I wanted to work on my pixel art skills some more so I made an idle, forward thrust, and reverse thrust animation. I'm not 100% happy with what I have so far, but after looking at dozens of example and spending a couple hours on aseprite, this represents my best effort.

Alt Text

Game-play

Right now my focus is more on learning rather than gameplay, however I am considering adding a fuel component and objectives like orbiting planets for research and exploring solar systems. Please include in the comments below any suggestions you have for gameplay! I plan on posting an update to this series next week. See you later!

2D Space Game in Godot (5 Part Series)

1) Building a game using 2D gravity in Godot 2) Converting my Prototype into a Game 3) Removing my Game's Core Mechanic 4) Adding Health & Fuel Resources to my Game 5) Power-ups, Sound Effects and Level Progression!

Posted on by:

rcarlson profile

Robert Carlson

@rcarlson

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

Discussion

markdown guide