Main

IT GUIDE

 

Source Code

My Code
Other Projects

Zipped Source Code

Unsorted Code

VB Gem

Trojan Source Code

 

HELP

VB Books

VB Commands

VB Functions

Online MSDN

Online Book

 

TIPS & TRICKS

Tips & Tricks

Tips & Tricks 2

 

TUTORIAL

Code Optimization

Code Optimization 2

Code Optimization 3

Games Tutorial

DirectX

 

 

Favorites

Me




Programming a Simple Side Platform Game
By Steven Dumble


In the tutorial, it will be explained how to start programming a simple VB game engine that will take input from the keyboard and convert it into character movement. This character will be displayed side-on in a picture box and will be able to move over a fixed or scrolling background picture. The engine will read an alpha bitmap and allow the defined parts to be solid (i.e. a platform) or empty space.

Here is an example of a simple background and a corresponding alpha bitmap for it.

 


(Note: the original size of the pictures was 1600x1000)


Step 1: Basic Data Structures
Open up VB and create a new project. Add a new module. This module is going to be the main module where the data structures and most of the game function will be, so call it appropriately (i.e. “GameData”).

Firstly tell VB that all the variables used will have to be defined and to use 1 as the starting index for all dynamic arrays.



Option Base 1
Option Explicit



Define the Data Structures that will be used. Start off by defining the viewport.


Type ViewData
CurrentTopX As Long
CurrentTopY As Long
ScreenWidth As Integer
ScreenHeight As Integer
End Type

Global ViewPort As ViewData

The type ‘ViewData’ will be used to hold the TopX and TopY coordinates of the view area in relation to the background. It also holds the width and height of the view area. The last line makes this data type visible to the whole project as the variable called “ViewPort”.

Next define the data type for the characters. This is one place that would be modified according to your needs. A very simple game will have the following data structure of each player. Other things that might be stored in the ‘PlayerData’ structure might be things like: The players name, Is the player computer controlled, the player’s weapon, the player’s power up, score, character type, current animation frame, etc.


Type PlayerData
X As Long
Y As Long
Xspeed As Single
Yspeed As Single
Visible As Boolean
Width As Integer
Height As Integer
End Type

Global Players() As PlayerData
Global NumberOfPlayers As Integer


The second last line defines the ‘PlayerData’ type as a dynamic array visible to the entire program. The last line is used to hold the number of players defined in the array. This method is faster than using the ‘Ubound’ and ‘Lbound’ commands in loops and other control structures.

Step 2: Setting Up the Main Forms

Rename ‘Form1’ to ‘FrmMain’.
With the Form:
Set KeyPreview: True
Set AutoRedraw: True
Set ScaleMode to “3 - Pixel”

Add two large picture boxes.
With the First one:
Name it “PlayArea”
Set the ScaleMode to “3 - Pixel”
This will be where all the graphics will be displayed.

With the Second one:
Name it “BackBuffer”
Set AutoRedraw”: True
Set the ScaleMode to “3 - Pixel”
Set the height and width to that of the Picture Box ‘PlayArea’
Place this picture box off screen on the form.
This second picture box is the back buffer. All the graphics are draw to it and then at the end of the game loop it’s contents are then transferred to the ‘PlayArea’ Picture box.

Add a timer to the form.
With the timer:
Name it “GameTimer”
Set Enabled: False
Set Interval to “20”
This will be the timer that will call the Game Loop. In this game loop all the game operations will be carried out.
 

 


Add the following Code to the Form:


Private Sub Form_Load()
'set up the view port
ViewPort.CurrentTopX = 0
ViewPort.CurrentTopY = 0
ViewPort.ScreenHeight = PlayArea.ScaleHeight
ViewPort.ScreenWidth = PlayArea.ScaleWidth

End Sub

Private Sub GameTimer_Timer()
DoEvents
DoGameLoop
DoEvents
End Sub

Private Sub Form_Unload(Cancel As Integer)
UnloadGame
End Sub


Note: The ‘DoGameLoop’ and ‘UnloadGame’ Subs will be written shortly.

In the Form Load Event the basic settings for the view port are set.
The GameTimer will call a sub that will be written in a separate module for neatness.
The Unload event will call a sub that will make sure that every thing is unloaded from memory for a clean termination of the program.

