移动代码c++

movement code c++

本文关键字:c++ 代码 移动      更新时间:2023-10-16

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

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

这是我到目前为止所做的;这使得AI在Z轴向上移动25个百分点,然后向下移动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 );

让我们假设幽灵从位置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;
}

当在方块中移动而不是上下移动时,你有四种不同的移动状态而不是只有两种,因此bool不再足以存储当前的移动状态。一旦达到移动状态的结束条件,您就进入下一个移动状态(操作符++%在实现这一点时可能会派上用场)。

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

所以现在它只是来回移动因为移动是用x轴表示的

在二维空间中它将是

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

在3D中,你需要用这三个来表示它在3D坐标系中

x+y+z (done through matrices)

阅读这一节的例子

c++ directx第一人称摄像机

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

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

你需要某种状态来表示鬼当前所处的移动阶段(它有比真和假更多的状态)。移动逻辑是一个单独处理每个状态的开关。

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;
}

好的,假设你想在一个正方形模式中使用X和Y值编程移动一个2d正方形空间,Loop<1>将计算X值直到end(或destination)---------然后Loop<2>将一直计算到max(或destination),同时保持X值在max destination。此时,您已经移动到"L"形

        |<y>
        |
  <x>___|

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

如果我正在编写这样的程序,我会倾向于编写一个更通用的OOP解决方案。如果你希望未来的实体能够以其他形状移动,例如三角形、菱形、五边形等,这将很好地帮助你实现这个目标。根据你的程序的范围,下面的代码要么是"容易扩展的",要么是"完全多余的"。

实现或获取Point类,以便您可以使用(例如)ghost_pos。X和ghost_pos。而不是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点的移动…到Z,再回到A。它应该有:

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

给Ghost类一个LoopedPath实例。用正方形的四个点实例化它(在你的例子中,(0,0),(0,25),(25,25),(25,0))。在每个游戏周期中,调用move(ghost_movement)。渲染时,在getCurrentPosition()处绘制鬼影

对于这些简单的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;
};

没有测试,但这就是要点。这比仅仅移动一个正方形更容易管理和使用。