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;
}
}
}
}