Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail


Донат для форума - использовать для поднятия настроения себе и модераторам

А ещё здесь можно купить рекламу за 25 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru

Ответ
 
Опции темы
Старый 12.06.2011, 17:07   #861
Beermonza
Инженер ИС
Профессионал
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
Репутация: 746
По умолчанию

Цитата:
Сообщение от Alexan-Dwer Посмотреть сообщение
Вопрос №2: стоит ли вывод буфера продублировать событием OnPaint, что бы застраховаться от неожиданностей?
От каких? ...таймер работает всегда, даже если форма не в фокусе, или свернута, иначе события в игре разойдутся с изображением. OnPaint будет лишний раз выводить изображение.
__________________
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума   Ответить с цитированием
Старый 12.06.2011, 20:19   #862
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Адрес: Россия
Сообщений: 136
Репутация: 38
По умолчанию

Неожиданностью я считал сворачивание формы. Если в масштабных играх нажать Alt+Tab, а потом восстановить игру, то приходится ждать ~ 5 секунд, что бы увидеть картинку.
Вопрос относительно таймера, какой интервал ему выставлять? Во многих статьях читал, что ставить его меньше 50 мс не имеет смысла. Разве во время воспроизведения видеозаставок таймер не останавливается (но это уже не по теме)?
Alexan-Dwer вне форума   Ответить с цитированием
Старый 12.06.2011, 22:13   #863
Пепел Феникса
Модератор
Заслуженный модератор
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Адрес: Москва
Сообщений: 21,003
Репутация: 3436

icq: 446843180
skype: phoenix_proger
По умолчанию

Цитата:
Если в масштабных играх нажать Alt+Tab, а потом восстановить игру, то приходится ждать ~ 5 секунд, что бы увидеть картинку.
это связанно с DirectX, а именно с первичными поверхностями, ибо она может быть лишь одна, и приложение потеряв фокус, теряет и поверхность, а её надо восстановить.
__________________
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума   Ответить с цитированием
Старый 12.06.2011, 23:06   #864
Beermonza
Инженер ИС
Профессионал
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
Репутация: 746
По умолчанию

Цитата:
Сообщение от Alexan-Dwer Посмотреть сообщение
Неожиданностью я считал сворачивание формы. Если в масштабных играх нажать Alt+Tab, а потом восстановить игру, то приходится ждать ~ 5 секунд, что бы увидеть картинку.
Кроме особенностей отображения посредством видеокарты и применяемых библиотек, если игра на одного пользователя, то можно и нужно просто тормозить таймер игры и отрисовку вообще. Если игра сетевая, то таймер останавливать нельзя, ...а у меня отрисовка выполнена в конце игрового таймера, т.е. таймер задает и интервал игровой и дает команду на построение и вывод изображения. При этом "в холостую" вывода на форму нет, только тогда, когда произошли изменения, а происходят они каждый такт, с выставленным интервалом 31 мс. В противоположность этому, видеокарта с библиотеками типа OpenGL или DirectX - молотит на сколько может, выводя изображение постоянно, ...от сюда и запредельный fps, который является показателем производительности.

Цитата:
Сообщение от Alexan-Dwer Посмотреть сообщение
Вопрос относительно таймера, какой интервал ему выставлять? Во многих статьях читал, что ставить его меньше 50 мс не имеет смысла. Разве во время воспроизведения видеозаставок таймер не останавливается (но это уже не по теме)?
Однако кроме левого совета - "ставить меньше 50 мс не имеет смысла", в этих статьях не упоминается ничего по сущности таймера TTimer, и на что он способен. Он использует стандартный Windows-таймер - SetTimer/KillTimer, у которого разрешение 16 мс, а не 50 мс (!). Все зависит от тормозности самого внутреннего кода таймера. Если применен тормозный код, то это не значит, что таймер медленный, ...только и всего. Всегда с TTimer можно рассчитывать на 64-65 fps в 2D игре - это очень много, достаточно 30, ...интервал 31 мс. А вот как сделать так, чтобы такой fps получить - это другой вопрос ...в этой теме ответ есть.

