Часть1_Visual Basic.Net - Игровой цикл в 1000/сек на API таймере
Visual basic API timer Организация игрового цикла с помощью Api таймера на Visual Basic.Net. Точность 1 мс.
Если взять встроенный таймер от Net, то он не дает разрешения срабатывания меньше чем 16 мс! Да, еще у него разброс срабатывания может растянутся до 55 мс. Связано это с тем, что у этого таймера низкий приоритет в системе. Например если сработают другие события Windows, например события клавиатуры, то система начинает обрабатывать сначала эти события, как более важные, а другие события оставляет на потом! [spoiler] Под игровым циклом подразумевается цикл логики игры, а не частота вывода графики на экран. Для игровой логики хотелось бы частота побольше, чем 65/сек Вот как раз для этого можно подключить Api таймер, конечно и у него тоже бывает погрешности, но сравните 55мс и 1,2 или 3 мс в плюс минус. С помощью него можно прокручивать игровой цикл с частотой 1000 в секунду И не только, хоть и графику.
Объявляем переменные для работы таймера и подключаем API таймер Вот весь код Здесь есть возможность перемещаться вправо по коду, если что!
/*http://esate.ru, gally*/
Public Class Form1
'для обеспечения работы апи-таймера
Dim timer As myCallback = AddressOf apitimer1 'от названия зависит обращение к
'процедуре, можете дать свое!
Public Const elapse_Periodically As Integer = 1
Public Declare Function timeKillEvent Lib "winmm.dll" (ByVal uID As Integer) As Integer
Public Declare Function timeSetEvent Lib "winmm.dll" (ByVal interval_Ms As Integer, ByVal resolution_Ms As Integer, ByVal lpFunction As [Delegate], ByVal dwUser As Integer, ByVal uFlags As Integer) As Integer
Private Delegate Sub myCallback(ByVal uID As Integer, ByVal uMsg As Integer, ByVal dwUser As Integer, ByVal dw1 As Integer, ByVal dw2 As Integer)
Dim timerID As Integer
Const strnull As String = Nothing
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'этот код можно поместить не обязательно здесь
'timer api
timerID = timeSetEvent(1, 0, timer, strnull, elapse_Periodically)
'где цифра "1" после timeSetEvent, сразу за скобкой,
'вы указываете с какой частотой в мс он будет срабатывать
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
If keyData = Keys.Escape Then
'эдесь вы убираете таймер, например после завешения игры
'Api таймер, сборщиком мусора не убрать полностью
'Но я лично, часто не убирал, куда только сообщения отсылаются!!!
'Все равно система нормально работала
'но об этом ньюансе во второй части
timeKillEvent(timerID)
End
End If
End Function
'Dim timer As myCallback = AddressOf apitimer1 - названия должны совпадать
Public Sub apitimer1()
'Здесь помещаете код, цикл игры
End Sub
End Class