cocos2d-x学习笔记(7)--动作(Actions)

cocos2d-x学习笔记(7)--动作(Actions)

本文出自https://shuwoom.com博客,欢迎访问!

       动作在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:

 

 首先,定义一些如下常量和变量:

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中添加如下动作类:

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中添加了一个函数用于操作对应动作类的创建:

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函数的用法:

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父类的子类全部补充完即可:

//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);
}
//弹出一行字幕
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我们可以切换到另外的动作。

 

 

 

 

 

............

 

 


 

 源代码下载地址:http://download.csdn.net/download/wen294299195/4525809

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值