2011-11-17 119 views
0

我正在使用DirectX在C++中进行游戏。我绘制了一个基本的AI。我想要的AI走动为正方形,例如:移动代码C++

  • 的AI,直到它达到25向上移动Z轴,
  • 那么AI沿着由25 X轴移动时,
  • 然后沿着Z轴向下,沿着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 

我使用了AI的翻译职位ghost_Xghost_Z

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

那么你的问题是什么? –

+0

即时通讯努力让我的脑袋围绕其余的if循环,使人工智能在一个正方形中移动,而不是仅仅向前和向后 – DK10

+0

您需要提供比这更多的代码。所有变量代表什么? – StevieG

回答

7

假设鬼位置开始,运行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; 
} 
+0

谢谢你正是我需要的:) – DK10

1

当方块,而不只是向上和向下走,你有四个不同的运动状态,而不是只有两个,因此一个bool没有任何更足以存储当前的运动状态。一旦达到运动状态的结束条件,就进入下一个运动状态(运营商++%可能会方便地实现该状态)。

1

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

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

在二维空间这将是

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

在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

1

你需要某种状态中的在其中流动相的鬼魂表示目前处于(其状态多于正确和错误)。然后移动逻辑就是一个单独处理每个状态的开关。

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

好吧,让我们假设你想用X和Y值编程绕二维方形空间中移动以正方形图案,环< 1>将计数的X值,直到结束(或目的地) ---------然后循环2>将计数到最大(或目的地),同时将X值保持在最大目的地。此时你在一个“L”形陆续

`

 |<y> 
     | 
    <x>___| 

`

然后,您可以反向循环(即倒数)开始与X值,同时保持DEST /最大值。

1

如果我编程这样的事情,我会倾向于制定一个更通用的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单位。这需要一些高中水平的Trig知识。

创建一个类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)它首先检查当前路径是否为done,如果是,则用下一个未经过转换的点重新实例化它。然后它叫currentPath.move(distance)
  • 公开方法point getCurrentPosition()

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

1

简单人工智能沿着这些线的更好的方法是使用方法点代替。沿线的东西:

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

未经测试,但这是它的要义。这对于移动不仅仅是一个方形而言更易于管理和使用。