索引篇:
http://www.cocoachina.com/bbs/read.php?tid=227226
http://www.cocoachina.com/bbs/read.php?tid=227229
http://www.cocoachina.com/bbs/read.php?tid=227305
http://www.cocoachina.com/bbs/read.php?tid=227328
http://www.cocoachina.com/bbs/read.php?tid=227522
http://www.cocoachina.com/bbs/read.php?tid=227643
http://www.cocoachina.com/bbs/read.php?tid=227702
好长时间没更新了,这次准备加入敌人的攻击,将敌人波数设置为三波,最后一波会有个小boss。
打完第三波就会出现胜利画面。如果玩家死亡就出现失败界面。
这里采用比较简单的方法控制敌人,即每隔一段时间,让敌人进行攻击,如果不在范围内,则向玩家移动。
在MainScene的init中:
this->schedule(schedule_selector(MainScene::enemyMove), 3);
```
这里是每隔3秒让敌人进行一次动作。
用到的函数:
void MainScene::enemyMove(float dt)
{
for(auto enemy: _enemys)
{
if("dead" != enemy->getState()&&_player && "dead" != _player->getState())
{
if(_player->isInRange(enemy))
{
if("attacking" != enemy->getState())
{
enemy->attack();
_player->beHit(enemy->getAttack());
this->updateHealth();
}
}else
{
enemy->walkTo(_player->getBestAttackPosition(enemy->getPosition()));
}
}
}
}
```
还增加了更新玩家血量的代码,具体可以下载源代码参考。
然后玩家会死亡,对象会被释放,之前没考虑这个情况,所以很可能会出现指针指向无效对象的情况,以前用到_player的地方需要添加相应的检查。
在MainScene中增加变量记录关卡总数和当前关卡,两个vector来记录每一关每个怪的类型和位置:
int _maxLevel;
int _level;
std::vector<std::vector> _enemyTypes;
std::vector<std::vector> _enemyPositions;
```
并在initLevel中进行初始化:
void MainScene::initLevel()
{
_level = 0;
_maxLevel = 2;
std::vector types;
types.push_back(Player::ENEMY1);
types.push_back(Player::ENEMY2);
_enemyTypes.push_back(types);
types.clear();
types.push_back(Player::ENEMY1);
types.push_back(Player::ENEMY2);
types.push_back(Player::ENEMY2);
_enemyTypes.push_back(types);
types.clear();
types.push_back(Player::ENEMY1);
types.push_back(Player::ENEMY1);
types.push_back(Player::ENEMY2);
types.push_back(Player::BOSS);
_enemyTypes.push_back(types);
std::vector positions;
positions.push_back(VisibleRect::center());
positions.push_back(VisibleRect::right() - Vec2(200, 0));
_enemyPositions.push_back(positions);
positions.clear();
positions.push_back(VisibleRect::center());
positions.push_back(VisibleRect::right() - Vec2(200, 0) + Vec2(0, 200));
positions.push_back(VisibleRect::right() - Vec2(200, 0) - Vec2(0, 200));
_enemyPositions.push_back(positions);
positions.clear();
positions.push_back(VisibleRect::center() + Vec2(0, 200));
positions.push_back(VisibleRect::center() - Vec2(0, 200));
positions.push_back(VisibleRect::right() - Vec2(200, 0) + Vec2(0, 200));
positions.push_back(VisibleRect::right() - Vec2(200, 0) - Vec2(0, 200));
_enemyPositions.push_back(positions);
}
```
然后将addEnemy替换为新的函数:
void MainScene::addEnemyByLevel(int level)
{
if(level > _maxLevel)
{
return;
}
auto types = _enemyTypes;
auto positions = _enemyPositions;
for(int ii=0; ii< types.size();ii++)
{
addOneEnemy(types, positions);
}
}
```
注意,Player中的类型中添加了一个新类型Boss。然后还需要增加变量来记录关卡总数目,目前的关卡等。
如果玩家死亡,弹出一个新界面,提示玩家游戏结束,并有一个按钮可以返回开始场景。
如果打完第三波,也会弹出类似界面,提示玩家胜利。
void MainScene::enemyDead(Ref* obj)
{
auto player= dynamic_cast(obj);
if(Player::PlayerType::PLAYER == player->getPlayerType())
{
_player = nullptr;
auto layer = GameOverLayer::create();
layer->setText("You Died!");
this->addChild(layer,10000);
}
else
{
_enemys.eraseObject(player,true);
log("onEnemyDead:%d", _enemys.size());
if(_enemys.size() == 0)
{
if(_level == 2)
{
auto layer = GameOverLayer::create();
layer->setText("You Win!");
this->addChild(layer,10000);
return;
}
showNextLevelItem();
}
}
}
```
新增加了一个GameOverLayer。
代码提交了一下,名称为:"add enemy attack, boss, lose if die, win if clear level."
有些地方不太流畅,感觉判断触摸敌人的那块需要改进。 代码应该还存在着不少不完善的地方,希望发现的人能帮忙指出,谢谢!