cocos2d-x 3.2 椭圆运动


直接上代码:

//
//  OvalAction.h
//  LSWGameIOS
//
//  Created by lsw on 14-10-27.
//
//

#ifndef __LSWGameIOS__OvalAction__
#define __LSWGameIOS__OvalAction__

#include "cocos2d.h"

typedef struct OvalConfig {
    cocos2d::Vec2 centerPos;
    float a;
    float b;
    bool moveClockDir;
    std::pair<int, int> zOrder;
}LOvalConfig;

class MoveOvalBy : public cocos2d::ActionInterval {
public:
    MoveOvalBy();
    ~MoveOvalBy();
    
    bool initWithDuration(float dt, const OvalConfig& c);
    virtual MoveOvalBy* clone() const override;
    virtual MoveOvalBy* reverse() const override;
    virtual void update(float dt);
    virtual void startWithTarget(cocos2d::Node *target) override;
    
    static MoveOvalBy* create(float dt, const OvalConfig& c);
    
protected:
    OvalConfig _config;
    
    inline float getPosXAtOval(float dt) {
        if (_config.moveClockDir) {
            return _config.a * cos(4 * MATH_PIOVER2 * dt);
        }
        return _config.a * cos(4 * MATH_PIOVER2 * (1 - dt));
    }
    
    inline float getPosYAtOval(float dt) {
        if (_config.moveClockDir) {
            return _config.b * sin(4 * MATH_PIOVER2 * dt);
        }
        return _config.b * sin(4 * MATH_PIOVER2 * (1 - dt));
    }
    
    
};

#endif /* defined(__LSWGameIOS__OvalAction__) */


cpp文件:

//
//  OvalAction.cpp
//  LSWGameIOS
//
//  Created by lsw on 14-10-27.
//
//

#include "OvalAction.h"

USING_NS_CC;

MoveOvalBy::MoveOvalBy()
{
    
}

MoveOvalBy::~MoveOvalBy()
{
    
}

MoveOvalBy *MoveOvalBy::create(float dt, const OvalConfig &c)
{
    auto moveOvalBy = new MoveOvalBy();
    if (moveOvalBy && moveOvalBy->initWithDuration(dt, c))
    {
        moveOvalBy->autorelease();
        return moveOvalBy;
    }
    
    return nullptr;
}

bool MoveOvalBy::initWithDuration(float dt, const OvalConfig &c)
{
    if (ActionInterval::initWithDuration(dt))
    {
        _config = c;
        return true;
    }
    
    return false;
}

void MoveOvalBy::update(float dt)
{
    if (_target)
    {
        float x = getPosXAtOval(dt);
        float y = getPosYAtOval(dt);
        _target->setPosition(_config.centerPos + Vec2(x, y));
        if (dt <= 0.5)
        {
            _target->setZOrder(_config.zOrder.first);
        }
        else
        {
            _target->setZOrder(_config.zOrder.second);
        }
    }
}

MoveOvalBy *MoveOvalBy::clone() const
{
    auto moveOvalBy = new MoveOvalBy();
    if (moveOvalBy && moveOvalBy->initWithDuration(_duration, _config))
    {
        moveOvalBy->autorelease();
        return moveOvalBy;
    }
    
    return nullptr;
}

MoveOvalBy *MoveOvalBy::reverse() const
{
    OvalConfig newConfig;
    newConfig.a = _config.a;
    newConfig.b = _config.b;
    newConfig.centerPos = _config.centerPos;
    newConfig.moveClockDir = !_config.moveClockDir;
    newConfig.zOrder = _config.zOrder;
    return MoveOvalBy::create(_duration, newConfig);
}

void MoveOvalBy::startWithTarget(Node *target)
{
    ActionInterval::startWithTarget(target);
}


调用方法:

auto s1 = Sprite::create("CloseSelected.png");
    addChild(s1);
    s1->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
    auto s2 = Sprite::create("CloseNormal.png");
    addChild(s2);
    OvalConfig c;
    c.a = 100;
    c.b = 10;
    c.centerPos = s1->getPosition();
    c.moveClockDir = false;
    c.zOrder.first = -1;
    c.zOrder.second = 1;
    s2->runAction(RepeatForever::create(MoveOvalBy::create(1.0f, c)));








原文地址:https://www.cnblogs.com/shiweihappy/p/4246414.html