Sunday, March 23, 2014

Game A Week - #3 - Orbital Golf

Here is how the past week went: (Play the game here!)

I really wanted to integrate a physics engine in order to get all of the benefits one provides.  So, I decided to implement Orbital Golf, a physics heavy golfing game that I had developed a rough prototype of several years ago in Unity.  You can play the old Unity prototype here. I pulled the dart-box2d package into my Dart project, which is a Dart port of Box2D. I then implemented a basic Collider component as well as a rough BoxCollider component.  I managed to get a small box to fall and land on a large static box acting as the ground.

I fixed a major scaling issue with rendering.  I added in a second moving box that bounces off the first box.  I implemented a CircleCollider component and the ability to programmatically create a circle mesh.  I created a simple wrapper around mouse input to allow that as an input option. I then spent hours trying unsuccessfully to detect then the mouse clicks an object.

After continuing to struggle with detecting clicked objects by trying to "unproject" the mouse position as a raycast into the scene, I decided to try going the other direction.  (I was able to successfully unproject the mouse position and create a ray vector pointing into the scene, but detecting the ray hitting objects posed the problem.)  I implemented a temporary Clicker component that projects its own world position into screen space whenever the mouse button is pressed and then sees if it matches (within a range)  the mouse position.  It worked great, and since I only needed to be able to detect clicks on the ball, this works fine for the game.

I implemented a Planet component that calculates gravity based upon distance to the planet.  I also implemented a Ball component that uses gravity of surrounding planets to apply forces and move the ball around.

I made it so that if ball is clicked on, dragged, and then released, it applies a force relative to how much the mouse was dragged in order to fling the ball around.  I added in a simple counter to count how many hits were made. I ran into odd issues with trying to make a "factory" method to generate planets.  It seems like a bug in Dart, but I need to investigate it further before I report it.

I set up a goal circle that is a static Box2D sensor.  I implemented a callback system for when two Box2D objects collider and made it so when the ball and goal touch, it displays a winning message. I also implemented a line renderer to show the force vector to be applied to the ball.  It's very crude, but does the job.

I set up a simple level system that can switch between various levels. I also tried working on displaying a trajectory prediction line, but it turns out to be fairly complicated.  I had tried doing a similar thing back with the old Unity version.  You can see there is a prediction line in the Unity version, but it doesn't take into account any collisions or friction with surfaces.  I was hoping to have a superior prediction line with this prototype, but that doesn't appear to be possible for a one week challenge.

I decided to change things up a bit and instead of working on gameplay I would try and make it look a little better.  I implemented a Texture2D object and the ability to set textures on a Material.  I wrote a simple new shader that took a single texture.  I found a checkerboard pattern image online and I now have a goal with a checkerboard texture applied to it in order to help it stand out more.

I changed focus once more and I added the ability to make the game go fullscreen using the Fullscreen API. I also added in a wrapper around touch events to be able to get touches on a touchscreen.  These two features together make it work much better on a mobile device, and I tested the game on my Android phone (Galaxy Note 3).

I also made a quick update so that the force line moves along with the ball instead of sitting out in space where you first clicked the ball.

Play the game here!

Final Thoughts
I was quite happy with what I accomplished this week.  I actually had almost the entire week off of work which helped me be more productive.

As usual, there were several features I wish I could have added:

Better scoring - scoring based upon the flight time of the ball divided by the number of hits
Better camera - a camera that uses mouse wheel and pinching to zoom
Prediction line - as you probably read above, I really wanted a line to predict ball trajectory
Non-spherical planets - ovals, simple terrain
Orbiting planets - planets orbiting around other planets as moons
More debris and obstacles - things cluttering the way

To be honest, I'm glad the week is over.  It's good to be able to switch over to a different game every week.  I really like the concept of Orbital Golf  and I believe it has great potential, but there are other ideas I'd love to try out.  I have this next week off of work as well, so hopefully I can whip up something awesome.


João Pinto said...

Hello, is the source code available somewhere ?


Patrick McCarthy said...

Having only spent one week (in my free time!) to develop this game, my first instinct is to tell you to do the same.

Try to implement it yourself in a week as a learning experience.

Having said that, I do have the code on GitHub, although it is very hacked together and was never meant to be consumed by anyone else in its current form.

Patrick McCarthy said...

I just decided to rename my repo: