Space Shooter – Week 01

So I have chosen my first project, an Asteroids game! Asteroids is an old-time favorite and one of the most successful arcade games of it’s time. I chose this style of game because for one it’s mechanics are simple to wraps ones head around as a developer, and because it’s so simple that it offers a bunch of opportunity for extending with new ideas. This is going to be a mobile game released on iOS and Android, and I am hoping to create an HD look for it. However the style of the game could change as the project matures. I do have some idea of where I would like to take this game, maybe I will include the game design document in a future update.

Progress Report

So I have already been working on this over the past week, here is a little video demo’ing my progress:

As you can see it’s not too much to look at visually, but it’s a start. The main hurdle was figuring out a system for replicating the asteroids style screen wrap effect for the ship. To do this I created a block in unity and scaled it to encapsulate the viewable area. I then disabled it’s mesh renderer so that it’s hidden in scene. I used a default cube for this and not a box collider for debugging purposes, so that I could re-enable the mesh to see if the bounds were where I wanted them.

Screenshot of world bounds

Also the background moves slightly in the opposite direction of the ship. This is based off of the velocity of the ship scaled by a speed multiplier. The background itself is a generated sphere so all I had to do was rotate it as the ship moves.

Major Problems Solved

Using the WorldBounds object as a trigger, I am able to fire OnTriggerExit when the ship leaves the predefined space. I’m pretty sure I did this in an overcomplicated way, but I took it as a challenge to write a function that would work in any situation. Basically the function repeats a value in a range, so let say we have a lower bound of 2 and an upper bound of 12. If you pass in 15 the return value would be 5 and if you passed in -3 the return value would be 7. The function is ran on the X,Y,Z of the ships objects transform using the WorldBounds as the min and max values, and then wraps the ship in the axes that need it. See the implementation below:

void OnTriggerExit(Collider other) {
		var otherPos = other.gameObject.transform.position;

		otherPos.x = repeatValue (minBounds.x, maxBounds.x, otherPos.x);
		otherPos.y = repeatValue (minBounds.y, maxBounds.y, otherPos.y);
		otherPos.z = repeatValue (minBounds.z, maxBounds.z, otherPos.z);

		other.gameObject.transform.position = otherPos;

    /// <summary>
    /// Wraps a value within bounds
    /// </summary>
    /// <param name="min">Minimum bound</param>
    /// <param name="max">Maximux bound</param>
    /// <param name="value">Value to repeat within min and max</param>
    /// <returns>The value repeated within the bounds</returns>
	private float repeatValue(float min, float max, float value) {
        // make sure min and max are correct
        float _min = Mathf.Min(min, max);
        float _max = Mathf.Max(min, max);

        // if we are within the bounds, no need to repeat
        if (value >= _min && value <= _max)
            return value;

        // else store the sign
        float minSign = min > 0 ? 1 : -1;
        float maxSign = max > 0 ? 1 : -1;
        float newValue;

        if (minSign == -1 && maxSign == 1)
            // set all values to positive space
            float newMin = Mathf.Abs(_min);
            float newMax = Mathf.Abs(_max);
            newValue = Mathf.Abs(value);
            float newRange = newMin + newMax;

            // find the repeated value and set back to regular space
            newValue = mod(value + newMin, newRange) - newMin;

        else if (minSign == 1 && maxSign == 1)
            if (value > min)
                newValue = mod(value, _max) + _min;
                newValue = _max - mod(_min, value);
        else // both negative
            if (value < min)
                newValue = mod(value, _max) + _max;
                newValue = _min - mod(_max, value);

        return newValue;

    /// <summary>
    /// Custom mod used to mirror python mod functionality
    /// </summary>
    /// <param name="k"></param>
    /// <param name="n"></param>
    /// <returns></returns>
    float mod(float k, float n) { return ((k %= n) < 0) ? k + n : k; }

As you can see, I have written a custom modulus function. This is because I wrote the initial function in python for quick testing. Once I got this working with all the test cases, I re-wrote the function in C# for Unity, only to find out that the return values from the function were different. Turns out the Python and C# treat the mod ( % ) operator differently, but luckily I found a solution on Stack Overflow for replicating the python functionality in c#.

Here is the original python code if you are interested with the test cases:

def repeatValue(minBound, maxBound, value):
    # make sure that our values are correct min and max
    _min = min(minBound, maxBound)
    _max = max(minBound, maxBound)

    # if value are in bounds, return the value
    if _min <= value <= _max:
        print ('default version')
        return value

    # if not lets find the correct value
    minSign = 1 if minBound > 0 else -1
    maxSign = 1 if maxBound > 0 else -1

    newValue = None

    if (minSign == -1 and maxSign == 1):
        print ('first version')
        # move into positive number space
        newMin = abs(_min)
        newMax = abs(_max)
        newValue = abs(value)

        newRange = newMin + newMax
        newValue = ((value + newMin) % newRange) - newMin
    elif minSign == 1 and maxSign == 1:
        print ('second version')
        if value > _min:
            newValue = value % _max + _min
            newValue = _max - (_min % value)
    else: # both negative
        print ('third version')
        if value < _min:
            newValue = value % _max + _max
            newValue = _min - _max % value
    return newValue

# here are the test cases

print(repeatValue (-10, 10, 15)) # should be -5

print(repeatValue(-10, 10, -17)) # should be 3

print(repeatValue (10, -10, 16)) # should be -4

print(repeatValue (10, -10, 5)) # should be 5

print(repeatValue (10, -10, -3)) # should be -3

print(repeatValue (10, 20, 23)) # should be 13

print(repeatValue (10, 20, 7)) # should be 17

print(repeatValue (-10, -20, -23)) # should be -13

print(repeatValue (-10, -20, -7)) # should be -17

print(repeatValue (-13.4, 14.4, 15.4)) # should be -12.4

print(repeatValue (-13.4, 14.4, -14.4)) # should be 13.4

Assets Used

The assets I have in there now are all from the Unity asset store.  There was a sale over the past few days called the Tomorrow Sale which pretty much was exactly what I needed.  Everything on sale had something to do with space.  I was able to purchase packages for asteroids, the space background, ships, and even special effects.  I spent less than $100 total for everything, here are the assets that I purchased:

As you can see, not a bad deal for this many assets!  I got pretty much everything I need to get the player ships, asteroids, weapon visual effects, and backdrops built.  I still may need to pick up some assets for the enemies and sound effects later.

Next Steps

Next on the agenda I will continue working on the prototype. I think that the thing that will keep this interesting for me will be actually having new playable progress every week. I took a game design class in San Francisco about a year ago, and the most important take away for me was that successful games are made fun first. They figure out what it is that is fun about the game, and then extend upon it from there visually. I think for now I will focus on the controls and fine tuning the movement of the ship and the firing mechanics. I also want to start getting some builds onto mobile to start doing some actual on device testing. At that point I will reach upon you guys to see if anyone out there would be interested in being part of the ‘alpha’ builds!

Here’s a list of what I would like to accomplish for next week:

  • Add thrusters to ship
  • Add shooting fx
  • Add asteroids to destroy
  • Add asteroids destruction effect
  • Add link to game design document

Any thought’s, questions, or feedback?  Let me know in the comments!