Cocos2d-x移植的Tween算法

时间:3/14/2012

平台:xcode 4.2 + cocos2d-x  *.11.0 

首先说明,cocos2d-x已经有实现这些算法了,本人只是出于兴趣动手实现下

不知道tween算法的朋友看看这个:

原文链接:http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html

Tween又称为补间动画或中间动画;

上图:

Cocos2d-x移植的Tween算法_第1张图片


//
//  CCTween.h
//  cocos2dUI_b
//
//  Created by rorger on 12-3-12.
//  Copyright 2012年 __MyCompanyName__. All rights reserved.
//

/*
 find more information here:http://www.robertpenner.com/easing/
 http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html
 */
#ifndef cocos2dUI_b_CCTween_h
#define cocos2dUI_b_CCTween_h
#include "cocos2d.h"
#include "platform.h"
USING_NS_CC;
typedef enum {
    CCTweenLinear,
    CCTweenQuadratic,
    CCTweenCubic,
    CCTweenQuartic,
    CCTweenQuintic,
    CCTweenSinusoidal,
    CCTweenExponential,
    CCTweenCircular,
    CCTweenElastic,
    CCTweenBack,
    CCTweenBounce
}CCTweenType;

typedef enum{
    CCTweenEaseIn,
    CCTweenEaseOut,
    CCTweenEaseInOut
}CCTweenEaseType;
 
//Linear,Quadratic,Cubic,Quartic,Quintic,Sinusoidal,Exponential,Circular,Elastic,Back,Bounce
class CCTween {
public:
    CCTween(CCTweenType type,CCTweenEaseType easeType);
    virtual bool init();
    virtual ~CCTween();

    static CCTween* tweenWithTypeEaseType(CCTweenType type,CCTweenEaseType easeType);
    CGFloat Tween(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration, CGFloat a=0, CGFloat p=0, CGFloat s=0);
    CGFloat Linear(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    
    CGFloat Quadratic(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat QuadraticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat QuadraticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat QuadraticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    
    CGFloat Cubic(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat CubicIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat CubicOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat CubicInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    
    CGFloat Quartic(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat QuarticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat QuarticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat QuarticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    
    CGFloat Quintic(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat QuinticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat QuinticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat QuinticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    
    CGFloat Sinusoidal(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat SinusoidalIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat SinusoidalOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat SinusoidalInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    
    CGFloat Exponential(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat ExponentialIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat ExponentialOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat ExponentialInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    
    CGFloat Circular(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat CircularIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat CircularOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat CircularInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    
    CGFloat Elastic(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration, CGFloat a, CGFloat p);
    CGFloat ElasticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p);
    CGFloat ElasticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p);
    CGFloat ElasticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p);
    
    CGFloat Back(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration, CGFloat s);
    CGFloat BackIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat s);
    CGFloat BackOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat s);
    CGFloat BackInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat s);
    
    CGFloat Bounce(CGFloat time, CGFloat beginValue, CGFloat changeValue, CGFloat duration);
    CGFloat BounceIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat BounceOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
    CGFloat BounceInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d);
     
public:
    CC_SYNTHESIZE(CCTweenEaseType, tweenEaseType, TweenEaseType);
    CC_SYNTHESIZE(CCTweenType, tweenType, TweenType);
};
#endif
//
//  CCTween.cpp
//  cocos2dUI_b
//
//  Created by rorger on 12-3-12.
//  Copyright 2012年 __MyCompanyName__. All rights reserved.
//

#include "CCTween.h"
#include "math.h"

#define pi acos(-1.0)

CCTween::CCTween(CCTweenType type,CCTweenEaseType easeType){
    this->tweenType = type;
    this->tweenEaseType = easeType;
}

bool CCTween::init(){
    return true;
}

CCTween* CCTween::tweenWithTypeEaseType(CCTweenType type,CCTweenEaseType easeType){
    CCTween * pRet = new CCTween(type,easeType);
    if (pRet && pRet->init()) {
        return pRet;
    }
    return NULL;
}

CCTween::~CCTween(){
    
}

CGFloat CCTween::Linear(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * (t / d) + b; 
    
}

CGFloat CCTween::Quadratic(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result=0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = QuadraticIn(t, b, c, d);
            break;
        case CCTweenEaseOut:
            result = QuadraticOut(t, b, c, d);
            break;
        case CCTweenEaseInOut:
            result = QuadraticInOut(t, b, c, d);
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}

CGFloat CCTween::QuadraticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * (t /= d) * t + b;
}
CGFloat CCTween::QuadraticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return -c * (t /= d) * (t - 2) + b;
}
CGFloat CCTween::QuadraticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if ((t /= (d/2)) < 1) 
        return c / 2 * t * t + b;
    else
        return -c / 2 * ((--t) * (t - 2) -1) + b;
}