Если в таймере с интервалом 16 мс не успевает выполниться внутренний код, то интервал автоматически увеличится еще на 16, если снова не успевает - еще добавит 16, и так пока не будет знать, что код выполнен. Может быть так, что на выполнение кода нужно 20 мс, но таймер с 16 мс интервалом будет выполнять код через каждые 31-32 мс. Минимальный интервал не точный он лежит в пределах 15-18 мс. Если на внутренний код требуется 31 мс, то таймер может работать нестабильно, то увеличивая, то уменьшая скорость, могут быть рывки в изображении. Так что интервал нужно выбирать с умом: 16, 31, 48, 65, 81 и т.д. - все эти интервалы показывают разную скорость анимации, ...у меня.
__________________
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума   Ответить с цитированием
Старый 13.06.2011, 15:08   #865
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Адрес: Россия
Сообщений: 136
Репутация: 38
По умолчанию

Чем дальше, тем интересней…
Я еще не занимался оптимизацией таймера, но ваши слова побудили меня задуматься о том, что пора пересмотреть код.
Сейчас у меня таймер работает так:
  1. Очистка буфера (FillRect).
  2. Проверка переменной, отвечающей за стадию игры. Если игра еще не началась, то работа с меню. Иначе обработка перемещения NPC и игрока; далее я рисую в буфере карту, игрока и NPC, попавших в зону видимости.
  3. Вывод буфера на форму.
Теперь я решил добавить в таймер переменную Redraw типа Boolean = False. Если в игре произошли изменения, то поменять значение на True. Вывод буфера на форму осуществлять только при Redraw = True.

ИМХО: таймер — что-то вроде рекурсии, со стеком. То есть, если таймер сработал, то он вызывает себя и выполняет код. Если он это не успевает сделать, то добавляет задание в стек. Система пытается выполнить все задания из стека, но так как она выполняет только одно, а добавляются сразу два, то поручается зависание. Прошу простить и исправить, если это полная чушь.

Я так и не понял, идеальный таймер, это тот, у которого интервал должен быть примерно равен времени выполнению кода или интервал нужно специально сделать меньше (больше)?

Ради эксперимента поступил так:
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
var
T: Cardinal;
begin
T:=GetTickCount;
{Внутренний код...}
T:=GetTickCount-T;
Memo1.Lines.Add('In BreakPoint['+IntToStr(BreakPoint)+'] '+IntToStr(T)+' ms');
Memo1.Lines.SaveToFile('C:\logs\Timer on '+IntToStr(Timer.Interval)+'.txt');
end;
В логах:
С интервалом >=40: In BreakPoint[0] 31 ms | In BreakPoint[0] 16 ms | In BreakPoint[0] 15 ms...
При интервале 30-38: In BreakPoint[0] 32 ms | In BreakPoint[0] 15 ms | In BreakPoint[0] 16 ms | ... | In BreakPoint[2] 31 ms
А при <=16: In BreakPoint[0] 15 ms | In BreakPoint[0] 16 ms | In BreakPoint[0] 31 ms | In BreakPoint[0] 16 ms | In BreakPoint[0] 31 ms

Так как кадров на перемещении персонажа у меня всего 3, причем 1 и 3 спрайты одинаковы, то анимацию я делаю так: кадры меняю, когда задержка анимации равна 4, потом я ее обнуляю. Задержка изменяется в событии таймера. Получается, что анимация из трех кадров занимает 15*x мс, где x это интервал таймера.

Вывод: при интервале 15 и меньше анимацию не заметить, с 30-40 смотрится красиво, после 60 эффект замедленной съемки.
Alexan-Dwer вне форума   Ответить с цитированием
Старый 13.06.2011, 16:15   #866
Beermonza
Инженер ИС
Профессионал
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
Репутация: 746
По умолчанию

Для глаза комфортно 30 кадров в секунду, больше он не ощутит, если анимация раскадрована. 3D совсем другое дело, там нужно не менее 60 кадров в секунду.

С TTimer'ом мудрить не нужно, он сам оттянет время, на то он и простейший чтобы засунуть в него код и не думать успеет он выполниться за интервал или нет. Не успеет - увидишь замедление анимации, а если таймеры на игровой процесс и анимацию разные, то будет дискретное отображение кадров, рывками, то несколько раз один и тот же, то с пропуском некоторых.

Чтобы измерить скорость кода через таймер, интервал ставь 1000 мс иначе таймер вмешивается в расчет и после GetTickCount где-нибудь на середине кода оттягивает время, и подсчет уже будет некорректный. Лучше тогда вместо таймера использовать просто кнопку, чтобы по каждому нажатию видеть сколько мс забирает на себе внутренний код.
__________________
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума   Ответить с цитированием
Старый 13.06.2011, 17:45   #867
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Адрес: Россия
Сообщений: 136
Репутация: 38
По умолчанию

