这是与语言无关的问题,更多的是关于我的游戏模型。

我有一个带有元素的蛇游戏,但我平滑地移动元素,它们不只是每次移动 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/

10-11 00:46