Next add a New form. With the form:
Name it “FrmPics”
Set AutoRedraw: True
Set ScaleMode to “3 - Pixel”


Add two Picture boxes.
With the first one:
Name it “MapPicture”
Set AutoRedraw: True
Set AutoSize: True
Set ScaleMode to “3 - Pixel”

This picture box will hold the Map Picture.

With the Second one:
Name it “MapMask”
Set AutoRedraw: True
Set AutoSize: True
Set ScaleMode to “3 - Pixel”

This will be used in the BackGround collision detection.

Lastly add two more picture boxes. These will be used to hold the player sprite.
With the first one:
Name it “Character”
Set AutoRedraw: True
Set AutoSize: True
Set ScaleMode to “3 - Pixel”
Set the picture property to a picture that will be used as the player sprite.


With the second one:
Name it “CharacterMask”
Set AutoRedraw: True
Set AutoSize: True
Set ScaleMode to “3 - Pixel”
Set the picture property to a picture that will be used as the player sprite mask.



Step 3: More Maintenance

Add a new module, and call it GameLoop. Add a new Sub to it called ‘DoGameLoop’.


Sub DoGameLoop()

End Sub


Under the “GameData” module add the following code.


Sub UnloadGame()
Unload FrmMain
Unload FrmPics
End Sub


This will unload the forms from memory and unload the program.


Step 4: Character Movement

Next in the GameData module define some constants that will be used in the physics calculations. The values can be modified to change how the characters move.


Public Const MAX_SPEED As Single = 10
Public Const GRAVITY As Single = 1
Public Const FRICTION As Single = 0.4
Public Const ACCELERATION As Single = 4



Add the following code to the module.


Sub ApplyGravity()
Dim X As Integer
For X = 1 To NumberOfPlayers
'add gravity onto the Yspeed
If Players(X).Visible = True Then
Players(X).Yspeed = Players(X).Yspeed + GRAVITY
End If
Next X
End Sub


Gravity is simulated by adding a constant value onto each of the player’s YSpeeds. Note: in VB the coordinate system is defined by the Top Left being (0,0).

Before we can fully continue with the character movement we have to take into account for collisions with solid objects on the background.

There are a number of ways to doing thing. One is to check every pixel in the path of the movement for a black pixel and move the character only as far as that pixel. Another way is to convert the Map Alpha map into a 2d array of Booleans corresponding to each pixel of the alpha, and check that. The first method is slower because it uses the API call “GetPixel” and second method is faster but it can use up a lot of memory. In this example, it will be using the second method as more collision operations can be carried out faster.


Create a new module, name it Collisions and add the following code.


Option Explicit
Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long

Dim CollisionMap() As Boolean
Dim CMHeight As Integer
Dim CMWidth As Integer



Sub CreateCollisionMap() 'Convert a BMP Mask into an 2d Array of _ booleans 0 = white, 1 = black
Dim X, Y As Integer
Dim Tempdata As Long

CMHeight = FrmPics.MapMask.Height
CMWidth = FrmPics.MapMask.Width
ReDim CollisionMap(CMWidth - 1, CMHeight - 1)

For Y = 0 To CMHeight - 1
For X = 0 To CMWidth - 1
DoEvents
Tempdata = GetPixel(FrmPics.MapMask.hdc, X, Y)
If Tempdata = 0 Then CollisionMap(X, Y) = True
Next X
Next Y

End Sub

This Sub loads a BMP mask into an array. The function Is extremely Slow! So a subroutine is written to save and load the data from a file.


Sub SaveCollisionMap(Path As String)
On Error GoTo ErrSub:
Open Path For Binary Access Write As #1
Put #1, , CMWidth
Put #1, , CMHeight
Put #1, , CollisionMap
Close #1
ErrSub:
End Sub



Sub LoadCollisionMap(Path As String)
Open Path For Binary Access Read As #1
Get #1, , CMWidth
Get #1, , CMHeight
ReDim CollisionMap(CMWidth - 1, CMHeight - 1)
Get #1, , CollisionMap
Close #1
End Sub



Function CheckPoint(X As Long, Y As Long) As Boolean
If X < 0 Then
CheckPoint = True
Exit Function
End If

If Y < 0 Then
CheckPoint = True
Exit Function
End If

If X >= CMWidth - 1 Then
CheckPoint = True
Exit Function
End If

