动作管理
我们来给一个节点,赋予运动轨迹.
spr1->runAction(new MoveBy(1.2f,Vec2(winSize.width * 0.5,0)));
本质是有一个update函数,动态改变它的位置。
_target->setPosition(_startPosition + _positionDelta * t);
之前节点的update,是通过scheduler来管理的,我们增加一个类actionManager来管理action的update。其关系如下:scheduler所有update->系统定义update和节点update,系统定义update->actionManager的update.
void Engine::initGame()
{
if(_gameApp)
_gameApp->applicationEnter();
Scheduler::getInstance()->scheduleUpdateWithPriority(ActionManager::getInstance());
}
/********************************************************************
Copyright(C), 2012-2013,
FileName:ActionManager.h
Description:
Author:cloud
Created:2014/10/23
history:
23:10:2014 10:36 by
*********************************************************************/
#pragma once
#include "Singleton.h"
#include "vector"
#include "base/SchedulerDelegate.h"
#include "export/Node.h"
#include "export/Action.h"
namespace cloud
{
struct ActionItem
{
Action* action;
Node* target;
int tag;
};
class ActionManager :public Singleton<ActionManager>,public SchedulerDelegate
{
public:
typedef std::vector<ActionItem> ActionItemChild;
DECLARE_SINGLETON_CREATE_DESTROY
ActionManager();
~ActionManager();
void update(float dt);
void addAction(Action *action, Node *target);
void removeAction(const Action *action);
void removeAllActionsFromTarget(const Node *target);
void removeActionByTag(int tag,const Node *target);
Action *getActionByTag(int tag,const Node *target);
int getNumberOfRunningActionsInTarget(const Node *target);
protected:
std::vector<ActionItem> _children;
};
}
/********************************************************************
Copyright(C), 2012-2013,
FileName:ActionManager.cpp
Description:
Author:cloud
Created:2014/10/23
history:
23:10:2014 10:36 by
*********************************************************************/
#include "ActionManager.h"
#include "Scheduler.h"
namespace cloud
{
IMPLEMENT_SINGLETON_ALL(ActionManager);
ActionManager::ActionManager()
{
_priority = Scheduler::PRIORITY_SYSTEM;
}
ActionManager::~ActionManager()
{
}
void ActionManager::update(float dt)
{
for(int i = 0; i < _children.size();++i)
{
ActionItemChild::iterator it = _children.begin();
(*it).action->update(dt);
if ((*it).action->isDone())
{
Action *action = (*it).action;
(*it).action->stop();
removeAction(action);
}
}
}
void ActionManager::addAction(Action *action, Node *target)
{
ActionItem actionItem;
actionItem.action = action;
actionItem.target = target;
actionItem.tag = action->getTag();
_children.push_back(actionItem);
action->startWithTarget(target);
}
void ActionManager::removeAction(const Action *action)
{
ActionItemChild::iterator it = _children.begin();
while(it != _children.end())
{
if(action == (*it).action)
{
it=_children.erase(it);
delete action;
action = NULL;
break;
}
else
{
++it;
}
}
}
void ActionManager::removeAllActionsFromTarget(const Node *target)
{
ActionItemChild::iterator it = _children.begin();
while(it != _children.end())
{
if(target == (*it).target)
{
Action* action = (*it).action;
delete action;
it=_children.erase(it);
}
else
{
++it;
}
}
}
void ActionManager::removeActionByTag(int tag,const Node *target)
{
ActionItemChild::iterator it = _children.begin();
while(it != _children.end())
{
if(target == (*it).target && tag == (*it).tag)
{
Action* action = (*it).action;
delete action;
it = _children.erase(it);
}
else
{
++it;
}
}
}
Action *ActionManager::getActionByTag(int tag,const Node *target)
{
for(int i = 0; i < _children.size();++i)
{
ActionItemChild::iterator it = _children.begin();
if(target == (*(it+i)).target && tag == (*(it+i)).tag)
{
return (*(it+i)).action;
}
}
}
int ActionManager::getNumberOfRunningActionsInTarget(const Node *target)
{
int total = 0;
for(int i = 0; i < _children.size();++i)
{
ActionItemChild::iterator it = _children.begin();
if(target == (*(it+i)).target )
{
++total;
}
}
return total;
}
}