【问题标题】:How to make "Enemies" orbit around the Player?如何让“敌人”围绕玩家运行?
【发布时间】:2019-08-29 17:29:04
【问题描述】:

我试图让敌人的精灵在玩家精灵靠近时绕着他们旋转。我正在使用极坐标系来找到它们应该停留的点。目前精灵闪烁并且不能正确地保持在适当的位置,我无法完全弄清楚为什么。

使用enemySprite坐标时似乎出现了问题。当使用设定的数字时,没有闪烁,它的行为符合预期。

目前代码将敌人的位置设置在圆圈上,而不是逐渐移动。

        for (auto enemyShip = enemyShipStorage.begin(); enemyShip != enemyShipStorage.end();)
        {
            if (!(*enemyShip).isOffScreen)
            {
                //Finding theta in degrees
                //All positions use floats - sf::Vector2f
                float theta = std::atan2((*enemyShip).m_sprite.getPosition().y - player.m_sprite.getPosition().y, (*enemyShip).m_sprite.getPosition().x - player.m_sprite.getPosition().x) * (180 / 3.141f);

                //normalised so 0 is up
                theta -= 90; 

                if (theta < 0)
                {
                    theta += 360;
                }
                else if (theta > 360)
                {
                    theta -= 360;
                }


                //currently using fixed radius distance while testing
                (*enemyShip).m_endPos.x = player.m_sprite.getPosition().x + (400 * std::cos(theta * (3.141f / 180)));
                (*enemyShip).m_endPos.y = player.m_sprite.getPosition().y + (400 * std::sin(theta * (3.141f / 180)));

                //set position to be at the point on the circle
                (*enemyShip).m_sprite.setPosition((*enemyShip).m_endPos);
         }
         ship++

预期的结果是敌人在玩家周围形成一个圆圈而不闪烁。

只是想提前说声谢谢你的帮助。

【问题讨论】:

  • 次要,但为什么对度数的热爱?坚持使用弧度将有助于在未来解决随机转换错误。此外,很高兴知道职位等是什么类型。最后,直接设置位置是糟糕的游戏编码。它欺骗了眼睛,因为真正的工作与力量一起工作。你最好给你的敌舰“冲”向一个目标点——从长远来看,它看起来会更加现实。
  • 我还想说调试您的位置数学输出 - 确保每个滴答的结果都相同。如果它们不是,那么您就有了闪烁的来源。这可以像 printf 每个 tic 的 x/y 位置一样简单,看看它何时变化。
  • 现在编辑帖子以显示类型。你能给我指出任何与让船只冲向某一点有关的事情吗?读起来会很有趣,因为我不确定我会从哪里开始这样的事情。为了便于阅读,我使用度数将切换到弧度。
  • 通过脉冲,我的意思是应用每 tic 的加速度(对于微积分,基本上意味着每 tic 为速度添加一个值,然后每 tic 将速度添加到您的位置。)困难的部分是知道何时以及如何减速以免超出目标。
  • 它还有助于控制抽动的长度,使其不会以光速运行。使您的游戏同步到 vblank (vsync) 有助于限制模拟运行的速度。不过,您也可以使用其他值。

标签: c++ trigonometry sfml


【解决方案1】:

您使用(*enemyShip).m_sprite.getPosition() 获取位置,计算一些变换,然后使用(*enemyShip).m_sprite.setPosition(...) 设置位置。

想一想。

每一帧,敌舰都会跳到一个新的位置,你会再次变形。该代码完全按照您的要求执行。

相反,您需要两个职位。改造前后。

【讨论】:

  • 如果我保存了最后一个位置,我将如何利用它来使功能稳定。我在转换发生之前使用 getPosition() ,因此它不应该影响之后的结果。然后下一帧它将再次计算转换,但基于其新位置。
  • 如果不查看其余代码,这是不可能的。你如何产生敌人,并在一般情况下移动它们?
  • 所以目前我只是在屏幕上生成了一些敌人。它们以不同的起始位置生成。我现在禁用了他们正在使用的移动功能,以便我可以更好地测试这个功能而不会干扰
  • 那么只需将theta -= 90; 替换为theta += 1; 船就会绕着你的船转一圈,但速度取决于FPS,并且由于数值精度而缓慢地远离/靠近。
  • 值得一提的是,我注意到闪烁是因为船旋转得非常快。即使将 theta 设置为 +=1,它也会以荒谬的速度旋转。当我打印输出时,它似乎不合逻辑。它从 0 到 325.773,然后到 2.12,最后到 55.72。我还想说谢谢你的坚持和帮助。我很感激:)
猜你喜欢
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多