# VBForums UtilityBank > UtilityBank - Tutorials >  Video Game Making Tips (VB6 & VB.Net)

## Jacob Roman

*Prologue*
I've been wanting to make a thread like this for months. Only I wanted to teach people on how to make video games. But what stopped me is that theres so much information out there on Game Design, you can write an entire book on each category....literally. I actually have huge books on them. I have 2 whole entire books on Game Physics, 3 books on 3D Engine programming, a whole book on AI, etc. I've practically played video games all my life since I was 2 years old during the Atari 2600 days, and later on after, the Amiga 500 as well as the Nintendo. And continue to play video games to this day, even the retro ones since now I am a collector. Ever since I was a kid, I wondered what made these games tick logically, which got me into the world of programming. But recently since about over two years ago, I wondered what made these games tick mechanically, which got me into the world of electronics and modding as a hobby, with my latest project being a Nintoaster (a fully functional Nintendo inside a toaster.) I've been programming since I was 10 years old. I'm 31 now. And it began on the Amiga 500 using Amiga BASIC. However with VB, I have about 16 years of experience. And I noticed a trend that I unfortunately followed that other beginners in VB have. So instead of giving you 10000 page document on how to make games, I'm gonna teach you what to do and what not to do when it comes to make games using VB, which includes VB6 as well as VB.Net. So forget everything you learned in school cause its about to get real. I'm not gonna go too much into detail. I'm just gonna explain what you should be doing and not doing when making "good" games using VB.

*Beginners Trap*
When people learn VB for the first time, they are taught how to use buttons, labels, textboxes, pictureboxes, timers, and other objects. They learn all of the "common" properties associated with the objects, and how to program them to make these objects do something. When they are taught how to program, they learn their basics, such as If statements, variable declarations, For loops, Do loops, Select Case statements, and other useful code commands. Then they are told to "Write a program to do this and that." This ends up becoming a constant loop with every assignment. They learn a new object and/or new command and they have to write a program on it. This is fine, but this mentality persists even to the experienced VB user when they wanna jump into doing something on their own and make a small game. For a beginner, this is fine because they become more familiar with how to use code and vb based objects, but then they make game after game after game, only to be doing the same thing. For many even years to come. Using pictureboxes / imageboxes as sprites, using timers (even multiple timers) for game loops, labels for text. You then begin learning the hard way of things that you weren't taught in school as your games get larger and more complex. You find you can't make sprites transparent using pictureboxes, only to try to hide it by making the background the same color as the sprites background. You find the timers are a little sluggish at times. Your labels look too bland and plain. Worse of all, theres little to no sound. And when you do a search online how to play sound in VB, you tend to run into the sndPlaySound API which is severely limited to only playing one sound at a time. This is when your game design skills are now at the point to where you will want a higher order of programming. 

*API's*
To vastly improve your games beyond of what VB6 alone can do and beyond what VB.Net's .Net library has built in, there are a number of great API's out there you can use to make your programs stand out and be more powerful. API stands for Application Programming Interface. API's basically in a nutshell are subs/functions stuffed in a DLL file (mostly and commonly ones that you can find in your System32 SYSWOW64 directories in your Windows folder) that can be accessed using another programming language that is capable of using API's. There are 1000s of API's out there, even ones you can create on your own (thats another subject). Languages such as VB6, VB.Net, C#, Java, and C++ are able to utilize subs and functions inside DLL's. Thats the beauty of DLL files. Its made in one language and can be accessed by another. Some languages have their own way of communicating with the DLL's built in to Windows such as C++'s header library installed with the language. So by doing a simple #include <****.h> for example (yea I know, just replace the **** with the header of your choice), you have just gained access to a number of built in functions, with some even accessing functions from a DLL built into Windows. So how do I do APIs in VB you ask? Try this and put this one line in your General Declarations of your Form:



```
Private Declare Function ShowCursor Lib "user32" (ByVal Show As Long) As Long
```

