標籤:style blog http io os ar for sp 檔案
1.
跟我合作的美工兼策劃說要給主角加上主角光環,繞橢圓形移動。cocos2d內建沒有,參考網上的寫了一個。
2.橢圓數學知識
有關橢圓的數學知識我已經忘光了!網上找了點資料:
a是橢圓的長半軸,b是橢圓的短半軸。 o是角度,範圍是[0, 2π]。我們需要知道橢圓上的位置,可以用下面的公式:
3.直接代碼了..
OvalActionInterval.h
#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
OvalActionInterval.cpp
#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);}
參考:http://blog.csdn.net/ufolr/article/details/7447773
我這裡還加上了zOrder,這樣有透視效果。
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));
http://www.waitingfy.com/archives/1343
cocos2d 繞橢圓移動