• Cocos2d-x 3.1.1 学习日志14--CocosStudio学习必看


    听说Cocos Studio非常久了,主要是由于骨骼动画。眼下看来Cocos2d-x播放动画的方式仅仅有2种:

      第一种:是播放序列帧动画,即将动画的每一帧都载入进缓存里,须要播放时再使用Animation类来播放,这样的方法简单暴力。应对一些细节要求低的动画场景的时候。这么干无伤大雅。

    可是当动画帧数稍高的时候就会须要大量的图片,消耗资源非常大。

      另外一种:是由Cocos2d-x提供的Action类来播放动画,这样的动画是在帧循环中靠调整每次渲染的坐标来打到动画效果。因为帧循环是1/60秒刷新一次,会让这样播放的动画很流畅,并且不须要每一帧图片的资源。这样的方案的缺点是播放动画的节点仅仅能载入一张图片资源。当我们要实现一个例如以下的动画时,

    假设单从代码实现须要创建多个精灵,还要绑定各个精灵之间的协调和联动,总之会很很的麻烦。

      骨骼动画能够兼容以上两种方法的长处,同一时候不包括它们的缺点。所以如今越来越多的公司使用Cocos Studio来制作动画。

          要使用Cocos Studio 首先要到官网 http://cn.cocos2d-x.org/download 下载你须要的Studio 版本号。因为Cocos2d-x引擎本身的版本号迭代速度比較快,有些版本号的Studio并不能与引擎兼容。这里附上论坛上一个较为具体的版本号相应下载 http://www.cocoachina.com/bbs/read.php?tid=154886。我使用的是刚公布不久的3.2版引擎。Cocos Studio 1.5.0.1可以对其兼容。

      初次使用我想完毕两个学习目标:

      第一是学会制作骨骼动画。http://www.cocoachina.com/bbs/read.php?

    tid=189665 这个链接里有具体的描写叙述。跟着一步一步来就能够了。我就不做复述了。

    (小插曲:我在试用mac版本号刚公布的studio时发现了非常多Bug,建议大家还是在window平台下使用)

      第二是在Cocos2d-xproject中使用Studio制作的动画。

      首先在Cocos2d-x的根文件夹下找到cocos2d-x-3.2cocoseditor-support文件夹,将cocostudio文件夹以及其包括的文件拷贝到你新建project所在文件夹下。然后用vs打开新建的项目。右击解决方式-》加入-》现有项目,把cocostudio加入进project。

    接着右键你的project-》属性-》cc++-》常规-》附加包括文件夹,把cocostudio的文件夹导入进去。最后接着右键你的project-》属性-》通用属性-》引用-》加入新引用。

      如今我们能够開始写代码了,首先要设计有个Hero类。用他来播放动画,代码例如以下:

     1 #ifndef __HERO_H__
     2 #define __HERO_H__
     3 #include "cocos2d.h"
     4 #include "cocos-ext.h"
     5 #include "CocoStudio.h"
     6 USING_NS_CC;
     7 using namespace cocostudio;
     8 USING_NS_CC_EXT;
     9 enum DIRECTION { LEFT, RIGHT, NONE };
    10 class Hero:public Sprite
    11 {
    12 public:
    13     CREATE_FUNC(Hero);
    14     bool init();
    15     void runLeft(float dt);
    16     void runRight(float dt);
    17     void attack();
    18     void death();
    19     void stop();
    20 
    21     DIRECTION dir;
    22     Size size;
    23     Armature* armature;
    24     bool isAniRunLeft;
    25     bool isAniRunRight;
    26 };
    27 #endif

       我们在Hero的init函数里初始化动画,并调用一个stop函数载入一个站立时的动画:

     1 #include "Hero.h"
     2 
     3 bool Hero::init()
     4 {
     5     Sprite::init();
     6     size = Director::getInstance()->getWinSize();
     7     ArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("Hero0.png", "Hero0.plist", "Hero.ExportJson");
     8     armature = Armature::create("Hero");
     9     armature->setScale(0.7f);
    10     armature->setPosition(Vec2(size.width / 2, size.height / 2));
    11     addChild(armature);
    12     stop();
    13     
    14     dir = NONE;
    15     isAniRunLeft = false;
    16     isAniRunRight = false;
    17     return true;
    18 }
    19 void Hero::stop()
    20 {
    21     armature->getAnimation()->play("loading");
    22 }
    23 void Hero::runLeft(float dt)
    24 {
    25     float dis = dt * 200;
    26     setPositionX(getPositionX() - dis);
    27 }
    28 void Hero::runRight(float dt)
    29 {
    30     float dis = dt * 200;
    31     setPositionX(getPositionX() + dis);
    32 }
    33 void Hero::attack()
    34 {
    35     armature->getAnimation()->play("attack");
    36 }
    37 void Hero::death()
    38 {
    39     armature->getAnimation()->play("death");
    40 }

      接着我们须要一个场景类。让我们的Hero在这个场景里面动起来:

     1 #ifndef __HELLOWORLD_SCENE_H__
     2 #define __HELLOWORLD_SCENE_H__
     3 
     4 #include "cocos2d.h"
     5 #include "cocos-ext.h"
     6 #include "CocoStudio.h"
     7 #include "Hero.h"
     8 USING_NS_CC_EXT;
     9 class menuDelegate
    10 {
    11 public:
    12     virtual void stopstate() = 0;
    13 };
    14 class Panel :public Menu
    15 {
    16 public:
    17     menuDelegate* exm;
    18     MenuItem* getSelectItem()
    19     {
    20         return _selectedItem;
    21     }
    22     static Panel* create()
    23     {
    24         Panel* ret = new Panel;
    25         ret->init();
    26         ret->autorelease();
    27         return ret;
    28     }
    29     bool init()
    30     {
    31         Menu::init();
    32         scheduleUpdate();
    33         return true;
    34     }
    35     void update(float dt)
    36     {
    37         if (this->getSelectItem() && this->getSelectItem()->isSelected())
    38             this->getSelectItem()->activate();
    39         else
    40         {
    41             exm->stopstate();
    42         }
    43     }
    44 };
    45 class HelloWorld : public cocos2d::Layer,public menuDelegate
    46 {
    47 public:
    48     // there's no 'id' in cpp, so we recommend returning the class instance pointer
    49     static cocos2d::Scene* createScene();
    50 
    51     // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    52     virtual bool init();
    53 
    54     // a selector callback
    55     void menuCloseCallback(cocos2d::Ref* pSender);
    56 
    57     // implement the "static create()" method manually
    58     CREATE_FUNC(HelloWorld);
    59 
    60     void stopstate();
    61     void update(float dt);
    62     void moveRight();
    63     void moveLeft();
    64     void moveAttack();
    65     void moveDead();
    66     void loadMenu();
    67     Hero* hero;
    68     Panel* menu;
    69 };
    70 #endif // __HELLOWORLD_SCENE_H__

      下面是场景类的cpp文件:

      1 #include "HelloWorldScene.h"
      2 
      3 USING_NS_CC;
      4 using namespace cocostudio;
      5 Scene* HelloWorld::createScene()
      6 {
      7     // 'scene' is an autorelease object
      8     auto scene = Scene::create();
      9     
     10     // 'layer' is an autorelease object
     11     auto layer = HelloWorld::create();
     12 
     13     // add layer as a child to scene
     14     scene->addChild(layer);
     15 
     16     // return the scene
     17     return scene;
     18 }
     19 
     20 // on "init" you need to initialize your instance
     21 bool HelloWorld::init()
     22 {
     23     //////////////////////////////
     24     // 1. super init first
     25     if ( !Layer::init() )
     26     {
     27         return false;
     28     }
     29     
     30     Size visibleSize = Director::getInstance()->getVisibleSize();
     31     Vec2 origin = Director::getInstance()->getVisibleOrigin();
     32 
     33     /////////////////////////////
     34     // 2. add a menu item with "X" image, which is clicked to quit the program
     35     //    you may modify it.
     36 
     37     // add a "close" icon to exit the progress. it's an autorelease object
     38     auto closeItem = MenuItemImage::create(
     39                                            "CloseNormal.png",
     40                                            "CloseSelected.png",
     41                                            CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
     42     
     43     closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
     44                                 origin.y + closeItem->getContentSize().height/2));
     45 
     46     // create menu, it's an autorelease object
     47     auto menu = Menu::create(closeItem, NULL);
     48     menu->setPosition(Vec2::ZERO);
     49     this->addChild(menu, 1);
     50 
     51     /////////////////////////////
     52     // 3. add your codes below...
     53 
     54     // add a label shows "Hello World"
     55     // create and initialize a label
     56     
     57     auto label = LabelTTF::create("Hello World", "Arial", 24);
     58     
     59     // position the label on the center of the screen
     60     label->setPosition(Vec2(origin.x + visibleSize.width/2,
     61                             origin.y + visibleSize.height - label->getContentSize().height));
     62 
     63     // add the label as a child to this layer
     64     this->addChild(label, 1);
     65     loadMenu();
     66     hero = Hero::create();
     67     addChild(hero);
     68     scheduleUpdate();
     69     return true;
     70 }
     71 void HelloWorld::update(float dt)
     72 {
     73     if (hero->dir == RIGHT)
     74     {
     75         hero->runRight(dt);
     76     }
     77     if (hero->dir == LEFT)
     78     {
     79         hero->runLeft(dt);
     80     }
     81 }
     82 void HelloWorld::loadMenu()
     83 {
     84     Size size = Director::getInstance()->getWinSize();
     85     auto closeItem1 = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_0(HelloWorld::moveLeft, this));
     86     auto closeItem2 = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_0(HelloWorld::moveRight, this));
     87     auto closeItem3 = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_0(HelloWorld::moveAttack, this));
     88     auto closeItem4 = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_0(HelloWorld::moveDead, this));
     89     menu = Panel::create();
     90     menu->addChild(closeItem1);
     91     menu->addChild(closeItem2);
     92     menu->addChild(closeItem3);
     93     menu->addChild(closeItem4);
     94     menu->alignItemsHorizontally();
     95     menu->setPositionY(menu->getPositionY() / 2);
     96     menu->exm = this;
     97     addChild(menu);
     98 }
     99 
    100 void HelloWorld::moveRight()
    101 {
    102     if (hero->dir == NONE)
    103         hero->armature->getAnimation()->play("run");
    104     float num = hero->armature->getRotationY();
    105     if (num == -180)
    106     {
    107         hero->armature->setRotationY(0);
    108     }
    109     hero->dir = RIGHT;
    110 }
    111 void HelloWorld::moveLeft()
    112 {
    113     if (hero->dir == NONE)
    114         hero->armature->getAnimation()->play("run");
    115     float num = hero->armature->getRotationY();
    116     if (num == 0 )
    117     {
    118         hero->armature->setRotationY(-180);
    119     }
    120     hero->dir = LEFT;
    121 }
    122 void HelloWorld::moveDead()
    123 {
    124     hero->death();
    125 }
    126 void HelloWorld::moveAttack()
    127 {
    128     hero->attack();
    129 }
    130 void HelloWorld::stopstate()
    131 {
    132     if (hero->dir == NONE)
    133         return;
    134     float num = hero->armature->getRotationY();
    135     if (num == 0)
    136     {
    137         hero->stop();
    138         CCLOG("111111");
    139     }
    140     else if (num == -180)
    141     {
    142         hero->stop();
    143         hero->armature->setRotationY(-180);
    144     }
    145     hero->dir = NONE;
    146 }
    147 void HelloWorld::menuCloseCallback(Ref* pSender)
    148 {
    149 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
    150     MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    151     return;
    152 #endif
    153 
    154     Director::getInstance()->end();
    155 
    156 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    157     exit(0);
    158 #endif
    159 }
    
    

    结束!!

    。。


    本人cocos2dx 2.x和3.x的源代码淘宝地址(欢迎大家光顾):https://shop141567464.taobao.com/?spm=a313o.7775905.1998679131.d0011.pzUIU4

  • 相关阅读:
    《WF in 24 Hours》读书笔记
    《WF in 24 Hours》读书笔记
    《Sams Teach Yourself Windows® Workflow Foundation in 24 Hours》读书笔记目录
    Oops, 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine error
    RemoteViews嵌入ListView复杂布局
    Mysql访问 for橙子小海
    Android中AppWidget的分析与应用:AppWidgetProvider .
    Android 常用网站
    linux下vi命令大全
    最优秀的5个Linux文本编辑器
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5122685.html
Copyright © 2020-2023  润新知