libcocos2dのソースの中に組み込んでやれば他のActionと同様に呼び出せるようになる。
ソースの中にdefineしてしまっているが自然長や初速度、摩擦係数などを変更すれば動きをもっと激しくすることも可能。
SpringMoveBy.h
#ifndef SPRINGMOVE_H_ #define SPRINGMOVE_H_ #include "cocos2d.h" class CC_DLL SpringMoveBy : public cocos2d::ActionInterval { public: static SpringMoveBy* create(float duration, const cocos2d::Vec2& position, float mass, float k); // // Overrides // virtual SpringMoveBy* clone() const override; virtual SpringMoveBy* reverse(void) const override; virtual void startWithTarget(cocos2d::Node *target) override; /** * @param time In seconds. */ virtual void update(float time) override; CC_CONSTRUCTOR_ACCESS: SpringMoveBy() {} virtual ~SpringMoveBy() {} /** * initializes the action * @param duration in seconds */ bool initWithDuration(float duration, const cocos2d::Vec2& position, float mass, float k); protected: cocos2d::Vec2 _startPosition; cocos2d::Vec2 _delta; float _k; float _mass; cocos2d::Vec2 _previousPos; float _velocity; float _accel; float _position; private: CC_DISALLOW_COPY_AND_ASSIGN(SpringMoveBy); }; #endif /* SPRINGMOVE_H_ */
SpringMoveBy.cpp
#include "SpringMove.h" USING_NS_CC; // // SpringMoveBy // #define GRAVITY 9.80665 // 重力加速度 #define NATURAL_LENGTH 0 // 自然長 #define FIRST_ACCEL GRAVITY // 初期加速度 #define FIRST_VEROCITY 60 // 初期速度 #define FIRST_POSITION 0 // 初期位置 #define FRICTION 0.996 // 摩擦係数 USING_NS_CC; SpringMoveBy* SpringMoveBy::create(float duration, const Vec2& position, float mass, float k) { SpringMoveBy *springMoveBy = new (std::nothrow) SpringMoveBy(); springMoveBy->initWithDuration(duration, position, mass, k); springMoveBy->autorelease(); return springMoveBy; } bool SpringMoveBy::initWithDuration(float duration, const Vec2& position, float mass, float k) { CCASSERT(mass >=0, "Number of mass must be >= 0"); if (ActionInterval::initWithDuration(duration) && mass>=0) { _delta = position; _mass = mass; _k = k; _velocity = FIRST_VEROCITY; _accel = FIRST_ACCEL; _position = FIRST_POSITION; return true; } return false; } SpringMoveBy* SpringMoveBy::clone() const { // no copy constructor auto a = new (std::nothrow) SpringMoveBy(); a->initWithDuration(_duration, _delta, _mass, _k); a->autorelease(); return a; } void SpringMoveBy::startWithTarget(Node *target) { ActionInterval::startWithTarget(target); _previousPos = _startPosition = target->getPosition(); } void SpringMoveBy::update(float t) // _delta = 現在座標 { if (_target) { auto force = -_k * ( _position - NATURAL_LENGTH ) + _mass * GRAVITY; _accel = force / _mass; _velocity += _accel * t; _velocity = _velocity * FRICTION; _position += _velocity * t; #ifdef CC_ENABLE_STACKABLE_ACTIONS Vec2 currentPos = _target->getPosition(); Vec2 diff = currentPos - _previousPos; _startPosition = diff + _startPosition; Vec2 newPos = _startPosition; newPos = _startPosition + Vec2(0,_position); _target->setPosition(newPos); _previousPos = newPos; #else _target->setPosition(_startPosition + Vec2(0, _position)); #endif // !CC_ENABLE_STACKABLE_ACTIONS } } SpringMoveBy* SpringMoveBy::reverse() const { return SpringMoveBy::create(_duration, Vec2(-_delta.x, -_delta.y), _mass, _k); }
動作例 |
0 件のコメント:
コメントを投稿