CGFloat CCTween::Cubic(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = CubicIn(t, b, c, d);
            break;
        case CCTweenEaseOut:
            result = CubicOut(t, b, c, d);
            break;
        case CCTweenEaseInOut:
            result = CubicInOut(t, b, c, d); 
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::CubicIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * (t /= d) * t * t + b;
}

CGFloat CCTween::CubicOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
      return c*((t=t/d-1)*t*t + 1) + b;
}

CGFloat CCTween::CubicInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if ((t/=d/2) < 1) return -c/2 * ( sqrt(1 - t*t) - 1) + b;
    return c/2 * ( sqrt(1 - (t-=2)*t) + 1) + b;
}


CGFloat CCTween::Quartic(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = QuarticIn(t, b, c, d); 
            break;
        case CCTweenEaseOut:
            result = QuarticOut(t, b, c, d); 
            break;
        case CCTweenEaseInOut:
            result = QuarticInOut(t, b, c, d); 
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::QuarticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * (t /= d) * t * t * t + b;
}

CGFloat CCTween::QuarticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return -c * ((t=t/d-1)*t*t*t - 1) + b;
}

CGFloat CCTween::QuarticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if ((t /= (d/2)) < 1) 
        return c / 2 * t * t * t *t + b;
    else
        return -c / 2 * ((t -= 2) * t * t *t - 2)+ b;
}



CGFloat CCTween::Quintic(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = QuinticIn(t, b, c, d);
            break;
        case CCTweenEaseOut:
            result = QuinticOut(t, b, c, d);
            break;
        case CCTweenEaseInOut:
            result = QuinticInOut(t, b, c, d);
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::QuinticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * (t /= d) * t * t * t * t + b;
}

CGFloat CCTween::QuinticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * ((t= t/d-1) * t * t *t * t + 1)+ b;
}

CGFloat CCTween::QuinticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if ((t /= (d/2)) < 1) 
        return c / 2 * t * t * t *t * t + b;
    else
        return c / 2 * ((t -= 2) * t * t *t * t+ 2)+ b;
}



CGFloat CCTween::Sinusoidal(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = SinusoidalIn(t, b, c, d);
            break;
        case CCTweenEaseOut:
            result = SinusoidalOut(t, b, c, d);
            break;
        case CCTweenEaseInOut:
            result = SinusoidalInOut(t, b, c, d);
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::SinusoidalIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return -c * cos(t/d * (pi/2)) + c + b;
}

CGFloat CCTween::SinusoidalOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * sin(t/d * (pi/2)) + b;
}

CGFloat CCTween::SinusoidalInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return -c/2 * (cos(pi*t/d) - 1) + b;
}


CGFloat CCTween::Exponential(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = ExponentialIn(t, b, c, d);
            break;
        case CCTweenEaseOut:
            result = ExponentialOut(t, b, c, d);
            break;
        case CCTweenEaseInOut:
            result = ExponentialInOut(t, b, c, d);
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::ExponentialIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return (t==0) ? b : c * pow(2, 10 * (t/d - 1)) + b;
}

CGFloat CCTween::ExponentialOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return (t==d) ? b+c : c * (-pow(2, -10 * t/d) + 1) + b;
}

CGFloat CCTween::ExponentialInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if (t==0) return b;
	if (t==d) return b+c;
	if ((t/=d/2) < 1) return c/2 * pow(2, 10 * (t - 1)) + b;
    return c/2 * (- pow(2, -10 * --t) + 2) + b;
}

CGFloat CCTween::Circular(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = CircularIn(t, b, c, d);
            break;
        case CCTweenEaseOut:
            result = CircularOut(t, b, c, d);
            break;
        case CCTweenEaseInOut:
            result = CircularInOut(t, b, c, d);
			break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::CircularIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return -c * (sqrt(1 - (t/=d)*t) - 1) + b;
}

