Часть2_Visual Basic.Net - Игровой цикл в 1000/сек на API таймере
API таймер Часть 2
А теперь мы подробнее разберем дополнительные возможности программирования
с использованием API таймера
Первая часть статьи находиться
[spoiler]
Здесь будет рассмотрено подключение одновременно двух и даже трех таких таймеров,
где можно будет задавать различные интервалы для каждого.
А также менять интервалы этого специфичного апи таймера в реальном времени,
то есть, сама программа, уже скомпилированная,
может менять интервал, частоту срабатывания апи таймера
Сейчас я приведу код, который очень просто подключает два таймера.
Один будет срабатывать каждую 1 миллисекунду, а другой 10 миллисекунд
По сравнению с кодом, который был в первой части, здесь будет добавлено
всего несколько строчек кода к нему, который выполнит нашу поставленную выше цель.
Скопируйте весь код, приведенной в .
Измените название подпрограммы на gameloop1, в котором будет крутиться код.
Там у него было название apitimer1.
Public Sub gameloop1()
End Sub
Вы можете сами называть имя, как хотите, но я стараюсь, чтобы вы быстрее освоили
суть.
Обращение к этой подпрограмме происходит по имени этой подпрограммы.
То есть, в нашем конкретном случае gameloop1.
Поэтому также придется изменить прежнюю строчку кода
Dim timer As myCallback = AddressOf apitimer1
На это
Dim time1 As myCallback = AddressOf gameloop1
И также, изменить имя переменной timer на time1.
Не на timer1, а ту будет путаница для компилятора.
Обозначение AddressOf как бы перенаправляет сообщения апи функции
на подпрограмму gameloop1.
Каждый раз, когда срабатывает таймер timeSetEvent в библиотеке windows
winmm.dll, он каждый раз адресует сообщения на gameloop1.
Но таймер еще не работает, нужно его создать.
А создается он такой строчкой.
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
Этот код можно помещать там, где именно вы хотите создать таймер, я
для простоты поместил его в Form1_Load.
timeSetEvent состоит из четырех параметров.
- Нас интересуют первый и третий параметр.
В первом параметре, где мы поставили один, означает, что таймер
будет срабатывать с частотой 1 миллисекунд.
Он принимает значание integer, на заметку<, и не может ставиться меньше одного.
В третьем параметре указывается имя переменной time1.
Его имя должно соответствовать созданной ранее переменной типа myCallback
Dim time1 As myCallback = AddressOf gameloop1
А строчкой
timeKillEvent(timerID1)
Вы уничтожаете таймер timerID1. timerID1 несет в себе иденфикационный номер,
по которому идет обращение системы windows. Эту строку вы тоже можете
поместить там где хотите. Я изменил для краткости, поместив его в Form1_FormClosed
А был он в первой части в обработчике клавиатуры.
Ну, что теперь, давайте сделаем то, что хотели, а именно подключим два таймера
с разными интервалами.
Это делается легко добавляем такую строку.
Dim time2 As myCallback = AddressOf gameloop2
В итоге всё это будет выглядеть таким образом.
Dim time1 As myCallback = AddressOf gameloop1
Dim time2 As myCallback = AddressOf gameloop2
Создаем вторую аналогичную подпрограмму с именем,
как вы думаете?
Public Sub gameloop2()
End Sub
И нужно создать второй таймер. Создадим его в Form1_Load.
В итоге это все будет выглядеть вот так.
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID1 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
Привожу полный код
Получилось! Один срабатывает 1000 раз в секунду, другой 100 раз в секунду.
Подключение двух таких таймеров, я рассказываю свой личный опыт, дало
более плавный стабильный код. Была в этом у меня нужда, так как, там были и
сообщения клавиатуры, мыши, звук и графика.
Когда был один таймер, чаще всего возникали поддергивания экрана, так как
всё это было завязано на одном таймере. Здесь у вас появляется некоторая свобода.
В одном, вы можете просто крутить графику, а в другом обрабатывать все остальное.
Можете крутить графику не с частотой 100, а 200, а можете и 60/сек!
Ещё дополнительные ньюансы!
Вы можете увидеть в коде, что строчка
timeKillEvent(timerID1)
Так и осталась одна. Что это означает в нашем случае?
Если посмотреть на код, находящейся в Form1_Load, вы можете догадаться.
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID1 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
В этом конкретном случае это просто означает строкой
timeKillEvent(timerID1)
остановку сразу двух таймеров!
Но вдруг возникнет такая ситуация, что нам нужно остановить только один из них?
Делается это тоже очень просто!
Добавьте, где происходят глобальные инициализации переменных, к строке
Dim timerID1 As Integer
дополнительную строку
Dim timerID2 As Integer
И в Form1_Load измените код
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID1 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
На
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID2 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
Все! Теперь у вас появляется выбор!
Система идентифицировала, что вы подключили уже два апи таймера к вашей
программе. А в прошлом случае был один! Только сообщения разделялись
по-разному, с разными интервалами!
Можете остановить первый таким образом
timeKillEvent(timerID1)
А второй
timeKillEvent(timerID2)
Следующий вопрос.
А как сделать так, чтобы можно было изменить на ходу шаг
интервала таймера?
По логике, кажется достаточно просто вызвать где нибудь туже строку,
но только со значением 5 миллисекунд.
timerID1 = timeSetEvent(5, 0, time1, strnull, elapse_Periodically)
Но не получиться!
А получиться таким образом
timeKillEvent(timerID1)
timerID1 = timeSetEvent(5, 0, time1, strnull, elapse_Periodically)
Если вы хотите сходу, так скажем, во время работы программы,
изменить число тактов в секунду, нужно всегда использовать эти две строки.
Чтобы изменить интервал, вам нужно уничтожить сначала таймер, и пересоздать его.
На заметку: некоторые специально привязывают fps к частоте обновления монитора,
считая что это дополнительно гарантирует плавное отображение графики!
Для справки:
Вы также можете средствами например, узнать частоту обновления
монитора. У некоторых, это может быть 60, чаще 75, бывает и 85,
у особенных мониторов и 100.
И помещать такой код для графики
timerID1 = timeSetEvent(1000/Частота_обновления_монитора, 0, time1, strnull, elapse_Periodically)
Но здесь ещё можно дать совет!Дело в том, что при создании двух таймеров, и даже трех таймеров,
они, таймеры, ни такие уж и независимые друг от друга!
Например, если окажется так, что в первой процедуре
Public Sub gameloop1()
End Sub
Код будет не успевать за таймером, то это скажется и на второй процедуре
Public Sub gameloop2()
End Sub
Замедление в первой, а во второй?! Но, если вы хотите избежать этого, то поместите
код, у которого высока вероятность большой нагрузки,
не в первую процедуру gameloop1(), а во вторую gameloop2().
Даже если gameloop2() и зависнет по-страшному, gameloop1()
будет скакать, как и скакал!
Но если этот же тяжелый код будет стоять в gameloop1(),
то он будет работать медленно, не в нежелаемый изначальна такт,
а вот gameloop2(), и если есть gameloop3(),
вообще не будут никак тактировать!
И ещё мой личный совет, создавайте все-таки всегда timerID2,
timerID3, если нужно. Больше независимости друг на друга. ИМХО.
Другой вопрос. А не многовато ли для игрового темпа целых 1000 тактов?!
Ответ: Я не скажу строго определенно, но мне кажется лучше 1000, игровой темп будет
более плавным, так как темп игры будет разбит на малых приращениях, а у
этого апи таймера все-таки есть маленькие погрешности. ИМХО!
Возможно, есть у некоторых такой вопрос! Вот я решил сделать игровой цикл
в 1000 раз в секунду, а графику в 60. И я все сделал правильно! Конкретно,
игровой цикл, я расцениваю, как вполне предсказуемым по нагрузке и
помещаю его в gameloop1(), а графику, я оцениваю как тяжелую, непредсказуемую,
мне там тормоза не нужны, и я это всё помещаю в gameloop2().
Вот, что если у меня графика зависнет на 22 кадров, в то время как идет игровой
цикл с 1000/сек, а я ведь настроил таймер для графики на 1000/текущая_частота_обновления_экрана.
Может ли случиться так, что графика не успеет нормально до конца отрисоваться, как
уже пошел следующий такт от таймера, а он все-таки же невстроенный, а API???
Ответ: Графика будет до конца отрисововаться, так как процедура
не может начаться вновь, пока не завершиться, "не дойдет до конца End Sub".
Это значит, что автоматически, когда нагрузка графики станет в норме, вновь
поднимется до 60 FPS.
Здесь иногда удобно. Пользователю нет сильной разницы между 200 FPS и 100 FPS.
Но в тоже время есть больше необходимость сохранять игровой темп,
что мы и реализовали!
Но бывает и такой случай, когда наступает страшный тормоз! Как быть?
FPS = 4, игровой темп под 1000, А-а-а. Изображения, так скажем,
не плавно едят, а стали сильно подпрыгивать, и долго стоять на месте!!!
Сделать игровой цикл с меньшим тактированием, так как скорость
игры возникла по части графики, а не по части ИИ. Ну что уж поделать!
Но бывает и другой или дополнительный случай, когда есть возможность
отключить на ходу некоторые суперэффекты,
когда например FPS падает ниже 24. Например, если есть
анизотропная фильтрация, то в случае необходимости, перевести ее с 8 до 4!
Например здесь, я упомянул наличие возможностей обхода каллапса FPS, но думаю
игродел знает лучше, как это сделать со своей игрушкой!
И с помощью чего, можно решить эти две проблемы!
Есть несколько решений
У Visual Basic.Net есть неплохой счетчик. Называется StopWatch
Это не таймер, а счетчик. Им можно замерять прошедшие такты, миллисекунды,
от начала его включения. Я сам часто его использую для измерения
скорости кода.
Но в этом конкретном контексте есть простое решение!
То есть вы наверное догадались, что нужно что-то, которое вносила бы
коррекцию по части циклов.
Кидайте на форму элемент управления таймер.net - элемент управления
и TextBox, выбирите его свойства, где Enabled справа сделайте true,
И потом напишите интервал в 1000.
Делается это просто! Объявляется глобальная переменная
Dim fps As Integer
Дальше прописываете в процедуре gameloop2() такой код
Public Sub gameloop2()
fps = fps + 1
End Sub
На форме кликаете на Timer1 и вводите такой код
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
TextBox1.Text = "FPS = " + fps.ToString + " кадров/сек"
fps = 0
End Sub
Для наглядности я показал вам, как вы можете считать количество кадров.
Но возникает сомнение, а как же я буду точно корректировать, чтобы
справляться с перегрузкой, если измеряю
только с разностью одной секунды?!
Например, можно так сделать.
Делаете интервал таймера.net на 200
А в обработчике таймера пишите такой код
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
fps = fps * 5
TextBox1.Text = "FPS = " + fps.ToString + " кадров/сек"
fps = 0
End Sub
Почему три таймера могут быть полезны, а не два?
Потому что, бывает опрашивать клавиатуру и мышь 1000 раз бывает излишним.
Но бывает и наоборот, это удобно!
Зависит от жанра игры.
Но для справки с частотой 100 в секунду в большинстве вполне нормально!
Киньте два элемента Textbox и Timer.net и задайте ему интервал в 1000.
И не забудьте включить этот таймер.
Вот такой код
Я сделал возможность имитировать загруженность через цикл.
Можете попробовать увеличивать число в Textbox-е и
смотреть примитивное "FPS". Для наглядности все это!
И также там, в обработчике таймера.нет можно корректировать
частоту циклов, если что. Как это делать я показал,
с помощью двух строк, с использованием timeKillEvent.
А также, если посчитаете нужным, отключить некритичные красивости
графики.
Примерно это выглядило бы так.
If fps < 20 Then
'справляетесь с зависоном
End If
Хочу отмететь
Что не все ньюансы этого апи таймера я знаю!
Но я указал те места, на которые сам споткнулся.
Например, совершенно точно, что там вы не сможете
крутить код вместе с такими элементами управления, как
PictureBox, TextBox, Label.
Наконец дописал!
Если вы хотите воспринимать данную статью, как основную часть
2D или 3D движка, то пожалуйста!
</cut>
А теперь мы подробнее разберем дополнительные возможности программирования
с использованием API таймера
Первая часть статьи находиться
[spoiler]
Здесь будет рассмотрено подключение одновременно двух и даже трех таких таймеров,
где можно будет задавать различные интервалы для каждого.
А также менять интервалы этого специфичного апи таймера в реальном времени,
то есть, сама программа, уже скомпилированная,
может менять интервал, частоту срабатывания апи таймера
Сейчас я приведу код, который очень просто подключает два таймера.
Один будет срабатывать каждую 1 миллисекунду, а другой 10 миллисекунд
По сравнению с кодом, который был в первой части, здесь будет добавлено
всего несколько строчек кода к нему, который выполнит нашу поставленную выше цель.
Скопируйте весь код, приведенной в .
Измените название подпрограммы на gameloop1, в котором будет крутиться код.
Там у него было название apitimer1.
Public Sub gameloop1()
End Sub
Вы можете сами называть имя, как хотите, но я стараюсь, чтобы вы быстрее освоили
суть.
Обращение к этой подпрограмме происходит по имени этой подпрограммы.
То есть, в нашем конкретном случае gameloop1.
Поэтому также придется изменить прежнюю строчку кода
Dim timer As myCallback = AddressOf apitimer1
На это
Dim time1 As myCallback = AddressOf gameloop1
И также, изменить имя переменной timer на time1.
Не на timer1, а ту будет путаница для компилятора.
Обозначение AddressOf как бы перенаправляет сообщения апи функции
на подпрограмму gameloop1.
Каждый раз, когда срабатывает таймер timeSetEvent в библиотеке windows
winmm.dll, он каждый раз адресует сообщения на gameloop1.
Но таймер еще не работает, нужно его создать.
А создается он такой строчкой.
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
Этот код можно помещать там, где именно вы хотите создать таймер, я
для простоты поместил его в Form1_Load.
timeSetEvent состоит из четырех параметров.
- Нас интересуют первый и третий параметр.
В первом параметре, где мы поставили один, означает, что таймер
будет срабатывать с частотой 1 миллисекунд.
Он принимает значание integer, на заметку<, и не может ставиться меньше одного.
В третьем параметре указывается имя переменной time1.
Его имя должно соответствовать созданной ранее переменной типа myCallback
Dim time1 As myCallback = AddressOf gameloop1
А строчкой
timeKillEvent(timerID1)
Вы уничтожаете таймер timerID1. timerID1 несет в себе иденфикационный номер,
по которому идет обращение системы windows. Эту строку вы тоже можете
поместить там где хотите. Я изменил для краткости, поместив его в Form1_FormClosed
А был он в первой части в обработчике клавиатуры.
Ну, что теперь, давайте сделаем то, что хотели, а именно подключим два таймера
с разными интервалами.
Это делается легко добавляем такую строку.
Dim time2 As myCallback = AddressOf gameloop2
В итоге всё это будет выглядеть таким образом.
Dim time1 As myCallback = AddressOf gameloop1
Dim time2 As myCallback = AddressOf gameloop2
Создаем вторую аналогичную подпрограмму с именем,
как вы думаете?
Public Sub gameloop2()
End Sub
И нужно создать второй таймер. Создадим его в Form1_Load.
В итоге это все будет выглядеть вот так.
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID1 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
Привожу полный код
|
Получилось! Один срабатывает 1000 раз в секунду, другой 100 раз в секунду.
Подключение двух таких таймеров, я рассказываю свой личный опыт, дало
более плавный стабильный код. Была в этом у меня нужда, так как, там были и
сообщения клавиатуры, мыши, звук и графика.
Когда был один таймер, чаще всего возникали поддергивания экрана, так как
всё это было завязано на одном таймере. Здесь у вас появляется некоторая свобода.
В одном, вы можете просто крутить графику, а в другом обрабатывать все остальное.
Можете крутить графику не с частотой 100, а 200, а можете и 60/сек!
Ещё дополнительные ньюансы!
Вы можете увидеть в коде, что строчка
timeKillEvent(timerID1)
Так и осталась одна. Что это означает в нашем случае?
Если посмотреть на код, находящейся в Form1_Load, вы можете догадаться.
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID1 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
В этом конкретном случае это просто означает строкой
timeKillEvent(timerID1)
остановку сразу двух таймеров!
Но вдруг возникнет такая ситуация, что нам нужно остановить только один из них?
Делается это тоже очень просто!
Добавьте, где происходят глобальные инициализации переменных, к строке
Dim timerID1 As Integer
дополнительную строку
Dim timerID2 As Integer
И в Form1_Load измените код
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID1 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
На
timerID1 = timeSetEvent(1, 0, time1, strnull, elapse_Periodically)
timerID2 = timeSetEvent(10, 0, time2, strnull, elapse_Periodically)
Все! Теперь у вас появляется выбор!
Система идентифицировала, что вы подключили уже два апи таймера к вашей
программе. А в прошлом случае был один! Только сообщения разделялись
по-разному, с разными интервалами!
Можете остановить первый таким образом
timeKillEvent(timerID1)
А второй
timeKillEvent(timerID2)
Следующий вопрос.
А как сделать так, чтобы можно было изменить на ходу шаг
интервала таймера?
По логике, кажется достаточно просто вызвать где нибудь туже строку,
но только со значением 5 миллисекунд.
timerID1 = timeSetEvent(5, 0, time1, strnull, elapse_Periodically)
Но не получиться!
А получиться таким образом
timeKillEvent(timerID1)
timerID1 = timeSetEvent(5, 0, time1, strnull, elapse_Periodically)
Если вы хотите сходу, так скажем, во время работы программы,
изменить число тактов в секунду, нужно всегда использовать эти две строки.
Чтобы изменить интервал, вам нужно уничтожить сначала таймер, и пересоздать его.
На заметку: некоторые специально привязывают fps к частоте обновления монитора,
считая что это дополнительно гарантирует плавное отображение графики!
Для справки:
Вы также можете средствами например, узнать частоту обновления
монитора. У некоторых, это может быть 60, чаще 75, бывает и 85,
у особенных мониторов и 100.
И помещать такой код для графики
timerID1 = timeSetEvent(1000/Частота_обновления_монитора, 0, time1, strnull, elapse_Periodically)
Но здесь ещё можно дать совет!Дело в том, что при создании двух таймеров, и даже трех таймеров,
они, таймеры, ни такие уж и независимые друг от друга!
Например, если окажется так, что в первой процедуре
Public Sub gameloop1()
End Sub
Код будет не успевать за таймером, то это скажется и на второй процедуре
Public Sub gameloop2()
End Sub
Замедление в первой, а во второй?! Но, если вы хотите избежать этого, то поместите
код, у которого высока вероятность большой нагрузки,
не в первую процедуру gameloop1(), а во вторую gameloop2().
Даже если gameloop2() и зависнет по-страшному, gameloop1()
будет скакать, как и скакал!
Но если этот же тяжелый код будет стоять в gameloop1(),
то он будет работать медленно, не в нежелаемый изначальна такт,
а вот gameloop2(), и если есть gameloop3(),
вообще не будут никак тактировать!
И ещё мой личный совет, создавайте все-таки всегда timerID2,
timerID3, если нужно. Больше независимости друг на друга. ИМХО.
Другой вопрос. А не многовато ли для игрового темпа целых 1000 тактов?!
Ответ: Я не скажу строго определенно, но мне кажется лучше 1000, игровой темп будет
более плавным, так как темп игры будет разбит на малых приращениях, а у
этого апи таймера все-таки есть маленькие погрешности. ИМХО!
Возможно, есть у некоторых такой вопрос! Вот я решил сделать игровой цикл
в 1000 раз в секунду, а графику в 60. И я все сделал правильно! Конкретно,
игровой цикл, я расцениваю, как вполне предсказуемым по нагрузке и
помещаю его в gameloop1(), а графику, я оцениваю как тяжелую, непредсказуемую,
мне там тормоза не нужны, и я это всё помещаю в gameloop2().
Вот, что если у меня графика зависнет на 22 кадров, в то время как идет игровой
цикл с 1000/сек, а я ведь настроил таймер для графики на 1000/текущая_частота_обновления_экрана.
Может ли случиться так, что графика не успеет нормально до конца отрисоваться, как
уже пошел следующий такт от таймера, а он все-таки же невстроенный, а API???
Ответ: Графика будет до конца отрисововаться, так как процедура
не может начаться вновь, пока не завершиться, "не дойдет до конца End Sub".
Это значит, что автоматически, когда нагрузка графики станет в норме, вновь
поднимется до 60 FPS.
Здесь иногда удобно. Пользователю нет сильной разницы между 200 FPS и 100 FPS.
Но в тоже время есть больше необходимость сохранять игровой темп,
что мы и реализовали!
Но бывает и такой случай, когда наступает страшный тормоз! Как быть?
FPS = 4, игровой темп под 1000, А-а-а. Изображения, так скажем,
не плавно едят, а стали сильно подпрыгивать, и долго стоять на месте!!!
Сделать игровой цикл с меньшим тактированием, так как скорость
игры возникла по части графики, а не по части ИИ. Ну что уж поделать!
Но бывает и другой или дополнительный случай, когда есть возможность
отключить на ходу некоторые суперэффекты,
когда например FPS падает ниже 24. Например, если есть
анизотропная фильтрация, то в случае необходимости, перевести ее с 8 до 4!
Например здесь, я упомянул наличие возможностей обхода каллапса FPS, но думаю
игродел знает лучше, как это сделать со своей игрушкой!
И с помощью чего, можно решить эти две проблемы!
Есть несколько решений
У Visual Basic.Net есть неплохой счетчик. Называется StopWatch
Это не таймер, а счетчик. Им можно замерять прошедшие такты, миллисекунды,
от начала его включения. Я сам часто его использую для измерения
скорости кода.
Но в этом конкретном контексте есть простое решение!
То есть вы наверное догадались, что нужно что-то, которое вносила бы
коррекцию по части циклов.
Кидайте на форму элемент управления таймер.net - элемент управления
и TextBox, выбирите его свойства, где Enabled справа сделайте true,
И потом напишите интервал в 1000.
Делается это просто! Объявляется глобальная переменная
Dim fps As Integer
Дальше прописываете в процедуре gameloop2() такой код
Public Sub gameloop2()
fps = fps + 1
End Sub
На форме кликаете на Timer1 и вводите такой код
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
TextBox1.Text = "FPS = " + fps.ToString + " кадров/сек"
fps = 0
End Sub
Для наглядности я показал вам, как вы можете считать количество кадров.
Но возникает сомнение, а как же я буду точно корректировать, чтобы
справляться с перегрузкой, если измеряю
только с разностью одной секунды?!
Например, можно так сделать.
Делаете интервал таймера.net на 200
А в обработчике таймера пишите такой код
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
fps = fps * 5
TextBox1.Text = "FPS = " + fps.ToString + " кадров/сек"
fps = 0
End Sub
Почему три таймера могут быть полезны, а не два?
Потому что, бывает опрашивать клавиатуру и мышь 1000 раз бывает излишним.
Но бывает и наоборот, это удобно!
Зависит от жанра игры.
Но для справки с частотой 100 в секунду в большинстве вполне нормально!
Киньте два элемента Textbox и Timer.net и задайте ему интервал в 1000.
И не забудьте включить этот таймер.
Вот такой код
|
Я сделал возможность имитировать загруженность через цикл.
Можете попробовать увеличивать число в Textbox-е и
смотреть примитивное "FPS". Для наглядности все это!
И также там, в обработчике таймера.нет можно корректировать
частоту циклов, если что. Как это делать я показал,
с помощью двух строк, с использованием timeKillEvent.
А также, если посчитаете нужным, отключить некритичные красивости
графики.
Примерно это выглядило бы так.
If fps < 20 Then
'справляетесь с зависоном
End If
Хочу отмететь
Что не все ньюансы этого апи таймера я знаю!
Но я указал те места, на которые сам споткнулся.
Например, совершенно точно, что там вы не сможете
крутить код вместе с такими элементами управления, как
PictureBox, TextBox, Label.
Наконец дописал!
Если вы хотите воспринимать данную статью, как основную часть
2D или 3D движка, то пожалуйста!
</cut>
2730
06.08.2011



.