You have just accessed a function called ShowCursor from the DLL file named user32. And it must be spelled the same with the data types being the same as the functions built in. To use this function, just put the function whereever you desire such as Form_Load, type in ShowCursor 0 to make the cursor invisible. To make it reappear, your program upon exit will need to have ShowCursor 1 or itll remain invisible. 

Now for the fun part. If you wanted to name it something else, you would have to do this:



```
Private Declare Function Make_My_Cursor_Visible Lib "user32" Alias "ShowCursor" (ByVal Show As Long) As Long
```

With this, you can use the new name you called it Make_My_Cursor_Visible, but you can't use ShowCursor.  Nuff said about that but now you know. These API's can only be declared in the General Declarations of either your Form, Module, and/or Class.

*Graphical API's*
Now that you know what API's are, there are a bunch of graphical API's out there. The most commonly used are BitBlt, StretchBlt, and TransparentBlt API's (TransparentBlt  I recommend over the other two.) These are well beyond capable of removing the background of your sprites, so the background can blend in with the background of your sprite rather than be some flat color box. Your sprite is not trapped inside a picturebox. Instead its is own graphic which was loaded in memory from file or from a resource. Personally I recommend from file due to the fact that as your games get more complex, you need a way to organize your graphics. This either can be files on its own or from a massive sized data file compressed to whatever format you desire or even from winzip. Now there is a catch to using the other two API's for transparency. The ones that are not TransparentBlt. You will also need to create a Mask, which is the same image, only blacked out or whited out with the background being the opposite color. TransparentBlt on the other hand can be used to select a color of your choosing to be removed from the background while at the same time can act as StretchBlt due to the fact that it can stretch as well. Rather than using VB6's Autoredraw (DoubleBuffer in .Net), you can even blit all of your graphics onto a backbuffer not seen by the user, and when the frames complete, the entire buffer can be blitted onto the screen per frame. This is known as a Double Buffer. StretchDIBits Is another powerful graphical API, as you can write out an entire buffer and display it instantly. As I said before I'm not gonna go into detail on how to use them, but a simple search in VBForums or Google can show you how they can be used. Then as you get better over time, you now want a higher order of graphical capabilites. You actually wanna utilize the video card in your computer rather than do software rendering. Welcome to the world of DirectX!

*DirectX*
This was primary designed by Microsoft as a universal standard for game companies to take full advantage of the hardware in order to render high end graphics and sound back when people had to manually select multiple options and drivers just to get their game working on their computer (cause back then during the Windows 95 era, there was no standard!) But now since the creation of DirectX, and 11 versions later, this industry standard persists now even to today. Though there are other graphical libraries such as OpenGL and XNA, DirectX is the most commonly used, and continues to be supported. Unfortunately, VB6 only uses DirectX7 & DirectX8 and VB.Net only uses DirectX9. Although I haven't used VB 2012 yet, I doubt it uses DirectX11. MS favors C# and C++ more in that regard in my opinion. DirectX not only does 2D and 3D graphics in fullscreen and windowed, but also does 2D and 3D sound, music (both mp3 and midi), input with keyboard, joystick, mouse, or other devices, and networking for massively multiplayer games!!! MMORPG anyone? With all of these powerful tools, you can build a professionally elegant game that you would find on the shelve at a store! But it comes at a cost. You need to acquire the skills to make such games, such as realistic game physics, 3D modeling, lighting, animation, special effects, collision detection, and the list goes on. But as you become better and better, many of these techniques you can find online open source, or even at your local bookstore over in the programming section. However, working with DirectX is much easier than you think. But its a small learning curve pass messing with VB objects, which you will no longer need. Unless you need to of course. Here are a couple screenshots of me using DirectX in VB6 for 2D and 3D:





*VB Tips*
I feel its better I list them rather than put em in one paragraph
 In VB6, always set your form / pictureboxes Scalemode to vbPixels. Its in vbTwips by default. VB.Net is now vbPixels as default. Always show your form in the Form_Load event using the .Show method. All the code executed in Form_Load is done before the form is even shown. Unless you intend to use a splash screen, then this can be disregarded. Never ever use Timers for game loops and animation. Most people continue using it to avoid high CPU. This is ok for tiny games but its not good practice. At the same time, most large games use a lot of CPU anyways. Also if you have more than one timer running at the same time, the entire code of one timer must complete before the next one can even fire. This is why, for example, if you are using one timer for a game loop and the other to check for collision, that it only sometimes registers a collision rather than every time. Timers are also considered low end timers. The solution to this is to not use a timer at all and stick with a Game loop locked at 60 frames per second to handle all of your game related code such as controls, physics, collision, rendering, ai, etc. See my projects such as A* Pathfinding, and Managed Game Loop in my sig to see how. DirectX though, you don't need to lock the framerate. This is done automatically through DirectX. Always put a DoEvents (Application.DoEvents in VB.Net) at the end of your Game loop. Not at the beginning. This I learned just recently over a year ago. This way you can close out of your program easier without worrying itll not close or if using DirectX, the dreaded Automation Error. Try your best to ween yourself off of built in objects unless you absolutely need them. You find your projects looking better graphically and professionally. Class modules I found the hard way to execute more than twice as slow as regular modules with the same code. At least in VB6. VB.Net I haven't timed it yet. So if you are using VB6, use modules over class modules for functions and subs that are constantly called in your main game loop for speed and optimization purposes. Organize your code. All of your sprite code should be in the sprite module, all of your physics in another module, all of your collision in another, main game code in another, controls in another, DX initialization in another, API's in another (its more elegant this way), AI in another, Sound, Music, etc. You'll come to find as your game gets more complex, it becomes a hell of a lot easier to Debug. Never cram all of your code in one file!

This is what I came up with so far, and I may edit it over time. If anyone has any questions, recommendations, or found I screwed up somewhere, let me know. I kept it as brief as possible. Game Programming is the most complex programming in existence, and some find it the hardest to learn. Comment below!  :big yellow:

----------


## Jacob Roman

*Simple Proper Game Loop*
Here is a way to setup a realtime game loop locked at 60 frames per second. Matter of fact, you can lock it at any framerate you desire, but since monitors tend to have a 60Hz refresh rate, its recommended you lock it at 60 frames per second. 

Note - If you choose to use DirectX though, you do not need to lock the framerate, since DirectX does it for you.

VB6

vb Code:
Option Explicit Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As LongPrivate Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long Private Ticks_Per_Second As CurrencyPrivate Start_Time As CurrencyPrivate Milliseconds As LongPrivate Last_Time As Long Private Get_Frames_Per_Second As LongPrivate Frame_Count As Long Private Running As Boolean Public Function Hi_Res_Timer_Initialize() As Boolean    If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then        Hi_Res_Timer_Initialize = False    Else        QueryPerformanceCounter Start_Time        Hi_Res_Timer_Initialize = True    End IfEnd Function Public Function Get_Elapsed_Time() As Single    Dim Last_Time As Currency    Dim Current_Time As Currency        QueryPerformanceCounter Current_Time    Get_Elapsed_Time = (Current_Time - Last_Time) / Ticks_Per_Second    QueryPerformanceCounter Last_TimeEnd Function Private Sub Lock_Framerate(Target_FPS As Long)    Static Last_Time As Currency    Dim Current_Time As Currency    Dim FPS As Single        Do        QueryPerformanceCounter Current_Time        FPS = Ticks_Per_Second / (Current_Time - Last_Time)    Loop While (FPS > Target_FPS)        QueryPerformanceCounter Last_TimeEnd Sub Private Function Get_FPS() As String    Frame_Count = Frame_Count + 1            If Get_Elapsed_Time - Milliseconds >= 1 Then        Get_Frames_Per_Second = Frame_Count        Frame_Count = 0        Milliseconds = Get_Elapsed_Time    End If        Get_FPS = "FPS: " & Get_Frames_Per_SecondEnd Function Private Sub Shutdown()    Running = False    Unload MeEnd Sub Private Sub Main()    With Me        .Show        .ScaleMode = vbPixels        .AutoRedraw = True        .BackColor = RGB(0, 0, 0)    End With     Running = True    Hi_Res_Timer_Initialize    Milliseconds = Get_Elapsed_Time    Game_LoopEnd Sub Private Sub Game_Loop()    Do While Running = True        'Game Code Here        Lock_Framerate 60        DoEvents    LoopEnd Sub Private Sub Form_Load()    MainEnd Sub Private Sub Form_Unload(Cancel As Integer)    ShutdownEnd Sub