CGFloat CCTween::CircularOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c * sqrt(1 - (t=t/d-1)*t) + b;
}

CGFloat CCTween::CircularInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if ((t /= (d/2)) < 1) 
		return -c/2 * (sqrt(1 - t*t) - 1) + b;
    else
        return c/2 * (sqrt(1 - (t-=2)*t) + 1) + b;
}



CGFloat CCTween::Elastic(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn: 
            result = ElasticIn(t, b, c, d, a, p); 
            break;
        case CCTweenEaseOut: 
            result = ElasticOut(t, b, c, d, a, p); 
            break;
        case CCTweenEaseInOut: 
            result = ElasticInOut(t, b, c, d, a, p); 
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::ElasticIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p){
    if (t==0) return b;  
    if ((t/=d)==1) return b+c; 
    if (!p) p=d*.3;
    CGFloat s;
	if (!a || a < fabs(c)) {
		a=c;   s=p/4; 
	}
	else 
        s = p/(2*pi) * asin(c/a);
	return -(a*pow(2,10*(t-=1)) * sin( (t*d-s)*(2*pi)/p)) + b;
}

CGFloat CCTween::ElasticOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p){
    if (t==0) return b;  
    if ((t/=d)==1) return b+c;
    if (!p) p=d*.3;
    CGFloat s;
	if (!a || a < fabs(c)){
        a=c;   s=p/4;
    }
	else   s = p/(2* pi) * asin (c/a);
	return  (a*pow(2,-10*t) * sin( (t*d-s)*(2*pi)/p ) + c + b);
}

CGFloat CCTween::ElasticInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p){
    if (t==0) return b;
    if ((t/=d/2)==2) return b+c;
    if (!p) p=d*(.3*1.5);
    CGFloat s;
	if (!a || a < fabs(c)) {
        a=c;   s=p/4;
    }
	else   s = p/(2*pi) * asin (c/a);
	if (t < 1) 
		return -.5*(a*pow(2,10*(t-=1)) * sin( (t*d-s)*(2*pi)/p )) + b;
	else 
		return a*pow(2,-10*(t-=1)) * sin( (t*d-s)*(2*pi)/p )*.5 + c + b;
}


CGFloat CCTween::Back(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat s){//s==-1 as undefined.
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn: 
            result = BackIn(t, b, c, d, s); 
            break;
        case CCTweenEaseOut: 
            result = BackOut(t, b, c, d, s); 
            break;
        case CCTweenEaseInOut: 
            result = BackInOut(t, b, c, d, s); 
            break;
        default:
            CCLog("Error Happen! CCTweenEaseType not set yet\n");
            break;
    }
    return result;
}
CGFloat CCTween::BackIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat s){
	if (s == 0) s = 1.70158; // if s undefined
    return  c*(t/=d)*t*((s+1)*t - s) + b;
}

CGFloat CCTween::BackOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat s){
    if (s == 0) s = 1.70158; // if s undefined
	return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
}

CGFloat CCTween::BackInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat s){
    if (s == 0) s = 1.70158; // if s undefined
	if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
	return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
}


CGFloat CCTween::Bounce(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    CGFloat result = 0;
    switch (tweenEaseType) {
        case CCTweenEaseIn:
            result = BounceIn(t, b, c, d);
            break;
        case CCTweenEaseOut:
            result = BounceOut(t, b, c, d);
            break;
        case CCTweenEaseInOut: 
            result = BounceInOut(t, b, c, d);
            break;
        default:
            break;
    }
    return result;
}
CGFloat CCTween::BounceIn(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    return c- BounceOut(d-t, 0, c, d) + b;
}

CGFloat CCTween::BounceOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if ((t/=d) < (1/2.75)) {
        return c*(7.5625*t*t) + b;
    } else if (t < (2/2.75)) {
        return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    } else if (t < (2.5/2.75)) {
        return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    } else {
        return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    }
}

CGFloat CCTween::BounceInOut(CGFloat t, CGFloat b, CGFloat c, CGFloat d){
    if (t < d/2) return BounceIn(t*2, 0, c, d) * .5 + b;
    else return BounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
}

