Форум программистов, компьютерный форум, киберфорум
Программирование игр
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/29: Рейтинг темы: голосов - 29, средняя оценка - 4.62
4 / 4 / 0
Регистрация: 28.10.2015
Сообщений: 51

Game loop, игровая петля и ограничение FPS

17.10.2016, 12:52. Показов 5973. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, решил параллельно с xna/monogame'ом, поковырять LWJGL и познакомится с java. Посмотрел серию замечательных уроков по созданию простого 3d движка на джаве, и к своему стыду встал в самом начале. Во втором уроке показывалось создание "главной петли" с ограничением числа кадров до 60, но на видео видно что фреймрейт намного выше 200 - 500 кадров с секунду, пытался велосипедить, нарыл в гугле кучу примеров, не сработал ни один. Кто это делал поделитесь опытом как сделать петлю с верхним ограничением кадров и выделением дельты времени.
Вот текущее решение найденное в интернете:
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public void Start()
    {
        long lastLoopTime = System.nanoTime();
        int targetFPS = 60;
        int fps = 0;
        long optimalTime = 1000000000 / targetFPS;
        long lastFPS = 0;
        
        while(Window.open) 
        {   
            
            long nowTime = System.nanoTime();
            long updateLenght = nowTime - lastLoopTime;
            lastLoopTime = nowTime;
            double delta = updateLenght / (double)optimalTime;
            lastFPS += updateLenght;
            fps++;
            
            if(lastFPS > 1000000000)
            {
                System.out.println(fps);
                fps = 0;
                lastFPS = 0;
            }
            
            try 
            {
                Thread.sleep(lastLoopTime - System.nanoTime() + optimalTime / 1000000);
            } 
            catch (Exception e) 
            {
                
            }
            
            Window.events();
        }
    }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.10.2016, 12:52
Ответы с готовыми решениями:

Как снять ограничение 60 FPS
После установки 10 винды, появились ограничения 60 фпс во всех играх. Как бороться не знаю. Xbox отключал и удалял, не помогло. Надеюсь на...

Есть ли встроенная функция для подсчёта/ограничение fps?
Или самому считать?

Warining For-loop variable 'i' may be undefined after loop
Как исправить код, что бы программа работала корректно. var Form1: TForm1; implementation {$R *.dfm} procedure...

9
47 / 47 / 7
Регистрация: 26.12.2014
Сообщений: 189
18.10.2016, 10:00
Ну если вас оно устраивает пользуйтесь на здоровье. От себя добавлю, что нужно учитывать особенности игры
при проектировании игрового цикла.
0
4 / 4 / 0
Регистрация: 28.10.2015
Сообщений: 51
18.10.2016, 14:03  [ТС]
Да в том то и проблема что она меня не устраивает. Во первых нету верхнего ограничения, во вторых недавно заметил что скачет GC из-за заморозки треда, ничего страшного, но всё равно напрягает.
От себя добавлю, что нужно учитывать особенности игры
при проектировании игрового цикла.
Проблема номер два: перелистал с десяток статей и одна противоречит другой. В одной говорится что нужно ограничивать обновление логики а рендер пусть молотит сколько сможет, во второй наоборот, нужно ограничить рендер 60 обновлениями за секунду, а логика пусть обновляется сколько сможет, в третьей что они должны обновляться с равной частотой, но зачем тогда разбивать "апдейт" на логику и рендер. Плюс писалось что отдельно нужно обрабатывать ввод с максимально возможной частотой, а потом зашла речь об отдельном обновлении физ движка. В общем меня это окончательно загнало в ступор.
0
47 / 47 / 7
Регистрация: 26.12.2014
Сообщений: 189
18.10.2016, 14:14
Цитата Сообщение от Gypnori Посмотреть сообщение
рендер пусть молотит сколько сможет
Глупость прочел.