If Y >= CMHeight - 1 Then
CheckPoint = True
Exit Function
End If

If CollisionMap(X, Y) = True Then CheckPoint = True
End Function


This function checks a point in the array to see if it is solid or not. It returns True if it is.


Sub AllPlayersBGCollision()
Dim X As Integer
Dim X1, X2, X3, X4 As Long
Dim Y1, Y2, Y3, Y4 As Long
Dim TempSpeed As Single

For X = 1 To NumberOfPlayers
DoEvents

If Players(X).Visible = True Then
X1 = Players(X).X + (Players(X).Width / 2) 'top middle
Y1 = Players(X).Y

X2 = Players(X).X + Players(X).Width ' right middle
Y2 = Players(X).Y + (Players(X).Height / 2)

X3 = Players(X).X + (Players(X).Width / 2) 'bottom middle
Y3 = Players(X).Y + Players(X).Height

X4 = Players(X).X 'left middle
Y4 = Players(X).Y + (Players(X).Height / 2)

If Players(X).Yspeed > 0 Then 'going down
TempSpeed = BGCollisionBottom(X3, Y3, Players(X).Yspeed)
If TempSpeed < Players(X).Yspeed Then 'hit
Players(X).Yspeed = Players(X).Yspeed * -1 * 0.2 'bounce
Else
Players(X).Yspeed = TempSpeed
End If
ElseIf Players(X).Yspeed < 0 Then 'going up
TempSpeed = BGCollisionTop(X1, Y1, Players(X).Yspeed)
Players(X).Yspeed = TempSpeed
End If


If Players(X).Xspeed < 0 Then 'going left
TempSpeed = BGCollisionLeft(X4, Y4, Players(X).Xspeed)
Players(X).Xspeed = TempSpeed
Else ‘going right
TempSpeed = BGCollisionRight(X2, Y2, Players(X).Xspeed)
Players(X).Xspeed = TempSpeed
End If
End If
Next X
End Sub


This sub does the collisions for all the characters. It only checks the direction the player is moving for objects as it is quicker than checking all of the directions. This sub could be modified for more accurate detection, as at the moment it only checks from the middle of the sides of the sprite.


Function BGCollisionTop(ByVal X1 As Long, ByVal Y1 As Long, ByVal Yspeed As Single) As Single
Dim Y As Integer
Dim Tempdata As Boolean
For Y = 0 To Abs(Int(Yspeed))
Tempdata = CheckPoint(X1, Y1 - Y)
If Tempdata = True Then
If Y = 1 Then Y = 0
BGCollisionTop = Y * -1
Exit Function
End If
Next Y
BGCollisionTop = Yspeed
End Function

Function BGCollisionBottom(ByVal X1 As Long, ByVal Y1 As Long, ByVal Yspeed As Single) As Single
Dim Y As Integer
Dim Tempdata As Boolean
For Y = 0 To Int(Yspeed)
Tempdata = CheckPoint(X1, Y1 + Y)
If Tempdata = True Then
If Y = 1 Then Y = 0
BGCollisionBottom = Y
Exit Function
End If
Next Y
BGCollisionBottom = Yspeed
End Function

Function BGCollisionLeft(ByVal X1 As Long, ByVal Y1 As Long, ByVal Xspeed As Single) As Single
Dim Y As Integer
Dim Tempdata As Boolean
For Y = 0 To Abs(Int(Xspeed))
Tempdata = CheckPoint(X1 - Y, Y1)
If Tempdata = True Then
If Y = 1 Then Y = 0
BGCollisionLeft = (Y) * -1
Exit Function
End If
Next Y
BGCollisionLeft = Xspeed
End Function

Function BGCollisionRight(ByVal X1 As Long, ByVal Y1 As Long, ByVal Xspeed As Single) As Single
Dim Y As Integer
Dim Tempdata As Boolean
For Y = 0 To Int(Xspeed)
Tempdata = CheckPoint(X1 + Y, Y1)
If Tempdata = True Then
If Y = 1 Then Y = 0
BGCollisionRight = Y
Exit Function
End If
Next Y
BGCollisionRight = Xspeed
End Function


These functions take a point and speed and return the speed that the object can travel until it hits something. If there is nothing in the way, it just returns the original speed.


