码迷,mamicode.com
首页 > 其他好文 > 详细

Cocos2d-x 3.2 学习笔记(十四)保卫萝卜之界面UI

时间:2015-01-16 12:53:25      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:

     保卫萝卜~上一篇说了使用CocoStudio制作主界面,这里来完善主界面动画及后续界面(主题界面ThemeUI、场景选择界面SelectMapUI),主要涉及的控件PageView。
  学习要写笔记,记录自己的步骤(练手作)。
一、主界面动画
 
     上一篇的主界面是静态的,这样很不好看。如果有玩过保卫萝卜就知道它的主界面是动的,云啊、叶子啊都在动,OK加几行代码来实现。
先看效果图:
技术分享
  加入如下代码:
bool MenuScene :: init()
{
      if ( !Layer :: init() )
      {
           return false ;
      }
    
    
      cocos2d ::ui :: Widget* layout = cocostudio ::GUIReader :: getInstance()-> widgetFromJsonFile ("MainUi.json" );
      this ->addChild ( layout);
      Button * btnAdventure = ( Button*) layout ->getChildByName ( "btnAdventure");
      Button * btnBossHome = ( Button*) layout ->getChildByName ( "btnBossHome");
      Button * btnBoss = ( Button*) layout ->getChildByName ( "btnBoss");
      btnAdventure ->addTouchEventListener ( this, toucheventselector (MenuScene :: btnClick));
      btnBossHome ->addTouchEventListener ( this, toucheventselector (MenuScene :: btnClick));
      btnBoss ->addTouchEventListener ( this, toucheventselector (MenuScene :: btnClick));
    
      ImageView * cloud1 = ( ImageView*) layout ->getChildByName ( "cloud1");
      ImageView * cloud2 = ( ImageView*) layout ->getChildByName ( "cloud2");
      Vec2 size = Director ::getInstance ()-> getVisibleSize();
      cloud1 ->runAction ( RepeatForever:: create (Sequence :: create( MoveBy ::create ( 10,
           Vec2 (size . x+ cloud1 ->getCustomSize (). width, 0 )),Place :: create( Vec2 (0 , cloud1-> getPositionY ())),nullptr )));
      cloud2 ->runAction ( RepeatForever:: create (Sequence :: create( MoveBy ::create ( 20,
           Vec2 (size . x+ cloud2 ->getCustomSize (). width, 0 )),Place :: create( Vec2 (0 , cloud2-> getPositionY ())),nullptr )));
      ImageView * bird = ( ImageView*) layout ->getChildByName ( "bird");
      bird ->runAction ( RepeatForever:: create (
           Sequence ::create (
           MoveBy ::create ( 1, Vec2 (0 , 50)),
           MoveBy ::create ( 1, Vec2 (0 ,- 50)), nullptr )));

      ImageView * leaf2 = ( ImageView*) layout ->getChildByName ( "leaf2");
      ImageView * leaf3 = ( ImageView*) layout ->getChildByName ( "leaf3");
      RotateTo * rotateTo = RotateTo:: create (0.1f , 20);
      RotateTo * rotateTo2 = RotateTo:: create (0.1f , 0);
      leaf2 ->runAction ( RepeatForever:: create (
           Sequence ::create (
           Repeat ::create ( Sequence:: create (rotateTo , rotateTo2, nullptr ),2 ),
           DelayTime ::create ( 5), nullptr )));
      leaf3 ->runAction ( RepeatForever:: create (
           Sequence ::create (
           DelayTime ::create ( 8),
           Repeat ::create ( Sequence:: create (rotateTo , rotateTo2, nullptr ),2 ),
           DelayTime ::create ( 4), nullptr )));

      return true ;
}
  OK,加入动作表现之后界面利马生动起来。
 
二、主题选择
 
  1、场景UI制作
     菜单部分使用PageView控件,这个控件是翻页效果,先看效果:
技术分享
 
     在CocoStudio中创建ThemeUI并使用PageView控件如:
 
技术分享
技术分享
 
  2、加入舞台
  这里有五个页面,分别是
  天际主题、森林主题、沙漠主题、海底主题、未开放的极地,
  每个页面下面的sign标签是通关数和总关卡数,这里是需要变动的。
  PageView控件可以使用手指滑动,也要有按钮的互动,因此有两个左右按钮,点击左上角的home会返回主界面。
  首先,把导出的json文件加至舞台,添加事件以及默认页:
cocos2d::ui::Widget* layout = cocostudio::GUIReader::getInstance()->widgetFromJsonFile("ThemeUI/ThemeUI.json");
  this->addChild(layout);

  Button* btnMenu = (Button*)layout->getChildByName("btnMenu");
  _btnLeft = (Button*)layout->getChildByName("btnLeft");
  _btnRight = (Button*)layout->getChildByName("btnRight");
  btnMenu->addTouchEventListener(this,toucheventselector(ThemeScene::btnClickMenu));
  _btnLeft->addTouchEventListener(this,toucheventselector(ThemeScene::btnClickLeft));
  _btnRight->addTouchEventListener(this,toucheventselector(ThemeScene::btnClickRight));

  _pageView = (PageView*)layout->getChildByName("pageView");
  _pageView->addEventListenerPageView(this,pagevieweventselector(ThemeScene::pageEvent));
  int index = _pageView->getPages().size();
  while (index-->0)
  {
    Layout* pageIndex = (Layout*)_pageView->getPage(index);
    pageIndex->setUserData((int*)index);
    pageIndex->addTouchEventListener(this,toucheventselector(ThemeScene::layputEvent));
  }
  changePage( 0 );
  这里有两个事件  1、PageView的翻动事件。2、点击PageView子页的事件
  这里有两个注意点
  1、翻动PageView要与按钮对应,首页左向按钮消失,尾页右向按钮消失
  2、点击按钮翻动PageView
