您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x3.1.1动画制作编辑核心代码

2014-07-09 12:58 218 查看
其实已经有人写了相关的博客了,该作者也给出了代码和详细操作过程,只不过那个版本有点久,所以不能直接用在新版本上。

这里先给一下那个链接:cocos2d-x动画制作(cocos2d-x2.1)

我这里只是将它修改到3.1.1版本能使用的程序。所以各种资源,还请从上述链接中下载,详细过程还请参照该文。

具体修改如下。

将该文中的14-19这几行,在3.1.1版本中,array和vector是不能等同的,所以做如下替换:

Vector<SpriteFrame*> walkFrames(8);
char str[100] = {0};
for (int i = 1; i <= 8; i++)
{
sprintf(str, "bear%1d.png",i);
auto frame = cache->getSpriteFrameByName( str );
walkFrames.pushBack(frame);
}


原因是:在 Cocos2d-x v3.0 beta 之前,存在另一个顺序性容器 cocos2d::CCArray,这将会被弃用。

关于cocos2d::Vector:

cocos2d::Vector<T> 是一个封装了动态大小的数组的顺序型容器。

它的元素是连续存储的,cocos2d::Vector<T> 的存储是自动处理的。其内部的数据结构实现实际上是STL标准的顺序型容器 std::vector。

cocos2d::Vector<T> 常用操作的复杂度(效率)如下:

随机访问 - 常量 0(1)

在末尾插入或者移除元素 - 分摊常量 0(1)

插入或移除元素 - cocos2d::Vector<T> 长度线性相关 O(n)

更详细的情参见:http://www.cocoachina.com/gamedev/cocos/2014/0504/8302.html

另外,23-28行也有点问题,以前的版本是什么情况我也没去探究,但是现在break必须在循环中或者switch中使用。所以修改如下:

_bear->runAction( RepeatForever::create( Animate::create(walkAnimation) ) );


下边给出完整的修改后的HelloWorldScene.cpp文件代码(里边我自己添加了移动的功能,点击小熊可以小小娱乐一下):

#include "HelloWorldScene.h"

USING_NS_CC;

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);

////////////////////////////////////////////////////////////////////////////////////////////////////////
// add bear animate
SpriteFrameCache *cache = SpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("Bears.plist");
_actors = SpriteBatchNode::create("Bears.png");
this->addChild(_actors);

_bear = Sprite::createWithSpriteFrameName("bear1.png");
Size winSize = Director::sharedDirector()->getWinSize();
_bear->setPosition(ccp(winSize.width - 140, winSize.height / 2 ));
_actors->addChild(_bear);
// 为每帧创建图片
Vector<SpriteFrame*> walkFrames(8);
char str[100] = {0};
for (int i = 1; i <= 8; i++)
{
sprintf(str, "bear%1d.png",i);
auto frame = cache->getSpriteFrameByName( str );
//CCSpriteFrame *frame = cache->getSpriteFrameByName(CCString::createWithFormat("bear%1d.png", i)->getCString());
walkFrames.pushBack(frame);
}

// 创建动画
auto *walkAnimation = Animation::createWithSpriteFrames(walkFrames, 1.0f / 12.0f);
_bear->runAction( RepeatForever::create( Animate::create(walkAnimation) ) );

////////////////////////////////////////////////////////////////////
/*下边这一段删掉则没有移动的功能*/
auto goleft = Sprite::create("CloseNormal.png");
auto goright = Sprite::create("CloseNormal.png");

// position the sprite on the center of the screen
goleft ->setPosition( ccp(40, 40) );
goright ->setPosition( ccp(winSize.width-40,40));

auto l = EventListenerTouchOneByOne::create();
l->setSwallowTouches(true);

l->onTouchBegan = [](Touch *touch, Event *event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());

Point locationInNode = target->convertToNodeSpace(touch->getLocation());
Size s = target->getContentSize();
Rect rect = Rect( 0 , 0 , s.width , s.height );

if( rect.containsPoint(locationInNode)){
log("sprite began... x = %f , y = %f ",locationInNode.x ,locationInNode.y );
target->setOpacity(255);
return true;
}
return false;
};////////////////

l->onTouchMoved = [](Touch *touch , Event * event ){};

l->onTouchEnded = []( Touch* touch ,Event *event ){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
auto s = Director::getInstance()->getWinSize();

//auto actionTo = MoveTo::create(2, Vec2(s.width-40, s.height-40));
auto actionTo = MoveTo::create(2, Vec2(160, s.height / 2));
auto actionBy = MoveBy::create(2, Vec2(-500,0));
auto actionByBack = actionBy->reverse();
//_bear->runAction( actionBy);
//_bear->runAction( actionByBack);
//_bear->runAction( actionTo);
if( target->getPositionX() > (s.width / 2) ){
target->runAction( actionBy);
}else{
target->runAction( actionByBack);
}

};
_eventDispatcher->addEventListenerWithSceneGraphPriority(l, _bear);
/*移动功能,截止处*/
return true;
}

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 Ap
901b
ps do not implement a close button.","Alert");
return;
#endif

Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}


则项目运行之后可达到上述2.1版本的所给的效果。

# 另外这里要提起一点:截止3.1.1版本,CCAnimation之类的,不需要再使用CC开头的,最好直接用Animation,可能使用CCAnimation也能编译通过,但是已经是warning,以后可能就是error了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息