Конференция "Игры" » Повтор (Replay) в играх.
 
  • AlexanderMS © (08.01.08 17:36) [0]
    Решил в игре реализовать возможность автоматической записи гонки с целью последующего её просмотра.
    Возник вопрос: достаточно ли каждый кадр запоминать только управление игрока (клавиши, которые он нажал)? Могу ли я
    затем снова запустить гонку с такими же исходными параметрами, восстанавливая только коды нажатых клавиш? Гарантировано ли, что гонка будет идти точно так же? В игре random не используется (всё зависит только от управления игрока).
    Знаю, что вопрос может показаться глупым. Но у меня возникли сомнения в том, что результаты операций с вещественными числами всегда одинаковы. Вдруг подведёт округление, и вместо того, чтобы нормально проехать, машина во что-нибудь врежется. :)
  • Piroxyline (10.01.08 09:46) [1]
    Если рандом не используется, то да. Только надо отдельно запоминать моменты нажатия и отжатия клавиш.
  • AlexanderMS © (10.01.08 10:04) [2]

    > Piroxyline   (10.01.08 09:46) [1]

    Большое спасибо.
  • @!!ex © (10.01.08 10:15) [3]
    > [2] AlexanderMS ©   (10.01.08 10:04)

    Не верь тому, что написано в [1].

    Смотри ситуацию:
    Игрок играет. У него фпс 200. На 100 кадре он нажимает влево, на 101 отпускает. Теперь повтор. Проигрывается с фпс 100. на 50 кадре отрабатывается нажатие, на 51 отпускаени... и что мы получаем? Мы получаем что машина едет влево дольше в два раза!!! Объяснять, чем это грозит - надо?

    Есть несколько решений этой проблемы..
    Я в свое время делал так:
    Делим секунду на 20 частей. Запоминаем положение и скорость машины в каждом отсчете(никаких нажатий клавиш, только состояние машины).
    Во время воспроизведения получаем некоторое текущее значение отсчета, например 21.7, получаем сплайн по трем точка(21,22,23), получаем положение и скорость машины в точке 21.7
    Работает замечательно, и повторяемость гарантируема при любых данных.
  • @!!ex © (10.01.08 10:16) [4]
    Кстати, рандом тоже можно использовать, только нужно запоминать/восстаналивать RandSeed
  • AlexanderMS © (10.01.08 16:23) [5]
    @!!ex, интересно.
    Спасибо, а то я подумал, что мой вопрос вообще глупый. :)
    А если моменты нажатия/отжатия неважны, а имеет значение текущее состояние клавишы в данном кадре?
    Например (выполняется каждый кадр):

           Player.EngineOn := KeyPressed[Player.Index, Key_Gas];
           Player.TurningLeft := KeyPressed[Player.Index, Key_Left];
           Player.TurningRight := KeyPressed[Player.Index, Key_Right];
    ...



    Запомню каждый кадр либо массив KeyPressed, либо флаги EngineOn, TurningLeft и т. п., нормально будет?
  • @!!ex © (10.01.08 16:28) [6]
    > [5] AlexanderMS ©   (10.01.08 16:23)

    Забудь о клавишах. Запоминай состояния. Поворот колесо, ускорение, и т.д.
    клавиши слишком ненадежный источник информации.
  • AlexanderMS © (10.01.08 16:42) [7]
    Спасибо, я понял.
  • Hruks (11.08.08 10:47) [8]
    С симуляторами понятно.
    Хотя при количестве объектов в несколько десятков и подробной симуляции - писать многие параметры объектов будет накладно. Например у автомобиля независимая подвеска и все 4 колеса имеют своё положение относительно корпуса автомобиля. И 5 раз в секунду писать все данные всех объектов?

    А что на счёт стратегий?
    Писать в риплей команды юнитам? Или всё же ввод пользователя писать?
  • @!!ex © (11.08.08 11:17) [9]
    Бесполезно писать ввод пользователя!!! НЕЛЬЗЯ его писать.
    Тайминги при реплее не совпадут и будет большой десинх...
    А они не совпадут, гарантирую.
  • grisme © (11.08.08 17:38) [10]
    может просто записывать ротации и трансляции каждой машины?
    ну, или вектора движения (+остальной физики, если надо).
    при реплее, соотв-но, просто применять ротации и трансляции к машинам, с учётом "свободной" камеры.
  • @!!ex © (11.08.08 17:59) [11]
    > [10] grisme ©   (11.08.08 17:38)

    Когда делал реплеи для самолета - записывал позицию и вращение с фиксированным таймингом(50 мс). И при воспроизведении просто получал нужное значение, если тайминг не кратный 50 мс, то просто интерполяцию проводил и получал положение машины. Вроде вполне адекватно получилось.
  • XProger © (13.08.08 04:18) [12]
    Если Update игровой механики происходит независимо от FPS то всё будет отлично работать, даже и с random'ом при сохранении изначального RandSeed.
    Всё это круто до тех пор пока не решишь сетевой код игры писать.
  • XProger © (13.08.08 04:26) [13]
    Выразился возможно неясно, разъясню: записи одного только ВВОДА пользователя вполне достаточно для воссоздания записи хоть 48-ми часовой игры, при условии что Update "независим" от FPS, т.е. количество вызовов Update при записи будет полностью соответствовать количеству вызовов при проигрывании независимо от конфигурации компьютера. Но в сетевой игре часто используются синхронизации позиций различными видами интерполяций, поэтому для записи демок сетевой игры (как и для самой сетевой игры) одного только ввода недостаточно.

    Вот типичный MainLoop игры с константным Updates Per Second (UPS):

     dUPS := 1000 div UPS;
     OldTime := Timer.Time - dUPS;
     while not FQuit do
     begin
       // тут можно ещё цикл обработки сообщений вставить
       // или же оставить его в onUpdate
       while Timer.Time - OldTime >= dUPS do
       begin
         onUpdate;
         inc(OldTime, dUPS);
       end;
       onRender;
     end;

  • @!!ex © (13.08.08 09:25) [14]
    > [12] XProger ©   (13.08.08 04:18)

    Даже в этом случае нужно очень постаратся, чтобы не получиться десинх...
    Например, если игра реагирует на нажатие немедленно, а записывается нажатие только в зависимости от Update Time, то может получится, некоторое различие по времени, что привдет к десинху.
    А если и реакцию на нажатие привязать к UpdateTime, то может создастся ощущение, что игра тормозит... Особенно будет заметно, если игрок привык кликать несколько десятков раз в секунду...
    Хотя это тема, конечно. Так работаю тповторы в Периметре, насколько мне известно.
  • Medbe}I{onok XML © (13.08.08 12:58) [15]
    Бесполезно писать ввод пользователя!!! НЕЛЬЗЯ его писать.
    Тайминги при реплее не совпадут и будет большой десинх...
    А они не совпадут, гарантирую.


    В авиасиме ил2 используются оба подхода.
    Можно создать маленький компактный трек в котором только управляющие воздействия органов управления (проигрывается верно если нет изменения в моделях).
    Либо другой трек, куда пишутся все объекты и их расположение (проигрывается верно для любых версий моделей).
  • XProger © (15.08.08 14:16) [16]
    @!!ex, я считаю, что задачей Update как раз является обработка игровой логики, и соответственно ввода. DeltaTime в коде приведённом выше не нужен.
  • @!!ex © (15.08.08 14:46) [17]
    > [16] XProger ©   (15.08.08 14:16)

    DeltaTime позволяет достичь большей четкости на мощных компах...
    А четкость нужна, особенно на чемпах.
  • место (15.08.08 19:54) [18]

    > @!!ex ©   (10.01.08 10:15) [3]

    Игрок играет. У него фпс 200. На 100 кадре он нажимает влево, на 101 отпускает. Теперь повтор. Проигрывается с фпс 100. на 50 кадре отрабатывается нажатие, на 51 отпускаени... и что мы получаем? Мы получаем что машина едет влево дольше в два раза!!! Объяснять, чем это грозит - надо?


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

    вроде бы так должно быть:


    > XProger ©   (13.08.08 04:18) [12]
    > Если Update игровой механики происходит независимо от FPS
    > то всё будет отлично работать, даже и с random'ом при сохранении
    > изначального RandSeed.
    > Всё это круто до тех пор пока не решишь сетевой код игры
    > писать.


    я думал, что нужно хранить события и время между ними, но все никак не могу найти способа при проигрывании отмерять записанное время.
  • @!!ex © (15.08.08 21:13) [19]
    > не совсем понятно как в таком случае устроенна игра. по
    > идее машина должна ехать не зависимо от кадров, да и время
    > не кадрами должно отмеряется, а то будет как с досовскими
    > играми запустил на современном компе и все несется со скоростью
    > света.

    ПОчему то есть желание написать матом... Но я помобю в себе это желание и разжую....

    Машина едет нормально, а вот получает событие нажатия клавиши на несколько МС позже, чем она была нажата при игре.
  • место (16.08.08 11:18) [20]

    > @!!ex ©   (15.08.08 21:13) [19]


    > ПОчему то есть желание написать матом... Но я помобю в себе
    > это желание и разжую....
    >
    > Машина едет нормально, а вот получает событие нажатия клавиши
    > на несколько МС позже, чем она была нажата при игре.


    так МС или кадров? просто изначально было сказано про кадры.

    есть?!! пиши в асю 1/\1/\2/\4/\3/\5/\6/\9/\8, выслушаю :-)
  • @!!ex © (16.08.08 12:15) [21]
    > так МС или кадров? просто изначально было сказано про кадры.

    **яяя. Все. я молчу.


    > есть?!! пиши в асю 1/\1/\2/\4/\3/\5/\6/\9/\8, выслушаю :
    > -)

    н.... зачем мне это?
  • XProger © (16.08.08 13:00) [22]
    Видимо связь односторонняя, а жаль, вроде даже и код приводил...
  • имя (01.08.09 08:50) [23]
    Удалено модератором
  • имя (01.08.09 08:50) [24]
    Удалено модератором
 
Конференция "Игры" » Повтор (Replay) в играх.
Есть новые Нет новых   [134430   +2][b:0][p:0.001]