Цитата Сообщение от Gypnori Посмотреть сообщение
В общем меня это окончательно загнало в ступор.
Цитата Сообщение от godmode Посмотреть сообщение
нужно учитывать особенности игры
при проектировании игрового цикла.
Что у вас гонки, обилие физики, симулятор сборщика пасьянсов?
0
4 / 4 / 0
Регистрация: 28.10.2015
Сообщений: 51
18.10.2016, 16:06  [ТС]
Я не делаю конкретную игру, я хочу разобраться со внутреннем устройством игрового движка, но думаю одним из итогов работы хотел бы видеть такую сцену, т.е. отображение большого количества простых объектов с неким подобием физики.
0
 Аватар для BOGG ART
592 / 459 / 147
Регистрация: 09.12.2013
Сообщений: 2,385
Записей в блоге: 2
18.10.2016, 16:36
Цитата Сообщение от godmode Посмотреть сообщение
рендер пусть молотит сколько сможет
Это глупо. Но увы много кто так делает, и зря.
Цитата Сообщение от Gypnori Посмотреть сообщение
нужно ограничить рендер, а логика пусть обновляется сколько сможет
Что за логика такая должна быть, чтоб её так вот пускать в свободное плавание?

Добавлено через 1 минуту
Что-то перемещалось? Нет? Зачем тогда дёргать Collision Detection?
0
47 / 47 / 7
Регистрация: 26.12.2014
Сообщений: 189
18.10.2016, 23:47
Цитата Сообщение от Gypnori Посмотреть сообщение
Я не делаю конкретную игру, я хочу разобраться со внутреннем устройством игрового движка, но думаю одним из итогов работы хотел бы видеть такую сцену, т.е. отображение большого количества простых объектов с неким подобием физики.
Отлично, задержкой в физике можно принебречь.
Дрежите алгоритм, перепишите себе на языки какие вам надо.
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
Imports Microsoft.DirectX
Public Class Form1
 
    Private render_th As System.Threading.Thread = Nothing
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
 
        Me.Show()
 
        Me.render_th = New System.Threading.Thread(AddressOf Me.Render)
        Me.render_th.Start(Me.Handle)
 
    End Sub
 
    Private Function Fix_FPS(ByRef Max As Int32) As Boolean
 
        Static save_tc As Int32 = -1
        Static accum_div As Int32 = 0, div As Double = 0.0R
        Static accum As Double = 0
        Static accum_fps As Int32 = 0
 
        Dim tc As Int32 = System.Environment.TickCount
 
        accum_div += 1
        accum += div
 
        If ((tc - save_tc) >= 1000) Then
 
            div = Fix(accum_div / Max)
            save_tc = tc
            accum_div = 0.0R
            accum_fps = 0
            accum = 0.0R
 
            Return True
 
        End If
 
        If (div > 0.0R) AndAlso ((accum \ div) >= 1.0R) AndAlso (accum_fps <= Max) Then
 
            accum -= (accum \ div) * div
 
            accum_fps += 1
 
            Return False
 
        Else
 
            Return True
 
        End If
 
    End Function
 
    Private Sub Render(ByVal handle As IntPtr)
 
        Dim d3dpp As Direct3D.PresentParameters = New Direct3D.PresentParameters
 
        Dim device As Direct3D.Device = Nothing
 
        d3dpp.Windowed = True
        d3dpp.SwapEffect = Direct3D.SwapEffect.Discard
 
        d3dpp.EnableAutoDepthStencil = True
        d3dpp.AutoDepthStencilFormat = Direct3D.DepthFormat.D24S8
 
        d3dpp.PresentationInterval = Direct3D.PresentInterval.Immediate
        d3dpp.BackBufferWidth = 1024
        d3dpp.BackBufferHeight = 768
 
        d3dpp.BackBufferFormat = Direct3D.Manager.Adapters.Default.CurrentDisplayMode.Format
        '____________________________________________________
 
        device = New Direct3D.Device(0, Direct3D.DeviceType.Hardware, handle, Direct3D.CreateFlags.HardwareVertexProcessing, d3dpp)
 
        Dim save_tc As Int32 = System.Environment.TickCount
        Dim fps As Int32 = 0
 
        Do
 
            System.Threading.Thread.Sleep(1)
 
            If (Me.Fix_FPS(60) = True) Then Continue Do
 
            Dim tc As Int32 = System.Environment.TickCount
 
            fps += 1
 
            If ((tc - save_tc) >= 1000) Then
 
                save_tc = tc
                Me.Invoke(Sub() Me.Text = "FPS: " & fps.ToString)
 
                fps = 0
 
            End If
 
            Try
 
                device.BeginScene()
 
                device.Clear(Direct3D.ClearFlags.Target Or Direct3D.ClearFlags.Stencil Or Direct3D.ClearFlags.ZBuffer, Color.Orange.ToArgb, 1.0F, 0)
 
                device.EndScene()
                device.Present()
 
            Catch ex As Exception
 
                Debug.Print(ex.ToString)
 
                Exit Do
 
            End Try
 
        Loop
 
    End Sub
 