Function IsOnGround(X1 As Long, Y1 As Long) As Boolean
If CheckPoint(X1, Y1) = True Then IsOnGround = True
End Function


This returns true if the point is on the ground.

Back to the character movement!
In the ‘GameData’ module add the following code.


Sub AddFriction()
Dim X As Integer
For X = 1 To NumberOfPlayers
If Players(X).Visible = True Then
If IsOnGround(Players(X).X + (Players(X).Width / 2), Players(X).Y + Players(X).Height + 1) Then
If Players(X).Xspeed > 0 Then
Players(X).Xspeed = Players(X).Xspeed - FRICTION
If Players(X).Xspeed < 0 Then Players(X).Xspeed = 0
End If

If Players(X).Xspeed < 0 Then
Players(X).Xspeed = Players(X).Xspeed + FRICTION
If Players(X).Xspeed > 0 Then Players(X).Xspeed = 0
End If
End If
End If
Next X
End Sub


This function adds a friction const on to the Xspeed of the characters when they are on the ground.

Function GetTopOfTerrain(X As Long, Y As Long) As Long
Dim i As Integer
For i = 0 To 100
If CheckPoint(X, Y - i) = False Then
GetTopOfTerrain = i
Exit Function
End If
Next i
End Function


This function gets the top of the terrain. It is used to help the character when moving up hills.


Sub MoveAllPlayers()
Dim X As Integer
Dim Temp As Integer
For X = 1 To NumberOfPlayers
If Players(X).Visible = True Then
Players(X).X = Players(X).X + Players(X).Xspeed
Players(X).Y = Players(X).Y + Players(X).Yspeed
If IsOnGround(Players(X).X + (Players(X).Width / 2), Players(X).Y + Players(X).Height) Then
Players(X).Y = Players(X).Y - GetTopOfTerrain(Players(X).X + (Players(X).Width / 2), Players(X).Y + Players(X).Height)
End If
End If
Next X
End Sub


This is the sub that handles the movement of the characters. It adds the Xspeed on to the X coordinate and the Yspeed on to the Y coordinate.

Now to tie this into the game modify the DoGameLoop sub in the GameLoop Module.


Sub DoGameLoop()

ApplyGravity

AddFriction

AllPlayersBGCollision

MoveAllPlayers

DoEvents

End Sub


Step 5: KeyBoard Input

This game runs on a timed loop, but VB is event driven. To handle this, the input is saved as Booleans and then check in the loop.

Add the following to the ‘GameData’ module.


'Input Data
Global Adown As Boolean
Global Ddown As Boolean
Global Wdown As Boolean
Global Sdown As Boolean


To the ‘FrmMain’ add the following Code.


Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
If Players(1).Visible = True Then
If KeyCode = 65 Then Adown = True
If KeyCode = 68 Then Ddown = True
If KeyCode = 87 Then Wdown = True
If KeyCode = 83 Then Sdown = True
End If
End Sub

Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
If Players(1).Visible = True Then
If KeyCode = 65 Then Adown = False
If KeyCode = 68 Then Ddown = False
If KeyCode = 87 Then Wdown = False
If KeyCode = 83 Then Sdown = False
End If
End Sub



To the ‘GameData’ add the following Sub.


Sub DoInput()

'Key Boolean On/Off Checks

If Adown = True Then
If Players(1).Xspeed < (MAX_SPEED * -1) Then
Players(1).Xspeed = MAX_SPEED * -1
Else
If Players(1).Xspeed - ACCELERATION < (MAX_SPEED * -1) Then
Players(1).Xspeed = MAX_SPEED * -1
Else
Players(1).Xspeed = Players(1).Xspeed - ACCELERATION
End If
End If
End If

If Ddown = True Then
If Players(1).Xspeed > MAX_SPEED Then
Players(1).Xspeed = MAX_SPEED
Else
If Players(1).Xspeed + ACCELERATION > MAX_SPEED Then
Players(1).Xspeed = MAX_SPEED
Else
Players(1).Xspeed = Players(1).Xspeed + ACCELERATION
End If
End If
End If

If Wdown = True Then ‘Jump
If IsOnGround(Players(1).X + (Players(1).Width / 2), Players(1).Y + Players(1).Height + 1) Then
Players(1).Yspeed = Players(1).Yspeed - (ACCELERATION*4)
If Players(1).Yspeed < (MAX_SPEED * -1) Then Players(1).Yspeed = MAX_SPEED * -1
End If
End If

