植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs
文件位置
实现功能的代码文件位置在Class\Scenes\GameScene文件夹中,具体如下图所示。
ZombiesAppearControl.h
/* 僵尸出现波数控制 */
class ZombiesAppearControl
{
public:/***对于进攻的不同波数创建不同数量僵尸*/int getZombiesNumbersForAppearFrequency(const unsigned int& ZombiesAppearFrequency);/***获取僵尸波数*/int getZombiesAppearFrequency() const;/***获取上一波僵尸是否已经阵亡*/bool getLastFrequencyZombiesWasDeath() const;/***获取计时是否开始*/bool getIsBegin() const;/***获取是否显示文字*/bool getIsShowWords() const;/***获取时间*/double getTime() const;/***使每一行的僵尸等概率出现*/int getEqualProbabilityForRow();/***设置僵尸出现波数* 1.传递参数设置*/void setZombiesAppearFrequency(const unsigned int zombiesAppearFrequency);/***设置僵尸出现波数* 2.自增加一*/void setZombiesAppearFrequency();/***设置上一波僵尸是否死亡*/void setLastFrequencyZombiesWasDeath(bool lastFrequencyZombiesWasDeath);/***设置时间清零*/void setTimeClear();/***设置时间自增*/void setTimeAdd();void setTimeAdd(const double t);/***设置是否开始*/void setIsBegin(const bool isBegin);/***设置是否显示文字*/void setIsShowWords(const bool isShowWords);/***创建不同种类的僵尸*/ZombiesType createDifferentTypeZombies(const unsigned int& ZombiesAppearFrequency);/***创建不同种类的僵尸*/ZombiesType createDifferentTypeZombies();CC_CONSTRUCTOR_ACCESS:ZombiesAppearControl();~ZombiesAppearControl();private:int _zombiesAppearFrequency; // 僵尸出现波次bool _lastFrequencyZombiesWasDeath; // 上一波僵尸已阵亡 bool _isBegin; // 计时是否开始bool _isShowWords; // 是否显示文字double _time; // 计时OpenLevelData* _openLevelData;default_random_engine _random; // 随机数引擎set<int> _judgeZombieRow; // 判断僵尸所在行unsigned int _zombiesPosition[5] = // 僵尸位置{130,268,406,544,682};
};
这段代码是一个名为ZombiesAppearControl的类的定义,用于控制僵尸出现的波数和相关的属性和方法。让我逐个解释一下类中的成员和方法的作用:
成员变量:
_zombiesAppearFrequency
: 僵尸出现的波数_lastFrequencyZombiesWasDeath
: 上一波僵尸是否已经阵亡_isBegin
: 计时是否开始_isShowWords
: 是否显示文字_time
: 时间计时_random
: 随机数引擎_judgeZombieRow
: 判断僵尸所在行的集合_zombiesPosition
: 僵尸位置数组方法:
getZombiesNumbersForAppearFrequency(const unsigned int& ZombiesAppearFrequency)
: 根据传入的进攻波数返回对应的僵尸数量getZombiesAppearFrequency() const
: 获取当前的僵尸波数getLastFrequencyZombiesWasDeath() const
: 获取上一波僵尸是否已经阵亡getIsBegin() const
: 获取计时是否开始getIsShowWords() const
: 获取是否显示文字getTime() const
: 获取时间getEqualProbabilityForRow()
: 使每一行的僵尸等概率出现setZombiesAppearFrequency(const unsigned int zombiesAppearFrequency)
: 设置僵尸出现的波数(通过参数设置)setZombiesAppearFrequency()
: 设置僵尸出现的波数(自增加一)setLastFrequencyZombiesWasDeath(bool lastFrequencyZombiesWasDeath)
: 设置上一波僵尸是否阵亡setTimeClear()
: 设置时间清零setTimeAdd()
: 设置时间自增(默认增加一个时间单位)setTimeAdd(const double t)
: 设置时间自增(增加指定的时间单位)setIsBegin(const bool isBegin)
: 设置计时是否开始setIsShowWords(const bool isShowWords)
: 设置是否显示文字createDifferentTypeZombies(const unsigned int& ZombiesAppearFrequency)
: 创建不同种类的僵尸(根据传入的进攻波数)createDifferentTypeZombies()
: 创建不同种类的僵尸(使用当前的僵尸波数)构造函数和析构函数:
ZombiesAppearControl()
: 构造函数~ZombiesAppearControl()
: 析构函数注释中的代码是C++的语法,描述了类的成员变量和方法的声明。
ZombiesAppearControl.cpp
构造函数
ZombiesAppearControl::ZombiesAppearControl() :_zombiesAppearFrequency(0)
, _lastFrequencyZombiesWasDeath(false)
, _isBegin(false)
, _isShowWords(false)
, _time(0)
, _openLevelData(OpenLevelData::getInstance())
{_random.seed(time(nullptr));
}
这是ZombiesAppearControl类的构造函数的实现代码。让我逐行解释一下构造函数的功能:
ZombiesAppearControl()
: 构造函数的定义_zombiesAppearFrequency(0)
: 将僵尸出现波数初始化为0_lastFrequencyZombiesWasDeath(false)
: 将上一波僵尸是否已经阵亡初始化为false_isBegin(false)
: 将计时是否开始初始化为false_isShowWords(false)
: 将是否显示文字初始化为false_time(0)
: 将时间计时初始化为0_openLevelData(OpenLevelData::getInstance())
: 获取OpenLevelData类的实例并将其赋值给_openLevelData成员变量,这个类可能是游戏关卡数据的管理类或者其他相关类的实例_random.seed(time(nullptr))
: 使用当前时间作为随机数引擎的种子,从而生成不同的随机数序列构造函数的作用是初始化类的成员变量,并对必要的变量进行赋值和初始化操作。这里使用了C++的成员初始化列表来对成员变量进行初始化,以提高代码的效率和可读性。
createDifferentTypeZombies函数
ZombiesType ZombiesAppearControl::createDifferentTypeZombies(const unsigned int& zombiesAppearFrequency)
{int number = rand() % 100;int sum = 0, i = -1;auto zombiesTypeProbability = _openLevelData->readLevelData(_openLevelData->getLevelNumber())->getZombiesTypeProbabilityFrequency().at(zombiesAppearFrequency);for (auto& probability : zombiesTypeProbability){++i;sum += probability;if (number < sum){return static_cast<ZombiesType>(_openLevelData->readLevelData(_openLevelData->getLevelNumber())->getZombiesType().at(i));}}return ZombiesType::None;
}
这是
ZombiesAppearControl
类中的createDifferentTypeZombies
方法的实现代码。让我逐行解释一下这个方法的功能:
ZombiesType ZombiesAppearControl::createDifferentTypeZombies(const unsigned int& zombiesAppearFrequency)
: 方法定义,返回ZombiesType
类型的值,表示创建的不同种类的僵尸。
int number = rand() % 100;
: 生成一个0到99之间的随机数,表示概率的比较值。
int sum = 0, i = -1;
: 初始化变量sum
为0,用于计算概率的累加值;初始化变量i
为-1,用作循环中的索引。
auto zombiesTypeProbability = _openLevelData->readLevelData(_openLevelData->getLevelNumber())->getZombiesTypeProbabilityFrequency().at(zombiesAppearFrequency);
: 从OpenLevelData
类中读取与指定zombiesAppearFrequency
对应的僵尸类型概率,并将其赋值给zombiesTypeProbability
变量。
for (auto& probability : zombiesTypeProbability)
: 遍历zombiesTypeProbability
中的每个概率值。
++i;
: 将索引i
递增1。
sum += probability;
: 将当前概率值累加到sum
中。
if (number < sum)
: 判断随机数number
是否小于概率累加值sum
。
- 如果条件成立,说明随机数落在当前概率范围内,执行以下代码块:
return static_cast<ZombiesType>(_openLevelData->readLevelData(_openLevelData->getLevelNumber())->getZombiesType().at(i));
: 从OpenLevelData
类中读取与指定索引i
对应的僵尸类型,并将其转换为ZombiesType
枚举类型后返回。如果没有返回值,说明随机数不在任何概率范围内,执行以下代码块:
return ZombiesType::None;
: 返回ZombiesType::None
,表示没有创建任何僵尸类型。此方法的作用是根据给定的僵尸出现波数,根据概率随机选择一种僵尸类型进行创建。通过比较随机数和概率累加值,确定选择哪种僵尸类型。方法中涉及到了读取关卡数据的操作,使用了
OpenLevelData
类的实例来获取相关数据。
getEqualProbabilityForRow函数
int ZombiesAppearControl::getEqualProbabilityForRow()
{uniform_int_distribution<unsigned>number(0, 4);if (_judgeZombieRow.size() == 5){_judgeZombieRow.clear();}unsigned int row;do{row = number(_random);} while (_judgeZombieRow.count(row));_judgeZombieRow.insert(row);return _zombiesPosition[row];
}
这是
ZombiesAppearControl
类中的getEqualProbabilityForRow
方法的实现代码。让我逐行解释一下这个方法的功能:
int ZombiesAppearControl::getEqualProbabilityForRow()
: 方法定义,返回整数类型的值,表示选择的僵尸所在行。
uniform_int_distribution<unsigned>number(0, 4);
: 创建一个均匀分布的整数随机数生成器,范围为0到4,用于生成随机行数。
if (_judgeZombieRow.size() == 5)
: 检查_judgeZombieRow
集合的大小是否为5,即是否已经选择了5行。
- 如果条件成立,说明已经选择了5行,执行以下代码块:
_judgeZombieRow.clear();
: 清空_judgeZombieRow
集合,重新开始选择行数。
unsigned int row;
: 声明变量row
,用于存储随机选择的行数。
do { ... } while (_judgeZombieRow.count(row));
: 循环执行以下代码块,直到选择的行数不在_judgeZombieRow
集合中。
row = number(_random);
: 生成一个随机行数并将其赋值给row
变量。
_judgeZombieRow.insert(row);
: 将选择的行数插入_judgeZombieRow
集合中,用于记录已选择的行数。
return _zombiesPosition[row];
: 返回与选择行数对应的僵尸位置。此方法的作用是在五行中均匀地选择一行作为僵尸出现的位置。它使用了随机数生成器生成随机行数,并通过集合
_judgeZombieRow
来确保每次选择的行数不重复。最后,根据选择的行数返回对应的僵尸位置_zombiesPosition[row]
。
getZombiesNumbersForAppearFrequency函数
int ZombiesAppearControl::getZombiesNumbersForAppearFrequency(const unsigned int& ZombiesAppearFrequency)
{const unsigned int number = _openLevelData->readLevelData(_openLevelData->getLevelNumber())->getZombiesNumbers().at(ZombiesAppearFrequency);return number + rand() % number;
}
这是
ZombiesAppearControl
类中的getZombiesNumbersForAppearFrequency
方法的实现代码。让我逐行解释一下这个方法的功能:
int ZombiesAppearControl::getZombiesNumbersForAppearFrequency(const unsigned int& ZombiesAppearFrequency)
: 方法定义,返回整数类型的值,表示特定僵尸出现波数的僵尸数量。
const unsigned int number = _openLevelData->readLevelData(_openLevelData->getLevelNumber())->getZombiesNumbers().at(ZombiesAppearFrequency);
: 从OpenLevelData
类中读取与给定僵尸出现波数ZombiesAppearFrequency
对应的僵尸数量,并将其赋值给常量number
。
return number + rand() % number;
: 返回一个在number
范围内的随机数,通过将随机数取模number
并加上number
本身来实现。这样做可以生成一个在0到number-1
之间的随机数,然后加上number
本身,使得随机数的范围在number
到2*number-1
之间。此方法的作用是根据给定的僵尸出现波数,从关卡数据中读取对应的僵尸数量,并返回一个在该数量范围内的随机数。这样可以实现每次出现的僵尸数量有一定的变化性。
其他函数
其他函数非常简单,请自行阅读。