2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2009 On-Core
|
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "2d/CCActionGrid.h"
|
|
|
|
|
|
|
|
#include "2d/CCGrid.h"
|
|
|
|
#include "2d/CCNodeGrid.h"
|
|
|
|
#include "base/CCDirector.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
// implementation of GridAction
|
|
|
|
|
2021-10-23 23:27:14 +08:00
|
|
|
bool GridAction::initWithDuration(float duration, const Vec2& gridSize)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
if (ActionInterval::initWithDuration(duration))
|
|
|
|
{
|
|
|
|
_gridSize = gridSize;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void GridAction::startWithTarget(Node* target)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ActionInterval::startWithTarget(target);
|
|
|
|
cacheTargetAsGridNode();
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
GridBase* targetGrid = _gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
if (targetGrid && targetGrid->getReuseGrid() > 0)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
if (targetGrid->isActive() && targetGrid->getGridSize().width == _gridSize.width &&
|
|
|
|
targetGrid->getGridSize().height == _gridSize.height)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
targetGrid->reuse();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CCASSERT(0, "Invalid grid parameters!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (targetGrid && targetGrid->isActive())
|
|
|
|
{
|
|
|
|
targetGrid->setActive(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto newgrid = this->getGrid();
|
|
|
|
_gridNodeTarget->setGrid(newgrid);
|
|
|
|
_gridNodeTarget->getGrid()->setActive(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GridAction::cacheTargetAsGridNode()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_gridNodeTarget = dynamic_cast<NodeGrid*>(_target);
|
2019-11-23 20:27:39 +08:00
|
|
|
CCASSERT(_gridNodeTarget, "GridActions can only used on NodeGrid");
|
|
|
|
}
|
|
|
|
|
|
|
|
GridAction* GridAction::reverse() const
|
|
|
|
{
|
|
|
|
// FIXME: This conversion isn't safe.
|
2021-12-25 10:04:45 +08:00
|
|
|
return (GridAction*)ReverseTime::create(this->clone());
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
GridBase* GridAction::getGrid()
|
|
|
|
{
|
|
|
|
// Abstract class needs implementation
|
|
|
|
CCASSERT(0, "Subclass should implement this method!");
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// implementation of Grid3DAction
|
|
|
|
|
|
|
|
GridBase* Grid3DAction::getGrid()
|
|
|
|
{
|
|
|
|
return Grid3D::create(_gridSize, _gridNodeTarget->getGridRect());
|
|
|
|
}
|
|
|
|
|
|
|
|
Vec3 Grid3DAction::getVertex(const Vec2& position) const
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Grid3D* g = (Grid3D*)_gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
return g->getVertex(position);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vec3 Grid3DAction::getOriginalVertex(const Vec2& position) const
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Grid3D* g = (Grid3D*)_gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
return g->getOriginalVertex(position);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Grid3DAction::setVertex(const Vec2& position, const Vec3& vertex)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Grid3D* g = (Grid3D*)_gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
g->setVertex(position, vertex);
|
|
|
|
}
|
|
|
|
|
|
|
|
Rect Grid3DAction::getGridRect() const
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
Grid3D* g = (Grid3D*)_gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
return g->getGridRect();
|
|
|
|
}
|
|
|
|
|
|
|
|
// implementation of TiledGrid3DAction
|
2021-12-25 10:04:45 +08:00
|
|
|
TiledGrid3DAction* TiledGrid3DAction::create(float duration, const Vec2& gridSize)
|
2019-11-27 00:49:56 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
TiledGrid3DAction* ret = new TiledGrid3DAction();
|
2021-12-08 00:11:53 +08:00
|
|
|
if (ret->initWithDuration(duration, gridSize))
|
2019-11-27 00:49:56 +08:00
|
|
|
{
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete ret;
|
|
|
|
return nullptr;
|
|
|
|
}
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
GridBase* TiledGrid3DAction::getGrid()
|
|
|
|
{
|
|
|
|
return TiledGrid3D::create(_gridSize, _gridNodeTarget->getGridRect());
|
|
|
|
}
|
|
|
|
|
|
|
|
Quad3 TiledGrid3DAction::getTile(const Vec2& pos) const
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
TiledGrid3D* g = (TiledGrid3D*)_gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
return g->getTile(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
Quad3 TiledGrid3DAction::getOriginalTile(const Vec2& pos) const
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
TiledGrid3D* g = (TiledGrid3D*)_gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
return g->getOriginalTile(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TiledGrid3DAction::setTile(const Vec2& pos, const Quad3& coords)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
TiledGrid3D* g = (TiledGrid3D*)_gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
return g->setTile(pos, coords);
|
|
|
|
}
|
|
|
|
|
|
|
|
// implementation AccelDeccelAmplitude
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
AccelDeccelAmplitude* AccelDeccelAmplitude::create(Action* action, float duration)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
AccelDeccelAmplitude* ret = new AccelDeccelAmplitude();
|
2021-12-08 00:11:53 +08:00
|
|
|
if (ret->initWithAction(action, duration))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete ret;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool AccelDeccelAmplitude::initWithAction(Action* action, float duration)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
if (ActionInterval::initWithDuration(duration))
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_rate = 1.0f;
|
2019-11-23 20:27:39 +08:00
|
|
|
_other = (ActionInterval*)(action);
|
|
|
|
action->retain();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
AccelDeccelAmplitude* AccelDeccelAmplitude::clone() const
|
|
|
|
{
|
|
|
|
// no copy constructor
|
|
|
|
if (_other)
|
|
|
|
return AccelDeccelAmplitude::create(_other->clone(), _rate);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
AccelDeccelAmplitude::~AccelDeccelAmplitude()
|
|
|
|
{
|
|
|
|
CC_SAFE_RELEASE(_other);
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void AccelDeccelAmplitude::startWithTarget(Node* target)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ActionInterval::startWithTarget(target);
|
|
|
|
_other->startWithTarget(target);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AccelDeccelAmplitude::update(float time)
|
|
|
|
{
|
|
|
|
float f = time * 2;
|
|
|
|
|
|
|
|
if (f > 1)
|
|
|
|
{
|
|
|
|
f -= 1;
|
|
|
|
f = 1 - f;
|
|
|
|
}
|
|
|
|
|
|
|
|
((AccelDeccelAmplitude*)(_other))->setAmplitudeRate(powf(f, _rate));
|
|
|
|
}
|
|
|
|
|
|
|
|
AccelDeccelAmplitude* AccelDeccelAmplitude::reverse() const
|
|
|
|
{
|
|
|
|
if (_other)
|
|
|
|
return AccelDeccelAmplitude::create(_other->reverse(), _duration);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// implementation of AccelAmplitude
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
AccelAmplitude* AccelAmplitude::create(Action* action, float duration)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
AccelAmplitude* ret = new AccelAmplitude();
|
2021-12-08 00:11:53 +08:00
|
|
|
if (ret->initWithAction(action, duration))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete ret;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool AccelAmplitude::initWithAction(Action* action, float duration)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
if (ActionInterval::initWithDuration(duration))
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_rate = 1.0f;
|
2019-11-23 20:27:39 +08:00
|
|
|
_other = (ActionInterval*)(action);
|
|
|
|
action->retain();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
AccelAmplitude* AccelAmplitude::clone() const
|
|
|
|
{
|
|
|
|
// no copy constructor
|
|
|
|
if (_other)
|
|
|
|
return AccelAmplitude::create(_other->clone(), _duration);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
AccelAmplitude::~AccelAmplitude()
|
|
|
|
{
|
|
|
|
CC_SAFE_DELETE(_other);
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void AccelAmplitude::startWithTarget(Node* target)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ActionInterval::startWithTarget(target);
|
|
|
|
_other->startWithTarget(target);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AccelAmplitude::update(float time)
|
|
|
|
{
|
|
|
|
((AccelAmplitude*)(_other))->setAmplitudeRate(powf(time, _rate));
|
|
|
|
_other->update(time);
|
|
|
|
}
|
|
|
|
|
|
|
|
AccelAmplitude* AccelAmplitude::reverse() const
|
|
|
|
{
|
|
|
|
if (_other)
|
|
|
|
return AccelAmplitude::create(_other->reverse(), _duration);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeccelAmplitude
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
DeccelAmplitude* DeccelAmplitude::create(Action* action, float duration)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
DeccelAmplitude* ret = new DeccelAmplitude();
|
2021-12-08 00:11:53 +08:00
|
|
|
if (ret->initWithAction(action, duration))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete ret;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
bool DeccelAmplitude::initWithAction(Action* action, float duration)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
if (ActionInterval::initWithDuration(duration))
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_rate = 1.0f;
|
2019-11-23 20:27:39 +08:00
|
|
|
_other = (ActionInterval*)(action);
|
|
|
|
action->retain();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
DeccelAmplitude::~DeccelAmplitude()
|
|
|
|
{
|
|
|
|
CC_SAFE_RELEASE(_other);
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void DeccelAmplitude::startWithTarget(Node* target)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ActionInterval::startWithTarget(target);
|
|
|
|
_other->startWithTarget(target);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DeccelAmplitude::update(float time)
|
|
|
|
{
|
|
|
|
((DeccelAmplitude*)(_other))->setAmplitudeRate(powf((1 - time), _rate));
|
|
|
|
_other->update(time);
|
|
|
|
}
|
|
|
|
|
|
|
|
DeccelAmplitude* DeccelAmplitude::clone() const
|
|
|
|
{
|
|
|
|
// no copy constructor
|
|
|
|
if (_other)
|
|
|
|
return DeccelAmplitude::create(_other->clone(), _duration);
|
2021-12-25 10:04:45 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
DeccelAmplitude* DeccelAmplitude::reverse() const
|
|
|
|
{
|
|
|
|
return DeccelAmplitude::create(_other->reverse(), _duration);
|
|
|
|
}
|
|
|
|
|
|
|
|
// implementation of StopGrid
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void StopGrid::startWithTarget(Node* target)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ActionInstant::startWithTarget(target);
|
|
|
|
cacheTargetAsGridNode();
|
2021-12-25 10:04:45 +08:00
|
|
|
GridBase* grid = _gridNodeTarget->getGrid();
|
2019-11-23 20:27:39 +08:00
|
|
|
if (grid && grid->isActive())
|
|
|
|
{
|
|
|
|
grid->setActive(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StopGrid::cacheTargetAsGridNode()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_gridNodeTarget = dynamic_cast<NodeGrid*>(_target);
|
2019-11-23 20:27:39 +08:00
|
|
|
CCASSERT(_gridNodeTarget, "GridActions can only used on NodeGrid");
|
|
|
|
}
|
|
|
|
|
|
|
|
StopGrid* StopGrid::create()
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
StopGrid* action = new StopGrid();
|
|
|
|
action->autorelease();
|
|
|
|
return action;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
StopGrid* StopGrid::clone() const
|
|
|
|
{
|
|
|
|
return StopGrid::create();
|
|
|
|
}
|
|
|
|
|
|
|
|
StopGrid* StopGrid::reverse() const
|
|
|
|
{
|
|
|
|
// no reverse, just clone it
|
|
|
|
return this->clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
// implementation of ReuseGrid
|
|
|
|
|
|
|
|
ReuseGrid* ReuseGrid::create(int times)
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
ReuseGrid* action = new ReuseGrid();
|
2021-12-08 00:11:53 +08:00
|
|
|
if (action->initWithTimes(times))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
action->autorelease();
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete action;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ReuseGrid::initWithTimes(int times)
|
|
|
|
{
|
|
|
|
_times = times;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-12-25 10:04:45 +08:00
|
|
|
void ReuseGrid::startWithTarget(Node* target)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
ActionInstant::startWithTarget(target);
|
|
|
|
cacheTargetAsGridNode();
|
|
|
|
|
|
|
|
if (_gridNodeTarget->getGrid() && _gridNodeTarget->getGrid()->isActive())
|
|
|
|
{
|
|
|
|
_gridNodeTarget->getGrid()->setReuseGrid(_gridNodeTarget->getGrid()->getReuseGrid() + _times);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReuseGrid::cacheTargetAsGridNode()
|
|
|
|
{
|
2021-12-25 10:04:45 +08:00
|
|
|
_gridNodeTarget = dynamic_cast<NodeGrid*>(_target);
|
2019-11-23 20:27:39 +08:00
|
|
|
CCASSERT(_gridNodeTarget, "GridActions can only used on NodeGrid");
|
|
|
|
}
|
|
|
|
|
|
|
|
ReuseGrid* ReuseGrid::clone() const
|
|
|
|
{
|
|
|
|
return ReuseGrid::create(_times);
|
|
|
|
}
|
|
|
|
|
|
|
|
ReuseGrid* ReuseGrid::reverse() const
|
|
|
|
{
|
|
|
|
// no reverse, just clone it
|
|
|
|
return this->clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_CC_END
|