Updates

Updates to my project have been on hold for awhile.  The last few weeks have been busy, and I’ve been sick on and off as well. I feel that if I had a well established work habit on this project I would have been able to power through but unfortunately my progress has stalled.  Another theme which has been holding me back lately is wanting to balance my programming with reading on AS3 so that I don’t simply end up programming Java in AS3.  I’ve been trying to fit in some reading and discovery in as well and have discovered still more things I want to change.

A second worry of mine is that my fun home project is starting to turn into another type of work, I want to make sure that I enjoy this project and am able to bring my best work to it rather than always feeling under pressure for deadlines.  Due to these factors I’m going to be taking a hiatus to read some more AS3, do some heavy refactoring and try to get the code base to where I feel comfortable releasing it again.  There is a lot going on right now so I don’t have any specific dates but I hope I’ll be ready to come back to my schedule my the end of November.

If I have something interesting to write about in the meantime there may be some posts up here.

Happy Halloween!

Refactoring – My process

My game project has been moving forward fairly well, however the next step opened my eyes to some structural flaws in the program. These may require a bit of time to fix but luckily it’s still a small program and most of these things can be resolved fairly easily.  I do want to go through my process of how I step back, look at the program with fresh eyes and try to map out both it’s current and future structure.

I’m one of those people that can stare blankly at code in Analysis Paralysis for way too long. I finally sat down today to map out, restructure, and get the new developments into it. My schedule is kind of shot for this release cycle considering today is supposed to be release day, but I can bump it forward a week and get out a new release as well as new source code for people next Sunday.  I was expecting a few bumps in the beginning as I get my work habits down and learn to fit in time around all the other chaos in my life.  It also ends up well as I want to release the game versions and source code at the same time anyway, it’s a bad idea to release separately as bugs could be added or removed in the cleanup of the source code.

One of the best ways I have to avoid the endless search for code perfection is to start writing and mapping things out, by getting things down where I can see them I trigger my switch that moves me from contemplation into action.  It often doesn’t matter what I start with, but the best idea I normally find is simply write down the current area’s structure, either in list form, diagrams, or just freeform stream of thought.  With that in mind find what works for you, just don’t sit there for three hours looking at your code.

Current File Structure

If you haven’t had the chance to see the source code for the game(Click on it to get focus), right now the current code structure is as follows:

game>engine>

  • CollisionDetector
  • DirectionNormalizer
  • KeyboardControl
  • ShooterGameManager

obstacle>bullet

  • Bullet

obstacle>ship

  • EnemyMovement
  • EnemyShip (inherits ship)
  • HeroMovement
  • HeroShip (inherits ship)
  • Ship

I’m sure you can tell just by looking at the file structure and names that there are a lot of problems (the player’s ship is an obstacle? To what? The singularity)

So for starters I need to take a look at the structure and what sort of structure would be better for my program.  Then I need to look at what each class does, and when it does more than one thing, I need to break it down into multiple classes due to the Single responsibility principle.

Splitting the classes

Ok let’s get started! Not all of the refactoring below will be perfect but it will be an improvement and programming is all about movement in the right direction.

CollisionDetector checks if there are collisions between the images of various on screen objects with various methods such as checkForShipCollisions, and checkForBulletCollisions, it also manages a list of enemy ships, and checks if a ship exits the screen.  If this wasn’t clearly too much for collision detector to handle, it also triggers actions if collisions occur such as ships taking damage, removing dead ships from the list, and adding to the player’s score.  This sort of growth often happens when a program is built, something needs to be done, it is added into another class quickly and the class grows beyond it’s original scope.  Our best course of action is to split the responsibility up and create the new classes as needed. CollisionDetector can actually be split up into three different methods:

CollisionDetector

  • Checks for collisions between an array of objects and a specific object returning an array of the objects it collided with

OnScreenImageManager

  • Contains arrays of objects that have images currently on the screen
  • Can add an object or remove an object from both the screen and the list

ShipManager

  • Can receive a list of ships that had collisions occur and execute the required actions (take damage, increase score, etc)

Next we have our DirectionNormalizer which looks fine, then we have KeyboardControl which has one problem.  It creates bullets which are independent objects managing their own state so when we do something like tell the game to pause, or stop, the bullets keep on going (you may have noticed that when your game ended). We can solve that by passing the bullet to our new OnScreenImageManager once it is created. For our ShooterGameManager we will leave things as they are but make a note to look over it again and work with the code (it can probably be refactored but I want to focus on our other classes for now rather than the main game area).

Many of our various objects that will be present on the screen would be improved by sharing a common parent that defines behavior so that we can add, remove, or stop them as needed.

We could have all ships, and bullets inherit a new GameObject class which defines .remove(), .pause(), and unPause() methods which can be implemented by all objects, that way when we need to pause or stop the game we can use our OnScreenImageManager to get the various game objects and loop through them calling the correct method to stop the objects.  (We may want to add a .getAllGameObjects method to our OnScreenImageManager to help with this)

Movement is starting to separate on it’s own, we now have EnemyMovement and HeroMovement which implies that we need a super class Movement that both can inherit from in order to reduce repetition, DRY is very important to keep in mind while programming.

New list of classes

So we now have the following Classes in our program:

  • CollisionDetector
  • OnScreenImageManager
  • ShipManager
  • DirectionNormalizer
  • KeyboardControl
  • ShooterGameManager
  • GameObject
  • Ship (inherits GameObject)
  • EnemyShip (inherits Ship)
  • HeroShip (inherits Ship)
  • Bullet (inherits GameObject)
  • Movement
  • EnemyMovement (inherits Movement)
  • HeroMovement (inherits Movement)

Restructuring the packages

I would restructure as follows:

game>engine>main

  • ShooterGameManager

game>engine>screen

  • CollisionDetector
  • OnScreenImageManager
  • ShipManager

game>engine>movement

  • DirectionNormalizer
  • Movement
  • EnemyMovement
  • HeroMovement

game>engine>input

  • KeyboardControl

game>engine>objects

  • GameObject
  • Ship (inherits GameObject)
  • EnemyShip (inherits Ship)
  • HeroShip (inherits Ship)
  • Bullet (inherits GameObject)

Now there are many other changes we can make but it’s a good idea not to bite off more than you can chew in any given refactoring session.  This will allow us to have a decent sized todo list.

The TODO List

I use Trello to manage my lists and my list is as follows:

  • Make OnScreenImageManager
  • Make ShipManager
  • Change Collision Detector
  • Test game
  • Add bullet support to OnScreenImageManager
  • Make GameObject
  • Add GameObject inheritance to objects
  • Test game
  • Make Movement class
  • Add Movement inheritance to movement classes
  • Test game
  • Create new package structure
  • Assign classes and modify dependencies as needed
  • Test Game

Well I guess it’s time to get started, I’ll post the source once I’m finished.