VB.Net

vb.net Code:
Option Explicit On Public Class Form1     Private Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef X As Long) As Integer    Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef X As Long) As Integer     Private Ticks_Per_Second As Long    Private Start_Time As Long     Private Milliseconds As Integer    Private Get_Frames_Per_Second As Integer    Private Frame_Count As Integer     Private Running As Boolean     Private Function Hi_Res_Timer_Initialize() As Boolean        If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then            Hi_Res_Timer_Initialize = False        Else            QueryPerformanceCounter(Start_Time)            Hi_Res_Timer_Initialize = True        End If    End Function     Private Function Get_Elapsed_Time() As Single        Dim Last_Time As Long        Dim Current_Time As Long         QueryPerformanceCounter(Current_Time)        Get_Elapsed_Time = Convert.ToSingle((Current_Time - Last_Time) / Ticks_Per_Second)        QueryPerformanceCounter(Last_Time)    End Function     Private Function Get_Elapsed_Time_Per_Frame() As Single        Static Last_Time As Long        Static Current_Time As Long         QueryPerformanceCounter(Current_Time)        Get_Elapsed_Time_Per_Frame = Convert.ToSingle((Current_Time - Last_Time) / Ticks_Per_Second)        QueryPerformanceCounter(Last_Time)    End Function     Private Sub Lock_Framerate(ByVal Target_FPS As Long)        Static Last_Time As Long        Dim Current_Time As Long        Dim FPS As Single         Do            QueryPerformanceCounter(Current_Time)            FPS = Convert.ToSingle(Ticks_Per_Second / (Current_Time - Last_Time))        Loop While (FPS > Target_FPS)         QueryPerformanceCounter(Last_Time)    End Sub     Private Function Get_FPS() As String        Frame_Count = Frame_Count + 1         If Get_Elapsed_Time() - Milliseconds >= 1 Then            Get_Frames_Per_Second = Frame_Count            Frame_Count = 0            Milliseconds = Convert.ToInt32(Get_Elapsed_Time)        End If         Get_FPS = "Frames Per Second: " & Get_Frames_Per_Second    End Function     Private Sub Game_Loop()        Do While Running = True            'Game Code Here            Lock_Framerate(60)            Me.Text = Get_FPS()            Application.DoEvents()        Loop    End Sub     Private Sub Main()        With Me            .Show()            .BackColor = Color.FromArgb(255, 0, 0, 0)            .DoubleBuffered = True        End With         Hi_Res_Timer_Initialize()        Running = True        Game_Loop()    End Sub     Private Sub Shutdown()        Running = False        Application.Exit()    End Sub     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load        Main()    End Sub     Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.FormClosing        Shutdown()    End SubEnd Class

----------


## Nightwalker83

Could you please clarify, Always show your form in the Form_Load event using the .Show method?

I don't think this is what you mean since the form is already loaded


vb Code:
Private Sub Form_Load() Me.ShowEnd Sub

----------


## Jacob Roman

The Form_Load event executes code *before* the form is completely loaded. For example, if you were to do something simple such as a "Hello World" program and do this:



```
Private Sub Form_Load()
     Print "Hello World"
End Sub
```

