@poe - Not sure. Thanks, though!
@eigenbom - Alright, sure.
Python scripting's pretty easy to use, and you use a special API for scripting with the BGE to do what you need to do.
I do scripting with Geany, which supports some basic code-completion and code folding, which is a really nice feature to have. Blender can use external Python script files, and compiles them when it does so, as well, giving you a bit more of a speed increase as opposed to simply using .py files. The Python module for working with the BGE comes with a lot of good features and functionality, even apart from actual game development. It has stuff like adding game objects in and orienting objects to other objects, but also has features like Vectors and Eulers built-in, which are really helpful, as well.
The camera's being fixed is simple - I parented the camera to a 'helper' cube, which sets its position to be its target's position, which is the Player's position in the world. I didn't have to use the Helper cube, but it's helpful since I have fairly complete control over the camera - how far away it is from its target, how fast it moves to its target, etc., although the camera probably won't change for this game.
Axis aligned quads are also simple to implement. Each sprite frame is present in the game scene in a hidden layer as a simple plane, facing upwards on the +Z axis. This is done so that I can replace the mesh of the sprite object easily to make animation.
I could also move around the UV values of the sprite objects, but duplicated objects share meshes in the BGE, and so would share sprite images when animating (i.e. explosions created at two different times would have the same UV values). However, this can be greatly useful when you want to have many, many sprites that share a single animation, like a series of torches in a level. Rather than giving them all logic to animate, you can make all but one of them copies of the original, and animate just that one. So, by manually replacing the mesh of each object, each object, even duplicates, can have unique animations.
In my game, any "2D" object's sprite is rotated 45 degrees on the global X axis to face the camera. Because the sprite object is rotated, the sprite frames (the mesh of the sprite object) are also rotated. I could use the Halo setting for this, like particles would use, but then the sprites would rotate around on their local X axes, 'spinning' to face the camera.
Mirroring a sprite is simple if it's straight on, but with a true 3D top-down view, it's a bit more complex. Doing this with a global
Z-rotation (with a two-sided sprite) will have the sprite rotated 45 degrees in the opposite direction.
Think of it like an object that you want to rotate is on a stand. You want to rotate the object, so you rotate that stand by 180 degrees. If the object is rotated 45 degrees to face you, then 180 degrees later, it's facing away from you, both on the Z axis (around) as well as the X axis (up and down).
I have to do two rotations - rotate the sprite by 90 degrees on its local X-axis to face me, and then rotate it 180 degrees around on the Y axis if the object should be mirrored. This is an example of where the BGE's Euler class helps out a lot. Here's an example:
ori = Euler()
ori.x += pi * 0.25
obj['sprite'].orientation = ori
I create a Euler object, rotate it by 45 degrees (a quarter of pi) on the global
X axis to face the camera, then rotate it on its local
Y-axis by a 180 degree rotation if the object should be mirrored, so that you don't have the object face away if it's mirrored. Then, I assign the Euler directly back to the sprite's orientation matrix (the BGE handles conversion).
So, that's about it.
I recently got an idea to implement actual enemy bases, since Kitheif suggested stealth and cover. I think those would be a nice change of locale.