标签:style blog http io os ar for sp 文件
#ifndef __JumpGame__OvalInterval__
#define __JumpGame__OvalInterval__
#include "CCActionInterval.h"//包含系统延时类动作头文件
using namespace cocos2d;
// 定义一个结构来包含确定椭圆的参数
typedef struct OvalConfig {
    //中心点坐标
    Vec2 centerPosition;
    //椭圆a长半轴
    float a;
    //椭圆b短半轴
    float b;
    //是否逆时针运动
    bool moveInAnticlockwise;
    //two zOrder
    std::pair<int, int> zOrder;
} lOvalConfig;
/**
  以椭圆方式移动
*/
class CC_DLL MoveOvalBy : public ActionInterval{
public:
    MoveOvalBy();
    //用“动作持续时间”和“椭圆控制参数”初始化动作
    bool initWithDuration(float t, const OvalConfig& c);
    virtual MoveOvalBy* clone() const override;
    virtual MoveOvalBy* reverse() const override;
    virtual void update(float t);//利用update函数来不断的设定坐标
    virtual void startWithTarget(Node *target) override;
public:
    //用“动作持续时间”和“椭圆控制参数”创建动作
    static MoveOvalBy *create(float t, const OvalConfig& c);
    
protected:
    OvalConfig _config;
    
    //x = a * cos(t)  t = [0, 2Pi]
    inline float getPositionXAtOval(float t ){//返回X坐标
        //参数方程
        if(_config.moveInAnticlockwise == false){
            return _config.a * cos(6.2831852 * (1 - t));
        }else{
            return _config.a * cos(6.2831852 * t);
        }
        
    }
    //y = b * sin(t)  t = [0, 2Pi]
    inline float getPositionYAtOval(float t ){//返回Y坐标
        //参数方程
        if(_config.moveInAnticlockwise == false){
            return _config.b * sin(6.2831852 * (1 - t));
        }else{
            return _config.b * sin(6.2831852 * t);
        }
    }
private:
    CC_DISALLOW_COPY_AND_ASSIGN(MoveOvalBy);
};
#endif 
#include "OvalActionInterval.h"
MoveOvalBy::MoveOvalBy(){
}
//
//MoveOvalBy
//
MoveOvalBy* MoveOvalBy::create(float t, const OvalConfig& c){//利用之前定义的椭圆的参数初始化椭圆
    MoveOvalBy *action = new MoveOvalBy();
    action->initWithDuration(t, c);
    action->autorelease();
    
    return action;
}
bool MoveOvalBy::initWithDuration(float t, const OvalConfig& c){
    if (ActionInterval::initWithDuration(t)){
        _config = c;
        return true;
    }
    
    return false;
}
void MoveOvalBy::update(float t){
    //t [0, 1]
    //log("t:%f", t);
    if (_target){
        float x = getPositionXAtOval(t);//调用之前的坐标计算函数来计算出坐标值
        float y = getPositionYAtOval(t);
        _target->setPosition(_config.centerPosition + Vec2(x, y));//由于我们画计算出的椭圆你做值是以原点为中心的,所以需要加上我们设定的中心点坐标
        
        if(t <= 0.5){
            _target->setLocalZOrder(_config.zOrder.first);
        }else{
            _target->setLocalZOrder(_config.zOrder.second);
        }
    }
}
MoveOvalBy* MoveOvalBy::clone() const{
    auto action = new MoveOvalBy();
    action->initWithDuration(_duration, _config);
    action->autorelease();
    return action;
}
MoveOvalBy* MoveOvalBy::reverse() const{
    OvalConfig newConfig;
    newConfig.centerPosition = _config.centerPosition;
    newConfig.a = _config.a;
    newConfig.b = _config.b;
    newConfig.moveInAnticlockwise = !_config.moveInAnticlockwise;
    newConfig.zOrder = _config.zOrder;
    return MoveOvalBy::create(_duration, newConfig);
}
void MoveOvalBy::startWithTarget(Node *target){
    ActionInterval::startWithTarget(target);
}a等于b的时候就是圆形了。
有时候在游戏中稍微用上点数学知识感觉很爽。
调用如下:
auto size = this->getContentSize();
 
    auto ball = Sprite::createWithSpriteFrameName("defenceBall.png");
    this->addChild(ball);
    ball->setPosition(Vec2(size.width * 0.5, size.height * 0.5) + Vec2(0, 10));
 
    OvalConfig config;
    config.a = 100;
    config.b = 20;
    config.centerPosition = ball->getPosition();
    config.moveInAnticlockwise = true;
    config.zOrder = make_pair(-1, 0);
    auto moveAction = MoveOvalBy::create(1.0, config);
 
    ball->runAction(RepeatForever::create(moveAction));标签:style blog http io os ar for sp 文件
原文地址:http://blog.csdn.net/fox64194167/article/details/40479793