Run the code and you will see that it has not appeared. But if you add Me.Show prior to Printing "Hello World":



```
Private Sub Form_Load()
     Me.Show
     Print "Hello World"
End Sub
```

Then when you run the program, it has actually printed "Hello World" onto the form. The reason for this is because you forced the form to appear using Me.Show.

----------


## Bonnie West

> The Form_Load event executes code *before the form is completely loaded*.


Well, according to the Life Cycle of Visual Basic Forms:




> *Loaded, But Not Shown*
> 
> The event that marks the beginning of this state is the familiar Load event. *Code you place in the Form_Load event procedure is executed as soon as the form enters the loaded state*.
> 
> When the Form_Load event procedure begins, the controls on the form have all been created and loaded, and the form has a window — complete with window handle (hWnd) and device context (hDC) — *although that window has not yet been shown*.





> For example, if you were to do something simple such as a "Hello World" program and do this:
> 
> 
> 
> ```
> Private Sub Form_Load()
>      Print "Hello World"
> End Sub
> ```
> ...


I believe the actual reason is because the Form's AutoRedraw property was False and when it was shown, it was painted, thus whatever was printed was erased. The following experiment confirms that:



```
Private Sub Form_Load()
    AutoRedraw = True
    Print "Hello World"
End Sub
```



BTW, according to my benchmarks, using the Me keyword when accessing any property or method is a bit slower than one without. Optimizing Objects mentions:




> When calling an object from Visual Basic, each "dot" requires Visual Basic to make multiple calls.
> 
> 
>  To write the most efficient applications, minimize the use of dots when referencing an object.

----------


## Jacob Roman

Autoredraw causes slowdown as well because of the fact it has to redraw. Its ok to use for pure VB drawing and graphical APIs to avoid flickering, but not DirectX because you are already working with an offscreen buffer in memory.

----------


## Nightwalker83

@ Jacob 

Are you going to add any more tips?

----------


## Jacob Roman

Sure in due time. Just that I'm caught up in a bunch of projects, always working, and hanging out with my gf. I will in the near future though.

----------


## Niya

Wait....you have a gf ?

----------


## Niya

Just kidding. I couldn't resist  :Wink:

----------


## Jacob Roman

I just wanna add some new information regarding anyone who wants to get started in MMORPG's. And I can't believe how late I was on finding this out. But Microsoft dropped support for DirectPlay many many years ago. It was too complex for small programs, and not complex enough for large scale games and programs. Basically it had potential but was a horrific failure and was designed horribly. Winsock is still wideley used I'm pretty sure in MMORPG's as well as their own libraries they created similar to Winsock. I may ask Blizzard entertainment in the forums (the creators of World of Warcraft) just to find out.

W00t 5000th post!!!

----------


## xman2000

> I just wanna add some new information regarding anyone who wants to get started in MMORPG's. And I can't believe how late I was on finding this out. But Microsoft dropped support for DirectPlay many many years ago. It was too complex for small programs, and not complex enough for large scale games and programs. Basically it had potential but was a horrific failure and was designed horribly. Winsock is still wideley used I'm pretty sure in MMORPG's as well as their own libraries they created similar to Winsock. I may ask Blizzard entertainment in the forums (the creators of World of Warcraft) just to find out.
> 
> W00t 5000th post!!!


Hi Jacob Roman,

i am very interested in Emulators in VB6.0, and in VBA and VB.NET too.
Video Games emulators maybe PixelArt or HD, Ps3, PS2, Sega Genesis Megadrive, SNES Super Nes, Gameboy GBA, anyone.
Directx, OpenGL, 3D, 2D, and PureVB6.
if you can i am like very mutch you put a Source-code PACK to downloads  with emulators, games and PDF, Word docs into a blog to downloads.
and put here in the forum the tutorials, codes and Development help to others Users peoples help to improve the codes.
i am will work for personal use with this Games and Emulators in next year only 2022.
thank you.

----------

