2011-03-19 10:34:26 +08:00
|
|
|
/****************************************************************************
|
2012-09-24 21:22:20 +08:00
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
2011-03-19 10:34:26 +08:00
|
|
|
Copyright (c) 2008-2010 Ricardo Quesada
|
2011-07-01 15:08:23 +08:00
|
|
|
Copyright (c) 2011 Zynga Inc.
|
2011-03-19 10:34:26 +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.
|
2010-08-05 14:32:04 +08:00
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "CCAction.h"
|
2010-12-22 15:15:04 +08:00
|
|
|
#include "CCActionInterval.h"
|
2013-10-14 14:01:00 +08:00
|
|
|
#include "CCNode.h"
|
2010-08-05 14:32:04 +08:00
|
|
|
#include "CCDirector.h"
|
2013-12-03 14:47:35 +08:00
|
|
|
#include "CCString.h"
|
2010-08-05 14:32:04 +08:00
|
|
|
|
2012-04-18 18:43:45 +08:00
|
|
|
NS_CC_BEGIN
|
2010-08-05 14:32:04 +08:00
|
|
|
//
|
|
|
|
// Action Base Class
|
|
|
|
//
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Action::Action()
|
2013-11-16 21:08:00 +08:00
|
|
|
:_originalTarget(nullptr)
|
|
|
|
,_target(nullptr)
|
2013-08-29 03:42:25 +08:00
|
|
|
,_tag(Action::INVALID_TAG)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
|
|
|
}
|
2012-04-18 18:43:45 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Action::~Action()
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-08-22 11:05:06 +08:00
|
|
|
CCLOGINFO("deallocing Action: %p - tag: %i", this, _tag);
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
2012-04-18 18:43:45 +08:00
|
|
|
|
2013-12-11 17:15:27 +08:00
|
|
|
std::string Action::description() const
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-12-12 09:37:56 +08:00
|
|
|
return StringUtils::format("<Action | Tag = %d", _tag);
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
2012-04-14 19:11:57 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Action::startWithTarget(Node *aTarget)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_originalTarget = _target = aTarget;
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Action::stop()
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
_target = nullptr;
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-07-07 13:01:21 +08:00
|
|
|
bool Action::isDone() const
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
return true;
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Action::step(float dt)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2011-06-10 17:51:37 +08:00
|
|
|
CC_UNUSED_PARAM(dt);
|
2012-04-19 14:35:52 +08:00
|
|
|
CCLOG("[Action step]. override me");
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Action::update(float time)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2011-06-10 17:51:37 +08:00
|
|
|
CC_UNUSED_PARAM(time);
|
2012-04-19 14:35:52 +08:00
|
|
|
CCLOG("[Action update]. override me");
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Speed
|
|
|
|
//
|
2013-06-20 14:13:12 +08:00
|
|
|
Speed::Speed()
|
2013-06-15 14:03:30 +08:00
|
|
|
: _speed(0.0)
|
2013-11-16 21:08:00 +08:00
|
|
|
, _innerAction(nullptr)
|
2013-06-14 08:25:14 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Speed::~Speed()
|
2011-03-19 10:34:26 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
CC_SAFE_RELEASE(_innerAction);
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-11-16 21:08:00 +08:00
|
|
|
Speed* Speed::create(ActionInterval* action, float speed)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
Speed *ret = new Speed();
|
|
|
|
if (ret && ret->initWithAction(action, speed))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
ret->autorelease();
|
|
|
|
return ret;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-16 21:08:00 +08:00
|
|
|
CC_SAFE_DELETE(ret);
|
|
|
|
return nullptr;
|
2011-03-19 10:34:26 +08:00
|
|
|
}
|
2010-08-25 16:08:10 +08:00
|
|
|
|
2013-11-16 21:08:00 +08:00
|
|
|
bool Speed::initWithAction(ActionInterval *action, float speed)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
CCASSERT(action != nullptr, "");
|
|
|
|
action->retain();
|
|
|
|
_innerAction = action;
|
|
|
|
_speed = speed;
|
2012-04-19 14:35:52 +08:00
|
|
|
return true;
|
2011-03-19 10:34:26 +08:00
|
|
|
}
|
2010-08-25 16:08:10 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Speed *Speed::clone() const
|
2013-06-14 08:25:14 +08:00
|
|
|
{
|
2013-06-19 06:06:53 +08:00
|
|
|
// no copy constructor
|
2013-06-20 14:13:12 +08:00
|
|
|
auto a = new Speed();
|
2013-06-15 14:03:30 +08:00
|
|
|
a->initWithAction(_innerAction->clone(), _speed);
|
2013-06-14 08:25:14 +08:00
|
|
|
a->autorelease();
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2013-07-18 07:56:19 +08:00
|
|
|
void Speed::startWithTarget(Node* target)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-07-18 07:56:19 +08:00
|
|
|
Action::startWithTarget(target);
|
|
|
|
_innerAction->startWithTarget(target);
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Speed::stop()
|
2011-03-19 10:34:26 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_innerAction->stop();
|
2013-06-20 14:13:12 +08:00
|
|
|
Action::stop();
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Speed::step(float dt)
|
2011-03-19 10:34:26 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_innerAction->step(dt * _speed);
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-07-07 13:01:21 +08:00
|
|
|
bool Speed::isDone() const
|
2011-03-19 10:34:26 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
return _innerAction->isDone();
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Speed *Speed::reverse() const
|
2011-03-19 10:34:26 +08:00
|
|
|
{
|
2013-06-19 00:59:34 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
return Speed::create(_innerAction->reverse(), _speed);
|
2011-07-01 15:08:23 +08:00
|
|
|
}
|
|
|
|
|
2013-11-16 21:08:00 +08:00
|
|
|
void Speed::setInnerAction(ActionInterval *action)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
if (_innerAction != action)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
CC_SAFE_RELEASE(_innerAction);
|
2013-11-16 21:08:00 +08:00
|
|
|
_innerAction = action;
|
2013-06-15 14:03:30 +08:00
|
|
|
CC_SAFE_RETAIN(_innerAction);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Follow
|
|
|
|
//
|
2013-06-20 14:13:12 +08:00
|
|
|
Follow::~Follow()
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
CC_SAFE_RELEASE(_followedNode);
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-11-16 21:08:00 +08:00
|
|
|
Follow* Follow::create(Node *followedNode, const Rect& rect/* = Rect::ZERO*/)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
Follow *follow = new Follow();
|
|
|
|
if (follow && follow->initWithTarget(followedNode, rect))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
follow->autorelease();
|
|
|
|
return follow;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-11-16 21:08:00 +08:00
|
|
|
CC_SAFE_DELETE(follow);
|
|
|
|
return nullptr;
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Follow* Follow::clone() const
|
2013-06-14 08:25:14 +08:00
|
|
|
{
|
2013-06-19 06:06:53 +08:00
|
|
|
// no copy constructor
|
2013-06-20 14:13:12 +08:00
|
|
|
auto a = new Follow();
|
2013-06-15 14:03:30 +08:00
|
|
|
a->initWithTarget(_followedNode, _worldRect);
|
2013-06-14 08:25:14 +08:00
|
|
|
a->autorelease();
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2013-07-16 03:43:22 +08:00
|
|
|
Follow* Follow::reverse() const
|
|
|
|
{
|
|
|
|
return clone();
|
|
|
|
}
|
|
|
|
|
2013-11-16 21:08:00 +08:00
|
|
|
bool Follow::initWithTarget(Node *followedNode, const Rect& rect/* = Rect::ZERO*/)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
CCASSERT(followedNode != nullptr, "");
|
2012-06-14 15:13:16 +08:00
|
|
|
|
2013-11-16 21:08:00 +08:00
|
|
|
followedNode->retain();
|
|
|
|
_followedNode = followedNode;
|
2013-06-14 08:25:14 +08:00
|
|
|
_worldRect = rect;
|
2013-07-12 14:47:36 +08:00
|
|
|
if (rect.equals(Rect::ZERO))
|
2012-06-14 15:13:16 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_boundarySet = false;
|
2012-06-14 15:13:16 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_boundarySet = true;
|
2012-06-14 15:13:16 +08:00
|
|
|
}
|
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
_boundaryFullyCovered = false;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-12 06:24:23 +08:00
|
|
|
Size winSize = Director::getInstance()->getWinSize();
|
2013-07-12 14:30:26 +08:00
|
|
|
_fullScreenSize = Point(winSize.width, winSize.height);
|
2013-07-11 16:38:58 +08:00
|
|
|
_halfScreenSize = _fullScreenSize * 0.5f;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_boundarySet)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_leftBoundary = -((rect.origin.x+rect.size.width) - _fullScreenSize.x);
|
|
|
|
_rightBoundary = -rect.origin.x ;
|
|
|
|
_topBoundary = -rect.origin.y;
|
|
|
|
_bottomBoundary = -((rect.origin.y+rect.size.height) - _fullScreenSize.y);
|
2012-06-14 15:13:16 +08:00
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
if(_rightBoundary < _leftBoundary)
|
2012-06-14 15:13:16 +08:00
|
|
|
{
|
|
|
|
// screen width is larger than world's boundary width
|
|
|
|
//set both in the middle of the world
|
2013-06-15 14:03:30 +08:00
|
|
|
_rightBoundary = _leftBoundary = (_leftBoundary + _rightBoundary) / 2;
|
2012-06-14 15:13:16 +08:00
|
|
|
}
|
2013-06-15 14:03:30 +08:00
|
|
|
if(_topBoundary < _bottomBoundary)
|
2012-06-14 15:13:16 +08:00
|
|
|
{
|
|
|
|
// screen width is larger than world's boundary width
|
|
|
|
//set both in the middle of the world
|
2013-06-15 14:03:30 +08:00
|
|
|
_topBoundary = _bottomBoundary = (_topBoundary + _bottomBoundary) / 2;
|
2012-06-14 15:13:16 +08:00
|
|
|
}
|
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
if( (_topBoundary == _bottomBoundary) && (_leftBoundary == _rightBoundary) )
|
2012-06-14 15:13:16 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_boundaryFullyCovered = true;
|
2012-06-14 15:13:16 +08:00
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2012-06-14 15:13:16 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
return true;
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
2012-06-14 15:13:16 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Follow::step(float dt)
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2011-06-10 17:51:37 +08:00
|
|
|
CC_UNUSED_PARAM(dt);
|
2010-08-05 14:32:04 +08:00
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
if(_boundarySet)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
// whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
|
2013-06-15 14:03:30 +08:00
|
|
|
if(_boundaryFullyCovered)
|
2012-04-19 14:35:52 +08:00
|
|
|
return;
|
|
|
|
|
2013-07-11 16:38:58 +08:00
|
|
|
Point tempPos = _halfScreenSize - _followedNode->getPosition();
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-07-12 14:11:55 +08:00
|
|
|
_target->setPosition(Point(clampf(tempPos.x, _leftBoundary, _rightBoundary),
|
2013-06-15 14:03:30 +08:00
|
|
|
clampf(tempPos.y, _bottomBoundary, _topBoundary)));
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-07-11 16:38:58 +08:00
|
|
|
_target->setPosition(_halfScreenSize - _followedNode->getPosition());
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2013-07-07 13:01:21 +08:00
|
|
|
bool Follow::isDone() const
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
return ( !_followedNode->isRunning() );
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
2012-06-14 15:13:16 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Follow::stop()
|
2010-08-05 14:32:04 +08:00
|
|
|
{
|
2013-11-16 21:08:00 +08:00
|
|
|
_target = nullptr;
|
2013-06-20 14:13:12 +08:00
|
|
|
Action::stop();
|
2010-08-05 14:32:04 +08:00
|
|
|
}
|
|
|
|
|
2012-04-18 18:43:45 +08:00
|
|
|
NS_CC_END
|
2010-08-05 14:32:04 +08:00
|
|
|
|
|
|
|
|