CGFloat CCTween::Tween(CGFloat t, CGFloat b, CGFloat c, CGFloat d, CGFloat a, CGFloat p , CGFloat s ){
    CGFloat result = 0 ;
    switch (tweenType) {
        case CCTweenLinear:
            result = Linear(t, b, c, d);
            break;
        case CCTweenQuadratic:
            result = Quadratic(t, b, c, d);
            break;
        case CCTweenCubic:
            result = Cubic(t, b, c, d);
            break;
        case CCTweenQuartic:
            result = Quartic(t, b, c, d);
            break;
        case CCTweenQuintic:
            result = Quintic(t, b, c, d);
            break;
        case CCTweenSinusoidal:
            result = Sinusoidal(t, b, c, d);
            break;
        case CCTweenExponential:
            result = Exponential(t, b, c, d);
            break;
        case CCTweenCircular:
            result = Circular(t, b, c, d);
            break;
        case CCTweenElastic:
            result = Elastic(t, b, c, d, a, p);
            break;
        case CCTweenBack:
            result = Back(t, b, c, d, s);
            break;
        case CCTweenBounce:
            result = Bounce(t,b,c,d);
            break;
            
        default:
            CCLog("Error! CCTweenType not set! In CCTween::Tween\n");
            break;
    }
    return result;
}



算法翻译完毕,写个test程序测试:

//
//  CCTweenTest.h
//  cocos2dUI_b
//
//  Created by rorger on 12-3-13.
//  Copyright 2012年 __MyCompanyName__. All rights reserved.
//

#ifndef cocos2dUI_b_CCTweenTest_h
#define cocos2dUI_b_CCTweenTest_h
#include "cocos2d.h"
#include "CCTween.h"
USING_NS_CC;
 
class CCTweenTest:public CCLayerColor{
public:
    CCTweenTest();
    virtual bool init();
    virtual void draw();
    virtual void visit();
    virtual void customVisit();
    virtual void menuEaseChoice(CCObject *pSender);
    virtual void menuTweenChoice(CCObject *pSender);
    virtual void menuCallBack(CCObject* pSender);
    virtual void beginRun();
    virtual void run(ccTime dt);
    CC_SYNTHESIZE(CCLayerColor*, fooLayer, FooLayer)
    CC_SYNTHESIZE(CCLayerColor*, barLayer, BarLayer)
    CC_SYNTHESIZE(CCLayerColor*, fooUnitLayer, FooUnitLayer)
    CC_SYNTHESIZE(CCLayerColor*, barLineLayer, BarLineLayer)
    CC_SYNTHESIZE(CCTween*, tween, Tween)
    
private:
    CGFloat t;
    CGFloat duration;
    bool isInitDone;
    CCMenuItemFont *menuItemRun;
};


#endif

//
//  CCTweenTest.cpp
//  cocos2dUI_b
//
//  Created by rorger on 12-3-13.
//  Copyright 2012年 __MyCompanyName__. All rights reserved.
//
#include "cocos2d.h"
#include "CCTweenTest.h"
#include "CCTween.h"
 
#define kSelectedColor  ccc3((GLubyte)(120),(GLubyte)(20),(GLubyte)(20))
#define kDisSelectedColor  ccc3((GLubyte)255, (GLubyte)255, (GLubyte)255) 
#define kSoftGreenColor ccc4(120, 150, 20,120)
#define kBarLayerHeight 140
#define kBarLayerBaseX 20
#define kBarLayerBaseY 30
#define kFooLayerBaseX 20
#define kFooLayerBaseY 260
#define kSlower 100
#define kFaster 50
USING_NS_CC;

CCTweenTest:: CCTweenTest(){
    isInitDone = false;
    tween = CCTween::tweenWithTypeEaseType(CCTweenLinear , CCTweenEaseIn);
}

