Часть1_Visual Basic.Net - Игровой цикл в 1000/сек на API таймере

Visual basic API timer
Организация игрового цикла с помощью Api таймера на Visual Basic.Net. Точность 1 мс.

Если взять встроенный таймер от Net, то он не дает разрешения срабатывания меньше чем 16 мс!
Да, еще у него разброс срабатывания может растянутся до 55 мс.
Связано это с тем, что у этого таймера низкий приоритет в системе. Например
если сработают другие события Windows, например события клавиатуры,
то система начинает обрабатывать сначала эти события, как более важные, а другие события оставляет на потом!

Под игровым циклом подразумевается цикл логики игры, а не частота вывода графики на экран.
Для игровой логики хотелось бы частота побольше, чем 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


Вторая часть статьи находиться здесь

http://www.esate.ru/blog/Visual_Basic_Net/321.html

</cut>
0       1379        05.08.2011

^