Code Structure / Level Design: Plants vs Zombies game level dissection
- by lalan
Hi Friends,
I am interested in learning the class structure of Plants vs Zombies, particularly level design; for those who haven't played it - this video contains nice play-through: http://www.youtube.com/watch?v=89DfdOIJ4xw.
How would I go ahead and design the code, mostly structure & classes, which allows for maximum flexibility & clean development? I am familiar with data driven design concepts, and would use events to handle most of dynamic behavior.
Dissection at macro level:
(Once every Level) Load tilemap, props, etc -- basically build the map 
(Once every Level) Camera Movement - might consider it as short cut-scene
(Once every Level) Show Enemies you'll face during present level  
(Once every Level) Unit Selection Window/Panel - selection of defensive plants
(Once every Level) Camera Movement - might consider it as short cut-scene
(Once every Level) HUD Creation - based on unit selection 
(Level Loop) Enemy creation - based on types of zombies allowed
(Level Loop) Sun/Resource generation
(Level Loop) Show messages like 'huge wave of zombies coming', 'final wave'
(Level Loop) Other unique events - Spawn gifts, money, tombstones, etc
(Once every Level) Unlock new plant
Potential game scripts:
a) Level definitions: Level_1_1.xml, Level_1_2.xml, etc. 
Level_1_1.xml :: Sample script
<map>
   <tilemap>tilemapFrontLawn</tilemap>
   <SpawnPoints> tiles where particular type of zombies (land vs water) may spawn</spawnPoints>
   <props> position, entity array -- lawnmower, </props>
</map>
<zombies>
   <... list of zombies who gonna attack by ids...>
</zombies>
<plants>
   <... list by plants which are available for defense by ids...>
</plants>
<progression>
   <ZombieWave name='first wave' spawnScript='zombieLightWave.lua' unlock='null'>
      <startMessages time=1.5>Ready</startMessages>
      <endMessages time=1.5>Huge wave of zombies incoming</endMessages>
   </ZombieWave>
</progression>
b) Entities definitions: .xmls containing zombies, plants, sun, lawnmower, coins, etc description. 
Potential classes:
//LevelManager - Based on the level under play, it will load level script. Few of the //               functions it may have:
class LevelManager
{
 public:
   bool load(string levelFileName);
   bool enter();
   bool update(float deltatime);
   bool exit();
 private:
   LevelData* mLevelData;
}
// LevelData - Contains the details of level loaded by LevelManager. 
class LevelData
{
   private: 
      string file;
      // array of camera,dialog,attackwaves, etc in active level
      LevelCutSceneCamera** mArrayCutSceneCamera; 
      LevelCutSceneDialog** mArrayCutSceneDialog;
      LevelAttackWave** mArrayAttackWave;
        ....
      // which camera,dialog,attackwave is active in level
      uint mCursorCutSceneCamera; 
      uint mCursorCutSceneDialog;
      uint mCursorAttackWave;
   public:
      // based on cursor, get the next camera,dialog,attackwave,etc in active level
      // return false/true based on failure/success
      bool nextCutSceneCamera(LevelCutSceneCamera**);
      bool nextCutSceneDialog(LevelCutSceneDialog**);          
}
// LevelUnderPlay- LevelManager 
class LevelUnderPlay
{
   private:
      LevelCutSceneCamera* mCutSceneCamera;
      LevelCutSceneDialog* mCutSceneDialog;
      LevelAttackWave* mAttackWave;
      Entities** mSelectedPlants;
      Entities** mAllowedZombies;
      bool isCutSceneCameraActive;
   public:
      bool enter();
      bool update(float deltatime);
      bool exit();
}
I am totally confused.. :(
Does it make sense of using class composition (have flat class hierarchy) for managing levels.
Is it a good idea to just add/remove/update sprites (or any drawable stuff) to current scene from LevelManager or LevelUnderPlay?
If I want to make non-linear level design, how should I go ahead? Perhaps I would need a LevelProgression class, which would decide what to do based on decision tree.
Any suggestions would be appreciated very much.
Thank for your time,
lalan