最近我在Spritekit中编码 我需要的是在SKNode移动时找到贝塞尔曲线的一个点跟随UIBezierPath.BTW贝塞尔曲线只有一个控制点。 我使用贝塞尔曲线方程来找到' t'并使用这个' t'为了得到这一点,我发现我的代码恰好符合"直线" bezier曲线。如果有一条大曲线,我就错了,我认为SKNode的速度不恒定。我很高兴知道哪里不对或得到其他解决方案。 这是我的代码,它用于测试。
-(void)setupTestCurve
{
float ts =0.56f;
float timeofmove = 5.0f;
SKSpriteNode* arrow = [SKSpriteNode spriteNodeWithImageNamed:@"blue_b_01"];
arrow.scale = 0.8;
arrow.anchorPoint = CGPointMake(0.5, 0.5);
[background addChild:arrow];
CGPoint point1 = CGPointMake(400, 400);
CGPoint point2 = CGPointMake(800, 100);
CGPoint controlP = CGPointMake(100, 100);
[ToolObjective setupTestCurve:(SKSpriteNode *)background startp:point1 endp:point2 anchorPoint:controlP];
CGPoint ps = [ToolObjective get3dPointbezierInterpolation:ts startp:point1 controlp:controlP endp:point2];
float twill = [ToolObjective get3dTofbezierInterpolation:point1 nowPoint:ps endp:point2 anchorPoint:controlP];
SKAction *w = [SKAction waitForDuration:twill * timeofmove];
SKAction *paction = [SKAction runBlock:^{
[ToolObjective setupTestpoint:background startp:ps color:[UIColor redColor]];
}];
SKAction *m = [SKAction sequence:@[w,paction]];
CGPathRef patharrow = [ToolObjective Get3dBezierPath:point1 endPoint:point2 anchorPoint:controlP];
SKAction *moveBow = [SKAction followPath:patharrow asOffset:NO orientToPath:YES duration:timeofmove];
[arrow runAction:[SKAction group:@[m,moveBow]]];
}
这是工具功能
/*
add a bezier curve to the background
*/
+(void)setupTestCurve:(SKSpriteNode *)background startp:(CGPoint)startPoint endp:(CGPoint)endpoint anchorPoint:(CGPoint)anchorPoint
{
UIBezierPath *path=[UIBezierPath bezierPath];
[path moveToPoint:startPoint];
[path addQuadCurveToPoint:endpoint controlPoint:anchorPoint];
SKShapeNode *circle = [SKShapeNode node];
circle.path = path.CGPath;
[background addChild:circle];
}
/*
get point on a bezier curve with 't'
*/
+(CGPoint) get3dPointbezierInterpolation:(CGFloat)t startp:(CGPoint)startp controlp:(CGPoint)controlp endp:(CGPoint)endp
{
CGFloat q0x = (1 - t) * startp.x + t * controlp.x;
CGFloat q1x = (1 - t) * controlp.x + t * endp.x;
CGFloat x = (1 - t) * q0x + t * q1x;
CGFloat q0y = (1 - t) * startp.y + t * controlp.y;
CGFloat q1y = (1 - t) * controlp.y + t * endp.y;
CGFloat y = (1 - t) * q0y + t * q1y;
return CGPointMake(x, y);
}
/*
get 't' of a bezier curve with a point on this bezier curve
*/
+(CGFloat) get3dTofbezierInterpolation:(CGPoint)startp nowPoint:(CGPoint)nowp endp:(CGPoint)endp anchorPoint:(CGPoint)controlp
{
CGFloat ax = (startp.x - 2 * controlp.x + endp.x);
CGFloat bx = (2 * (controlp.x - startp.x));
CGFloat cx = (startp.x - nowp.x);
CGFloat tx1,tx2;
CGFloat px = bx * bx - 4 * ax * cx;
if (px >= 0) {
tx1 = (-bx + sqrt(px)) / (2 * ax);
tx2 = (-bx - sqrt(px)) / (2 * ax);
}
if (tx1 == tx2) {
return tx1;
}
CGFloat ay = (startp.y - 2 * controlp.y + endp.y);
CGFloat by = (2 * (controlp.y - startp.y));
CGFloat cy = (startp.y - nowp.y);
CGFloat ty1,ty2;
CGFloat py = by * by - 4 * ay * cy;
if (py >= 0) {
ty1 = (-by + sqrt(py)) / (2 * ay);
ty2 = (-by - sqrt(py)) / (2 * ay);
}
if (ty1 == ty2) {
return ty1;
}
if (fabsf(tx1 - ty1) < 0.0001)
return tx1;
else if (fabsf(tx1 - ty2) < 0.0001) {
return tx1;
}
else if (fabsf(tx2 - ty1) < 0.0001) {
return tx2;
}
else if (fabsf(tx2 - ty2) < 0.0001) {
return tx2;
}
return 0;
}
/*
get bezier curve path with just one anchorPoint
*/
+(CGPathRef)Get3dBezierPath:(CGPoint)startPoint endPoint:(CGPoint)endPoint anchorPoint:(CGPoint)anchorPoint
{
UIBezierPath *path=[UIBezierPath bezierPath];
[path moveToPoint:startPoint];
[path addQuadCurveToPoint:endPoint controlPoint:anchorPoint];
return path.CGPath;
}
/*
add a point on bezier curve
*/
+(void)setupTestpoint:(SKSpriteNode *)background startp:(CGPoint)point color:(UIColor *)color
{
SKShapeNode *cpoint = [SKShapeNode node];
UIBezierPath *ppath = [UIBezierPath bezierPathWithRect:CGRectMake(point.x,point.y,10,10)];
cpoint.fillColor = color;
cpoint.path = ppath.CGPath;
[background addChild:cpoint];
}
您可以在项目中使用这些代码进行测试。 非常感谢你!
一天后,我发现sknode不是沿着bezier路径移动的恒定速度。使用此方法。
for (float i = 0; i < 1.0001f; i+=0.10f) {
CGPoint ps = [ToolObjective get3dPointbezierInterpolation: i startp:point1 controlp:controlP endp:point2];
[ToolObjective setupTestpoint:background startp:ps color:[UIColor yellowColor]];
}
因此,关键问题是找到一种方法使sknode具有恒定的速度。 我会在这里发布我的解决方案。或者你已经知道了,请告诉我!