gpt4 book ai didi

ios - SKSpriteNode 跟随 bezier 路径旋转

转载 作者:行者123 更新时间:2023-11-29 12:21:51 28 4
gpt4 key购买 nike

我正在尝试做的事情:使 SKSpriteNode 遵循 UIBezierPath,其中端点是用户触摸的位置。

问题:当用户触摸时,我将位置发送到播放器节点,播放器节点自行处理移动。然而,这仅在播放器节点“指向”向上时有效,例如在第一次触摸时。其他触摸会使玩家移动到错误的点。

描述问题的图片:http://i.stack.imgur.com/nleXj.png
我在 photoshop 中添加了一些解释性内容,所以这里是一个解释:
- Thick > 是我要移动的 SKSpriteNode。
- 紫色方 block 是触摸的确切位置,按顺序编号(实际上是为调试目的添加的 SKSpriteNodes)
- 细箭头是发生触摸时玩家的位置。

我认为问题出在玩家节点坐标系和场景坐标系之间的转换上。
例如:第一次触摸(当玩家 zRotation 没有改变时)将玩家移动到正确的位置。然而,第二个触摸在播放器节点坐标系中位于左侧,但随后它基本上在场景坐标系中向左移动,就好像如果节点旋转指向上方,则触摸随节点一起旋转。

代码:
游戏场景.m:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
[self playRiddle];

CGPoint touchPoint = [touch locationInNode:_player];
[_player moveTo:touchPoint];

SKSpriteNode *n = [SKSpriteNode spriteNodeWithColor:[UIColor purpleColor] size:CGSizeMake(10, 10)];
n.position = [self convertPoint:touchPoint fromNode:_player];
[_worldNode addChild:n];
}
}

播放器.m:

- (void)moveTo:(CGPoint)point {
_moving = YES;
[self removeActionForKey:@"move"];

CGVector vector = [self convertAngleToVector:[self shipOrientation]];
CGPoint controlPoint = CGPointMake(vector.dx, vector.dy);

UIBezierPath *path = [self createPathWindEndPoint:point controlPoint:controlPoint];
SKAction *move = [SKAction followPath:[path CGPath] asOffset:YES orientToPath:YES speed:15];
SKAction *done = [SKAction runBlock:^{
_moving = NO;
}];
[self runAction:[SKAction sequence:@[move, done]] withKey:@"move"];
}

- (UIBezierPath *)createPathWindEndPoint:(CGPoint)endpoint controlPoint:(CGPoint)cp {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointZero];

[path addQuadCurveToPoint:endpoint controlPoint:cp];

//Draw path
SKShapeNode *line = [SKShapeNode node];
line.path = [path CGPath];
[line setStrokeColor:[UIColor darkGrayColor]];
line.position = self.position;
[self.parent addChild:line];

return path;
}

- (CGVector)convertAngleToVector:(CGFloat)radians {
CGVector vector;
vector.dx = cos(radians) * 25;
vector.dy = sin(radians) * 25;
return vector;
}

- (CGFloat)shipOrientation {
return self.zRotation + M_PI_2;
}

_player 节点父级是添加到 GameScene 的 SKNode。我用 [node convertPoint: ..] 尝试了很多东西,但没有成功。会喜欢一些正确方向的指示。

谢谢!

最佳答案

我建议您使用绝对场景坐标而不是相对节点坐标来创建要遵循的路径。以下是如何执行此操作的示例:

游戏场景

1) 在touchesBegan中,进行以下更改,将触摸位置转换为场景坐标

CGPoint touchPoint = [touch locationInNode:self];

Player.m

2) 更改以下内容以在场景坐标中创建路径(见评论)

- (void)moveTo:(CGPoint)point {
_moving = YES;
[self removeActionForKey:@"move"];

CGVector vector = [self convertAngleToVector:[self shipOrientation]];
// Offset the control point by the node's position
CGPoint controlPoint = CGPointMake(vector.dx+self.position.x, vector.dy+self.position.y);

UIBezierPath *path = [self createPathWindEndPoint:point controlPoint:controlPoint];
// Use absolute path
SKAction *move = [SKAction followPath:[path CGPath] asOffset:NO orientToPath:YES speed:15];

SKAction *done = [SKAction runBlock:^{
_moving = NO;
}];
[self runAction:[SKAction sequence:@[move, done]] withKey:@"move"];
}

- (UIBezierPath *)createPathWindEndPoint:(CGPoint)endpoint controlPoint:(CGPoint)cp {
UIBezierPath *path = [UIBezierPath bezierPath];
// Use scene coordinates
[path moveToPoint:self.position];

[path addQuadCurveToPoint:endpoint controlPoint:cp];

//Draw path
SKShapeNode *line = [SKShapeNode node];
line.path = [path CGPath];
[line setStrokeColor:[UIColor darkGrayColor]];
// Line relative to the origin
line.position = CGPointZero;
[self.parent addChild:line];

return path;
}

关于ios - SKSpriteNode 跟随 bezier 路径旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30406802/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com