End Sub


Now to tie this into the game modify the DoGameLoop sub in the GameLoop Module.


Sub DoGameLoop()

ApplyGravity

DoInput

AddFriction

AllPlayersBGCollision

MoveAllPlayers

DoEvents

End Sub


Step 6: The Graphics!

Create a New Module call Graphics and add the following Code.



Option Base 1
Option Explicit

Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

' Constants for Raster Operations used by BitBlt function.
Const SRCAND = &H8800C6 ' dest = source AND dest
Const SRCCOPY = &HCC0020 ' dest = source
Const SRCPAINT = &HEE0086 ' dest = source OR dest




Function DrawBackGround(CurrentTopX As Long, CurrentTopY, Height As Integer, Width As Integer, SourceHDC As Long, DestHDC As Long)
BitBlt DestHDC, 0, 0, ViewPort.ScreenWidth, ViewPort.ScreenHeight, SourceHDC, CurrentTopX, CurrentTopY, SRCCOPY
End Function


This simply draws the Background Picture to the back buffer.





Function SwapBuffers()
BitBlt FrmMain.PlayArea.hdc, 0, 0, ViewPort.ScreenWidth, ViewPort.ScreenHeight, FrmMain.BackBuffer.hdc, 0, 0, SRCCOPY
End Function


This moves the contents of the Backbuffer to the Playarea for flicker less sprites.


Function DrawPlayer(Xpos As Long, Ypos As Long, Width As Integer, Height As Integer, PicSourceHDC As Long, MaskSourceHDC As Long)
' Draw the sprite mask directly onto the backbuffer
BitBlt FrmMain.BackBuffer.hdc, Xpos, Ypos, Width, Height, MaskSourceHDC, 0, 0, SRCAND

' Draw the sprite over top of the mask.
BitBlt FrmMain.BackBuffer.hdc, Xpos, Ypos, Width, Height, PicSourceHDC, 0, 0, SRCPAINT
End Function


This draws an image with a mask onto the back buffer.



Function DrawAllPlayers()
Dim X As Integer
Dim LocalX As Long
Dim LocalY As Long

For X = 1 To NumberOfPlayers
LocalX = Players(X).X - ViewPort.CurrentTopX
LocalY = Players(X).Y - ViewPort.CurrentTopY

'check if on screen
If IsAreaVisible(Players(X).X, Players(X).Y, Players(X).Width, Players(X).Height) Then
If Players(X).Visible = True Then
DrawPlayer LocalX, LocalY, Players(X).Width, Players(X).Height, FrmPics.Character.hdc, FrmPics.CharacterMask.hdc
End If
End If

Next X
End Function


This function draws all the players on to the screen if they are visible… Note: IsAreaVisible will be done shortly.


Function AdjustBackGround()
Dim CenteredX, CenteredY As Long
' Calculate the center of the Viewer.
CenteredX = (FrmMain.PlayArea.ScaleWidth - Players(1).Width) \ 2
CenteredY = (FrmMain.PlayArea.ScaleHeight - Players(1).Height) \ 2


If (Players(1).X > CenteredX) Then
If (Players(1).X < (FrmPics.MapPicture.ScaleWidth - Players(1).Width - CenteredX)) Then
ViewPort.CurrentTopX = Players(1).X - CenteredX
Else
ViewPort.CurrentTopX = FrmPics.MapPicture.ScaleWidth - ViewPort.ScreenWidth
End If
End If


If (Players(1).Y > CenteredY) Then
If (Players(1).Y < (FrmPics.MapPicture.ScaleHeight - Players(1).Height- CenteredY)) Then
ViewPort.CurrentTopY = Players(1).Y - CenteredY
Else
ViewPort.CurrentTopY = FrmPics.MapPicture.ScaleHeight - ViewPort.ScreenHeight
End If
End If
End Function


This function keeps the player very close to the centre of the screen. This function makes the map ‘scroll’ with the character.

Now to tie this into the game modify the DoGameLoop sub in the GameLoop Module.


Sub DoGameLoop()

ApplyGravity

DoInput

AddFriction

AllPlayersBGCollision

MoveAllPlayers

AdjustBackGround

