Cocos Studio1.5.0.1开发学习笔记(一)
听说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-x工程中使用Studio制作的动画。
首先在Cocos2d-x的根目录下找到cocos2d-x-3.2\cocos\editor-support目录,将cocostudio目录以及其包含的文件复制到你新建工程所在目录下。然后用vs打开新建的项目,右击解决方案-》添加-》现有项目,把cocostudio添加进工程。接着右键你的工程-》属性-》c\c++-》常规-》附加包含目录,把cocostudio的目录导入进去。最后接着右键你的工程-》属性-》通用属性-》引用-》添加新引用。
现在我们可以开始写代码了,首先要设计有个Hero类,用他来播放动画,代码如下:
#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函数加载一个站立时的动画:
#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 / , size.height / ));
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 * ;
setPositionX(getPositionX() - dis);
}
void Hero::runRight(float dt)
{
float dis = dt * ;
setPositionX(getPositionX() + dis);
}
void Hero::attack()
{
armature->getAnimation()->play("attack");
}
void Hero::death()
{
armature->getAnimation()->play("death");
}
接着我们需要一个场景类,让我们的Hero在这个场景里面动起来:
#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() = ;
};
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文件:
#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/ ,
origin.y + closeItem->getContentSize().height/)); // create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, ); /////////////////////////////
// 3. add your codes below... // add a label shows "Hello World"
// create and initialize a label auto label = LabelTTF::create("Hello World", "Arial", ); // position the label on the center of the screen
label->setPosition(Vec2(origin.x + visibleSize.width/,
origin.y + visibleSize.height - label->getContentSize().height)); // add the label as a child to this layer
this->addChild(label, );
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() / );
menu->exm = this;
addChild(menu);
} void HelloWorld::moveRight()
{
if (hero->dir == NONE)
hero->armature->getAnimation()->play("run");
float num = hero->armature->getRotationY();
if (num == -)
{
hero->armature->setRotationY();
}
hero->dir = RIGHT;
}
void HelloWorld::moveLeft()
{
if (hero->dir == NONE)
hero->armature->getAnimation()->play("run");
float num = hero->armature->getRotationY();
if (num == )
{
hero->armature->setRotationY(-);
}
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 == )
{
hero->stop();
CCLOG("");
}
else if (num == -)
{
hero->stop();
hero->armature->setRotationY(-);
}
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();
#endif
}
运行后的效果如下:

Cocos Studio1.5.0.1开发学习笔记(一)的更多相关文章
- 驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址
驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址 最近重新看了乾龙_Heron的<ARM 上电启动及 Uboot 代码分析>(下简称<代码分析>) ...
- 【前端】移动端Web开发学习笔记【2】 & flex布局
上一篇:移动端Web开发学习笔记[1] meta标签 width设置的是layout viewport 的宽度 initial-scale=1.0 自带 width=device-width 最佳实践 ...
- Rest API 开发 学习笔记(转)
Rest API 开发 学习笔记 概述 REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表示方式.获得这些表徵致使这些应用程序转变了其状态.随着 ...
- 步步为营 SharePoint 开发学习笔记系列总结
转:http://www.cnblogs.com/springyangwc/archive/2011/08/03/2126763.html 概要 为时20多天的sharepoint开发学习笔记系列终于 ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Chrome扩展,应用开发学习笔记之2---恶搞百度一下
Chrome扩展,应用开发学习笔记之2 恶搞百度一下 前面我们介绍了一个最简单的chrome扩展时钟,如今我来介绍一下一个恶搞百度一下的chrome扩展程序. 前面说过,manifest.json文件 ...
- 转载:使用Xilinx IP核进行PCIE开发学习笔记(一)简介篇
https://zhuanlan.zhihu.com/p/32786076 最近接触到一个项目,需要使用PCIE协议,项目要求完成一个pcie板卡,最终可以通过电脑进行通信,完成电脑发送的指令.这当中 ...
- 【前端】移动端Web开发学习笔记【1】
下一篇:移动端Web开发学习笔记[2] Part 1: 两篇重要的博客 有两篇翻译过来的博客值得一看: 两个viewport的故事(第一部分) 两个viewport的故事(第二部分) 这两篇博客探讨了 ...
- android开发学习笔记000
使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...
随机推荐
- iOS 多线程学习笔记 —— GCD
本文复制.参考自文章:iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http:// ...
- leetcode 最大矩形和
1.枚举法(超时) public class Solution { public int largestRectangleArea(int[] height) { int max=-1; for(in ...
- win8.1 无法安装 net framework3.5的解决办法
近期给重装系统时,发现Windows8.1无法安装.net framework 3.5,即使我离线下载了安装文件,还要求安装2.0和3.0....而且无法从Windows更新中获取,因此百度到以下方案 ...
- js判断是否为手机浏览器
JS判断手机浏览器 判断原理: JavaScript是前端开发的主要语言,我们可以通过 编写JavaScript程序来判断浏览器的类型及版本.JavaScript判断浏览器类型一般有两种办法,一种是根 ...
- .net对js和css、img剥离项目进行压缩优化、cdn加速
由于网站首页以及经常用的页面初始化慢,想后面想了对image.js和css进行迁移优化. 1.把他放到独立的域名上面,这个就要对image,js和css从原项目上面脱离,以及把原来很多页面引用的地址修 ...
- Asp.net网站后台代码不能访问-iis部署
最近自己写了点东西,部署的时候确发生了点问题,后台代码访问不了,错误为:由于扩展配置问题而无法提供您请求的页面.如果该页面是脚本,请添加处理程序. 错误详细提示: HTTP 错误 404.3 - ...
- OMCS的语音视频带宽占用
OMCS的语音.视频.电子白板.远程桌面等功能对网络带宽的要求分别如何了? 我们先假设一种常见的场景:假设N个在线用户同时进行1对1的多媒体沟通(即分为N/2组),在不考虑P2P通道的情况下,带宽的大 ...
- jQuery Vlidate 演示样例
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 有关Transaction not successfully started问题解决的方法
我的项目配置:struts2+hibernate3.3+spring3.2.5 主要问题:在进行更新和提交操作时出现下面异常 org.springframework.transaction.Trans ...
- 检查Oracle 中死事务的语句
SQL> SELECT KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */ 2 KTUXESTA Status, KTUXECFL Flags ...