bool CCTweenTest::init(){    
    fooLayer = CCLayerColor::layerWithColorWidthHeight(ccc4(120, 120, 120, 255), 400, 40);
    fooUnitLayer = CCLayerColor::layerWithColorWidthHeight(kSoftGreenColor, 40, 40);
    barLayer = CCLayerColor::layerWithColorWidthHeight(ccc4(120, 120,  120, 255), 300, kBarLayerHeight);
    barLineLayer = CCLayerColor::layerWithColorWidthHeight(kSoftGreenColor, 1, kBarLayerHeight);
    
    fooLayer->setAnchorPoint(ccp(0,0));
    fooUnitLayer->setAnchorPoint(ccp(0 ,0));
    barLayer->setAnchorPoint(ccp(0,0));
    barLineLayer->setAnchorPoint(ccp(0,0));
    
    fooLayer->setPosition(ccp(kFooLayerBaseX,kFooLayerBaseY));
    fooUnitLayer->setPosition(ccp(kFooLayerBaseX,260));
    barLayer->setPosition(ccp(kBarLayerBaseX,kBarLayerBaseY));
    barLineLayer->setPosition(ccp(kBarLayerBaseX,kBarLayerBaseY));
    this->addChild(fooLayer);
    this->addChild(fooUnitLayer);
    this->addChild(barLayer);
    this->addChild(barLineLayer);
    CCLayerColor *menuLayer1 = layerWithColorWidthHeight(ccc4(120, 120, 120, 120), 100, 60);
    CCLayerColor *menuLayer2 = layerWithColorWidthHeight(ccc4(120, 120, 120, 120), 100, 210);
    CCLayerColor *menuLayer3 = layerWithColorWidthHeight(ccc4(120, 120, 120, 120), 160,20);
    
    menuLayer1->setAnchorPoint(ccp(0,0));
    menuLayer2->setAnchorPoint(ccp(0,0));
    menuLayer1->setPosition(ccp(220,180));
    menuLayer2->setPosition(ccp(340,30));
    menuLayer3->setPosition(ccp(20,200));
    this->addChild(menuLayer1);
    this->addChild(menuLayer2);
    this->addChild(menuLayer3);
    
    CCMenuItemFont::setFontSize(16);
    char menuArray1[3][100]={"EaseIn", "EaseOut", "EaseInOut"};
    CCMenu * menu1 = CCMenu::menuWithItems(NULL);
    menu1->setPosition(CCPointZero);
    menuLayer1->addChild(menu1);
    for (int i=2; i>=0; i--) {
        CCMenuItemFont *menuEaseItem = CCMenuItemFont::itemFromString(menuArray1[2-i], this,
                                                                      menu_selector(CCTweenTest::menuEaseChoice));
        menuEaseItem->setTag(2-i);
        menuEaseItem->setAnchorPoint(ccp(0,0));
        menuEaseItem->setPosition(ccp(10,i*(int)(menuLayer1->getContentSize().height/3)));
        menu1->addChild(menuEaseItem, 0);
        if (i==2) {
            menuEaseItem->setColor(kSelectedColor);
        }
    }
     
    char menuArray2[11][100]={"Linear",   "Quadratic",  "Cubic",       "Quartic",
                              "Quintic",  "Sinusoidal", "Exponential", "Circular",
                              "Elastic",  "Back",       "Bounce"};
    CCMenuItemFont::setFontSize(16);
    CCMenu * menu2 = CCMenu::menuWithItems(NULL);
    menu2->setPosition(CCPointZero);
    menuLayer2->addChild(menu2);
    for (int i=10; i>=0; i--) {
        CCMenuItemFont *menuItem = CCMenuItemFont::itemFromString(menuArray2[10-i], this,
                                                                  menu_selector(CCTweenTest::menuTweenChoice));
        menuItem->setAnchorPoint(ccp(0,0));
        menuItem->setTag(10-i);
        menuItem->setPosition(ccp(10, i*(int)(menuLayer2->getContentSize().height/11)));
        menu2->addChild(menuItem,0);
        if (i==10) {
            menuItem->setColor(kSelectedColor);
        }
    }
    
    char menuArray3[3][100]={"Faster","Slower","Run"};
    CCMenuItemFont::setFontSize(16);
    CCMenu * menu3 = CCMenu::menuWithItems(NULL);
    menu3->setPosition(CCPointZero);
    menuLayer3->addChild(menu3);
    this->duration = kSlower;
    for (int i=0; i<=2; i++) {
        CCMenuItemFont *menuItem = CCMenuItemFont::itemFromString(menuArray3[i], this,
                                                                  menu_selector(CCTweenTest::menuCallBack));
        menuItem->setAnchorPoint(ccp(0,0));
        menuItem->setTag(i);
        menuItem->setPosition(ccp(i*(int)(menuLayer3->getContentSize().width/3)+10,0));
        menu3->addChild(menuItem,0);
        if (i==1) {
            menuItem->setColor(kSelectedColor);
        }
        if (i==2) {
            this->menuItemRun = menuItem;
        }
    }
    isInitDone = true;
    return isInitDone;
}

