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