cocos學習5

今天把捕魚達人的項目給做完了,基本功能都實現了,第一天把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類的遊戲了,希望可以很好的掌握。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章