最好的方法是什么?我看到了 CCEaseSineInOut 操作,但它看起来不能用于执行此操作。
我需要从屏幕的一侧移动到另一侧。精灵应该在屏幕上以正弦波模式移动。
最好的方法是什么?我看到了 CCEaseSineInOut 操作,但它看起来不能用于执行此操作。
我需要从屏幕的一侧移动到另一侧。精灵应该在屏幕上以正弦波模式移动。
我总是喜欢完全控制CCNode
运动。我只使用CCAction
s 来做非常基本的事情。虽然您的情况听起来很简单,可能与CCAction
s 一起使用,但我将向您展示如何CCNode
随着时间的推移根据任何函数移动 a。您还可以使用相同的技术更改比例、颜色、不透明度、旋转甚至锚点。
@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
s 中实现该参数化要容易得多。