Cocos2d - 将一个精灵从A点移动到B点,以正弦波运动
问题描述:
这样做的最佳方法是什么?我看到了CCEaseSineInOut动作,但它看起来并不像可以用来做到这一点。Cocos2d - 将一个精灵从A点移动到B点,以正弦波运动
我需要从屏幕的一侧移动到另一侧。精灵应该在屏幕上以正弦波形式移动。
答
我总是喜欢完全控制CCNode
议案。我只使用CCAction
来做非常基本的事情。尽管您的情况听起来很简单,可能与CCAction
有关,但我会告诉您如何根据任何功能随时移动CCNode
。您还可以使用相同的技术更改比例,颜色,不透明度,旋转角度,甚至锚点。
@interface SomeLayer : CCLayer
{
CCNode *nodeToMove;
float t; // time elapsed
}
@end
@implementation SomeLayer
// Assumes nodeToMove has been created somewhere else
-(void)startAction
{
t = 0;
// updateNodeProperties: gets called at the framerate
// The exact time between calls is passed to the selector
[self schedule:@selector(updateNodeProperties:)];
}
-(void)updateNodeProperties:(ccTime)dt
{
t += dt;
// Option 1: Update properties "differentially"
CGPoint velocity = ccp(Vx(t), Vy(t)); // You have to provide Vx(t), and Vy(t)
nodeToMove.position = ccpAdd(nodeToMove.position, ccpMult(velocity, dt));
nodeToMove.rotation = ...
nodeToMove.scale = ...
...
// Option 2: Update properties non-differentially
nodeToMove.position = ccp(x(t), y(t)); // You have to provide x(t) and y(t)
nodeToMove.rotation = ...
nodeToMove.scale = ...
...
// In either case, you may want to stop the action if some condition is met
// i.e.)
if(nodeToMove.position.x > [[CCDirector sharedDirector] winSize].width){
[self unschedule:@selector(updateNodeProperties:)];
// Perhaps you also want to call some other method now
[self callToSomeMethod];
}
}
@end
为了您的具体问题,你可以使用选项2 x(t) = k * t + c
,和y(t) = A * sin(w * t) + d
。
数学笔记#1:x(t)
和y(t)
被称为位置参数化。速度参数化为Vx(t)
和Vy(t)
。
数学笔记#2:如果您已经学过微积分,很容易就会发现,选项2可以防止位置误差随时间积累(特别是对于低帧率)。如果可能,请使用选项2.但是,当精度不是问题或用户输入正在改变参数设置时,使用选项1通常会更容易。
使用CCAction
s有许多优点。他们在特定的时间处理您的其他功能。他们保持跟踪,以便您可以轻松暂停并重新启动它们,或对它们进行计数。
但是,如果您确实需要一般管理节点,则可以这样做。例如,对于位置复杂或错综复杂的公式,更改参数化要比找出如何在CCAction
中实施参数化更容易。
您可以使用贝齐尔 - 请参阅http://stackoverflow.com/questions/14589474/cocos2d-2-x-understanding-ccbezierconfig-beheaviour –
如果您想实现正弦波模式比您需要做一些手动工作与cceasesineinout。对于正弦波的一个周期,您必须使用cceasesineinout三次。 – Renaissance