教你如何使用Cocos2D-X开发塔防游戏(一)

    作者:课课家教育更新于: 2019-03-27 08:59:45

      现在我们经常看到各种各样的塔防游戏,是不是很想自己也做一个出来玩玩?本篇教程将教你如何使用Cocos2d-x开发塔防游戏。

    教你如何使用Cocos2D-X开发塔防游戏(一)_Cocos2D-X教程_开发Cocos2D-X_Cocos2D-X游戏开发_课课家

      游戏开始界面

      修改AppDelegate中内容,将setDesignResolutionSize中改为

      (960, 640, ResolutionPolicy::FIXED_HEIGHT)

      保持传入的设计分辨率高度不变,根据屏幕分辨率修正设计分辨率的宽度。

      通过:

      auto scene = WelcomeScene::createScene();

      director->runWithScene(scene);

      来启动新的场景,进入开始游戏界面。

      首先是Kingdom Rush的LOGO以及该LOGO的动画

      加载资源文件xx.plist

      SpriteFrameCache::getInstance()->addSpriteFramesWithFile("mainmenu_spritesheet_32_1-hd.plist");

      添加背景图片

      //从SpriteFrameCache中加载图片

      auto sprite_background = Sprite::createWithSpriteFrameName("mainmenu_bg.png");

      //设置位置

      sprite_background->setPosition(Point(visibleSize.width/2,visibleSize.height/2));

      //添加背景,Zorder设置为-1为此场景最底层

      addChild(sprite_background,-1);

      然后添加kingdom Rush Logo

      sprite_Logo = Sprite::createWithSpriteFrameName("logo.png");

      //计算Logo图应该在的位置

      point_Logo.x = visibleSize.width/2,visibleSize.height;

      point_Logo.y = visibleSize.height-(sprite_Logo->getContentSize().height/2);

      //设置位置,初始大小

      sprite_Logo->setScale(0.2f);

      sprite_Logo->setPosition(point_Logo);

      addChild(sprite_Logo,1);

      这样LOGO就显示在了背景图片之上,初始大小为0.2倍,给它设置一个ScaleTo的动画例如ScaleTo::create(0.5,1.5,1.5),然后播放即可。

      在LOGO缩放动画完成后,会有Kingdom从左到右闪烁的动画,通过查看原游戏资源图片发现这是一个帧动画,每一帧的图片已经保存在plist当中,通过播放帧动画即可实现效果。

      //从资源中加图片,设置位置

      auto sprite = Sprite::createWithSpriteFrameName("logo_brillo_0001.png");

      sprite->setPosition(point_Logo);

      //生成帧动画

      SpriteFrame* frame = NULL;

      Vector aFrames(20);

      for (int len = 1;len spriteFrameByName(String::createWithFormat("logo_brillo_00d.png",len)->getCString());

      if(frame!=nullptr)

      aFrames.pushBack(frame);

      }

      addChild(sprite,2);

      auto animation = Animation::createWithSpriteFrames(aFrames,0.1f);

      //播放动画

      sprite->runAction(RepeatForever::create(Animate::create(animation)));

      动画RepeatForever::create创建一个不间断播放的动画,放置在Logo上覆盖,动画效果完成。

      创建一个动画序列Sequence,在序列中加入logo的缩放动画和帧动画,即可在logo缩放动画完成之后链接上帧动画,达到原有游戏效果。

      接下来是开始按键的生成以及动画。

      Cocos2d-x中,可以采用MenuItemSprite来定义一个精灵按键,方便设置按键效果以及监听。

      本文采用给Sprite添加监听的方式来实现一个按键,首先是加载资源图片,在上述动画序列Sequence的最后再添加一个开始按键的下移动画MoveTo即可实现,代码略。

      创建一个监听:

      auto button_Start_listener = EventListenerTouchOneByOne::create();

      设置onTouchBegan即点击后的相应

      button_Start_listener->onTouchBegan = [&](Touch* touch, Event* event){

      //获取点击目标

      auto target = static_cast(event->getCurrentTarget());

      //获取将世界坐标中触摸点转换为模型坐标后的点击坐标

      Point locationInNode = target->convertTouchToNodeSpace(touch);

      //获取目标的大小

      Size size = target->getContentSize();

      //创建rect区域

      Rect rect = Rect(0+40, 0+30, size.width-80, size.height/3 +15);

      //当点击坐标在区域内时

      if (rect.containsPoint(locationInNode))

      {

      //改变Button式样达到点击效果

      target->setDisplayFrame(SpriteFrameCache::getInstance()->spriteFrameByName("menu_startchain_0002.png"));

      return true;

      }

      return false;

      };

      因为点击整个场景的所有精灵时,都会依次执行所有的EventListenerTouchOneByOne,所以需要在onTouchBegan中加入对点击区域的判断,以此来判断是否点击在所需精灵中,rect即精灵所在区域,这里对原有精灵的rect进行了修正,即去掉START按键中链子以及其他的部分,当点击是,改变改精灵的图片,达到点击效果。

      设置点击后释放动作监听

      button_Start_listener->onTouchEnded = [&](Touch* touch, Event* event){

      auto target = static_cast(event->getCurrentTarget());

      static_cast(event->getCurrentTarget())->setDisplayFrame(SpriteFrameCache::getInstance()->spriteFrameByName("menu_startchain_0001.png"));

      button_Start->runAction(MoveTo::create(0.3f, Point(point_Logo.x,point_Logo.y)));

      button_Start->setVisible(false);

      setSaveMenuVisible();

      };

      点击后开始按键MoveTo到Logo后,隐藏,然后将开始游戏菜单上移。

      三个“NEW GAME”的背景图片是一个SPRITE,"CLOSE"按键设置监听方式与上述开始按键类似,也可使用MenuItemSprite方式,当点击开始按键后,给这些精灵添加MoveTo动画,移动到场景上。

      “NEW GAME”采用新建一个自定义精灵的方式:

      class SlotMenu : public Sprite

      {

      public:

      SlotMenu();

      ~SlotMenu();

      virtual bool initWithNum(int num);

      CREATE_FUNC(SlotMenu);

      void button_Savelot_Delete_callback(Ref* Psender);

      void conform_delete(Ref* pSender);

      void cancel_delete(Ref* pSender);

      void createNewGame();

      static SlotMenu* createMenu(int num);

      protected:

      Label* label_hint;

      MenuItemSprite* button_Savelot_Delete;

      Sprite* savelot;

      };

      首先我们自定义一个创建方法:

      SlotMenu* SlotMenu::createMenu(int num)

      {

      auto slotMenu = new SlotMenu();

      if (slotMenu && slotMenu->initWithNum(num))

      {

      slotMenu->autorelease();

      return slotMenu;

      }

      CC_SAFE_DELETE(slotMenu);

      return NULL;

      }

      其中num为传入参数,设置为3个NEW GAME中的哪一个按键。

      在initWithNum(int num)中,依次添加所有精灵。

      通过UserDefault::getInstance()->getBoolForKey方式设置某个记录游戏是否开始,若存在则显示当前记录并且将X按键显示如右图,所不存在则显示NEW GAME。

      点击X按键,显示“DELETE SLOT”和两个按键,例如删除按键:

      auto confirm_Delete = MenuItemSprite::create(Sprite::createWithSpriteFrameName("mainmenu_saveslot_confirmdelete_0001.png"),

      Sprite::createWithSpriteFrameName("mainmenu_saveslot_confirmdelete_0001.png"),

      CC_CALLBACK_1(SlotMenu::conform_delete, this));

      以及该按键监听:

      void SlotMenu::conform_delete(Ref* pSender)

      {

      savelot->getChildByTag(LABEL_HINT)->setVisible(false);

      savelot->removeChildByTag(NEWGAME);

      createNewGame();

      char temp[20];

      sprintf(temp, "is_savelot_%d_exit", this->num);

      UserDefault::getInstance()->setBoolForKey(temp,false);

      }

      文字采用Label方式创建,3个按键采用MenuItemSprite方式设置监听以及点击效果,监听内设置逻辑判断哪一项该隐藏哪一项该显示,具体代码略。

      将整个精灵的底层精灵设置监听,点击后跳转到新游戏界面

      if (rect.containsPoint(locationInNode)&&!savelot->getChildByTag(LABEL_HINT)->isVisible())

      {

      target->setDisplayFrame(SpriteFrameCache::getInstance()->spriteFrameByName("mainmenu_saveslot_0002.png"));

      return true;

      }

课课家教育

未登录