Я работаю над игрушкой для симулятора Direct3D9, в которой мне нужно создать камеру, которая удерживает позицию и точку зрения космического корабля игрока. На данный момент я ограничил свой код только для того, чтобы двигаться назад и вперед, вверх и вниз, а также обстреливать. Ниже мой код, и у него есть проблема. Все обернуто в класс, и все векторы инициализируются в D3DXVECTOR3 (0.0f, 0.0f, 0.0f) в конструкторе, за исключением LocalUp (D3DXVECTOR3 (0.0f, 1.0f, 0.0f)) и LocalAhead (D3DXVECTOR3 (0.0f , 0.0f, 1.0f)), а поплавки - 0.0f;Direct3D9 game: Космический аппарат
D3DXVECTOR3 Position, LookAt ,PosDelta, PosDeltaWorld, WorldAhead, WorldUp, LocalUp,
LocalAhead, Velocity;
D3DXMATRIX View, CameraRotation;
float SpeedX, SpeedY, SpeedZ;
void Update(float ElapsedTime)
{
SpeedX = 0.0f;
SpeedY = 0.0f;
if(IsKeyDown('A'))
{
SpeedX = -0.02f;
Velocity.x -= SpeedX;
}
if(IsKeyDown('D'))
{
SpeedX = 0.02f;
Velocity.x += SpeedX;
}
if(IsKeyDown('X'))
{
SpeedZ += 0.01f;
Velocity.z += SpeedZ;
}
if(IsKeyDown('Z'))
{
SpeedZ -= 0.01f;
Velocity.z -= SpeedZ;
}
if(IsKeyDown('W'))
{
SpeedY = 0.02f;
Velocity.y += SpeedY;
}
if(IsKeyDown('S'))
{
SpeedY = -0.02f;
Velocity.y -= SpeedY;
}
D3DXVec3Normalize(&Velocity, &Velocity);
PosDelta.x = Velocity.x * SpeedX;
PosDelta.y = Velocity.y * SpeedY;
PosDelta.z = Velocity.z * SpeedZ;
D3DXMatrixRotationYawPitchRoll(&CameraRotation, 0, 0, 0);
D3DXVec3TransformCoord(&WorldUp, &LocalUp, &CameraRotation);
D3DXVec3TransformCoord(&WorldAhead, &LocalAhead, &CameraRotation);
D3DXVec3TransformCoord(&PosDeltaWorld, &PosDelta, &CameraRotation);
Position += PosDeltaWorld;
LookAt = Position + WorldAhead;
D3DXMatrixLookAtLH(&View, &Position, &LookAt, &WorldUp);
}
и функция "D3DXMatrixPerspectiveFovLH" "IDirect3DDevice9 :: SetTransform" называются в другой части приложения. Поскольку они работают нормально, я больше не буду говорить о них.
Проблема в том, что всякий раз, когда скорость по оси Z довольно велика, и я стягиваюсь и двигаюсь в поперечном направлении, отдельно или в одно и то же время, скорость Z-оси камеры уменьшается. Более того, после того, как скорость почти равна 0, а затем я нажимаю клавишу, которая увеличивает скорость, смысл инвертирует вектор, а затем возвращается к норме. Это также происходит при изменении значения вектора на достаточно высоких скоростях (например, нажатие X, а затем немедленное нажатие «Z»). Может ли кто-нибудь объяснить мне, почему это происходит, и как я могу решить эту проблему?
Я также задам еще один вопрос: как я могу уменьшить скорость и скорость оси Y, если не нажата ни одна клавиша? Я хочу, чтобы эффект инерции реализовывался в игре.
Если есть кто-нибудь, кто может мне помочь, ответьте!
EDIT: НОВЫЙ КОД:
void NewFrontiers3DEntityPlayer::OnFrameUpdate(float ElapsedTime)
{
State.SpeedX = 0.0f;
State.SpeedY = 0.0f;
if(IsKeyDown(State.Keys[CAM_STRAFE_LEFT]))
State.SpeedX = -0.02f;
if(IsKeyDown(State.Keys[CAM_STRAFE_RIGHT]))
State.SpeedX = 0.02f;
if(IsKeyDown(State.Keys[CAM_MOVE_FORWARD]))
{
State.SpeedZ += 0.01f;
}
if(IsKeyDown(State.Keys[CAM_MOVE_BACKWARD]))
{
State.SpeedZ -= 0.01f;
}
if(IsKeyDown(State.Keys[CAM_MOVE_UP]))
State.SpeedY = 0.02f;
if(IsKeyDown(State.Keys[CAM_MOVE_DOWN]))
State.SpeedY = -0.02f;
State.Velocity.x = State.SpeedX;
State.Velocity.y = State.SpeedY;
State.Velocity.z = State.SpeedZ;
D3DXVec3Normalize(&State.Velocity, &State.Velocity);
State.PosDelta.x = State.Velocity.x * ElapsedTime;
State.PosDelta.y = State.Velocity.y * ElapsedTime;
State.PosDelta.z = State.Velocity.z * ElapsedTime;
D3DXMatrixRotationYawPitchRoll(&State.CameraRotation, 0, 0, 0);
D3DXVec3TransformCoord(&State.WorldUp, &State.LocalUp, &State.CameraRotation);
D3DXVec3TransformCoord(&State.WorldAhead, &State.LocalAhead, &State.CameraRotation);
D3DXVec3TransformCoord(&State.PosDeltaWorld, &State.PosDelta, &State.CameraRotation);
State.Position += State.PosDeltaWorld;
State.LookAt = State.Position + State.WorldAhead;
D3DXMatrixLookAtLH(&State.View, &State.Position, &State.LookAt, &State.WorldUp);
return;
}
"государство" является структурой, которая содержит всю информацию о камере.
Так как вы используете C++ я рекомендовал бы использовать классы вместо globals – Quest
Я использую классы, я использовал глобальные переменные, потому что здесь намного проще размещать сообщения. –