Project 2: Tank
Complete Playable Due 3/25/2016
Other Team Feedback Due 3/28/2016
Final Version Due 4/1/2016
Complete Playable Due 3/25/2016
Other Team Feedback Due 3/28/2016
Final Version Due 4/1/2016
Tank!
For your next project, you will create a single player (or split-screen multiplayer) tank game. This is another old standby -- tanks that move around the landscape, firing shells at each other. You have a fair amount of lattiude here to do something fun. However, your "basic" tank game should have the following features:- Playing field (with boundries) that the tanks can move in. This can be as simple has a large ground plane, with large objects as barriers around the edges, or you can do something more complicated.
- Interior barriers of some kind that constrain movement and/or shells. Again, this can be as simple as placing objects in your world (as simple as just cubes, rectangles, and such) that tanks can't go through or shoot through, or something more complicated, as you prefer.
- Tanks that can fire shells in a nice parabolic arc (a really basic gravity that only affects particles -- with tanks always at the same y position -- will do this for you)
- Shells cause damage to the tanks
- Tanks can be destroyed, with some visual effect -- the easiest would be to repace the tank model with a dead tank for a period of time (dead tanks should probably disappear eventually, for performance reasons) but you can get more complicated if you like
- Some kind of respawning (perhaps with a short time delay) after player tank is destroyed
- Simple AI for the enemy tanks. For the basic game, the AI can be pretty stupid, but the tanks should at least move and occasionally fire. Playing around with tank AI can complicated -- and very fun -- quickly.
Tank Extensions
Once you have your basic game working, it's time to add more features! As with pong, you have some lattitude, here are some examples of what you might do (these are just examples, you do not need to do all of them, of course -- you could also do something not on this list. Feel free to discuss any extensions with me.)- Integration with a physics engine (like ODE or Bullet). In some ways this will make your life easier -- collistion detection done for you! -- but in other ways your life will be much harder. The end result will be very cool, however. A simple (and less realistic) version would be to use a frictionless plane with forces to move the tanks around. A more realistice version would be to have motors on your tank, which drive it forward using friction.
- Levels that are described using some kind of data file (instead of hard-coded), and a level editor that creates levels. The level editor can be done using Ogre (either as a separate program, or as a mode of your game), or you can write a level editor that doees not use Ogre, but writes out level files in a format that your code can read in. You level editor can even be in a different language (python, etc) if you want.
- Better AI, than can handle complex enviornments, or that has simple strategy of some kind
- For complex environments, you may want to "pre-bake" in a navigational graph -- preset the routes that the enemy AI can take, and use these routes when moving the tanks around.
- Secondary weapons fire
- Large shells that do more damage / do area of effect damage (with some visual indication) / toss tanks into the air / etc
- Lasers / Machine guns / Rail guns
- Mines / oil slicks / etc
- Bouncing / ricocheting weapons, weapons that penetrate world geometry and/or other tanks
- Wacky weapons that reverse tank controls, force tank to constantly accelerate forward (or backwards), stall the tank so it can't move, shake / sway camera so the tank is hard to control, etc.
- Shells that modify the world. This can get very hard quickly, but you can "fake" deformable terrain without too much trouble by swapping "damaged" models for regular models, or removing models altogether
- Two players on the same screen (getting a good camera can be tricky here -- you want to be able to see both tanks, and perhaps add in AI tanks that yo can see as well)
- Two players, split screen
- Two players, networked
- This will require rather extensive work on your own, but I'm willing to help out if you feel inspired
- Powerups!
- Add to tank's health
- Shields
- Add ammo (for ammo limited weapons)
- Increased weapons damage / temporary additional secondary weapon / grow tank / shrink tank / etc
- Invulnerability / Invisibility / etc
- Add a nicer HUD
- health bar, statistics, radar, etc. Overlays are probably the easiest way to go here.
- An in-world indicator of where a shell will land if it is fired now (marking on the ground, or even the complete trajectory. You will need to create dynamic meshes using the OgreManual interface, described here
- Add some interesting cameras
- Cinematic view
- Shell POV for dramatic shots
- Add complex geometry, including allowing tanks to move in the y direction -- perhaps even with bridges, and tank-over-tank technology
- Add sounds. Some sound package for Ogre can be found here and here
Collaboration
You are strongly encouraged (though not required) to work in teans for this project. A team size of two is somewhat preferred -- a team of 3 is acceptable, though I will expect you to have a slightly more impressive final product. Team sizes larger than 3 will require some convincing -- I'll expect something really special from a larger team.For artwork (models, textures, etc), you can use any available public domain sources, or build your own from scratch, or some combination. As with all academic content, be sure to cite your sources! This is mostly an engineering class -- "programmer art" is perfectly acceptable.
Recommended Archtecture
The following is a recommended architecture for your tank project. Feel free to use any (or none!) of it as you please. You should make sure, however, that whatever you do is reasonably thought out.- Tank class
- Contains instance variables for:
- All entities and sceneNodes requried for a single tank (I used one entity for the tank body (attached to a tank scene node, which was attached to the root scene node) and one entity for the tank barrel (attached to a barrel scene node, whcih was attached to the tank scene node, so that the barrel could tilt independantly of the tank, but would translate along with it automatically)
- Various other parameters that describe the tank (health / velocity / anglular velocity / etc)
- Any physics / collision information requried for the tank (my version
keeps an AABB that I recalculate when the tank moves or rotates, so I
can use the cached value for speed. I didn't trust the AABB that ogre
kept track of (mostly because the comments in the header files warned
me not to)
- Contains functions that:
- Set the velocity / position / rotation / etc. of the tank. Setting the position changes the actual position of the SceneNode, changing the velocity has no immediate effect, but changes how the world think method handles the tank)
- Fire a shot from the tank
- Essentially makes a call to the projectile manager telling it the initial position and velocity of the shell
- Need some way of limiting the number of shots per second, or limiting the number of shots until you need to reload, or something else.
- Return any collision information (like an AABB for the entire tank), and any other tank features (health, etc)
- Static Object class (for a piece of world geometry)
- Contains instance variables for:
- All entites and sceneNodes requried for the piece of world geometry
- Any physics / collision information required for the geometry. Since this is static, you can just calculate an AABB at the beginning, and return it when requested
- Contains functions that:
- Return any collision information (like an AABB) for use in other classes / methods
- World Class
- Contains instance variables for:
- List of all static objects in the world
- List of all tanks in the world (if you want to be fancy, you could extend this to a list of "movable objects", of which tank is a subclass. Try to avoid virtual functions, if you can.
- Contains methods that:
- Think (Try to move each tank based on its velocity, and turn each tank in terms of angular velocity -- if the motion causes a collision, then undo the move. For this world, you can do something simple like checking against each other tank and piece of world geometry. For complex worlds you could do something more interesting, like storing world geometry in regions, and only checking for collisions within the proper region.
- Projectile Manager Class / Projectile Class
- Each projectile contains information on that projectile (location, velocity, entities & scene nodes, etc)
- Projectile manager contains a list of projectiles
- Contains methods that
- Spawn a projectile with a given positin and velocity (creates the mesh, creates an instance of the projectile class, adds the projectile to the list of projectiles handled by the manager, etc
- Think (move each projectile based on velocity, modify velocity based on gravity, check for collisions and either damager the appropiate tank (if a tank was hit), or do some area effect (if the ground was hit), or just kill the projectile
- (This class is not strictly required -- you could keep track of a list of projectiles in the world, but I thought my code was a little cleaner if projectiles were in a separate place, since they behave differently from other objects in the world)
- Camera Class
- Contains instance variables for
- Any necessary information on the object(s) we are tracking / following
- Camera speed / actual position / desired position / etc
- Ogre camera (requrired to actually change the camera)
- Containts methods that
- Think -- move the camera the appropriate amount for the current frame
- AI Manager / Tank AI
- Class for the Overall AI manager
- Contains a list of AIs for individual tanks
- Each think cycle, calls the think for all AIs
- Handles adding / removing AIs as tanks are spawned / destroyed
- Class that handles AI for an individual tank
- Contains a pointer to the tank controlled by the AI
- Contains a pointer to the world (to decide what to di)
- Contains a Think method that does the thinking for this tank
- User input / User class
- Sets the velocity / angular velocity / etc for the tank
- If the actual movement is done by the world, you can do all collision detection in one place.
- Fires shots when necessary
- Any other input
- You may well have some circular dependencies (For instance, my World class has a pointer to all tanks in the world, each tank has a pointer to the Projectile Manager (to spawn projectiles on firing), and my projectile manager has a pointer to the world class (to check for collisions on a projectile think). This is not a problem, but you do need to be a little careful when setting up all the classes to get the pointers initialized correctly.
- Feel free to add extra methods (expecially acessor methods) to you classes -- if, for instance, the projectile manager needs a way to get at some of the physics information in the world to handle projectile collisions, you can add some methods to the world to expose what you need.
- This project is more fun than pong -- but it is quire a bit more work, too.
Grading
Your code will be graded on the following metric- Basic Tank (technical): 50 points
- Compiles and runs
- User tank moves around screen and fires
- Tanks are stopped by world geometry and other tanks
- Tanks can be damaged and destroyed by firing
- Basic AI
- Complex Tank (technical): 40 points
- Enhancements are sufficiently complicated
- Enhancements are well executed and (reasonably) bug-free
- Fun Factor: 5 points
- This is more of a subjective measure -- how fun is your extended Tank?
- Playtesting report: 5 points
You are strongly encouraged to play each other's games. Give feedback, and get ideas for what you can do in your own game. In adition to informal feedback you give to other teams, each individual (not each team, but each individual) is requried to give formal feedback to at least one team. This formal feedback will be part of your grade for your project. Your formal feedback needs to include:- Best feature of the game, that should be emphasized, built upon
- Any bugs found (with reproduction steps!)
- Suggested features to add / things to change
- Overall feedback -- how are the controls? The pacing? The difficulty? Was it fun? Were there any "wow" moments?
Submission
You should create a subversion directory that contains everything you need to compile and run your code, under <your username>/cs420/Project2/. If you are working in a team, the system administrators will be happy to create a new subversion directory for you team. Place all of your required source files, project files, solution files, etc into this repository. Be sure to preserve any necessary directory heirarchies. You should also submit all art required by your program. You should not submit any object files, executable files, or Intellisense Databases.Place a README file at the top level of your subversion hierarchy which describes how to compile and run your submission, how to play your game, any features you want to highlight, and anything else I need to know to get the most out of your game.
It is strongly recommended that you keep all of your files in subversion from the beginnng of the project -- do not use subversion as a submit directory!