Cocos2d-x实现潜艇大战——简单工厂模式,对象池

潜艇大战游戏的简单介绍:

 

包括三个场景:

开始场景,游戏场景,结束场景

 

开始场景:

2个按钮:开始游戏、退出游戏,分别对应不同的事件响应函数,点击开始游戏按钮,场景跳转,点击退出游戏按钮,退出程序

 

结束场景:

与开始场景类似的2个按钮:重玩游戏、退出游戏,分别对应不同的事件响应函数,点击重玩游戏按钮,场景跳转回游戏场景,点击退出游戏按钮,退出程序

最上方一个GameOver的精灵,位居其下的是一个标签显示本轮得分,得分的变量是一个位于游戏场景对应的MainScene类中的静态变量score保存

 

游戏场景:

一艘战舰:可以控制它左右移动但不能超过屏幕的左右边界,按下空格键向下发射导弹攻击潜艇,击中潜艇得分,潜艇销毁

三艘潜艇:分别位于水下不同深度左右移动但不能超过屏幕的左右边界,随机一艘战舰会向上发射鱼雷攻击战舰,击中战舰则游戏结束,跳转场景至结束场景,潜艇销毁后再生成一艘新的潜艇

 

涉及到的主要类包括:

StartScene

MainScene

OverScene

Warship

Submarine

Bullet及其相关的类

 

设计类图如下:

 

 

 

 

关于子弹的处理,引入了简单工厂模式和对象池:

设计思路:

本案例涉及到了两种子弹:战舰的子弹和潜艇的子弹,区别在于子弹的精灵、移动的方向、大小不同,其他行为基本一致

故设计一个基类Bullet,定义了子弹的基本属性,分别定义战舰的子弹类WarshipBullet,潜艇的子弹类SubmarineBullet,它们都继承自Bullet类,定义不同的子弹属性,在Bullet类中定义了初始化的虚函数,生成子弹的虚函数

virtual void initialize();//对变量初始化,留给子类重写

virtual Bullet* get_bullet();

在子类中重写:

void WarshipBullet::initialize()
{
set_sprite_name("warship_bullet.png");
set_speed(-3);
bulletType=BulletType::WarshipBullet;
}

Bullet* WarshipBullet::get_bullet()
{
return WarshipBullet::create();

}

 

void SubmarineBullet::initialize()
{
set_sprite_name("submarine_bullet.png");
set_speed(3);
bulletType=BulletType::SubmarineBullet;
}

Bullet* SubmarineBullet::get_bullet()
{
return SubmarineBullet::create();

}

再定义一个工厂类,在该类中定义一个静态函数:

Bullet* BulletFactory::createBullet(Bullet::BulletType type)
{
Bullet* b=NULL;
switch (type)
{
case Bullet::BulletType::WarshipBullet:
b=new WarshipBullet();
break;
case Bullet::BulletType::SubmarineBullet:
b=new SubmarineBullet();
break;
default:
break;
}
return b->get_bullet();
}

根据C++中的继承和多态的特性(动态联编):

(1)类之间有继承体系

(2)声明具有相同函数签名的虚函数

(3)由成员函数来调用或通过指针、引用来访问虚函数

于是根据传入的子弹类型,就可以得到不同类型的子弹

 

好处:

如果需要修改某种子弹的功能,只需要修改该种子弹对应的类即可

如果需要增减某种子弹,只需要增减该种子弹对应的类以及在子弹工厂中增减对应的switch分支即可

 

另外,考虑到子弹需要不停地生成和销毁,如果使用传统的方式,定义一个集合Vector<Bullet*> bullets保存子弹,不停地create然后pushBack,当需要销毁时eraseObject,这样不停地生成,销毁,会降低计算机的性能,于是引入了对象池:

 

设计思路:当需要销毁子弹时,只需要将它隐藏起来即可,当需要生成时先从集合中寻找,如果找不到,则生成子弹

 

相关代码如下:

Bullet* ObjectPool::spawnBullet(Bullet::BulletType type)
{
Bullet* bullet=NULL;
bool flag=false;
if(bullets.size()==0)
{
bullet=BulletFactory::createBullet(type);
bullets.pushBack(bullet);
flag=true;
}
else
{
for (int i = 0; i < bullets.size(); i++)
{
bullet=bullets.at(i);
if(!bullet->isVisible() && bullet->bulletType==type)
{
flag=true;
break;
}
}
}
if(flag==false)
{
bullet=BulletFactory::createBullet(type);
bullets.pushBack(bullet);
}
return bullet;
}
void ObjectPool::unspawnBullet(Bullet* bullet)
{
bullet->setPositionY(-20);//防止子弹留在原地不停发生碰撞
bullet->setVisible(false);

}

 

源代码与分析类图下载地址:

https://download.csdn.net/download/dmk17771552304/10490498

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值