Вторник, 26 Ноября 2024, 13:17

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Проблема с камерой от первого лица .
AlexsSyrДата: Суббота, 04 Июля 2015, 16:32 | Сообщение # 1
почетный гость
Сейчас нет на сайте
Пытаюсь сделать игру от первого лица.
Вращение камеры я реализовал так

Код


               LevelStruct.Vector eyeLook = new LevelStruct.Vector();

               int x, y;

               x = Cursor.Position.X;
               y = Cursor.Position.Y;

               if (prevCoord)
               {
                   prevCoord = false;

                   if (x > prevPosX)
                   {
                      CamTurn = (CamTurn + 0.01) % 360;
                       
                   }

                   if (x < prevPosX)
                   {
                       CamTurn = (CamTurn - 0.01) % 360;
                      
                   }

                

                   if (y > prevPosY && Y > -2)
                        {
                          Y -= 0.01f;
                        }

                   if (y < prevPosY && Y < 2)
                        {
                     Y += 0.01f;
                        }
                           

               }
               else
               {
                   prevCoord = true;
                   prevPosX = x;
                   prevPosY = y;
               }

               if (Cursor.Position.X <= 50)
               {
                   Cursor.Position = new Point(Screen.PrimaryScreen.Bounds.Width - 60, Cursor.Position.Y);
                   prevCoord = false;
               }

               if (Cursor.Position.X >= Screen.PrimaryScreen.Bounds.Width - 50)
               {
                   Cursor.Position = new Point(60, Cursor.Position.Y);
                   prevCoord = false;
               }

               if (Cursor.Position.Y <= 50)
               {
                   Cursor.Position = new Point(Cursor.Position.X,Screen.PrimaryScreen.Bounds.Width / 2);
                   prevCoord = false;
               }

               if (Cursor.Position.Y >= Screen.PrimaryScreen.Bounds.Height - 50)
               {
                   Cursor.Position = new Point(Cursor.Position.X, Screen.PrimaryScreen.Bounds.Width / 2);
                   prevCoord = false;
               }

               eyeLook.X = (float)Math.Sin(CamTurn) + eye.X;

               eyeLook.Z = (float)Math.Cos(CamTurn) + eye.Z;
               eyeLook.Y = eye.Y +Y;

               return eyeLook;
           }


Функцию вызываю в таймере с интервалом 10.

Всё бы хорошо но есть одно но !!!
При ходьбе и одновременном повороте камеры её начинает дёргать.
Написал так
Код

    CamTurn = (CamTurn + 0.001) % 360;


Дёргаться перестало но поворачивать она стала очень медленно.
Как сделать вращение с хорошей скоростью и без дёрганья ?
Не знаю что делать. Подскажите пожалуйста как решить эту проблему .


Сообщение отредактировал AlexsSyr - Суббота, 04 Июля 2015, 16:36
SaiteiДата: Воскресенье, 05 Июля 2015, 14:06 | Сообщение # 2
старожил
Сейчас нет на сайте
AlexsSyr, просто ты жёстко говоришь "прибавь столько-то единиц такой-то переменной", но ты не учитываешь скорость работы процессора. У кого-то процессор слабее\мощнее - будет разниться скорость. Для того, чтобы исправить этот баг, надо считать каждый кадр dt и все твои расчеты домножать на это значение. dt - это время, которое нужно для обсчета и рендера одного кадра.
Потом ничего сложного: position.x += speed*dt; (это в качестве примера. С остальным тоже самое - просто необходимо домножить)
AlexsSyrДата: Воскресенье, 05 Июля 2015, 17:00 | Сообщение # 3
почетный гость
Сейчас нет на сайте
А как получить это время ?
Я так понял что это время прошедшее с последнего вызова функции ?

Добавлено (05 июля 2015, 17:00)
---------------------------------------------
Добавил синхронизацию по времени но результат такой же, ну может стало чуть лучше . Но дёрганье при больших значениях и маленькая скорость при маленьких так и остались.

