zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    【Java EE 学习 81】【CXF框架】【CXF整合Spring】
    【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
    【Java EE 学习 80 上】【WebService】
    【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】
    【Java EE 学习 79 上】【mybatis 基本使用方法】
    【Java EE 学习 78 下】【数据采集系统第十天】【数据采集系统完成】
    【Java EE 学习 78 中】【数据采集系统第十天】【Spring远程调用】
    【Java EE 学习 78 上】【数据采集系统第十天】【Service使用Spring缓存模块】
    【Java EE 学习 77 下】【数据采集系统第九天】【使用spring实现答案水平分库】【未解决问题:分库查询问题】
    【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5122685.html
Copyright © 2011-2022 走看看