七、Cocos Studio学习必看

目前看来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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值