SaiteiДата: Воскресенье, 05 Июля 2015, 18:02 | Сообщение # 4
старожил
Сейчас нет на сайте
Цитата AlexsSyr ()
А как получить это время ?
Я так понял что это время прошедшее с последнего вызова функции ?

Нет:
Код
float dt;
while(running) //MainLoop твоей игры, грубо говоря
{
float start = засечьВремя();
...
float end = засечьВремя();
dt = end - start;
}
AlexsSyrДата: Вторник, 07 Июля 2015, 19:46 | Сообщение # 5
почетный гость
Сейчас нет на сайте
Я так и сделал.
Вот исходники:
Скачать

Добавлено (07 июля 2015, 19:46)
---------------------------------------------
Я разобрался в чём дело.
Дело было в том что я очень резко двигал игрока

Код
public static void Left(int dt)
         {
             Class.GearX.SetVelocity((MyPlayer.eyeLook.Z - MyPlayer.eye.Z) * (-1) * 10 , Class.GearX.GetVelocityY(0), (MyPlayer.eyeLook.X - MyPlayer.eye.X) * 10, 0);

         }

Убрал * 10, работает хорошо
Но теперь игрок ползает как черепаха .
SaiteiДата: Вторник, 07 Июля 2015, 21:47 | Сообщение # 6
старожил
Сейчас нет на сайте
Цитата AlexsSyr ()
(int dt)

Стоп. С каких это делов dt - это int? Должен быть float, ещё лучше - double.
И я что-то не вижу где ты конкретно здесь домножаешь на dt. Мб поможет
AlexsSyrДата: Вторник, 07 Июля 2015, 22:03 | Сообщение # 7
почетный гость
Сейчас нет на сайте
Это функция движения влево, а не поворота, а dt это точное число миллисекунд. Для получения dt я использовал вот это
https://msdn.microsoft.com/ru-ru/library/system.diagnostics.stopwatch(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1

Добавлено (07 июля 2015, 22:03)
---------------------------------------------
Вся проблема в том что я не просто двигаю камеру, игрок является физическим объектом.

Сообщение отредактировал AlexsSyr - Вторник, 07 Июля 2015, 21:58
GudleifrДата: Пятница, 10 Июля 2015, 12:20 | Сообщение # 8
почти ветеран
Сейчас нет на сайте
В общем случае:

1. Нужно разделить действия на те, что не масштабируются по времени (видео эффекты, внутренние пересчеты и т.д.), масштабируются но не зависят от игрока (движение платформ, врагов...), и масшабируются и управляются (реакция на мышку/клавишу, движение камеры...). Разного вида действия попадают в разные части "цикла".
Например:
Код
DO
    TICK=TICK+1
    БЫСТРЫЕ СОБЫТИЯ
    AKEY=INKEY$
    IF TICK > SPEED
       TICK=0
       СЛУЧАИ И СОБЫТИЯ
          АВАРИИ
       SLEEP 1
       МЕРЦАНИЕ
       ОБРАБОТКА AKEY
       ДВИЖЕНИЕ ФИШКИ
LOOP WHILE AKEY <> ESC AND КОНЕЦ=0

Понятно, "цикл" может выглядеть совершенно иначе (могут быть даже десятки вложенных циклов), но суть проста: каждому типу действий - свое место. Неудачным подбором временных соотношений можно даже вызвать у игрока приступ морской болезни.

2. Нужно учитывать, что действие, совершенное игроком, почти никогда не является "единичным актом", но вызывает лавину независящих от него событий. Например, обработка прыжков.
Наиболее известная ошибка такого рода есть в DOOM: взрывы поднимаются в лифте, а оружие с задержкой стреляет не туда, куда игрок смотрел, нажимая на курок, а туда, куда он смотрит сейчас.

3. И самое главное: та "операционная система/движок", под которую Вы пишете, может трактовать "события", "задержки" и прочее совершенно своим непредсказуемым образом. И совместить "цикл", который нарисуете Вы с ее "моделью мира" может быть ужасно сложно.

P.S. и ни в одной из вселенных этот вопрос не относится ни к C, ни к C++, ни к любому другому языку программирования.


Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг