【问题标题】:movement code c++ [closed]运动代码c ++ [关闭]
【发布时间】:2011-11-17 13:10:02
【问题描述】:

我正在使用 DirectX 用 C++ 制作游戏。我画了一个基本的人工智能。我希望 AI 在一个正方形中移动,例如:

  • AI 向上移动 Z 轴直到达到 25,
  • 然后 AI 沿 X 轴移动 25,
  • 然后沿 Z 轴向下 25,
  • 然后沿 X 轴返回,直到完成正方形形状的完整移动。

这是我目前所拥有的;这使得 AI 在 Z 轴上移动 25 次,然后在 Z 轴下一次又一次地移动 25 次。

if (ghost_moves_forward == true)
{
    ghost_Z -= ghost_movement;
}
else if (ghost_moves_forward == false)
{
    ghost_Z += ghost_movement;
}


if (ghost_Z >= 25)
{
    ghost_moves_forward = true;
}
if (ghost_Z <= -25)
{
    ghost_moves_forward = false;
}

提前谢谢你。


编辑:

float ghost_X = 0; //make the AI move along the x axis
float ghost_Z = 0; // makes the AI move along the Z axis
int ghost_movement = 1; // speed the AI moves
bool ghost_moves_forward = true; // true when AI moves forward, false when its moving sideways
bool ghost_moves_sideways = true;// true when moving sideways, false when moving forwards

我使用ghost_Xghost_Z作为AI的翻译位置。

D3DXMatrixTranslation( &g_matLocal, ghost_X, 0, ghost_Z );

【问题讨论】:

  • 我正在努力让我的头脑绕过 if 循环的其余部分,以使 AI 在方形中移动,而不仅仅是向前和向后
  • 您将需要提供比这更多的代码。所有变量代表什么?这个代码片段是如何运行的(在循环中?递归调用?)
  • 您不应该将您的布尔值与truefalse 进行比较,它们可以直接在条件语句中使用:if (ghost_moves_forward)。您还在 else 中进行了无用的测试:如果 ghost_moves_forward 为真,则不能为假,因此您可以在 else 子句中删除 if
  • @Luc Touraille 也许副作用在 DK10 的代码中特别不稳定。那么测试实际上可能会做一些不平凡的事情。

标签: c++ directx artificial-intelligence


【解决方案1】:

假设幽灵从位置 startx, startz 开始

static int square_state = 0;

// bottom left to top left is done
if(z <= startz-25 && square_state == 0)
    square_state = 1;

// top left to top right is done
if(x >= startx+25 && square_state == 1)
    square_state = 2;

// top right to bottom right is done
if(z >= startz && square_state == 2)
    square_state = 3;

// bottom right to bottom left is done
if(x <= startx && square_state == 3)
    square_state = 0;

switch(square_state)
{
case 0: // bottom left to top left
    z -= movement;  
    break;

case 1: // top left to top right
    x += movement;
    break;

case 2: // top right to bottom right
    z += movement;
    break;

case 3: // bottom right to bottom left
    x -= movement;
    break;
}

【讨论】:

  • 谢谢你,这正是我所需要的 :)
【解决方案2】:

当进入正方形而不是上下移动时,您有四种不同的运动状态,而不仅仅是两种,因此bool 不足以存储当前的运动状态。一旦达到运动状态的结束条件,就进入下一个运动状态(操作符++% 可能会派上用场)。

【讨论】:

    【解决方案3】:

    您需要考虑 3D 空间和坐标几何来理解和编程 3D 运动。

    所以目前它只是来回移动的原因是在 x 轴上表示。

    在二维空间中

    X component of ghost movement + y component of ghost movement.
    

    在 3D 上,您需要在 3D 坐标系中使用所有三个来表示它

    喜欢

    x+y+z (done through matrices)
    

    在此处阅读此部分以获取示例

    c++ first person camera in directx

    更多信息在这里http://www.directxtutorial.com/tutorial9/b-direct3dbasics/dx9b5.aspx

    或这里http://msdn.microsoft.com/en-us/library/windows/apps/hh452775(v=vs.85).aspx

    【讨论】:

      【解决方案4】:

      您需要某种状态来表示幽灵当前处于哪个移动阶段(它具有更多的状态,而不仅仅是真假)。移动逻辑是一个单独处理每个状态的开关。

      switch (ghost_state)
      {
      case moving_up:
        ghost_Z += ghost_movement;
        if (ghost_Z >= 25)
        {
          ghost_Z = 25;
          ghost_state = moving_right;
        }
        break;
      
      case moving_right:
        ghost_X += ghost_movement;
        if (ghost_X >= 25)
        {
          ghost_X = 25;
          ghost_state = moving_down;
        }
        break;
      
      case moving_down:
        ghost_Z -= ghost_movement;
        if (ghost_Z <= 0)
        {
          ghost_Z = 0;
          ghost_state = moving_left;
        }
        break;
      
      case moving_left:
        ghost_X -= ghost_movement;
        if (ghost_X <= 0)
        {
          ghost_X = 0;
          ghost_state = moving_up;
        }
        break;
      }
      

      【讨论】:

        【解决方案5】:

        好的,假设您想以编程方式使用 X 和 Y 值以正方形模式在 2d 正方形空间中移动,Loop 将计数 X 值直到结束(或目的地) --------- 然后 Loop 将计数直到最大值(或目的地),同时将 X 值保持在最大值目的地。此时你已经移动成“L”形

        `

                |<y>
                |
          <x>___|
        

        `

        然后,您将从 X 值开始反转循环(即倒计时),同时保持 dest/max 值。

        【讨论】:

          【解决方案6】:

          如果我正在编写这样的程序,我会倾向于制作更通用的 OOP 解决方案。这很适合您希望未来实体能够以其他形状移动的项目,例如三角形、菱形、五边形等。根据程序的范围,以下是“易于扩展”或“完全矫枉过正”。

          实现或获取 Point 类,以便您可以使用(例如)ghost_pos.x 和 ghost_pos.z,而不是 ghost_X 和 ghost_Z。这不是绝对必要的,但它可以更轻松地在函数之间传递位置数据。

          创建一个函数Point point_between(Point a, Point b, float distance_from_a),它返回位于a 和b 之间的某个点c,并且距离a 点有distance_from_a 个单位。这需要一些高中水平的三角学知识。

          创建一个类LinearPath,它表示随着时间的推移从一个点到另一个点的直线移动。它至少应具有以下品质:

          • 一个公共构造函数,它需要两个点begin, end
          • 私人Point currentPosition,用于跟踪您当前在路径上的位置。
          • 公共方法point getCurrentPosition() - 我们希望用户能够读取 currentPosition,但不能覆盖它。
          • 一个公共方法move(float distance),它将currentPosition移向end(提示:为此使用point_between)。
          • 一个公共方法done,如果currentPosition等于end,则返回true。

          创建一个类LoopedPath,它代表从A点到B点到C点到C点到Z点再回到A点的移动。它应该有:

          • 一个接受点集合(数组、向量、队列等)的构造函数
          • 私人LinearPath currentPath,跟踪您当前所在的线性路径。
          • 一个公共方法move(float distance),它首先检查当前路径是否为done,如果是,则使用下一个未遍历的点重新实例化它。然后它调用currentPath.move(distance)
          • 一个公共方法point getCurrentPosition()

          给你的 Ghost 类一个 LoopedPath 的实例。用正方形的四个点实例化它(在你的例子中,(0,0),(0,25),(25,25),(25,0))。在每场比赛期间,请致电move(ghost_movement)。在渲染过程中,在getCurrentPosition()处绘制幽灵。

          【讨论】:

            【解决方案7】:

            按照这些思路,对于简单 AI 来说,一个更好的方法是使用航路点。大致如下:

            struct AIActor
            {
                AIActor( const Vector3& a_Origin ) : m_CurrentTarget( 0 ), m_Speed( .5f )
                {
                    m_WayPoints.push_back( a_Origin + Vector3( 0.f, 0.f, 25.f ) );
                    m_WayPoints.push_back( m_WayPoints.back() + Vector3( 25.f, 0.f, 0.f ) );
                    m_WayPoints.push_back( m_WayPoints.back() + Vector3( 0.f, 0.f, -25.f ) );
                    m_WayPoints.push_back( m_WayPoints.back() + Vector3( -25.f, 0.f, 0.f ) );
                }
                void Update( const float a_Delta )
                {
                    const Vector3& targetWP( m_WayPoints[ m_CurrentTarget ] ), &currentPos( GetPosition() );
                    Vector3 diff( targetWP - currentPos );
                    float diffLen = diff.Length();
                    diff *= std::min( m_Speed * a_Delta, diffLen ) / diffLen; // Moves us along at m_Speed, but if length is less than speed, then we stop at the waypoint
                    Vector3 newPos( currentPos + diff );
                    if( newPos.FuzzyEquals( targetWP ) ) // At the waypoint, move to next one!
                        m_CurrentTarget = m_CurrentTarget + 1 % m_WayPoints.size();
                    SetPosition( newPos );
                }
                unsigned int m_CurrentTarget;
                std::vector< Vector3 > m_WayPoints;
                float m_Speed;
            };
            

            没有经过测试,但这就是它的要点。这对于移动不仅仅是一个正方形更易于管理和使用。

            【讨论】:

              猜你喜欢
              • 2020-09-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-10-28
              • 1970-01-01
              • 2012-07-03
              • 1970-01-01
              • 2012-09-17
              相关资源
              最近更新 更多