cocos2d 绕椭圆移动

网友投稿 273 2022-09-16

cocos2d 绕椭圆移动

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 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);}

我这里还加上了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));

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:奥术飞弹打死精灵龙的概率
下一篇:Elasticsearch 入门
相关文章

 发表评论

暂时没有评论,来抢沙发吧~