GitHub Game Off 2016 - Day 14

What a day it was today! Life kind of got in the way as I had to renew my driver's license, but I did manage to get it done and soldier on. Things are very slow going at the moment and as things stand right now I'll most likely miss the deadline, but I'll still try to get something playable. I am still planning on publishing so I'll definitely have to take time and spend it on polishing.

Outcome

The outcome of today was that I managed to hook up my DDD Gravity Simulation to Unity. The glue that holds everything together is, in all honesty, a big bleeding mess. I'm slowly in the process of migrating some of my domain entry points into singletons or hopefully abstracting it behind some service layer. I do foresee quite a bit of work, but it is definitely making my life easier in terms of how to go about with adding new functionality now. I'm also quite excited about my gravity simulation implementation.

Below is the singleton in which I'm managing most of the process. It's currently more of a collection object that keeps track of all the bodies that exert a force on your ship.

using System.Collections.Generic;

namespace GOO2016.Domain.Gravity  
{
    public class Simulation
    {
        private readonly HashSet<Body> bodies;

        public IEnumerable<Body> Bodies => this.bodies;

        public const float BigG = 0.6f;

        private static volatile Simulation instance;

        private static object lockObject = new object();

        public static Simulation Instance
        {
            get
            {
                if(instance != null)
                {
                    return instance;
                }

                lock(lockObject)
                {
                    if(instance == null)
                    {
                        instance = new Simulation();
                    }
                }

                return instance;
            }
        }

        private Simulation()
        {
            this.bodies = new HashSet<Body>();
        }

        public void Add(Body bodyToAdd)
        {
            if(this.bodies.Contains(bodyToAdd))
            {
                return;
            }

            this.bodies.Add(bodyToAdd);
        }
    }
}

The collection of bodies do most of the heavy lifting as seen below:

using System.Collections.Generic;  
using UnityEngine;

namespace GOO2016.Domain.Gravity  
{
    public class Body
    {
        private readonly IMassComponent massComponent;
        private readonly IPositionComponent positionComponent;
        private readonly HashSet<Body> otherBodies;

        public float Mass => this.massComponent.Mass;
        public Vector2 Position => this.positionComponent.Position;

        public Vector2 NetForce
        {
            get
            {
                var netForce = Vector2.zero;

                foreach (var otherBody in this.otherBodies)
                {
                    var heading = otherBody.Position - this.Position;

                    var rSquared = heading.sqrMagnitude;

                    var force = Simulation.BigG * (this.Mass * otherBody.Mass) / rSquared;

                    netForce += heading.normalized * force;
                }

                return netForce;
            }
        }

        public Body(Simulation simulation, IMassComponent massComponent, IPositionComponent positionComponent)
        {
            this.otherBodies = new HashSet<Body>(simulation.Bodies);

            this.massComponent = massComponent;
            this.positionComponent = positionComponent;

            simulation.Add(this);

            foreach(var otherBody in this.otherBodies)
            {
                otherBody.otherBodies.Add(this);
            }
        }
    }
}

I've decided to have the Body class accept the simulation object it should be added to. I'm still deciding on whether I should just directly fetch the singleton, but for now this should be fine. There is also still some logic missing to remove a body from the simulation, but that should be trivial to add now.

I'm also aware that using HashSet as a collection should silently ignore adding duplicates, but I prefer to do check if a object exists in case I might want to add some extra logic related to adding duplicates. It's also just a bit more explicit and would allow for swopping out the backing structure without the worry that I lose my uniqueness.

The other plus side is I'm now calculating a net force vector. That would allow me to draw a nice HUD arrow that can display the current gravity vector applied to your ship.

Carry on wayward stars

I'm now getting ready to add a nice parallaxing background to assist with a more visual aid towards player movement. The only current indication that the ship is moving is the offset the camera is using. It's not obvious enough and I believe having a nice starry background would really help. That's it for today!

Sas van der Westhuizen

Intermediate Software Engineer at Entelect; "engineering" since 2015; loves games, rock climbing; been trying my hand at making games, but nothing good yet!

Johannesburg, South Africa