cocos2d-x学习笔记(7)--动作(Actions)
cocos2d-x学习笔记(7)--动作(Actions)
动作在cocos2d-x中可以说是精华部分(不是说其它的不好,而是这一部分内容特别丰富!!),作为重中之重,我们会分几个阶段来学习,先从简单的动作开始,然后通过组合简单的动作形成复杂动作。
一下就是我们将会用到的主要函数,函数有些多,但不一定全部要学,可以根据自己的需要来由选择性的学习。
1.Manual Transformation
2.MoveTo / MoveBy
3.RotateTo / RotateBy
4.JumpTo / JumpBy
5.Blink
6.FadeIn / FadeOut
7.Tint
8.Animation
9.Sequence: Move + Rotate
10.Sequence of InstantActions
step1:创建一个cocos2d-win32 application,并命名为action;
以下是我将用到的图片素材:
step2:
首先,定义一些如下常量和变量:
[cpp]
static int index = 1;//浏览到第几个动作
const int MAX_INDEX = 10;//总共要展示的动作种类数目
enum
{
MANUAL_ACTION = 1,
MOVE_ACTION,
ROTATE_ACTION,
JUMP_ACTION,
BLINK_ACTION,
FADE_ACTION,
TINT_ACTION,
ANIMATE_ACTION,
SEQUENCE_ACTION_1,
SEQUENCE_ACTION_2
};
创建一个基本的动作类(仅仅包含三个操作按钮),然后让其他的动作类继承此基础类,可以减少重复写按钮操作函数。
在HelloWorldScene.h中添加如下动作类:
[cpp]
class BasicActions:public CCLayer
{
protected:
CCSprite* m_player;
public:
virtual void onEnter();
virtual void onExit();
virtual std::string title();
void nextMenuCallback(CCObject* pSender);
void backMenuCallback(CCObject* pSender);
void restartMenuCallback(CCObject* psender);
};
//manual action
//基本的动作
class ActionManual:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//move action
//对象移动操作
class ActionMove:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//rotate action
//旋转动作
class ActionRotate:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//jump action
//跳跃动作
class ActionJump:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//blink action
//闪烁动作
class ActionBlink:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//fade action
//淡化动作
class ActionFade:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//tint action
//着色动作
class ActionTint:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//animate action
//动画(由帧组成)
class ActionAnimate:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//sequence action1
//连贯动作
class ActionSequence:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
};
//sequence action2
//连贯动作,带有事件响应
class ActionSequence2:public BasicActions
{
public:
virtual void onEnter();
virtual std::string title();
public:
void callback1();
void callback2();
};
由于在点击“back”、“next”两个按钮时会进行背景的切换,以更换动作:为了方便操作,我在HelloWorldScene.cpp中添加了一个函数用于操作对应动作类的创建:
[cpp]
CCLayer* runThisTest(int index)
{
CCLayer* pLayer = NULL;
switch (index)
{
case MANUAL_ACTION:
pLayer = new ActionManual(); break;
case MOVE_ACTION:
pLayer = new ActionMove();break;
case ROTATE_ACTION:
pLayer = new ActionRotate();break;
case JUMP_ACTION:
pLayer = new ActionJump();break;
case BLINK_ACTION:
pLayer = new ActionBlink();break;
case FADE_ACTION:
pLayer = new ActionFade();break;
case TINT_ACTION:
pLayer = new ActionTint();break;
case ANIMATE_ACTION:
pLayer = new ActionAnimate();break;
case SEQUENCE_ACTION_1:
pLayer = new ActionSequence();break;
case SEQUENCE_ACTION_2:
pLayer = new ActionSequence2();break;
}
return pLayer;
}
在runThisTest函数中index用来标记当前处于那个背景,以便创建响应的动作,这里我把BasicAction类中的成员函数定义罗列出来,方便大家理解runThisTest函数的用法:
[cpp]
void BasicActions::onEnter()
{
CCLayer::onEnter();
CCSize size = CCDirector::sharedDirector()->getWinSize();
//添加基本角色
m_player = CCSprite::spriteWithFile("player.png");
m_player->retain();//此处涉及到指针等内存管理机制,目前暂不展开做详细讨论,之后我会做一个专题来讲解这方面的知识
m_player->setPosition(ccp(size.width/2, size.height/2));
addChild(m_player, 1);
//添加标题
std::string strTitle = title();
const char* ptitle = strTitle.c_str();
CCLabelTTF* pLabel = CCLabelTTF::labelWithString(ptitle, "Arial", 30);
pLabel->setPosition(ccp(size.width/2, size.height-40));
addChild(pLabel);
//添加基本按钮
CCLabelTTF* pNextLabel = CCLabelTTF::labelWithString("Next ", "Arial", 30);
CCLabelTTF*pBackLabel = CCLabelTTF::labelWithString("Back ", "Arial", 30);
CCLabelTTF*pRestartLabel = CCLabelTTF::labelWithString("Restart ", "Arial", 30);
CCMenuItemLabel* pNextItem = CCMenuItemLabel::itemWithLabel(
pNextLabel, this, menu_selector(BasicActions::nextMenuCallback));
CCMenuItemLabel* pBackItem = CCMenuItemLabel::itemWithLabel(
pBackLabel, this, menu_selector(BasicActions::backMenuCallback));
CCMenuItemLabel* pRestartItem = CCMenuItemLabel::itemWithLabel(
pRestartLabel, this, menu_selector(BasicActions::restartMenuCallback));
CCMenu* pNextMenu = CCMenu::menuWithItem(pNextItem);
CCMenu* pBackMenu = CCMenu::menuWithItem(pBackItem);
CCMenu* pRestartMenu = CCMenu::menuWithItem(pRestartItem);
pNextItem->setPosition(ccp(size.width/2 +150, 50));
pBackItem->setPosition(ccp(size.width/2 - 150, 50));
pRestartItem->setPosition(ccp(size.width/2 , 50));
pNextMenu->setPosition(CCPointZero);
pBackMenu->setPosition(CCPointZero);
pRestartMenu->setPosition(CCPointZero);
addChild(pNextMenu,1);
addChild(pBackMenu, 1);
addChild(pRestartMenu,1);
}
void BasicActions::onExit()
{
m_player->release();
CCLayer::onExit();
}
std::string BasicActions::title()
{
return "";
}
void BasicActions::nextMenuCallback(CCObject* pSender)
{
if(index == MAX_INDEX)//已经是最后一个动作,不能再向下浏览
return ;
index++;
CCScene* scene = new CCScene();
//注意!!此处不能用CCScene::node(),node的释放方式是"autorelease",会与scene->release()重复
scene->addChild(runThisTest(index));
CCDirector::sharedDirector()->replaceScene(scene);
scene->release();
}
void BasicActions::backMenuCallback(CCObject* pSender)
{
if(index == 1)//index = 1表示上个动作不存在
return ;
index--;
CCScene* scene = new CCScene();
//注意!!此处不能用CCScene::node(),node的释放方式是"autorelease",会与scene->release()重复
scene->addChild(runThisTest(index));
CCDirector::sharedDirector()->replaceScene(scene);
scene->release();
}
void BasicActions::restartMenuCallback(CCObject* psender)
{
CCScene* scene = new CCScene();
scene->addChild(runThisTest(index ));
CCDirector::sharedDirector()->replaceScene(scene);
scene->release();
接下来,就只需把继承了BasicAction父类的子类全部补充完即可:
[cpp]
//Manual
void ActionManual::onEnter()
{
BasicActions::onEnter();
CCSize size = CCDirector::sharedDirector()->getWinSize();
//m_player->setScaleX(3.0f);//水平拉伸对象
//m_player->setScaleY(3.0);//垂直拉伸对象
//m_player->setPosition(ccp(200,200));改变对象的位置
//m_player->setOpacity(100);//设置透明度
//m_player->setRotation(120);//对对象进行旋转
//m_player->setColor(ccc3(255,0,0));//设置对象颜色
}
std::string ActionManual::title()
{
return "basic action function";
}
//move to / move by
void ActionMove::onEnter()
{
BasicActions::onEnter();
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCActionInterval* moveToAction = CCMoveTo::actionWithDuration(2,ccp(size.width - 50, size.height - 50));
//CCActionInterval是延时动作,与之对应的是CCActionInstant即时动作
//CCMoveTo每次执行都到达指定的地点
//actionWithDuration第一个参数是设置动作的时间(秒),第二个是动作最终的坐标位置
CCActionInterval* moveByAction = CCMoveBy::actionWithDuration(2,ccp(80, 80));
//CCMoveBy每次执行,x坐标增加80,y坐标增加80
CCActionInterval* moveBackAction = moveByAction->reverse();//按相反的方式返回,即x坐标减少80,y坐标减少80
//m_player->runAction(moveToAction);
//m_player->runAction(moveByAction);
//m_player->runAction(moveBackAction);
m_player->runAction(CCSequence::actions(moveByAction, moveBackAction, NULL));
}
std::string ActionMove::title()
{
return "MoveTo/MoveBy";
}
//rotate
void ActionRotate::onEnter()
{
BasicActions::onEnter();
CCActionInterval* actionTo = CCRotateTo::actionWithDuration(2,90);
CCActionInterval* actionBy = CCRotateBy::actionWithDuration(2,45);
CCActionInterval* actionReverse = actionBy->reverse();
//m_player->runAction(actionBy);
m_player->runAction(CCSequence::actions(actionBy, actionReverse, NULL));
}
std::string ActionRotate::title()
{
return "Rotate";
}
//jump action
void ActionJump::onEnter()
{
BasicActions::onEnter();
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCActionInterval* actionTo = CCJumpTo::actionWithDuration(2,ccp(size.width - 50, size.height- 50),50,5);
//第三个参数是跳跃的高度,第四个参数是跳跃的次数
CCActionInterval* actionBy = CCJumpTo::actionWithDuration(2,ccp(size.width - 50, size.height- 50), 50,5);
CCActionInterval* actionReverse = actionBy->reverse();
//m_player->runAction(actionTo);
//m_player->runAction(actionBy);
//m_player->runAction(actionReverse);
m_player->runAction(CCSequence::actions(actionBy, actionReverse, NULL));
}
std::string ActionJump::title()
{
return "JumpTo / JumpBy";
}
//blink action
void ActionBlink::onEnter()
{
BasicActions::onEnter();
CCActionInterval* action = CCBlink::actionWithDuration(2,10);
//第一个参数是动作时间,第二个是闪烁的次数
m_player->runAction(action);
}
std::string ActionBlink::title()
{
return "Blink";
}
//fade action
void ActionFade::onEnter()
{
BasicActions::onEnter();
CCActionInterval* action = CCFadeIn::actionWithDuration(1);
CCActionInterval* back = action->reverse();
//CCActionInterval* action = CCFadeOut::actionWithDuration(2);
//CCActionInterval* back = action->reverse();
m_player->runAction(CCSequence::actions(action,back,NULL ));
}
std::string ActionFade::title()
{
return "FadeIn / FadeOut";
}
//tint action
void ActionTint::onEnter()
{
BasicActions::onEnter();
CCActionInterval* action = CCTintTo::actionWithDuration(2,255,0,255);
CCActionInterval* back =action->reverse();
//后面三个参数是三基色
//m_player->runActin(action);
m_player->runAction(CCSequence::actions(action, back, NULL));
}
std::string ActionTint::title()
{
return "Tint";
}
//animate action
void ActionAnimate::onEnter()
{
BasicActions::onEnter();
CCAnimation* animation = CCAnimation::animation();
char frameName[100] = {0};
for(int i = 1; i<=5; i++)
{
sprintf(frameName, "player%d.png", i);
animation->addFrameWithFileName(frameName);
}
CCActionInterval* action = CCAnimate::actionWithDuration(3,animation, false);
m_player->runAction(action);
}
std::string ActionAnimate::title()
{
return "animate";
}
//sequence action
void ActionSequence::onEnter()
{
BasicActions::onEnter();
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCFiniteTimeAction* action = CCSequence::actions(
CCMoveTo::actionWithDuration(2,ccp(size.width - 50, size.height - 50)),
CCRotateBy::actionWithDuration(2,720), NULL);
m_player->runAction(action);
}
std::string ActionSequence::title()
{
return "move + rotate";
}
//sequence action2
void ActionSequence2::onEnter()
{
BasicActions::onEnter();
CCFiniteTimeAction* action = CCSequence::actions(
//CCPlace:放置到一个位置,是个即时动作
CCPlace::actionWithPosition(ccp(300,200)),
CCShow::action(),
CCMoveBy::actionWithDuration(1, ccp(100,0)),
//在游戏中,可能会出现一个角色使用某种技能召唤神兽之类的,一下的函数就是用于此
CCCallFunc::actionWithTarget(this, callfunc_selector(ActionSequence2::callback1)),//响应callback1事件,此事件召唤一个同伴
CCCallFunc::actionWithTarget(this, callfunc_selector(ActionSequence2::callback2)), NULL);//此事件弹出一行字
m_player->runAction(action);
}
std::string ActionSequence2::title()
{
return "sequence action2";
}
//弹出一个新角色
void ActionSequence2::callback1()
{
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCSprite* pSprite = CCSprite::spriteWithFile("friend.png");
pSprite->setPosition(ccp(size.width/4, size.height/3));
addChild(pSprite); www.2cto.com
}
//弹出一行字幕
void ActionSequence2::callback2()
{
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCLabelTTF* label = CCLabelTTF::labelWithString("callback 2 is called", "Arial", 20);
label->setPosition(ccp(size.width/4 + 200, size.height/3));
addChild(label);
}
step3:编译运行程序,我们就可以见到相应的效果,下面我截图给大家看:
这是程序运行后第一个出现的画面,通过点击next back 和 restart我们可以切换到另外的动作。
............
............
作者:wen294299195
相关新闻>>
- 发表评论
-
- 最新评论 更多>>