Game类是对一局游戏的抽象。它保存着游戏的所有数据,拥有一些游戏逻辑层面的方法。如:开始新游戏、重置滑板、道具生效等。
class Game { public: Game(void); ~Game(void); // 分数、命数 int score; int life; bool paused; int level; // 板 Paddle paddle; // 球 list<Ball*> balls; //Ball *balls[3]; // 砖块 //Block **blocks; list<Block*> blocks; // 道具 list<Item*> items; // 动画 list<Animation*> animations; // 新游戏 void new_game(); // 读取关卡 void load_stage(int level); // 装载材质 void set_textures(SDL_Texture *textures[]); // 有关道具的函数 void improve_ball(); void triple_ball(); // 重置滑板 void reset(); bool is_clear(); };
score、life、level 分别是分数、生命数、关卡号。
paused是暂停标志,如果是true,window类会停止更新游戏状态。
paddle是滑板对象。
new_game()用于开始一局新的游戏。要做的操作有:清空砖块、小球列表,重置滑板位置、长度、生命数等信息。
improve_ball()是用来实现小球升级道具的效果的函数,会将小球升级为高级版本(如果有的话)。P.S.我在考虑是否要把所有用于实现道具效果的函数加个命名前缀
我没有找到什么好的办法来确定小球当前的类型,最后使用了RTTI一个一个试......=。= ,因为我觉得如果给小球类加个变量表示它是什么类型,好像还不如干脆不集成这些类,直接用一个类的成员变量来区别小球呢......如果有更好的办法,请不吝赐教。
void Game::improve_ball() { Ball *temp = nullptr; for(list<Ball*>::iterator ball = balls.begin(); ball!=balls.end(); ++ball) { if(*ball) { // 这里把派生类当成基类了 cout << typeid(*ball).name(); if(dynamic_cast<NormalBall*>(*ball) != nullptr) { temp = new GravityBall(); temp->set_geometry((*ball)->get_geometry()); temp->speed = (*ball)->speed; temp->set_texture((*ball)->textures); temp->launch(); delete (*ball); *ball = temp; // TODO: 这里以后可以用拷贝构造函数重写 } else if(dynamic_cast<GravityBall*>(*ball) != nullptr) { temp = new SuperBall(); temp->set_geometry((*ball)->get_geometry()); temp->speed = (*ball)->speed; temp->set_texture((*ball)->textures); temp->launch(); delete (*ball); *ball = temp; } } } }