BitBlt, Sleep, Do/Loop, DoEvents, etc. in games
Hiyas,
I've finished making the core blit engine of my isometric game. I just fixed a problem involving blitting only visible tiles (my game uses multiple height levels), and the next problem to solve is to do with the game's blit/loop architechture.
Here's the basic architechture so far:
Code:
Private Sub Form_Load()
'Load/do stuff
Mouse
End Sub
Private Sub Mouse()
'Declarations, etc.
Do
'Clear the screen
GameForm.Cls
'Get mouse pos.
GetCursorPos CursorPos
CursorPos.X = CursorPos.X - (Me.Left / Screen.TwipsPerPixelX)
CursorPos.Y = CursorPos.Y - (Me.Top / Screen.TwipsPerPixelY)
'Scrolling if necessary
If GetActiveWindow = GameForm.hWnd Then
If CursorPos.X > -1 And CursorPos.X < 50 Then
Tactical.YOffset = Tactical.YOffset - 1
ElseIf CursorPos.X > (GameForm.Width / 15) - 50 And CursorPos.X < (GameForm.Width / 15) + 1 Then
Tactical.YOffset = Tactical.YOffset + 1
End If
If CursorPos.Y > -1 And CursorPos.Y < 50 Then
Tactical.XOffset = Tactical.XOffset - 1
ElseIf CursorPos.Y > (GameForm.Height / 15) - 50 And CursorPos.Y < (GameForm.Height / 15) + 1 Then
Tactical.XOffset = Tactical.XOffset + 1
End If
End If
'Blit sequence
For ZArray = 1 To Tactical.ZLevel
BlitStatus = 0
Ver = -1
Step = 0
Do Until Ver = ScreenVer
Hor = -1
If Step = 0 Then
Step = 1
ElseIf Step = 1 Then
Step = 0
Ver = Ver + 1
End If
Do Until Hor = ScreenHor
Hor = Hor + 1
HorBlit = (Hor - (Step / 2)) * 40
VerBlit = ((Ver + (Step / 2)) * 20) - 38
MapXCoOrd = Tactical.XOffset + Tactical.YOffset - (Tactical.YMapSize / 2) + Hor + Ver
MapYCoOrd = Tactical.XOffset - Tactical.YOffset + (Tactical.YMapSize / 2) - Hor + Ver + Step
If MapXCoOrd + ((ZArray - 1) * 2) > 0 And MapYCoOrd + ((ZArray - 1) * 2) > 0 And MapXCoOrd + ((ZArray - 1) * 2) < Tactical.XMapSize + 1 And MapYCoOrd + ((ZArray - 1) * 2) < Tactical.YMapSize + 1 Then
If CurrentLevelData.VisibleCheckArray(MapXCoOrd + ((ZArray - 1) * 2), MapYCoOrd + ((ZArray - 1) * 2), ZArray) = 1 And Not Map(MapXCoOrd + ((ZArray - 1) * 2), MapYCoOrd + ((ZArray - 1) * 2), ZArray).Tile = 0 Then
BitBlt GameForm.hDC, HorBlit, VerBlit, 40, 57, PicSource(1).hDC, (Map(MapXCoOrd + ((ZArray - 1) * 2), MapYCoOrd + ((ZArray - 1) * 2), ZArray).Tile - 1) * 40, 57, vbSrcAnd
BitBlt GameForm.hDC, HorBlit, VerBlit, 40, 57, PicSource(1).hDC, (Map(MapXCoOrd + ((ZArray - 1) * 2), MapYCoOrd + ((ZArray - 1) * 2), ZArray).Tile - 1) * 40, 0, vbSrcPaint
End If
End If
If BlitStatus = 0 And CursorPos.X > HorBlit And CursorPos.X < HorBlit + 40 And CursorPos.Y > VerBlit + 38 And CursorPos.Y < VerBlit + 57 Then
BitBlt GameForm.hDC, HorBlit, VerBlit, 40, 57, PicSource(0).hDC, 0, 57, vbSrcAnd
BitBlt GameForm.hDC, HorBlit, VerBlit, 40, 57, PicSource(0).hDC, 0, 0, vbSrcPaint
BlitStatus = 1
OffSetLabel.Caption = MapXCoOrd + ((ZArray - 1) * 2) & " " & MapYCoOrd + ((ZArray - 1) * 2)
End If
Loop
Loop
Next ZArray
'Refresh the screen
GameForm.Refresh
Sleep 10
DoEvents
Loop
End Sub
'If Q key pressed then quit the program instantly (doesn't exit the loop, just a straight 'End' command)
The problem is, when I move the mouse, the position/movement seems lagged. If I increase the value of Sleep, from say, 10 to 30, it's better. I know that I'm not supposed to use Sleep, but if I remove it, the 'lag' is just as bad, and my PC is a Duron 800! I tested this on my P200 with Sleep being 10, and I got about 1 FPS...hehe.
The form's default cursor is visible, and it isn't lagged. But, the cursor I'm blitting is. It's as if the call I'm using to get the mouse position isn't working.
Can someone please give me some basic code showing how I can have the best performance on any PC? I seem to remember using GetTickCount with DoEvents somehow, to limit FPS, or something like that... (I'm not totally sure how to use DoEvents)
Thanks,
-Git