平台游戏中的 Sprite Kit NPC 随机移动

Posted

技术标签:

【中文标题】平台游戏中的 Sprite Kit NPC 随机移动【英文标题】:Sprite Kit NPC random movement in a platform game 【发布时间】:2014-12-23 11:00:34 【问题描述】:

我在 Stack Overflow 上寻找解决方案,但没有找到解决随机 NPC 移动的问题。本质上,到目前为止我编写的代码是一个使用 Sprite Kit 的简单 2D 平台游戏:NPC 对象有一个单独的类。我在我的 GameScene (SKScene) 中初始化它没问题,到目前为止它的行为与我正确设置的物理世界一致。现在我正处于它只需要在任何方向上随机移动的部分。我已经设置了边界并使它与SKActions之类的东西一起移动,利用CGPointMake之类的东西,它会根据需要随机移动NPC,让它在那个位置稍等片刻并恢复移动。 BOOL 帮助了这个过程。但是,我很难让精灵在向左移动时向左看,在向右移动时向右看(根本不需要向上和向下看)。所以我在书中找到了一种使用 Vector 的方法。我在 GameScene 中使用的 NPC 类中设置了一个方法:

-(void)moveToward:(CGPoint)targetPosition

    CGPoint targetVector = CGPointNormalize(CGPointSubtract(targetPosition, self.position));
    targetVector = CGPointMultiplyScalar(targetVector, 150); //150 is interpreted as a speed: the larger the # the faster the NPC moves.
    self.physicsBody.velocity = CGVectorMake(targetVector.x, targetVector.y); //Velocity vector measured in meters per second.


    /*SPRITE DIRECTION*/
    [self faceCurrentDirection]; //Every time NPC begins to move, it will face the appropriate direction due to this method.

现在这一切都奏效了。但是手头的问题是在 update 方法中适当地调用这个 moveToward 方法。我尝试的第一件事是:

-(void)update:(NSTimeInterval)currentTime

    /*Called before each frame is rendered*/

    if (!npcMoving)
    
        SKAction *moving            = [SKAction runBlock:^ npcMoving = YES ]; //THIS IS THE CULPRIT!
        SKAction *generate          = [SKAction runBlock:^ [self generateRandomDestination]; ]; //Creates a random CGFloat X & CGFloat Y.
        SKAction *moveTowards       = [SKAction runBlock:^ _newLocation = CGPointMake(fX, fY);
                                                            [_npc moveToward:_newLocation]; ]; //Moves NPC to that random location.
        SKAction *wait              = [SKAction waitForDuration:4.0 withRange:2.0]; //NPC will wait a little...
        [_npc runAction:[SKAction sequence:@[moving, generate, moveTowards, wait]] completion:^ npcMoving = NO; ]; //...then repeat process.
    

矢量方法“moveToward”需要存在“update”方法才能发生 NPC 移动。我在开始时使用“npcMoving = YES”将其关闭,希望 NPC 将移动到目标位置并重新开始该过程。不是这种情况。如果我用'npcMoving = YES'删除SKAction,'update'方法每帧都会调用上述SKActions的整个序列,这反过来不会让我的NPC移动太远。它只是让它每帧更改目标位置,进而创建一个“多动症”NPC。有人可以推荐做什么吗?我绝对需要为方向属性和其他未来事物保留矢量移动,但我不知道如何使用“更新”方法正确实现这一点。

【问题讨论】:

【参考方案1】:

动作随着时间的推移执行任务。如果你的 npcMoving 标志为假,你每帧运行一个动作序列,这意味着超过 10 帧你将有 10 个动作序列同时运行。这将导致未定义的行为。

接下来,即使您要停止现有序列并重新运行它,在至少有一个动作有持续时间的每一帧运行一个动作实际上也是没有意义的。因为那样的话,具有持续时间的动作将无法在给定时间内完成其任务,因为它将在下一帧被替换。

总结:有持续时间的动作不适合每帧都需要调整的任务。

解决方案:

在需要时(即每一帧)通过更改演员的属性(即位置等)来执行任务 为参与者决定一项任务,然后为该任务运行相应的动作序列并等待它结束,然后再决定一项新任务

【讨论】:

所以我不得不重读你写的几遍才能真正了解所有内容,但现在我让该死的NPC按我的意愿移动!非常感谢大师老师!

以上是关于平台游戏中的 Sprite Kit NPC 随机移动的主要内容,如果未能解决你的问题,请参考以下文章

如何将你的Sprite Kit游戏从iOS移植到Mac OS X平台

如何确定节点出现在 sprite kit 中的顺序

Swift Sprite Kit 中的游戏中心

游戏中的三角学——Sprite Kit 和 Swift 教程

游戏中的三角学——Sprite Kit 和 Swift 教程

使用 Swift 在 Sprite Kit 游戏中重置高分