移动代码c++
movement code c++
我正在使用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_X
和ghost_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 ] ), ¤tPos( 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;
};
没有测试,但这就是要点。这比仅仅移动一个正方形更容易管理和使用。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值