![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|
|
|||||
|
strange mood
|
Есть игровой движок, главная функция повешена на setInterval и вызывается каждые скажем 10 мс. Т.е. подразумевается что всё обсчитывается 100 раз в секунду. Однако в реале всё работает раза в 2 медленнее - вместо 100 fps выдаётся где-то 50. Но ладно если б это были только кадры, но ведь это и количество просчётов, т.е. за одно и то же реальное время на различных машинах будет проходить различное игровое время.
Вопрос: как поддерживать игровое время в соответствии с реальным? Чтобы состояния, которые не успевают просчитаться, отбрасывались, чтобы кадры пропускались, но текущее состояние всегда соответствовало реальному времени.
__________________
тонкий тролль, осеянный благодатью |
|
|||||
|
стервочка (я мужик)
|
нужно логику игры не зависящую от итераторов.
пример перемещение должно быть реализовано так: package { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.TimerEvent; import flash.utils.Timer; import flash.utils.getTimer; public class Character extends EventDispatcher { public function Character(x:Number=0, y:Number=0) { super(); this._x = x; this._y = y; this._timer.addEventListener( TimerEvent.TIMER, this.updatePosition ); } private const _timer:Timer = new Timer( 100 ); private var _start_time:Number; private var _end_time:Number; private var _start_x:Number; private var _start_y:Number; private var _end_x:Number; private var _end_y:Number; private var _d_x:Number; private var _d_y:Number; private var _x:Number; public function get x():Number { return this._x; } private var _y:Number; public function get y():Number { return this._y; } public function moveTo(x:Number, y:Number, speed:Number=1):void { var dt:Number = Math.sqrt( x*x + y*y ) / speed; this._start_time = getTimer(); this._end_time = this._start_time + dt; this._start_x = this._x; this._end_x = x; this._d_x = ( this._end_x - this._start_x ) / dt; this._start_y = this._y; this._end_y = y; this._d_y = ( this._end_y - this._start_y ) / dt; if ( !this._timer.running ) this._timer.stop(); } private function updatePosition(event:Event=null):void { var time:Number = getTimer(); if ( this._end_time > time ) { time -= this._start_time; this._x = this._start_x + this._d_x * time; this._y = this._start_y + this._d_y * time; } else { this._x = this._end_x; this._y = this._end_y; this._timer.stop(); } } } } я бы даже сказал непомерно много. даже не знаю где может больше 30 пригодится ![]() Добавлено через 32 секунды P.S.: код не проверял. но смысл думаю понятен. |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Привязываться нужно к независимому времени, а не к сомнительным плавающим параметрам, типа FPS или интервалов.
|
|
|||||
|
strange mood
|
BlooDHounD,
Цитата:
![]() Как просплюсь, разберусь в вашем коде - насколько я понял, самая суть его лежит в последних строчках. __etc, я это и хочу узнать: как привязаться к независимому времени?
__________________
тонкий тролль, осеянный благодатью Последний раз редактировалось Gaen; 11.01.2009 в 22:00. |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Ну, например, getTimer() и Date.
|
|
|||||
|
блогер
Регистрация: May 2008
Адрес: (0, 10, 185) в локальной системе
Сообщений: 721
Записей в блоге: 6
|
BloodHound, в вашем коде сам черт ногу сломит - вы понему, чтоли, обфускатором прошлись?
В общем суть такова, что все объекты движутся по линейной или нелинейной зависимости. Чаще всего нам нужно узнать положение объекта для его отрисовки. Поэтому задаем положение объекта каждый кадр на ENTER_FRAME. Для расчета перемещения объекта за кадр при постойной скорости пользуемся следующей формулой : Чтобы расчитать время кадра пользуемся следующим методом: Для расчета координат объекта при нелинейном перемещении пользуемся твинерами. |
|
|||||
|
стервочка (я мужик)
|
Яски, гыыыы ...... Вы написали лучше? и в чём там ноги ломаются?
|
|
|||||
|
блогер
Регистрация: May 2008
Адрес: (0, 10, 185) в локальной системе
Сообщений: 721
Записей в блоге: 6
|
А я понял, это просто такой стиль форматирования - жутковат просто с непривычки.
UPD: Вообще ваш подход лучше — если считать прошедшее время за каждый кадр, будет накапливаться погрешность из-за слишком маленьких значений. Тут ошибочка: public function moveTo(x:Number, y:Number, speed:Number=1):void { var dt:Number = Math.sqrt( x*x + y*y ) / speed; Последний раз редактировалось Яски; 11.01.2009 в 23:34. |
|
|||||
|
стервочка (я мужик)
|
Яски, ваще-то не устал
тупо механическая ошибка, о которой я даже не подумал. |
|
|||||
|
Регистрация: Jan 2009
Сообщений: 15
|
Я использовал такой подход:
1. Логика четко фиксирована по времени - так гораздо легче считать, если есть события и их последствия, а не только простое перемещение. 2. Частота отрисовки подстраивается под производительность: Нам известен интервал между циклами отрисовки. Засекаем время обсчета логики и время отрисовки кадра. Если времени и на то и на другие не хватает, переходим к рассчету след. кадра, увеличиваем запас времени на отрисовку (время общего интервала минус время на обсчет). Обсчитываем логику пока не накопится достаточно времени для отрисовки. И так по циклу. Еще я отрисовку делал в бэкбуфер, а он по-любому выводился с фиксированной частотой, т.к. это занимало ничтожно мало времени в сравнении даже с обсчетом логики и картинка получалась достаточно плавной и при низком ФПС. И еще я использовал самонастройку, которая уменьшала количество не нужных особо объектов (частиц в эффектах) и ФПС был на достаточно хорошем уровне. Недостаток: вариант, когда на просчет логики не хватает времени, не рассматривался. Когда просчет съедает все время, отрисовки может не быть вообще, но это можно предусмотреть в алгоритме. И еще это было не на флеше, но, считаю, применить метод можно. Еще любят делать отдельные потоки для логики и отрисовки. Логика расчитывается отдельно, и картинка отрисовывается отдельно. Если это как-то объединить с подстройкой ко времени отрисовки, то можно получать нужное и при падении ФПС. зы: кстати у тебя в вопросе и ответ, просто внимательно его прочитай и подумай. - Просто не рисуй те кадры, которые не успевают отрисоваться, а логику считай всю. И будут кадры пропускаться, а текущее состояние соответствовать реальному времени ![]() Последний раз редактировалось puzzlesea; 13.01.2009 в 00:40. |
![]() |
![]() |
Часовой пояс GMT +4, время: 00:00. |
|
|
« Предыдущая тема | Следующая тема » |
|
|