2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
2020-10-17 16:32:16 +08:00
|
|
|
Copyright (c) 2013-2017 Chukong Technologies Inc.
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-10-01 16:24:52 +08:00
|
|
|
https://axmolengine.github.io/
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2023-06-11 13:08:08 +08:00
|
|
|
#include "ActionNode.h"
|
|
|
|
#include "ActionFrameEasing.h"
|
2019-11-23 20:27:39 +08:00
|
|
|
#include "ui/UIWidget.h"
|
|
|
|
#include "ui/UIHelper.h"
|
|
|
|
#include "ui/UILayout.h"
|
2020-10-21 10:12:00 +08:00
|
|
|
#include "CocoLoader.h"
|
2023-06-11 13:08:08 +08:00
|
|
|
#include "base/Utils.h"
|
|
|
|
#include "ActionManagerEx.h"
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
USING_NS_AX;
|
2019-11-23 20:27:39 +08:00
|
|
|
using namespace ui;
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
namespace cocostudio
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
ActionNode::ActionNode()
|
2021-12-25 10:04:45 +08:00
|
|
|
: _currentFrameIndex(0)
|
|
|
|
, _destFrameIndex(0)
|
|
|
|
, _fUnitTime(0.1f)
|
|
|
|
, _actionTag(0)
|
|
|
|
, _actionSpawn(nullptr)
|
|
|
|
, _action(nullptr)
|
|
|
|
, _object(nullptr)
|
|
|
|
, _frameArrayNum(0)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_frameArrayNum = (int)kKeyframeMax;
|
2021-12-25 10:04:45 +08:00
|
|
|
for (int i = 0; i < _frameArrayNum; i++)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2022-08-09 09:54:53 +08:00
|
|
|
_frameArray.emplace_back(new ax::Vector<ActionFrame*>());
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ActionNode::~ActionNode()
|
|
|
|
{
|
|
|
|
if (_action == nullptr)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE_NULL(_actionSpawn);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE_NULL(_action);
|
|
|
|
AX_SAFE_RELEASE_NULL(_actionSpawn);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE(_object);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& object : _frameArray)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
object->clear();
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_DELETE(object);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
_frameArray.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::initWithDictionary(const rapidjson::Value& dic, Ref* root)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Widget* rw = dynamic_cast<Widget*>(root);
|
2019-11-23 20:27:39 +08:00
|
|
|
if (nullptr == rw)
|
|
|
|
return;
|
|
|
|
|
|
|
|
setActionTag(DICTOOL->getIntValue_json(dic, "ActionTag"));
|
2021-12-25 10:04:45 +08:00
|
|
|
Widget* node = Helper::seekActionWidgetByActionTag(rw, getActionTag());
|
|
|
|
bool positionOffset = node && (nullptr == (dynamic_cast<Layout*>(node)));
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
int actionFrameCount = DICTOOL->getArrayCount_json(dic, "actionframelist");
|
2021-12-25 10:04:45 +08:00
|
|
|
for (int i = 0; i < actionFrameCount; i++)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
const rapidjson::Value& actionFrameDic = DICTOOL->getDictionaryFromArray_json(dic, "actionframelist", i);
|
2021-12-25 10:04:45 +08:00
|
|
|
int frameInex = DICTOOL->getIntValue_json(actionFrameDic, "frameid");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
int frameTweenType = DICTOOL->getIntValue_json(actionFrameDic, "tweenType");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
std::vector<float> frameTweenParameter;
|
|
|
|
int frameTweenParameterNum = DICTOOL->getArrayCount_json(actionFrameDic, "tweenParameter");
|
|
|
|
|
|
|
|
for (int j = 0; j < frameTweenParameterNum; j++)
|
|
|
|
{
|
|
|
|
float value = DICTOOL->getFloatValueFromArray_json(actionFrameDic, "tweenParameter", j);
|
2022-08-09 09:54:53 +08:00
|
|
|
frameTweenParameter.emplace_back(value);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool existPosition = DICTOOL->checkObjectExist_json(actionFrameDic, "positionx");
|
2019-11-23 20:27:39 +08:00
|
|
|
if (existPosition)
|
|
|
|
{
|
|
|
|
float positionX = DICTOOL->getFloatValue_json(actionFrameDic, "positionx");
|
|
|
|
float positionY = DICTOOL->getFloatValue_json(actionFrameDic, "positiony");
|
2021-12-25 10:04:45 +08:00
|
|
|
if (positionOffset && (nullptr != node->getParent()) &&
|
|
|
|
ActionManagerEx::getInstance()->getStudioVersionNumber() < 1600)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
Vec2 AnchorPointIn = node->getParent()->getAnchorPointInPoints();
|
|
|
|
positionX += AnchorPointIn.x;
|
|
|
|
positionY += AnchorPointIn.y;
|
|
|
|
}
|
2021-12-08 00:11:53 +08:00
|
|
|
ActionMoveFrame* actionFrame = new ActionMoveFrame();
|
2019-11-23 20:27:39 +08:00
|
|
|
actionFrame->setFrameIndex(frameInex);
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setPosition(Vec2(positionX, positionY));
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeMove);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
actionFrame->release();
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool existScale = DICTOOL->checkObjectExist_json(actionFrameDic, "scalex");
|
2019-11-23 20:27:39 +08:00
|
|
|
if (existScale)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
float scaleX = DICTOOL->getFloatValue_json(actionFrameDic, "scalex");
|
|
|
|
float scaleY = DICTOOL->getFloatValue_json(actionFrameDic, "scaley");
|
2021-12-08 00:11:53 +08:00
|
|
|
ActionScaleFrame* actionFrame = new ActionScaleFrame();
|
2019-11-23 20:27:39 +08:00
|
|
|
actionFrame->setFrameIndex(frameInex);
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setScaleX(scaleX);
|
|
|
|
actionFrame->setScaleY(scaleY);
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeScale);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
2021-12-25 10:04:45 +08:00
|
|
|
actionFrame->release();
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool existRotation = DICTOOL->checkObjectExist_json(actionFrameDic, "rotation");
|
2019-11-23 20:27:39 +08:00
|
|
|
if (existRotation)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
float rotation = DICTOOL->getFloatValue_json(actionFrameDic, "rotation");
|
2021-12-08 00:11:53 +08:00
|
|
|
ActionRotationFrame* actionFrame = new ActionRotationFrame();
|
2019-11-23 20:27:39 +08:00
|
|
|
actionFrame->setFrameIndex(frameInex);
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setRotation(rotation);
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeRotate);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
actionFrame->release();
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool existOpacity = DICTOOL->checkObjectExist_json(actionFrameDic, "opacity");
|
2019-11-23 20:27:39 +08:00
|
|
|
if (existOpacity)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
int opacity = DICTOOL->getIntValue_json(actionFrameDic, "opacity");
|
2021-12-08 00:11:53 +08:00
|
|
|
ActionFadeFrame* actionFrame = new ActionFadeFrame();
|
2019-11-23 20:27:39 +08:00
|
|
|
actionFrame->setFrameIndex(frameInex);
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setOpacity(opacity);
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeTint);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
actionFrame->release();
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool existColor = DICTOOL->checkObjectExist_json(actionFrameDic, "colorr");
|
2019-11-23 20:27:39 +08:00
|
|
|
if (existColor)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
int colorR = DICTOOL->getIntValue_json(actionFrameDic, "colorr");
|
|
|
|
int colorG = DICTOOL->getIntValue_json(actionFrameDic, "colorg");
|
|
|
|
int colorB = DICTOOL->getIntValue_json(actionFrameDic, "colorb");
|
2021-12-08 00:11:53 +08:00
|
|
|
ActionTintFrame* actionFrame = new ActionTintFrame();
|
2019-11-23 20:27:39 +08:00
|
|
|
actionFrame->setFrameIndex(frameInex);
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
2021-12-25 10:04:45 +08:00
|
|
|
actionFrame->setColor(Color3B(colorR, colorG, colorB));
|
2019-11-23 20:27:39 +08:00
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeFade);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
actionFrame->release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
initActionNodeFromRoot(root);
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
int ActionNode::valueToInt(std::string_view value)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
return atoi(value.data());
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
bool ActionNode::valueToBool(std::string_view value)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
int intValue = valueToInt(value);
|
|
|
|
if (1 == intValue)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
return false;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
float ActionNode::valueToFloat(std::string_view value)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
return utils::atof(value.data());
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
void ActionNode::initWithBinary(CocoLoader* cocoLoader, stExpCocoNode* cocoNode, ax::Ref* root)
|
2021-12-25 10:04:45 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
stExpCocoNode* stChildNode = cocoNode;
|
|
|
|
|
|
|
|
int actionNodeCount = stChildNode->GetChildNum();
|
|
|
|
stChildNode = stChildNode[0].GetChildArray(cocoLoader);
|
|
|
|
stExpCocoNode* frameListNode = nullptr;
|
|
|
|
for (int i = 0; i < actionNodeCount; ++i)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
std::string key = stChildNode[i].GetName(cocoLoader);
|
|
|
|
std::string value = stChildNode[i].GetValue(cocoLoader);
|
|
|
|
if (key == "ActionTag")
|
|
|
|
{
|
|
|
|
setActionTag(valueToInt(value));
|
|
|
|
}
|
|
|
|
else if (key == "actionframelist")
|
|
|
|
{
|
|
|
|
frameListNode = &stChildNode[i];
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
|
|
|
int actionFrameCount = frameListNode->GetChildNum();
|
|
|
|
stExpCocoNode* stFrameChildNode = frameListNode->GetChildArray(cocoLoader);
|
|
|
|
for (int i = 0; i < actionFrameCount; i++)
|
|
|
|
{
|
|
|
|
|
|
|
|
int frameIndex = 0;
|
|
|
|
int frameTweenType = 0;
|
|
|
|
float positionX = 0;
|
|
|
|
float positionY = 0;
|
|
|
|
float scaleX = 1;
|
|
|
|
float scaleY = 1;
|
|
|
|
float rotation = 0;
|
|
|
|
int opacity = 255;
|
|
|
|
int colorR = -1;
|
|
|
|
int colorG = -1;
|
|
|
|
int colorB = -1;
|
|
|
|
std::vector<float> frameTweenParameter;
|
|
|
|
|
|
|
|
int framesCount = stFrameChildNode[i].GetChildNum();
|
|
|
|
stExpCocoNode* innerFrameNode = stFrameChildNode[i].GetChildArray(cocoLoader);
|
|
|
|
for (int j = 0; j < framesCount; j++)
|
|
|
|
{
|
|
|
|
std::string key = innerFrameNode[j].GetName(cocoLoader);
|
|
|
|
std::string value = innerFrameNode[j].GetValue(cocoLoader);
|
|
|
|
|
|
|
|
if (key == "frameid")
|
|
|
|
{
|
|
|
|
frameIndex = valueToInt(value);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else if (key == "tweenType")
|
|
|
|
{
|
|
|
|
frameTweenType = valueToInt(value);
|
|
|
|
}
|
|
|
|
else if (key == "tweenParameter")
|
|
|
|
{
|
|
|
|
// There are no tweenParameter args in the json file
|
|
|
|
int tweenParameterCount = innerFrameNode[j].GetChildNum();
|
|
|
|
stExpCocoNode* tweenParameterArray = innerFrameNode[j].GetChildArray(cocoLoader);
|
|
|
|
for (int k = 0; k < tweenParameterCount; ++k)
|
|
|
|
{
|
|
|
|
std::string t_key = tweenParameterArray[j].GetName(cocoLoader);
|
|
|
|
std::string t_value = tweenParameterArray[j].GetValue(cocoLoader);
|
2022-08-09 09:54:53 +08:00
|
|
|
frameTweenParameter.emplace_back(valueToFloat(t_value));
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else if (key == "positionx")
|
|
|
|
{
|
|
|
|
positionX = valueToFloat(value);
|
|
|
|
}
|
|
|
|
else if (key == "positiony")
|
|
|
|
{
|
|
|
|
positionY = valueToFloat(value);
|
|
|
|
ActionMoveFrame* actionFrame = new ActionMoveFrame();
|
|
|
|
actionFrame->autorelease();
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setFrameIndex(frameIndex);
|
|
|
|
actionFrame->setPosition(Vec2(positionX, positionY));
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeMove);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
}
|
|
|
|
else if (key == "scalex")
|
|
|
|
{
|
|
|
|
scaleX = valueToFloat(value);
|
|
|
|
}
|
|
|
|
else if (key == "scaley")
|
|
|
|
{
|
|
|
|
scaleY = valueToFloat(value);
|
|
|
|
ActionScaleFrame* actionFrame = new ActionScaleFrame();
|
|
|
|
actionFrame->autorelease();
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setFrameIndex(frameIndex);
|
|
|
|
actionFrame->setScaleX(scaleX);
|
|
|
|
actionFrame->setScaleY(scaleY);
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeScale);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
}
|
|
|
|
else if (key == "rotation")
|
|
|
|
{
|
|
|
|
rotation = valueToFloat(value);
|
|
|
|
ActionRotationFrame* actionFrame = new ActionRotationFrame();
|
|
|
|
actionFrame->autorelease();
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setFrameIndex(frameIndex);
|
|
|
|
actionFrame->setRotation(rotation);
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeRotate);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
}
|
|
|
|
else if (key == "opacity")
|
|
|
|
{
|
|
|
|
opacity = valueToInt(value);
|
|
|
|
ActionFadeFrame* actionFrame = new ActionFadeFrame();
|
|
|
|
actionFrame->autorelease();
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setFrameIndex(frameIndex);
|
|
|
|
actionFrame->setOpacity(opacity);
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeFade);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
}
|
|
|
|
else if (key == "colorb")
|
|
|
|
{
|
|
|
|
colorB = valueToInt(value);
|
|
|
|
}
|
|
|
|
else if (key == "colorg")
|
|
|
|
{
|
|
|
|
colorG = valueToInt(value);
|
|
|
|
}
|
|
|
|
else if (key == "colorr")
|
|
|
|
{
|
|
|
|
colorR = valueToInt(value);
|
|
|
|
|
|
|
|
ActionTintFrame* actionFrame = new ActionTintFrame();
|
|
|
|
actionFrame->autorelease();
|
|
|
|
actionFrame->setEasingType(frameTweenType);
|
|
|
|
actionFrame->setEasingParameter(frameTweenParameter);
|
|
|
|
actionFrame->setFrameIndex(frameIndex);
|
|
|
|
actionFrame->setColor(Color3B(colorR, colorG, colorB));
|
|
|
|
auto cActionArray = _frameArray.at((int)kKeyframeTint);
|
|
|
|
cActionArray->pushBack(actionFrame);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
initActionNodeFromRoot(root);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
void ActionNode::initActionNodeFromRoot(Ref* root)
|
|
|
|
{
|
|
|
|
Widget* rootWidget = dynamic_cast<Widget*>(root);
|
|
|
|
if (rootWidget != nullptr)
|
|
|
|
{
|
|
|
|
Widget* widget = Helper::seekActionWidgetByActionTag(rootWidget, getActionTag());
|
|
|
|
if (widget != nullptr)
|
|
|
|
{
|
|
|
|
setObject(widget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::setUnitTime(float fTime)
|
|
|
|
{
|
|
|
|
_fUnitTime = fTime;
|
|
|
|
this->refreshActionProperty();
|
|
|
|
}
|
|
|
|
|
|
|
|
float ActionNode::getUnitTime()
|
|
|
|
{
|
|
|
|
return _fUnitTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::setActionTag(int tag)
|
|
|
|
{
|
|
|
|
_actionTag = tag;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ActionNode::getActionTag()
|
|
|
|
{
|
|
|
|
return _actionTag;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::setObject(Ref* node)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE(_object);
|
2019-11-23 20:27:39 +08:00
|
|
|
_object = node;
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RETAIN(_object);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Ref* ActionNode::getObject()
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
return _object;
|
|
|
|
}
|
|
|
|
|
|
|
|
Node* ActionNode::getActionNode()
|
|
|
|
{
|
|
|
|
Node* cNode = dynamic_cast<Node*>(_object);
|
|
|
|
if (cNode != nullptr)
|
|
|
|
{
|
|
|
|
return cNode;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::insertFrame(int index, ActionFrame* frame)
|
|
|
|
{
|
|
|
|
if (frame == nullptr)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int frameType = frame->getFrameType();
|
2021-12-25 10:04:45 +08:00
|
|
|
if (frameType < (int)_frameArray.size())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
auto cArray = _frameArray.at(frameType);
|
|
|
|
cArray->insert(index, frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::addFrame(ActionFrame* frame)
|
|
|
|
{
|
|
|
|
if (frame == nullptr)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int frameType = frame->getFrameType();
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (frameType < (int)_frameArray.size())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
auto cArray = _frameArray.at(frameType);
|
|
|
|
cArray->pushBack(frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::deleteFrame(ActionFrame* frame)
|
|
|
|
{
|
|
|
|
if (frame == nullptr)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int frameType = frame->getFrameType();
|
2021-12-25 10:04:45 +08:00
|
|
|
if (frameType < (int)_frameArray.size())
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
auto cArray = _frameArray.at(frameType);
|
|
|
|
cArray->eraseObject(frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::clearAllFrame()
|
|
|
|
{
|
2022-07-21 19:19:08 +08:00
|
|
|
for (auto&& array : _frameArray)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
array->clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
Spawn* ActionNode::refreshActionProperty()
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_object == nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
Vector<FiniteTimeAction*> cSpawnArray;
|
|
|
|
|
|
|
|
for (int n = 0; n < _frameArrayNum; n++)
|
|
|
|
{
|
|
|
|
auto cArray = _frameArray.at(n);
|
|
|
|
if (cArray->size() <= 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector<FiniteTimeAction*> cSequenceArray;
|
|
|
|
auto frameCount = cArray->size();
|
2021-12-25 10:04:45 +08:00
|
|
|
if (frameCount > 1)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < frameCount; i++)
|
|
|
|
{
|
|
|
|
auto frame = cArray->at(i);
|
|
|
|
if (i == 0)
|
|
|
|
{
|
|
|
|
// #11173 Fixed every node of UI animation(json) is starting at frame 0.
|
|
|
|
// if (frame->getFrameIndex() > 0)
|
|
|
|
// {
|
2021-12-31 12:12:40 +08:00
|
|
|
// DelayTime* cDelayTime =
|
|
|
|
// DelayTime::create(frame->getFrameIndex()
|
|
|
|
//* getUnitTime()); if (cDelayTime != nullptr)
|
2021-12-25 10:04:45 +08:00
|
|
|
// cSequenceArray.pushBack(static_cast<FiniteTimeAction*>(cDelayTime));
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto srcFrame = cArray->at(i - 1);
|
|
|
|
float duration = (frame->getFrameIndex() - srcFrame->getFrameIndex()) * getUnitTime();
|
|
|
|
Action* cAction = frame->getAction(duration);
|
|
|
|
if (cAction != nullptr)
|
|
|
|
cSequenceArray.pushBack(static_cast<FiniteTimeAction*>(cAction));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (frameCount == 1)
|
|
|
|
{
|
|
|
|
auto frame = cArray->at(0);
|
|
|
|
float duration = 0.0f;
|
|
|
|
Action* cAction = frame->getAction(duration);
|
|
|
|
if (cAction != nullptr)
|
|
|
|
cSequenceArray.pushBack(static_cast<FiniteTimeAction*>(cAction));
|
|
|
|
}
|
|
|
|
Sequence* cSequence = Sequence::create(cSequenceArray);
|
|
|
|
if (cSequence != nullptr)
|
|
|
|
{
|
|
|
|
cSpawnArray.pushBack(cSequence);
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_action == nullptr)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE_NULL(_actionSpawn);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE_NULL(_action);
|
|
|
|
AX_SAFE_RELEASE_NULL(_actionSpawn);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_actionSpawn = Spawn::create(cSpawnArray);
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RETAIN(_actionSpawn);
|
2019-11-23 20:27:39 +08:00
|
|
|
return _actionSpawn;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::playAction()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_object == nullptr || _actionSpawn == nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (_action != nullptr)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
_action->release();
|
|
|
|
}
|
|
|
|
|
|
|
|
_action = Sequence::create(_actionSpawn, nullptr);
|
|
|
|
_action->retain();
|
|
|
|
|
|
|
|
this->runAction();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::runAction()
|
|
|
|
{
|
|
|
|
Node* cNode = this->getActionNode();
|
|
|
|
if (cNode != nullptr && _action != nullptr)
|
|
|
|
{
|
|
|
|
cNode->runAction(_action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ActionNode::stopAction()
|
|
|
|
{
|
|
|
|
Node* cNode = this->getActionNode();
|
|
|
|
if (cNode != nullptr && _action != nullptr)
|
|
|
|
{
|
|
|
|
cNode->stopAction(_action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ActionNode::getFirstFrameIndex()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
int frameindex = 99999;
|
2019-11-23 20:27:39 +08:00
|
|
|
bool bFindFrame = false;
|
|
|
|
for (int n = 0; n < _frameArrayNum; n++)
|
|
|
|
{
|
|
|
|
auto cArray = _frameArray.at(n);
|
|
|
|
if (cArray->empty())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
bFindFrame = true;
|
|
|
|
auto frame = cArray->at(0);
|
2019-11-23 20:27:39 +08:00
|
|
|
int iFrameIndex = frame->getFrameIndex();
|
|
|
|
|
|
|
|
if (frameindex > iFrameIndex)
|
|
|
|
{
|
|
|
|
frameindex = iFrameIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!bFindFrame)
|
|
|
|
{
|
|
|
|
frameindex = 0;
|
|
|
|
}
|
|
|
|
return frameindex;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ActionNode::getLastFrameIndex()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
int frameindex = -1;
|
2019-11-23 20:27:39 +08:00
|
|
|
bool bFindFrame = false;
|
|
|
|
for (int n = 0; n < _frameArrayNum; n++)
|
|
|
|
{
|
|
|
|
auto cArray = _frameArray.at(n);
|
|
|
|
if (cArray->empty())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
bFindFrame = true;
|
2019-11-23 20:27:39 +08:00
|
|
|
ssize_t lastInex = cArray->size() - 1;
|
2021-12-25 10:04:45 +08:00
|
|
|
auto frame = cArray->at(lastInex);
|
|
|
|
int iFrameIndex = frame->getFrameIndex();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
if (frameindex < iFrameIndex)
|
|
|
|
{
|
|
|
|
frameindex = iFrameIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!bFindFrame)
|
|
|
|
{
|
|
|
|
frameindex = 0;
|
|
|
|
}
|
|
|
|
return frameindex;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
bool ActionNode::updateActionToTimeLine(float fTime)
|
|
|
|
{
|
|
|
|
bool bFindFrame = false;
|
|
|
|
|
|
|
|
ActionFrame* srcFrame = nullptr;
|
|
|
|
for (int n = 0; n < _frameArrayNum; n++)
|
|
|
|
{
|
|
|
|
auto cArray = _frameArray.at(n);
|
|
|
|
if (cArray->empty())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ssize_t frameCount = cArray->size();
|
|
|
|
for (int i = 0; i < frameCount; i++)
|
|
|
|
{
|
|
|
|
auto frame = cArray->at(i);
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
if (frame->getFrameIndex() * getUnitTime() == fTime)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
this->easingToFrame(1.0f, 1.0f, nullptr, frame);
|
2019-11-23 20:27:39 +08:00
|
|
|
bFindFrame = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-12-25 10:04:45 +08:00
|
|
|
else if (frame->getFrameIndex() * getUnitTime() > fTime)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
if (i == 0)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
this->easingToFrame(1.0f, 1.0f, nullptr, frame);
|
2019-11-23 20:27:39 +08:00
|
|
|
bFindFrame = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
srcFrame = cArray->at(i - 1);
|
|
|
|
float duration = (frame->getFrameIndex() - srcFrame->getFrameIndex()) * getUnitTime();
|
|
|
|
float delaytime = fTime - srcFrame->getFrameIndex() * getUnitTime();
|
|
|
|
this->easingToFrame(duration, 1.0f, nullptr, srcFrame);
|
|
|
|
// float easingTime = ActionFrameEasing::bounceTime(delaytime);
|
|
|
|
this->easingToFrame(duration, delaytime / duration, srcFrame, frame);
|
2019-11-23 20:27:39 +08:00
|
|
|
bFindFrame = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bFindFrame;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void ActionNode::easingToFrame(float duration, float delayTime, ActionFrame* srcFrame, ActionFrame* destFrame)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Action* cAction = destFrame->getAction(duration, srcFrame);
|
|
|
|
Node* cNode = this->getActionNode();
|
2019-11-23 20:27:39 +08:00
|
|
|
if (cAction == nullptr || cNode == nullptr)
|
|
|
|
{
|
|
|
|
return;
|
2021-12-25 10:04:45 +08:00
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
cAction->startWithTarget(cNode);
|
|
|
|
cAction->update(delayTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ActionNode::isActionDoneOnce()
|
|
|
|
{
|
|
|
|
if (_action == nullptr)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return _action->isDone();
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
} // namespace cocostudio
|