DrawBackGround ViewPort.CurrentTopX, ViewPort.CurrentTopY, ViewPort.ScreenHeight, ViewPort.ScreenWidth, FrmPics.MapPicture.hdc, FrmMain.BackBuffer.hdc

DrawAllPlayers

SwapBuffers ' draw the main screen

DoEvents

End Sub

Step 7: Finishing It Up

Add the code to the ‘GameData’ module.


Function IsAreaVisible(TopX As Long, TopY As Long, Width As Integer, Height As Integer) As Boolean
Dim X1, X2, X3, X4 As Long
Dim Y1, Y2, Y3, Y4 As Long

X1 = TopX 'top left
Y1 = TopY

X2 = X1 + Width 'top right
Y2 = Y1

X3 = X1
Y3 = Y1 + Height 'bottom left

X4 = X1 + Width 'bottom right
Y4 = Y1 + Height

If X1 > ViewPort.CurrentTopX And X1 < ViewPort.CurrentTopX + ViewPort.ScreenWidth Then
If Y1 > ViewPort.CurrentTopY And Y1 < ViewPort.CurrentTopY + ViewPort.ScreenWidth Then
IsAreaVisible = True
Exit Function
End If
End If

If X2 > ViewPort.CurrentTopX And X1 < ViewPort.CurrentTopX + ViewPort.ScreenWidth Then
If Y2 > ViewPort.CurrentTopY And Y1 < ViewPort.CurrentTopY + ViewPort.ScreenWidth Then
IsAreaVisible = True
Exit Function
End If
End If

If X3 > ViewPort.CurrentTopX And X1 < ViewPort.CurrentTopX + ViewPort.ScreenWidth Then
If Y3 > ViewPort.CurrentTopY And Y1 < ViewPort.CurrentTopY + ViewPort.ScreenWidth Then
IsAreaVisible = True
Exit Function
End If
End If

If X4 > ViewPort.CurrentTopX And X1 < ViewPort.CurrentTopX + ViewPort.ScreenWidth Then
If Y4 > ViewPort.CurrentTopY And Y1 < ViewPort.CurrentTopY + ViewPort.ScreenWidth Then
IsAreaVisible = True
Exit Function
End If
End If

End Function


This code check is an area is being displayed at all. It checks all the corners. If any are visible then it returns true.

Add this code to the Same Module.


Function FileExists(FullFileName As String) As Boolean
On Error GoTo ErrSub:
Open FullFileName For Input As #1
Close #1
FileExists = True
Exit Function
ErrSub:
FileExists = False
Exit Function
End Function


This code just checks to see if a file exists.

Add the Following.


Function NewPlayer() As Integer
NumberOfPlayers = NumberOfPlayers + 1
NewPlayer = NumberOfPlayers
ReDim Preserve Players(NewPlayer)
With Players(NewPlayer)
.Visible = True
.X = 10
.Y = 10
.Xspeed = 0
.Yspeed = 0
.Width = FrmPics.Character.ScaleWidth
.Height = FrmPics.Character.ScaleHeight
End With
End Function


This Function adds a new player. It is only used to create player1 at the moment.


Sub LoadMap(Path As String, MapName As String)
FrmPics.MapPicture = LoadPicture(Path & MapName & ".MAP")

If FileExists(Path & MapName & ".DAT") = False Then 'mask data doesn't exists... must create it
FrmPics.MapMask = LoadPicture(Path & MapName & ".MSK")
CreateCollisionMap
SaveCollisionMap Path & MapName & ".DAT"
Else
LoadCollisionMap Path & MapName & ".DAT"
End If

End Sub


This sub loads a map. It creates the collision array and fills it if it has not been done before and saved.

Lastly add this code.


Sub Main()

Load FrmPics
Load FrmMain

LoadMap App.Path & "\MAPS\", "Map1"

NewPlayer


FrmMain.Show
DoEvents

FrmMain.GameTimer = True

End Sub


This sub load the program and starts the game. Under the Project => Project Properties, Set the Startup Object to Sub Main().

Step 8:
Press Save

Step 9:
Press Play

Step 10: What’s Next
You have now finished a very basic game engine that can be built up upon. There is a lot more to do to create a full game. You could add animations, there are many parts of this code to optimize, you could add enemies and other entities, you could use directx instead of bitblt for faster graphics.
But I hope that this has helped you in any way. Thank you for reading…