【问题标题】:Pong: How does the paddle know where the ball will hit?Pong:桨怎么知道球会打到哪里?
【发布时间】:2011-01-02 09:19:02
【问题描述】:

在实现 Pacman 和 Snake 之后,我正在实现下一个非常经典的游戏:Pong。

实现非常简单,但我只剩下一个小问题。当其中一个桨(我不确定它是否称为桨)由计算机控制时,我很难将它定位在正确的位置。

球有一个当前位置、一个速度(目前是恒定的)和一个方向角。所以我可以计算出它会碰到电脑控制的桨的位置。所以我可以把桨放在那里。但是在真正的比赛中,电脑的球拍有可能会错过球。我怎样才能实现这个概率?

如果我只使用计算机的球拍击球的概率假设为 0.5,那么问题就解决了,但我认为并不是那么简单。

从最初的游戏来看,我认为概率取决于当前桨位置与球击中边界的位置之间的距离。

有人知道这是如何计算的吗?

【问题讨论】:

    标签: algorithm artificial-intelligence pong


    【解决方案1】:

    引用非常有趣的书“Racing the Beam”(Google 图书:http://books.google.co.uk/books?id=DqePfdz_x6gC&lpg=PP1&dq=racing%20the%20beam&pg=PA40#v=onepage&q&f=false),原始技术是:

    为了帮助模拟精确桨叶定位中固有的人为错误,AI 桨叶每八帧跳过一次调整。由此产生的行为明显不明显,但它允许计算机玩家的目标漂移到足以使其偶尔错过球。它在技术上实现起来也很简单,只需要一个掩码和二进制 AND 操作,为此存在相应的 6502 指令。程序员可以使用另一个单独的操作码测试结果是否为零,如果需要跳转以跳过移动桨的指令。

    即使是这种行为也必须稍作修改才能使游戏正常运行。如果 AI 球员每 8 帧就停止跟踪球,那么它会在几秒钟内失去同步,这是无可救药的。为了防止这种情况发生,AI 在球场顶部和底部附近遵循辅助球跟踪方案。如果球与其中一个墙壁发生碰撞,而桨也与之对齐,则桨会重新调整,从球上次撞击墙壁以来积累的任何漂移中恢复。结果是计算机桨和球的随机错位和重新对齐。

    【讨论】:

      【解决方案2】:

      我们为我们的高中 CS 课制作了一个(伪)3D 乒乓球游戏。我们所做的是,我们让计算机始终将球拍向球移动,但以最大速度移动——这样,如果球太远,它可能会错过球,但它仍然很聪明。这有帮助吗?

      【讨论】:

      • 当我在大学时,我们通过将桨的中心设置为等于球的中心(减去半径)来做到这一点。计算机不可能错过。
      【解决方案3】:

      我认为您应该让球拍始终从其当前位置移动到特定点,这将是预计球与球拍垂直对齐的位置。然后,您可能有 50% 的机会让球拍移动到这个确切的点并偏转球,有 25% 的机会它会过冲,可能会超出一些 X 像素,还有 25% 的机会会过冲。一个更好的方法可能是让它移动到钟形曲线上的那个位置,这样它每次都会错过不同的数量。

      【讨论】:

        【解决方案4】:

        其他答案讨论了如何在不同情况下确定正确的前进方向。您还可以通过开始朝这个方向移动,在电脑玩家“做出反应”之前添加一个延迟时间——这反映了人类玩家的典型反应。

        【讨论】:

          【解决方案5】:

          我不确定“官方”的做法是什么,但我一直只是使用(伪代码)

          if (ball is above paddle) {
              move paddle up
          }
          if (ball is below paddle) {
              move paddle down
          }
          

          然后我给了球拍一个稍微变化的速度,这个速度足够慢,以至于它不能总是跟上球。有点粗糙,但它有效。

          这个帖子还有一些你可能想看看的有趣想法:http://www.gamedev.net/community/forums/topic.asp?topic_id=439576

          【讨论】:

            【解决方案6】:

            碰巧我前几天写了一个pong克隆只是为了好玩。

            你可以玩here查看源码here

            AI 获取球的当前速度并乘以离墙的 x 距离。然后,它以上限速度向计算出的位置移动。它不考虑垂直反弹,但这是有意的(使 AI 可击败)。

            这里是相关的sn-p:

            /* Update enemy based on simple AI */
            enemy.update = function (delta) {
                var impactDistance, impactTime, targetY, speed;
                speed = .25; // a little slower than the human player
            
                if (ball.vx < 0) {
                    // Ball is moving away, AI takes a nap ..
                    return;
                }
            
                // Figure out linear trajectory ..
                impactDistance = width - ball.width - ball.x;
                impactTime = impactDistance / (ball.vx * .25 * 1000);
                targetY = ball.y + (ball.vy * .25 * 1000) * impactTime;
            
                if (Math.abs(targetY - (this.y + this.height/2)) < 10) {
                    // AI doesn't need to move
                    return;
                }
            
                if (targetY < this.y + (this.height / 2)) {
                    // Move up if ball is going above paddle
                    speed = -speed;
                }
            
                this.y += speed * delta;
                this.keepInBounds();
            };
            

            【讨论】:

            • 谢谢。看来我是个很差的乒乓球手。我输了 1 分 10 秒 ;) 可能是因为电脑在右边而不是人在玩的感觉很奇怪 ;)
            【解决方案7】:

            经过多次迭代后,如果您的桨(即您的桨或 AI 取决于您的视角)太靠近屏幕的顶部或底部,则根本不可能覆盖所需的距离。桨可以很容易地跟随球的 y 值。如果你太远,你会错过。

            或者,您可以在每次击球后将 AI 重置为中心,或者只要球在远离(即朝向对手)移动,就向中心移动

            或更简单地说:
            - 当球离开时向中心移动 - 在球接近时模拟球的 y 坐标。

            从这里你可以通过使 y 坐标模仿机制比球慢(更一致,可能是原始实现的样子;因为困难被抽象为简单的速度系数)来改变难度,或者添加随机误差到每个动作或其他。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-17
              • 1970-01-01
              • 1970-01-01
              • 2015-07-12
              • 2021-12-27
              • 2012-07-02
              相关资源
              最近更新 更多