这是与语言无关的问题,更多的是关于我的游戏模型。
我有一个带有元素的蛇游戏,但我平滑地移动元素,它们不只是每次移动 1 个块,而是每帧移动一些像素。
我有一个计算元素位置的更新循环,但我坚持正确的计算。
我有每个元素的标题:
typedef NS_ENUM(int, kElementHeading)
{
kElementHeadingNorth = 1,
kElementHeadingSouth,
kElementHeadingEast,
kElementHeadingWest
};
我还有速度 (x, y) 来确定蛇的前进方向。我的蛇运动有问题,因为我的元素位置错误。我设法将事物本地化为 2 个元素,但我的解决方案在更多元素上失败。
我尝试的第一个解决方案是保存头部改变方向的旋转点。这是有效的,但由于不同的情况,元素每转可以移动不同数量的像素。通常该元素会跳过这一点。我尝试增加它应该旋转的区域,但它增加了错误。我尝试修复这个错误,但元素仍然会与蛇分开(经常)。
在第二次尝试时,我决定将蛇头保持在屏幕的中心并围绕它移动世界。它适用于 2 个元素,因为我只是平稳地将下一个元素移动到相对于头部的所需位置。但这在更多元素上严重失败。如果你快速转弯,他们就会开始跳舞,而不是跟随路径。
我尝试的第三件事是为其他元素留下一条路径。但这不起作用,因为我打算将我的蛇放在屏幕的中央,而且从技术上讲,它永远不会移动以创建路径。
我希望复制像 Nimble Quest(或任何蛇)中的运动模式。
我应该如何实现蛇元素移动而没有错误?
这是我的第一种方法的代码,问题在于元素通常会脱落。代码是不言自明的。旋转点是改变方向的地方。
CFTimeInterval delta = self.lastTime - currentTime;
CGPoint currentPosition = self.playerSnake.head.sprite.position;
CGPoint velocity = self.playerSnake.velocity;
self.playerSnake.head.sprite.position = CGPointMake(currentPosition.x + velocity.x * delta * CONSTANTSPEEDFACTOR , currentPosition.y + velocity.y * delta * CONSTANTSPEEDFACTOR);
for (SnakeElement *element in self.playerSnake.elements) {
CGPoint currentPositionE = element.sprite.position;
CGPoint velocityE = element.velocity;
element.sprite.position = CGPointMake(currentPositionE.x + velocityE.x * delta * CONSTANTSPEEDFACTOR , currentPositionE.y + velocityE.y * delta * CONSTANTSPEEDFACTOR);
}
BOOL markToDelete = NO;
NSDictionary *deleteDictionary;
for (NSDictionary *dict in self.playerSnake.rotationPoints) {
CGPoint positionCoordinate = CGPointFromString(dict[@"position"]);
CGPoint velocityNew = CGPointFromString(dict[@"velocity"]);
double newAngle = [dict[@"angle"] doubleValue];
for (SnakeElement *element in self.playerSnake.elements) {
int xDifference = element.sprite.position.x - positionCoordinate.x;
int yDifference = element.sprite.position.y - positionCoordinate.y;
if ((xDifference > -2 && xDifference < 2) && (yDifference > -2 && yDifference < 2) ) {
element.velocity = velocityNew;
element.sprite.position = CGPointMake(element.sprite.position.x + xDifference, element.sprite.position.y + yDifference);
SKAction *action = [SKAction rotateToAngle:newAngle duration:0.2 shortestUnitArc:YES];
[element.sprite runAction:action];
if ([element isEqual:[self.playerSnake.elements lastObject]]) {
markToDelete = YES;
deleteDictionary = dict;
}
}
}
}
[self.playerSnake.rotationPoints removeObject:deleteDictionary];
如果我尝试增加转折点的捕捉区域,则元素往往会比宽度为 1 或 2 个像素时更频繁地脱落。我不确定为什么会发生这种情况。
最佳答案
这就是我建议您在评论中处理转折点的做法:
1..根据速度和自上一帧以来耗时计算元素应移动该帧的距离。 (三角洲)
2.. 计算元素当前位置到转折点的距离。这是我在评论中提到的 beforeDistance
3.. 计算元素在转弯后应向新目标转弯点移动的距离afterDistance = distanceToMoveThisFrame - beforeDistance
4.. 计算元素的新位置,从当前转折点开始,使用 afterDistance
朝向元素的下一个目标转折点
如果你遵循这个逻辑,你将永远不会超过或低于转折点。
关于ios - 平稳的蛇运动,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22289872/