cocos学习5

来源:互联网 发布:建筑大数据分析 编辑:程序博客网 时间:2024/06/03 08:22

今天把捕鱼达人的项目给做完了,基本功能都实现了,第一天把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类的游戏了,希望可以很好的掌握。




0 0
原创粉丝点击