Управление мышью для игры от первого лица в моногейме

#c# #monogame

#c# #моногейм

Вопрос:

Я пытаюсь создать игру от первого лица в Monogame, и до сих пор все, что я нашел или нашел в Интернете, не соответствовало моим стандартам. вот как я сейчас управляюсь с мышью:

         private void HandleMouse()
        {
            Vector2 mouseDifference;
            mouseNow = Mouse.GetState();
            if (mouseNow.X != mouseDefaultPos.X || mouseNow.Y != mouseDefaultPos.Y)
            {
                mouseDifference.X = mouseDefaultPos.X - mouseNow.X;
                mouseDifference.Y = mouseDefaultPos.Y - mouseNow.Y;
                leftrightRot  = mouseSens * mouseDifference.X;
                updownRot  = mouseSens * mouseDifference.Y;

                Mouse.SetPosition((int)mouseDefaultPos.X, (int)mouseDefaultPos.Y);

                UpdateViewMatrix();
            }
        }

        private void UpdateViewMatrix()
        {
            Matrix cameraRotation = Matrix.CreateRotationX(updownRot) * Matrix.CreateRotationY(leftrightRot);

            Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
            Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);

            Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);

            Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);


            viewMatrix = Matrix.CreateLookAt(new Vector3(0,0,0), cameraRotatedTarget, cameraRotatedUpVector);
        }
  

Моя проблема в том, что, хотя это решение работает, оно крайне непоследовательно, когда дело доходит до того, как далеко должна вращаться камера.
например, это происходит, когда я делаю круги с помощью мыши и вижу, что иногда мышь случайным образом прыгает больше, чем ожидалось.
Мои основные предположения несоответствия в fps, которые приводят к изменению времени между кадрами, что влияет на расстояние, на которое мышь может перемещаться за это время.

Я не знаю, является ли это причиной или мое предположение может даже вызвать это, но я хотел бы найти способ добиться последовательного движения мыши.

При необходимости я могу предоставить видео проблемы.

Заранее благодарю.

Ответ №1:

Мышь в Windows обновляется 240 раз в секунду. Игровой цикл выполняется со скоростью 60 кадров в секунду. Несоответствие может привести к большим дельтам мыши. Решение состоит в том, чтобы ограничить изменение дельты мыши:

 Vector2 mouseDifference;
const float MAXDELTA = 6; // Set to the appropriate value.
mouseNow = Mouse.GetState();
if (mouseNow.X != mouseDefaultPos.X || mouseNow.Y != mouseDefaultPos.Y)
{
    mouseDifference.X = Math.Min(MAXDELTA, mouseDefaultPos.X - mouseNow.X);
    mouseDifference.Y = Math.Min(MAXDELTA, mouseDefaultPos.Y - mouseNow.Y);
    leftrightRot  = mouseSens * mouseDifference.X;
    updownRot  = mouseSens * mouseDifference.Y;

    Mouse.SetPosition((int)mouseDefaultPos.X, (int)mouseDefaultPos.Y);

    UpdateViewMatrix();
}
  

Комментарии:

1. Я чувствую, что установка предельной дельты мыши — это просто решение одной проблемы путем создания другой, я считаю, что создание максимальной дельты мыши также будет проблемой при быстром перемещении мыши, на этот раз вместо того, чтобы вращаться больше, чем следовало бы, она будет вращаться меньше, чем должна.

2. @Aofekiko, единственный другой известный мне способ сделать это — подключить базовую ОС и предоставить функцию обратного вызова в вашем коде. Это не потокобезопасно, не переносимо и может быть помечено антивирусным программным обеспечением.

Ответ №2:

Это старая тема, но я решил поделиться решением. Решение, которое сработало для меня, — использовать объект GameTime, чтобы определить, на сколько игрок должен вращаться. Другими словами, поворот на (дельта * Скорость вращения * Время игры.Истекшее время.Всего секунд), так что каждый поворот зависит от того, сколько времени прошло с момента последнего кадра. Это защищает его от выпадения кадров, что, как я обнаружил, было проблемой для меня.