void ThemeScene::btnClickLeft(Button* btn, TouchEventType eventType)
{
  if( eventType == TOUCH_EVENT_ENDED )
  {
    auto nextPage = _pageView->getCurPageIndex() - 1;
    changePage( nextPage );
  }
}

void ThemeScene::btnClickRight(Button* btn, TouchEventType eventType)
{
  if( eventType == TOUCH_EVENT_ENDED )
  {
    auto nextPage = _pageView->getCurPageIndex() + 1;
    changePage( nextPage );
  }
}

void ThemeScene::changePage( int index )
{
  auto totalPage = _pageView->getPages().size();
  _btnLeft->setVisible( index != 0 );
  _btnRight->setVisible( index != ( totalPage-1 ) );

  if( index == _pageView->getCurPageIndex() ) return;

  if( index >= 0 && index <= totalPage-1 )
  {
    _pageView->scrollToPage( index );
  }
}

void ThemeScene::pageEvent(Ref* page,PageViewEventType type)
{
  log("EventType");
  changePage( _pageView->getCurPageIndex() );
}
  这样不管是按钮还是触摸都可以正确的显示按钮状态。
 
  3、场景选择处理
  在初始化PageView子页的时候加入了标记数据UserData,这个数据表示我们选择的场景类型
enum MapType
{
  Sky_Type,
  Forest_Type,
  Desert_Type,
  Seabed_Type,
  Max_Type
};
  这里的场景类型在后面的逻辑中是非常重要的数据,因此要找个地方去存储。
  选择主题事件触发
void ThemeScene::layputEvent(Layout* layout, TouchEventType eventType)
{
  if( eventType == TOUCH_EVENT_ENDED )
  {
    int sign = (int)layout->getUserData();
    log("layputEvent  %d",(int)layout->getUserData());
    if( sign >= 0 && sign < MapType::Max_Type )
    {
      auto type = MapType((int)layout->getUserData());
      SelectMapModel::getInstance()->setmapType(type);
      Director::getInstance()->replaceScene(SelectMapUI::createScene());
    }
    else
    {
      log("not open");
    }
  }
}
  Ok这样就没有任何问题了。目前关于数据记录的方法还没有完全想好,所以子页的sign显示就是默认的。
三、地图选择
 
     1、场景UI制作
技术分享
  场景类型MapType对应【1、2、3、6】
技术分享
技术分享
技术分享
 
  这里也有一个PageView,这里面我只做了一个pageItem,所有的地图子页都是一样的,可以用代码clone一下。当然每个场景的资源名字都是一样的,根据地图类型进行了区分。
  OK,看下效果吧:
技术分享
 
 
   2、初始化地图
     首先,Json文件加入舞台,然后加入事件,初始化PageView。先拿到一个PageView子页,然后去初始化子页再clone添加至PageView
_pageView = (PageView*)layout->getChildByName("panelSky")->getChildByName("pageView");
  Layout* item = (Layout*)_pageView->getChildByName("pageItem");
  item->removeFromParent();
  _pageView->removeAllPages();
  int count = SelectMapModel::getInstance()->getMapCount(SelectMapModel::getInstance()->getmapType());
  for (int idx = 1; idx <= count; idx++)
  {
    createOnlyPage(_pageView,item,idx);
  }

void SelectMapUI::createOnlyPage(PageView* page,Layout* item, int idx)
{
  std::string url = SelectMapModel::getInstance()->getMapResPath(SelectMapModel::getInstance()->getmapType());
  ImageView* mapImg = (ImageView*)item->getChildByName("mapImg");
  ImageView* towers = (ImageView*)item->getChildByName("towers");
  
  mapImg->loadTexture(url+StringUtil::combination("ss_map%02d.png",idx));
  towers->loadTexture(url+StringUtil::combination("ss_towers_%02d.png",idx));

  page->addPage((Layout*)item->clone());
}
  其中自写StringUtil::combination是字符组合类,图片的路径都是通过MapType类决定的,根据选择不同的主题来决定地图数及图片路径。
  ”开始“按钮,根据选择的地图来决定战斗场景的初始化。
void SelectMapUI::btnClick(Button* btn, TouchEventType eventType)
{
  if( eventType == TOUCH_EVENT_ENDED )
  {
    log("click btn is %s",btn->getName().c_str());
    int sceneID = _pageView->getCurPageIndex() + 1;
    SceneMgr::getInstance()->replaceScene(sceneID);
  }
}
四、最新进度
 
     目前,数据库、场景都已构架完毕,可以看下效果了。(地图太多了……时间不充裕目前只做了一个场景)
技术分享

Cocos2d-x 3.2 学习笔记(十四)保卫萝卜之界面UI

标签:

原文地址:http://www.cnblogs.com/Richard-Core/p/4228124.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!