Что-то у меня все время проскакивают числа 15, 16 и 31. Выставил интервал 32, буду обкатывать. Я тоже думаю 30 FPS для 2D это хорошо, ведь это не shooteer. Раз уж тут прозвучали слова о библиотеках DirectX, то хотел спросить вот еще что:
Если я создаю игру с размерами окна 1024x768 и у пользователя разрешение 800x600, то форма не будет полностью показана.
Поэтому я написал такой код:
Код:
program AlphaGame;

uses
  Forms, Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

procedure ChangeDisplayResolution(X, Y: Word);
var
dm: TDEVMODE;
begin
ZeroMemory(@dm, SizeOf(TDEVMODE));
dm.dmSize:=SizeOf(TDEVMODE);
dm.dmPelsWidth:=X;
dm.dmPelsHeight:=Y;
dm.dmFields:=DM_PELSWIDTH or DM_PELSHEIGHT;
ChangeDisplaySettings(dm, 0);
end;

var
W, H: Integer;
begin
W:=Screen.Width;
H:=Screen.Height;
if (W<>1024) and (H<>768) then
ChangeDisplayResolution(1024, 768);

  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;

if (W<>1024) and (H<>768) then ChangeDisplayResolution(W, H);
end.
Но что будет, если монитор не стандартный (4:3), а широкоформатный (16:9), у него 1024x768 даже в настройках нет ? Либо 1280×800, либо 1280×768 с черной полоской… В 3D играх за отображение графики отвечает уже названная библиотека. Когда она выводит текстуру ящика на 16:9, то он будет просто шире и ниже, чем у меня в 4:3. Может кто-то подскажет, как с этим быть?
Alexan-Dwer вне форума   Ответить с цитированием
Старый 13.06.2011, 18:59   #868
Beermonza
Инженер ИС
Профессионал
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
Репутация: 746
По умолчанию

Хуже чем 1024x768 сейчас никто не имеет, тут даже про 800х600 не думай. Если ты не применяешь библиотеки, то менять режим монитора не следует. Нужно только определить разрешение, залить все черным, а свою игру выводить по центру в размере 1024х768.
__________________
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума   Ответить с цитированием
Старый 13.06.2011, 19:17   #869
Alexan-Dwer
Форумчанин
 
Аватар для Alexan-Dwer
 
Регистрация: 20.04.2009
Адрес: Россия
Сообщений: 136
Репутация: 38
По умолчанию

Что в моей игре этот метод смотрится не интересно:

Название: e63c2b463b98.jpg
Просмотров: 133

Размер: 32.5 Кб

Скажите, а как более правильно: if A=False then A:=True или A:=True и все (то есть проверка, а потом присваивание или сразу присваивание)?

Последний раз редактировалось Beermonza; 13.06.2011 в 19:40.
Alexan-Dwer вне форума   Ответить с цитированием
Старый 13.06.2011, 19:49   #870
Beermonza
Инженер ИС
Профессионал
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
Репутация: 746
По умолчанию

У тебя изображение видать 800х600 изначально, поскольку черная область тоже 4:3 формат, а такое не используется. Лично мне, размазанная графика по экрану не нравится, ...должно быть все четко пиксел в пиксел.

Для заливки картинок переключайся в "Расширенный режим" сообщения, жми скрепку, или внизу "Дополнительные опции", окошко "Вложить файлы", туда можно загрузить форматы, указанные в таблице.

Цитата:
Сообщение от Alexan-Dwer
Скажите, а как более правильно: if A=False then A:=True или A:=True и все (то есть проверка, а потом присваивание или сразу присваивание)?
Сразу пиши A := True;, если кроме этого ничего в условии нет.
__________________
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его

Последний раз редактировалось Beermonza; 13.06.2011 в 19:51.
Beermonza вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Уроки по созданию игр для новичков... -=DeS=- Gamedev - cоздание игр: Unity, OpenGL, DirectX 750 14.11.2017 21:26
Музыка программистов - как вы относитесь к АРИИ? Весёлый Жека Свободное общение 46 10.10.2008 22:32
Конкурсы по созданию игр на Delphi mutabor Свободное общение 0 15.06.2007 12:40
Работа по созданию ПО remix Фриланс 3 22.04.2007 11:00


20:54.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.