void CCTweenTest::menuEaseChoice(CCObject *pSender){
   
    CCMenuItemFont* menuItem = (CCMenuItemFont*)pSender;
    CCLog("Previous EaseType:%d \n", this->tween->getTweenEaseType());
    switch (menuItem->getTag()) {
        case 0:
            this->tween->setTweenEaseType(CCTweenEaseIn);
            break;
        case 1:
            this->tween->setTweenEaseType(CCTweenEaseOut);
            break;
        case 2:
            this->tween->setTweenEaseType(CCTweenEaseInOut);
            break;
        default:
            break;
    }
    printf("Current EaseType :%d\n",menuItem->getTag());
    //set the color of selected menu
    for (int i=0; i<3; i++) {
        CCMenuItemFont *item = (CCMenuItemFont*)menuItem->getParent()->getChildByTag(i);
        item->setColor(kDisSelectedColor);
    }
    menuItem->setColor(kSelectedColor);
}

void CCTweenTest::menuTweenChoice(CCObject *pSender){
 
    CCMenuItemFont* menuItem = (CCMenuItemFont*)pSender;
    printf("Previous TweenType:%d \n", this->tween->getTweenType());
    
    this->tween->setTweenType((CCTweenType)menuItem->getTag());
    printf("Current TweenType :%d\n",menuItem->getTag());
    //set the color of selected menu
    for (int i=0; i<11; i++) {
        CCMenuItemFont *item = (CCMenuItemFont*)menuItem->getParent()->getChildByTag(i);
        item->setColor(kDisSelectedColor);
    }
    menuItem->setColor(kSelectedColor);
}

void CCTweenTest::menuCallBack(CCObject* pSender){
 
    CCMenuItemFont* menuItem = (CCMenuItemFont*)pSender;
    switch (menuItem->getTag()) {
        case 0:{
            CCMenuItemFont* menuItemD =(CCMenuItemFont*)menuItem->getParent()->getChildByTag(1);
            menuItem->setColor(kSelectedColor);
            menuItemD->setColor(kDisSelectedColor);
            this->duration = kFaster;
        }
            break;
        case 1:{
            CCMenuItemFont* menuItemD =(CCMenuItemFont*)menuItem->getParent()->getChildByTag(0);
            menuItem->setColor(kSelectedColor);
            menuItemD->setColor(kDisSelectedColor);
            this->duration = kSlower;
        }
            break;
        case 2:{
            printf("Running....\n");
            this->beginRun();
        }
            break;
        default:
            break;
    }
}


void CCTweenTest::customVisit(){
    if (!isInitDone) {
        CCLog("Not init  yet!\n");
        return;
    }
    
    CGFloat x=0,y=0;
    for (x=0; x<300; x++) {
        y = tween->Tween(x, 0, kBarLayerHeight, 300);
        ccDrawPoint(ccp(x + kBarLayerBaseX, y + kBarLayerBaseY)); 
    }

}

void CCTweenTest::visit(){
    CCLayerColor::visit();
    customVisit();
}

void CCTweenTest::draw(){
    CCLayerColor::draw();
}

void CCTweenTest::beginRun(){
    this->t=0;
    this->menuItemRun->setIsEnabled(false);
    this->schedule(schedule_selector(CCTweenTest::run), 0.01);
}

void CCTweenTest::run(ccTime dt){
    CGFloat  x=0;
    if (this->t <= this->duration) {
        x = tween->Tween(this->t, kFooLayerBaseX, 360, this->duration);
        this->fooUnitLayer->setPosition(ccp(x,kFooLayerBaseY));
        this->barLineLayer->setPosition(ccp(300 * (t/duration) + kBarLayerBaseX, kBarLayerBaseY));
        this->t++;
    }
    else{
        this->unschedule(schedule_selector(CCTweenTest::run));
        this->t=0;
        this->menuItemRun->setIsEnabled(true);
    }
}










说一下注意点:不要随便用autorelease, 如果使用了,则必须retain一次,不管在哪个函数中,必须调用一次。

ps:3.17发现一个bug,在Quintic算法中,switch语句少了一个break语句,已经纠正,另外,在win32平台下,不知道为什么,开始run之后,visit方法中的绘图颜色开始变得暗淡。后来直接在 customvisit方法中加入 glColor4ub (255,255,255,255); 搞定。

你可能感兴趣的:(c,算法,xcode,null,平台,menu)