大家好,我是Lampard!!
今天迎来捕鱼达人系列的第三篇博客更新,希望大家多多支持。
每次新建一个场景我们逃不开那三板斧:创建一个空的场景,添加一个层,然后填充这个层。
对于我们游戏场景来说也不例外,首先我们要把背景图片,背景音乐等准备好
auto GameLayerBg = Sprite::create("GameLayerBg.jpg");
GameLayerBg->setPosition(vsable.width / 2, vsable.height / 2);
this->addChild(GameLayerBg); // 背景
SimpleAudioEngine::getInstance()->playBackgroundMusic("GameLayerBGM.mp3", true);
// 音乐
然后因为我们大炮的位置是固定的(参照上一篇博客实体类),所以我们需要init的时候先把大炮的位置固定好
s1 = Shell::createShell(); s2 = Shell::createShell(); s3 = Shell::createShell();
s4 = Shell::createShell(); s5 = Shell::createShell();
s1->setPosition(150, 50); s2->setPosition(400, 50); s3->setPosition(650, 50);
s4->setPosition(900, 50); s5->setPosition(1150, 50);
s1->setScale(1.5); s2->setScale(1.5); s3->setScale(1.5);
s4->setScale(1.5); s5->setScale(1.5);
addChild(s1); addChild(s2); addChild(s3); addChild(s4); addChild(s5);
最后我们还要把鱼类给生成出来。因为我们是让鱼随机的,每秒钟生产一条,所以我们需要用到计时器
schedule(schedule_selector(GameLayer::goFish), 1.0f);
void GameLayer::goFish(float dt) {
auto fish = Fish::createFish();
CallFunc* callBack = CallFunc::create(CC_CALLBACK_0(Fish::Finish, fish));
fish->setPosition(rand()%280+900,rand()%620+100); // 位置是随机的
this->addChild(fish);
fish->runAction(Sequence::create(Spawn::create( fish->Swimming(), fish->Going(), NULL),callBack,NULL));
}
OK,现在我们的画面填充就基本实现了。
这款捕鱼达人小游戏游戏逻辑很简单,就是点击游动的鱼,然后就会播放被捕捉的动画,然后计数器就会记录被捕捉的鱼的数量。每一局的时间是限定的,所以我们还需要设置一个全局参数来记录时间值。规定时间内,捕捉到的鱼越多越好。
(1)设置监听事件获取触摸点
auto Listener = EventListenerTouchOneByOne::create();
Listener->onTouchBegan = [this](Touch* t, Event* e) {
log("Ontouch");
} // t是触摸点
(2)判断是否击中鱼
然后我们就可以用触摸点的位置与游动的鱼的位置进行判断,看触摸点是否在其中一条鱼的范围内,若击中则播放被捕捉的动画,改变捉到的鱼的数量,以及删除这条鱼。因为存在着许多条鱼,所以我们可以用向量来存储所有鱼,然后用迭代器遍历。
for (auto it = fishs->begin(); it != fishs->end(); it++) {
fish = *it;
CallFunc* callBack1 = CallFunc::create(CC_CALLBACK_0(Fish::Finish, fish));
if (fish->getBoundingBox().containsPoint(t->getLocation()))
{
log("CatchFish");
fish->stopAllActions();
fish->runAction(Sequence::create(fish->BeCatched(), action,callBack1, NULL));
// 如果击中了,则播放被捕捉的动画
Count++; // 捉到的鱼的数量加一,全局变量
voice = true;
break;
}
}
(3)播放子弹射出的动画
创建子弹射出的动画比较复杂,因为我们首先要判断是那一门大炮发射炮弹。然后就是,为了发射的子弹是朝着触摸点的方向
射出,所以我们还要用到反正切方法(atan)来偏转子弹的方向。
MoveTo * move = MoveTo::create(0.2, thePoint); // 移动到触摸点的速度
Bullet* bullet = Bullet::createBullet();
bullet->setPosition(Xray,80); // 发射的位置,xray是选择的大炮的x坐标
bullet->setRotation(turn); // turn 是偏转的角度,Rotation是偏转
addChild(bullet);
CallFunc* callBack = CallFunc::create(CC_CALLBACK_0(Bullet::Finish, bullet));
Animate* action = ActionTool::animationWithFrameName("gold0", -1, 0.1);
bullet->runAction(Sequence::create(move,bullet->Shooting(),callBack,NULL));
(4)设置全局变量存放时间以及被捕捉的鱼的数量
我们设置一个.h的文件来存放全局变量,为了其他文件能够访问,记得加上extern关键字。
#ifndef __GlobalData__H__
#define __GlobalData__H__
#include
extern double Time; // 时间
extern int Count; // 数量
#endif
(5)游戏胜利的判定
因为我们这个小游戏没有失败界面,只需要在时间结束后把捉到多少鱼的数量传递给胜利界面展示就可以了。所以我们应该利用计时器函数设立一个记录时间的方法,当时间到了之后,就跳转到胜利界面。
schedule(schedule_selector(GameLayer::addTime), 1.0f);
void GameLayer::addTime(float dt) {
Time = Time + 1;
if (Time > 15) {
Director::getInstance()->replaceScene(WinLayer::createScene());
}
}