时间: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又称为补间动画或中间动画;
上图:
//
// 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); 搞定。