七、Cocos Studio学习必看

来源:互联网 发布:寿光网络问政平台 编辑:程序博客网 时间:2024/05/31 18:52

目前看来Cocos2d-x播放动画的方式只有2种:

  • 第一种:是播放序列帧动画,即将动画的每一帧都加载进缓存里,需要播放时再使用Animation类来播放,这种方法简单暴力,应对一些细节要求低的动画场景的时候,这么干无伤大雅。但是当动画帧数稍高的时候就会需要大量的图片,消耗资源很大。

  • 第二种:是由Cocos2d-x提供的Action类来播放动画,这种动画是在帧循环中靠调整每次渲染的坐标来打到动画效果,由于帧循环是1/60秒刷新一次,会让这样播放的动画非常流畅,而且不需要每一帧图片的资源。这种方案的缺点是播放动画的节点只能加载一张图片资源,当我们要实现一个如下的动画时,

1408342959895802.jpg

如果单从代码实现需要创建多个精灵,还要绑定各个精灵之间的协调和联动,总之会非常非常的麻烦。


骨骼动画可以兼容以上两种方法的优点,同时不包含它们的缺点。所以现在越来越多的公司使用Cocos Studio来制作动画。


要使用CocosStudio首先要到官网下载你需要的Studio版本,由于Cocos2d-x引擎本身的版本迭代速度比较快,有些版本的Studio并不能与引擎兼容,这里附上论坛上一个较为详细的版本对应下载。我使用的是刚发布不久的3.2版引擎,Cocos  Studio1.5.0.1能够对其兼容。


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

  • 第一是学会制作骨骼动画,这个链接里有详细的描述,跟着一步一步来就可以了,我就不做复述了。

  • 第二是在Cocos2d-x工程中使用Studio制作的动画。


首先在Cocos2d-x的根目录下找到cocos2d-x-3.2\cocos\editor-support目录,将cocostudio目录以及其包含的文件复制到你新建工程所在目录下。然后用vs打开新建的项目,右击解决方案-》添加-》现有项目,把cocostudio添加进工程。接着右键你的工程-》属性-》c\c++-》常规-》附加包含目录,把cocostudio的目录导入进去。最后接着右键你的工程-》属性-》通用属性-》引用-》添加新引用。


现在我们可以开始写代码了,首先要设计有个Hero类,用他来播放动画,代码如下:

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


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

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


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

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


以下是场景类的cpp文件:

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


来源网址:http://blog.csdn.net/wxq_wuxingquan/article/details/38615183

0 0
原创粉丝点击