When I was younger, I played a game called Hover! that came on the Windows 95 installation disk. So, for this project I attempted to do a remake.
My version is much simpler than the Win 95 version, it lacks the powerups and whatnot, but its still playable.
The premise of the game is that you are in a hovercraft that you control in the same manner as you would a real hovercraft. Your movement direction is
independent of your orientation. To steer you turn the direction you wish to go and press forward to apply velocity in that direction. This non-direct
control system adds a layer of difficulty. The goal of the game is to collect your "flags" before the opponent collects theirs.
World maps are generated from an ASCII file. In the file, first you specify how precise you are being ie. how big you want each wall segment to be per chunk, then you describe where the walls in the world lie by placing 'X's in the text file where you want walls to appear. You also place the starting position of the user and the starting position of the opponent, as well as the locations of the flags for wach to capture. ReHover then reads in the file and builds the world to your specifications.
Since this is a hovercraft game where collisions with the walls are likely, full collision detection is implemented. You can use the walls to your advantage by bouncing off of them to help you make it around corners. Collision detection is implemented using an occupancy grid around the assumed radius of the hovercraft. Since the game world is formed using only right angles, the algorithm determines which side of the craft is colliding with a wall, ensures that it is not a false positive (it is possible to drive close enough to the wall that collisions would be constantly detected causing a stutter), and inverts the velocity along the axis that makes logical sense.
Collisions with the opposing player are handled differently. If the distance between the players is within 2x a craft radius (they are touching) then the angle between the crafts is calculated and whatever velocity the crafts have is used to hurdle them in the opposite direction. This is not true physics but it creates a kind of "force field" effect.
The opponent pilots itself using waypoints laid out in the text file. Waypoints are specified by placing lowercase 'a' through 'z' along the path you wish the opponent to take. The opponent figures out the angle to the next waypoint, and essentially pretends that someone has pointed it in the correct direction and is telling it to accelerate. Once the opponent "collides" with the imaginary waypoint (they are part of the wall occupancy grid) it selects the next waypoint and accelerates in that direction.
The heads up display in the upper left that gives the current progress of the player vs. the opponent is hierarchically modeled and then rendered in 2D by passing a variable to the shader that causes the projection matrix and the view matrix to be excluded from the rendering calculation.
I ran into quite a few hurdles during the creation of this program. First I struggled with how to handle collisions. Detecting them is quite simple, but reacting properly is a whole other beast. Since walls are specified in very small chunks, it is difficult to model where there face may be, so it is difficult to use standard intersection to figure out the impact angle.
The HUD also took an insanely long time. Every tutorial on how to do 2D rendering is made completely irrelevant because of how we are handling the shaders. It did not occur to me to just disable the perspective and view in the shader directly until after quite a bit of struggling.
Due to these problems, I did not have as much time as I would have like to make it look good by adding textures or make it more intersting by adding powerups like go faster or jump. As it is, it works, it is playable, but it is quite ugly.