It's been a pretty productive couple of weeks on the project, and I'm really happy with the progress. I've setup a basic game loop, shooting enemies, and level navigation. You can see the results in this video, and read about the additions below. It's definitely starting to feel like a game!
I wanted the game loop to be pretty simple, and easy to learn. You first start up with only the main objective to kill (the enemy "base" at the top of the map), and when you do you immediately progress to the next level. After this things continue to get harder the higher you get. Later on I plan to add random level generation, and path finding for the enemies.
The actual game loop itself was trivial to set up. When the level loads it takes a difficulty value, this affect the number of enemies that spawn, and the health of the “base” you are meant to destroy. When you kill the base this value gets incremented, and the level re-loads. When you die, it gets reset and you start over.
All of this was well and good, but without a display for player progress the whole experience basically sucked. The problem was, I hadn't yet gotten around to writing code for rendering text. I quickly looked into all my options, and decided that for now, using Direct Write would be a decent approach. I found a tutorial by Rodrigo Diaz, and got to work.
Sweet. No problems. It's a pretty simple set up, except for the fact nothing worked. After bashing my head against a wall for a bit I eventually found out that Direct Write can't share a back buffer with DX11, I needed to upgrade to DX11.1 for that. So it turns out that I'd be spending the weekend upgrading my renderer to the next Direct X version. Yet another reason you probably shouldn't roll your own game engine!
Finally I completed all that work, just so I could write "Level 1" at the top of the screen.
This was definitely a fun task, as it was my first dabble into any kind of game play. I wanted the enemy projectiles to move slowly enough that the player could dodge them. This meant that I couldn't just shoot straight at the player, I'd have to predict where they were going to be! I found a great blog post by Daniel at Danik Games covering the topic and got to work.
The end result was that shooting enemies would always hit the player unless the projectile velocity was too low to catch up. In this case the bullets were shot parallel to the player.
The addition of more accurate aiming definitely increased the difficulty of the game. You can vary your acceleration to throw off the projectiles, but they'll occasionally catch you off guard. However, the bullets move so slowly that half the time the shooter can't hit the player anyway, and shooting parallel to the player movement just made the shooters look stupid. In this case, I decided that the shooters should blend back to aiming directly at the player, and miss a little more gracefully.
For level navigation I wanted to keep most of the game play in my game to flat areas, however, I also wanted to be able to have interesting multi-tiered level layouts. I wanted a set up where I could do bridges over other game play areas. Additionally, I wanted navigation on the map to be 100% safe. I don't want to frustrate the player with falling off the map to an untimely death (backed into a corner and shot to death, yes, but fall off the world, no), and I definitely don't want to be chasing down ANY fall through the world bugs later in development.
I set up two systems. A navigation system, and a “snap to navigation” component system, and updated my spawning system to use the navigation system:
Currently in the game, all the enemies and the player stick to one navigation layer that covers the entire area of the test level. Additionally, another layer is set up to restrict enemy spawning positions. This makes the start area and the health pickup at the top of the map a little safer than the area close to the base.
The set up is pretty simple, and doesn't really give me the ability to do much in the way of physics simulations. However, I'm confident that it will get me through the first project using this engine. It also helps me keep the scope of what I'm trying to achieve within reasonable constraints. Afterwards, on another project I can look into integrating something like BulletSharp, and doing more complex physics based game play.