End Class
Дерзайте, творите, все в ваших руках.
0
4 / 4 / 0
Регистрация: 28.10.2015
Сообщений: 51
19.10.2016, 01:01  [ТС]
godmode Большое спасибо, сегодня с утра буду разбираться.
BOGG ART Вот я про то и говорю что одна статья противоречит другой, я замерял fps в xna там и в update и в draw везде 60.
0
47 / 47 / 7
Регистрация: 26.12.2014
Сообщений: 189
20.10.2016, 14:29
Цитата Сообщение от Gypnori Посмотреть сообщение
godmode Большое спасибо, сегодня с утра буду разбираться.
Сначала разберитесь, а потом благодарите.
Перепишите функцию, а то полета не будет.
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    Private Function Fix_FPS(ByRef Max As Int32) As Boolean
 
        Static save_tc As Int32 = -1
        Static accum_add As Int32 = 0, add As Single = 0.0F
        Static accum As Single = 0.0F
        Static accum_fps As Int32 = 0
 
        Dim tc As Int32 = System.Environment.TickCount
 
        accum_add += 1
        accum += add
 
        If ((tc - save_tc) >= 1000) Then
 
            If (accum_add = 0) Then accum_add = 1
 
            add = (Max / accum_add)
 
            save_tc = tc
            accum_add = 0.0F
            accum_fps = 0
            accum = 0.0F
 
            Return True
 
        End If
 
        If (accum >= 1.0F) AndAlso (accum_fps <= Max) Then
 
            accum -= 1.0F
 
            accum_fps += 1
 
            Return False
 
        Else
 
            Return True
 
        End If
 
    End Function
Вот так правильно ограничивает.
0
11 / 11 / 8
Регистрация: 13.04.2015
Сообщений: 159
26.10.2016, 09:45
https://habrahabr.ru/post/136878/
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.10.2016, 09:45
Помогаю со студенческими работами здесь

Warining For-loop variable 'i' may be undefined after loop
Что не так с кодом? При компиляции программы появляется предупреждение:&quot; Unit1.pas(46):For-loop variable 'i' may be undefined after...

Микрофризы , падения фпс , низкий 1% FPS и 0.1% fps
MSI Z370 A-PRO Intel i5-8600K ( Thermalright Macho Rev.A (BW) ) DDR4 2666 apecer 2 плашки по 8gb / разогнан до 3000 MSI rtx 2080...

Циклы: For…Next, For Each…Next, Do While…Loop, Do Until…Loop
кому не лень, помогите решить задачу, самому разбираться времени нету, и так работы много.. само задание - нужно сделать 13 вариант.. ...

Петля ?
Это петля ? Между sw3 и sw4 ?

петля в сети
всем доброго времени суток! проблема такая, есть большая сеть состоящая из НЕ управляемых комутаторов (за исключением пары штук), в эту...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru