今天把捕鱼达人的项目给做完了,基本功能都实现了,第一天把cocoscreator 做了一部分,算是熟悉了捕鱼达人的一些特点,
第二天用cocos2d-x写,感觉还是不错的,
首先把场景布置了一下,按钮跟打飞机的按钮是不同的,在这上面稍微花费了一点时间,星期二就让我们自己把一些场景布置以及场景的转换,
auto start = MenuItemImage::create(
"1.png",
"2.png",
CC_CALLBACK_1(HelloWorld::onStart, this));
start->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y - start->getContentSize().height + visibleSize.height/2 + 50));
auto quit = MenuItemImage::create(
"bbbbb1.png",
"bbbbb2.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
quit->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + start->getPositionY() - quit->getContentSize().height - 50));
auto menu = Menu::create(start,quit, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
需要加载两张不同的图片,点击到按钮就会切换图片达到按钮的效果;
就HelloWorldScene和打飞机的都一样的,所以没遇到什么困难;
第二天就把一些UI给加载到场景中,并且添加了一些动画;
首先是炮台与Bar以及+ - 按钮的显示,都和加载图片一样;
这天主要还是炮台的切换;
我是把炮台和+ - 按钮的点击事件在同一个类里面创建的;
先是给按钮点击事件赋值;
auto ss = (MenuItemFont*)pSender;
int sss = ss->getTag();
if (sss == 1){
if (type == 1)
{
type = 7;
}
else{
type -= 1;
}
}
else if (sss == 2){
if (type == 7)
{
type = 1;
}
else{
type += 1;
}
}
selectType(type);
假定有七个炮台的情况;
selectType(type)这是加载炮台的方法,根据type的值去切换炮台;
void Battery::selectType(int type){
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
if (battery1)
{
battery1->removeFromParent();
battery1 = NULL;
}
if (type == 1 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("1-1.png");
if (type == 2 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("2-1.png");
if (type == 3 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("3-1.png");
if (type == 4 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("4-1.png");
if (type == 5 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("5-1.png");
if (type == 6 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("6-1.png");
if (type == 7 && battery1 == NULL) battery1 = Sprite::createWithSpriteFrameName("7-1.png");
battery1->setPosition(Vec2(origin.x + visibleSize.width / 2 + 40, origin.y + battery1->getContentSize().height / 2 - 5));
this->addChild(battery1,5);
battery1->setRotation(rotation);
}
这就是炮台的创建,在之前有加载过plist文件;
这就实现了炮台的转换了;
还有一个比较简单的就是给炮台增加旋转;
这只要找到API赋值一些代码就行了;
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(Battery::onTouchBegan, this);
listener->onTouchEnded = CC_CALLBACK_2(Battery::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
这四句调用点击场景事件;
bool Battery::onTouchBegan(Touch* touch, Event *event)
{
return true;
}
void Battery::onTouchEnded(Touch* touch, Event *event)
{
auto location = touch->getLocation();
auto radian = atan2(location.y - 21.6f, location.x - 550.0f);
auto inclination = radian * 180 / 3.14;
auto kil = -(inclination)+90;
if (kil <= 70 && kil >= -70) {
rotation = kil;
battery1->setRotation(rotation);
}
}
这就把炮台的旋转可以实现了;
需要切换炮台的角度不变,把这角度在生成炮台地方调用就好了battery1就是生成的炮台;
battery1->setRotation(rotation); 只要一句就好了;
第三天把鱼的出现给进行一些调整;
并且可以发射子弹,跟随炮台的转动而转动;
void Battery::shutBullet(int type)
{
if (type == 1)
{
bullet1 = Sprite::create("bullet/wepen1.png");
}
if (type == 2)
{
bullet1 = Sprite::create("bullet/wepen2.png");
}
if (type == 3)
{
bullet1 = Sprite::create("bullet/wepen3.png");
}
if (type == 4)
{
bullet1 = Sprite::create("bullet/wepen4.png");
}
if (type == 5)
{
bullet1 = Sprite::create("bullet/wepen5.png");
}
if (type == 6)
{
bullet1 = Sprite::create("bullet/wepen6.png");
}
if (type == 7)
{
bullet1 = Sprite::create("bullet/wepen7.png");
}
bullet1->setPosition(Vec2(battery1->getPositionX(), battery1->getPositionY()));
this->addChild(bullet1,0);
bullet1->setRotation(rotation);
int s = type;
}
首先根据不同的炮台生成不同的子弹;
然后再点击事件里面给实现;
if (kil <= 70 && kil >= -70) {
rotation = kil;
battery1->setRotation(rotation);
shutBullet(type);
auto moveto = MoveBy::create(20.0f, Vec2((location.x - battery1->getPositionX()) * 1000, (location.y - battery1->getPositionY())*1000));
bullet1->runAction(moveto);
fenshu -= type;
}
这if判断语句就是在炮台旋转时候设定的点击事件;那么就肯定要跟随的;
之后又把鱼给实现了;
在创建鱼的时候我是每种鱼给他一个方法;
在根据一个随机数来判定哪种鱼出现的频率;
void Fish::creatfish()
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
fish1->setPosition(Vec2(visibleSize.width + fish1->getContentSize().width / 2, rand() % 640 + 100));
int ss = rand() % 640 + 100;
moves = rand() % 8 + 3;
auto move = MoveTo::create(moves, Vec2(-fish1->getContentSize().width / 2 , ss));
auto radian = atan2( - visibleSize.width , - fish1->getPositionY() + ss);
auto inclination = radian * 180 / 3.14;
auto rotation = (inclination)+90;
fish1->setRotation(rotation);
this->addChild(fish1);
fish1->runAction(move);
pget.pushBack(fish1);
}
void Fish::creatfish1()
{
fish1 = Sprite::createWithSpriteFrameName("GMarlinsFish_actor_001.png");
creatfish();
Animation* animation = Animation::create();
animation->setDelayPerUnit(moves / MOVE);
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_002.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_003.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_004.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_005.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_006.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_007.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_008.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_009.png"));
animation->addSpriteFrame(fish->getSpriteFrameByName("GMarlinsFish_actor_010.png"));
Animate* animate = Animate::create(animation);
fish1->runAction(RepeatForever::create(animate));
fishadd = 10;
}
上面是plist文件里面的图片;
这是其中的一个创建鱼游动的动画的方法;
我还有这样的方法六个 ;
由于代码太多就复制一个;
void Fish::update(float dt)
{
type = rand() % 99 + 1;
if (type >= 1 && type < 5)
{
creatfish1();//金鲨鱼
fishshu = 1;
}
if (type >= 5 && type < 30)
{
creatfish2();//花鱼(小)
fishshu = 2;
}
if (type >= 30 && type < 35)
{
creatfish3();//蓝鲨鱼
fishshu = 3;
}
if (type >= 35 && type < 45)
{
creatfish4();//乌龟
fishshu = 4;
}
if (type >= 45 && type < 70)
{
creatfish5();//金鱼(小)
fishshu = 5;
}
if (type >= 70 && type < 95)
{
creatfish6();//红鱼(小)
fishshu = 6;
}
if (type >= 95 && type <= 100)
{
creatfish7();//大鱼(大)
fishshu = 7;
}
}
然后就是用一个计时器把鱼出现的频率给调整一下;
今天把所有创建的场景以及碰撞之间的关系给确定了一下;
最主要的是把鱼与子弹碰撞的动画给实现了;
其他的修饰修饰就好了;
先是在子弹类与鱼类里面的鱼与子弹各自创建一个数组;
在Gamescene里面调用;
通过计时器把鱼与子弹的超出边界给删除;
for (int i = 0; i < fish1.size(); i++)
{
if (fish1.at(i)->getPositionX() <= - fish1.at(i)->getContentSize().width / 2)
{
fish->remove(fish1.at(i));
break;
}
}
for (int i = 0; i < bullet.size(); i++)
{
if (bullet.at(i)->getPositionX() <= - bullet.at(i)->getContentSize().width / 2||
bullet.at(i)->getPositionX() >= visibleSize.width + bullet.at(i)->getContentSize().width / 2||
bullet.at(i)->getPositionY() >= visibleSize.height + bullet.at(i)->getContentSize().height / 2)
{
battery->remove(bullet.at(i));
break;
}
}
再把碰撞的部分给完善;
for (int i = 0; i < fish1.size(); i++)
{
for (int j = 0; j < bullet.size(); j++)
{
if (fish1.at(i)->getBoundingBox().intersectsRect(bullet.at(j)->getBoundingBox())){
battery->remove(bullet.at(j));
bom(bullet.at(j));
//fish->remove(fish1.at(i));
if (bl == true)
{
fenshu += types * 10 * addfish;
fish->remove(fish1.at(i));
}
return;
}
}
bool bl 是碰撞随机随机死亡的一个函数,主要是增加游戏的乐趣;
bool Fish::dispatch()
{
int xuan = rand() % 99 + 1;
if (fishshu == 1)
{
if (xuan <= 0.5*10*types)
{
return true;
}
}
if (fishshu == 2)
{
if (xuan <= 1.2*10*types)
{
return true;
}
}
if (fishshu == 3)
{
if (xuan <= 0.5*10 *types)
{
return true;
}
}
if (fishshu == 4)
{
if (xuan <= 0.8*10 *types)
{
return true;
}
}
if (fishshu == 5)
{
if (xuan <= 1.2*10 *types)
{
return true;
}
}
if (fishshu == 6)
{
if (xuan <= 1.2*10 *types)
{
return true;
}
}
if (fishshu == 7)
{
if (xuan <= 0.5*10*types)
{
return true;
}
}
}
fishshu指每种鱼类的编号;
xuan也就给定的随机数;
types是炮台的等级,综合以上的几种情况给定概率死亡;
今天还有一个功能是把分数给实现了;
先给定一个初始分数;
每发射一发子弹减少相对应的分数;
这是在点击onTouchEnded的时候减的;
fenshu -= type;
每捕捉到鱼类也增加相应的分数;
fenshu += types * 10 * addfish;
addfish表示鱼类增加的分数除以十,在鱼类里面每生成一次,给定一次;
char str[20];
sprintf(str, "%d", fenshu);
auto label2 = (Label*)getChildByTag(3);
label2->setString(str);
文本数组在场景中显示,可实现分数的变化;可以在构造函数里面先申明一下;
auto label = Label::createWithTTF( "","fonts/arial.ttf", 32);
label->setPosition(Vec2(origin.x + visibleSize.width/5 + 15,origin.y + label->getContentSize().height/2 +15));
this->addChild(label, 3 ,3);
label->setColor(Color3B::BLUE);
做到现在还差的就是鱼的死亡动画了;
其他扩展的就慢慢来吧,趁着周末好好的温习一下;
下星期要接触RPG类的游戏了,希望可以很好的掌握。