# VBForums UtilityBank > UtilityBank - Tutorials >  Tutorial [Move with Keypress] NMs Game tutorial 0.1

## NoteMe

This is a tutorial to show you two ways of moving objects on a form in VB. The code has only been tested in VB6, but I guess it can be used for VB5 and easily implemented in .Net too. You should have some knowledge of arrays, and some knowledge of simple VB programming from before. It is not recommended that you know anything about APIs but you can manage the second bit a bit better if you know it. But if you have never used it at all. Don't turn around. The two ways I am going to show you are more or less equal when it comes to performance. The first way is (the way I did it for small games) by using a array for checking what keys that are hold down. The second method I will show is using an API call. But since this is not improving the speed in VB, I don't like to use it because it looks more complicated to use API calls for persons that are not used to it. I will only talk about the code here. And make a final example using both methods that you can download and play with in the end of this tutorial. So here we go.

----------


## NoteMe

*The Array Method:*

	As I said, we are going to use an array for the first example. It can be declared in the General Section in the top of the code like this:


VB Code:
'The key array that shows true if the key is down, and false if not
Dim KeyArray(100) As Boolean

	This is an array with 100 elements of Boolean value. What we want is to check if a special key is clicked and if it is, then we want to move it according to that key press. When you initialize an array like this the default value of all the bools in the array is false. So that means that no keys a pushed. 
	All the keys on the keyboard has a value. In VB you are most often using the KeyCode of that value to determine what key was pressed. The KeyDown event in VB has the following syntax:


VB Code:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
 End Sub

	Here you can see that it has a KeyCode parameter. This parameter you can use to check what key was pressed. We could have just checked what key was pressed here, and then taken action, but the problem here is if you press more then one key. Then you can have a problem, and the app might only respond to one of the key strokes, unless you make a big messy code. And we don't want that. So what we do is that we are setting the value in the array to true that has the same index as the key code. You don't even have to know yet what that value is. All you have to know is that in the array there is now one (if one key is down) or more(if more keys are down) values that are set to true. And we can check this afterwards. The code you need to write to make the value true is.


VB Code:
'Marks the element in the array as true if it the key is pushed
KeyArray(KeyCode) = True

	As you can see I am passing the parameter value as the index of the variable. And setting that element of the array as true. And it stays true. What we need now is a way to tell if the key has been released again. You might already have guessed it, yes we are going to use the KeyUp event. And we are going to use it the same way. Here is the code.


VB Code:
Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
     'Marks the element in the array as false if it the key is released
    KeyArray(KeyCode) = False
    
End Sub

	The only difference here is that we are setting it to false. So only the key we are releasing will be the one that will be set to false. Now we need to check to see what keys are pressed. I am using a Timer so it can check regularly and take action. It will be my game loop. But it would have been better to use a real game loop. But that is another tutorial. 
	Now we need to know what the KeyCodes are for the different keys. You can look all of them up at MSDN, but I am providing a small list of the KeyCodes that I am using here:




> 37 = Left Arrow
> 38 = Up Arrow
> 39 = Right Arrow
> 40 = Down Arrow
> 65 = A
> 87 = W
> 83 = S
> 68 = D


	The best way to check them is probably to use a loop, to loop through them. But I am not going to complicate things for beginners so I am using a lot of If statements to check them in stead. Now we can just check with our array to see if the array element 37 is pressed. If it is, then the left arrow was pressed. And we can take action from there. I have made for variables in the General Section of the code that holds the coordinates of the objects from before. It looks like this:


VB Code:
Dim iX As Integer           'The X coordinate for the first smilie
Dim iY As Integer           'The Y coordinate for the first smilie
Dim iY2 As Integer          'The X coordinate for the second smilie
Dim iX2 As Integer          'The Y coordinate for the second smilie

	Since they are in the General Section they are not deleted before the game ends. And we can use them in all the Functions and Subs that we need on this form. That means that we can just add to them or subtract to them as we need. We are doing that after we have found out what key was pressed. First we have to check what key was pressed. We do that like this:


VB Code:
If KeyArray(39) = True Then       'imgSmiley1 moves right
 End If

	If the variable in the array with the index of 39 is true, then we can do something. If you look in the small table I quoted you can see that the Right Arrow has this KeyCode, and then also has this index in the array. If it is then we will move the object to the right. So we have to add something to the X coordinate of the object. I am adding 25, but you can add what ever you want. You have to do that with every key that is pressed that you want to check for. If the left arrow was pressed, then you can subtract 25 from X, and if the down arrow was pressed then you can add 25 to the Y coordinate, and if the up arrow was pressed then you can subtract 25 from the Y coordinate. I am doing the same to the A, S, D, and W keys too so you can move two objects on the screen at the same time. Then you can see that you can press 4 keys at the same time and it will still work. The code to check all 8 keys are here:


VB Code:
If KeyArray(39) = True Then     'imgSmiley1 moves right
      iX = iX + 25
    End If
    If KeyArray(37) = True Then     'imgSmiley1 moves left
      iX = iX - 25
    End If
    If KeyArray(38) = True Then     'imgSmiley1 moves up
      iY = iY - 25
    End If
    If KeyArray(40) = True Then     'imgSmiley1 moves down
      iY = iY + 25
    End If
    If KeyArray(68) = True Then     'imgSmiley2 moves right
      iX2 = iX2 + 25
    End If
    If KeyArray(65) = True Then     'imgSmiley2 moves left
      iX2 = iX2 - 25
    End If
    If KeyArray(87) = True Then     'imgSmiley2 moves up
      iY2 = iY2 - 25
    End If
    If KeyArray(83) = True Then     'imgSmiley2 moves down
      iY2 = iY2 + 25
    End If

	Thats it. You still have nothing on the screen. But I will show you soon enough. First I want to explain the other way. With the GetAsyncKeyState API. There isn't much different from the Array way, so this will be a short section.

----------


## NoteMe

*GetAsyncKeyState API way:*

	To use an API in VB you first have to declare it. If you know what API to use, it's mostly copy paste work. The declaration of the GetAsyncKeyState API looks like this:


VB Code:
'Declaring the GetAsyncKeyState API, so we can use it
Private Declare Function GetAsyncKeyState Lib _
                "user32" _
                (ByVal vKey As Long) As Integer

	It doesn't look pretty. But it is useful. In this version we don't need to use the KeyDown and KeyUp events to figure out what key is pressed. It is all just an API call. The only parameter in we need is the KeyCode. As in with the Array way of doing it, it is the same KeyCodes. And the actions that are taken if something is pressed is also the same. We just need to call GetAsyncKeyState send the parameter for the KeyCode and test to see if it is not 0 (Zero). So the whole code to test all the KeyCodes would look like something like this:


VB Code:
If GetAsyncKeyState(39) <> 0 Then       'imgSmiley1 moves right
      iX = iX + 25
    End If
    If GetAsyncKeyState(37) <> 0 Then       'imgSmiley1 moves left
      iX = iX - 25
    End If
    If GetAsyncKeyState(38) <> 0 Then       'imgSmiley1 moves up
      iY = iY - 25
    End If
    If GetAsyncKeyState(40) <> 0 Then       'imgSmiley1 moves down
      iY = iY + 25
    End If
    If GetAsyncKeyState(65) <> 0 Then       'imgSmiley2 moves left
        iX2 = iX2 - 25
    End If
    If GetAsyncKeyState(83) <> 0 Then       'imgSmiley2 moves down
        iY2 = iY2 + 25
    End If
    If GetAsyncKeyState(68) <> 0 Then       'imgSmiley2 moves right
        iX2 = iX2 + 25
    End If
    If GetAsyncKeyState(87) <> 0 Then       'imgSmiley2 moves up
        iY2 = iY2 - 25
    End If

	That was all. The rest I have explained in the Array section of the tutorial.

----------


## NoteMe

*Wrap up:*

	Now we need to add some more to the app to make everything move and draw it to the screen. In my example I have both the ways of doing it in the same app. It is a label on the top that tells you what way is used at the moment. If you click it will use the other method. It is two different timers that use the different methods. The code to change between the timers, and to change the :


VB Code:
Private Sub lblMethod_Click()
     'If clicked then use the other method, and print it on the label
    If lblMethod.Caption = "Using Key Events" Then
        tmrArray.Enabled = False
        tmrAPI.Enabled = True
        lblMethod.Caption = "Using GetAsyncKey"
    Else
        lblMethod.Caption = "Using Key Events"
        tmrAPI.Enabled = False
        tmrArray.Enabled = True
    End If
    
End Sub

	I have called the first timer for tmrArray. When this one is running it is the first method that is used to check what key is pressed. The other timer is called tmrAPI, and when this one is running the GetAsynkKeyState version is running. No more fancy there. The default will be the Array method. I am setting it to the default in the Form Load event with this code:


VB Code:
'Setting the interval of the "game loop"/timer to 10 for the API version
tmrAPI.Interval = 10
'Setting the interval of the "game loop"/timer to 10 for the Array version
tmrArray.Interval = 10
'Makint the array version the default at start up.
tmrArray.Enabled = True

	The intervals will be 10 for both. So that means that it will check keypresses 100 times a second. It might not work that fast for your PC, but you can change it as you want. We also need to set some properties for the form. And we also need to draw the objects before anything else happens. Here is my code:


VB Code:
'Setting some properties for the Form,
    '   and are painting the first two pictures
With Me
    .AutoRedraw = True
    .KeyPreview = True
    .PaintPicture imgSmily1.Picture, iX, iY
    .PaintPicture imgSmily2.Picture, iX2, iY2
End With

	We are setting the AutoRedraw property to true. This is because if the window is getting resized or closed the drawings will disappear if we don't do it. We are setting the KeyPreview so we can trap the keyboard presses and releases. The two next lines, are actually function calls. They are painting the pictures to the form. I have two image boxes on the form called imgSmiley1 and imgSmiley2. I am sending the picture property and the X and Y coordinates for the two objects as parameters, and that will draw the smilies to the form. Just remember to have the visible property of the image boxes set to false. After each "frame"/"move" we have to draw them again. But first we have to clear everything that we have painted on the form, we do that by adding more or less the same lines at the end after checking for key presses in both the tmrAPI and the tmrArray events. The code for doing that is:


VB Code:
'Clears the screen
Me.Cls
'Paints the first smilie
Me.PaintPicture imgSmily1.Picture, iX, iY
'Paints the second smilie
Me.PaintPicture imgSmily2.Picture, iX2, iY2

	The first line is clearing the form, and the two next are drawing them to the new position. Thats all you need to do. you can try to make the app your self, or you can download the version that I have made here in the attachment. Hope you learned something new. 

ØØ

----------


## si_the_geek

The files within this thread (submitted: 25 Feb 2004) have been checked for malware by a moderator.

Disclaimer: _This does not necessarily mean that any compiled files (DLL/EXE/OCX etc) are completely safe, but any supplied code does not contain any obvious malware.  It also does not imply that code is error free, or that it performs exactly as described.

It is recommended that you manually check any code before running it, and/or use an automated tool such as Source Search by Minnow (available here or here).  
If you find any serious issues (ie: the code causes damage or some sort), please contact a moderator of this forum.

Usage of any code/software posted on this forum is at your own risk._


The above posts have been edited (with NoteMe's permission) to correct spelling/grammar errors.

----------


## metalmidget

Excellent tutorial, and i may be out of place replying to it, but i have only one thing to add. To get smoother motion which will slide and can have different speeds, I came up with this very simple sequence.

In the general section, declare 2 more variables:

VB Code:
Dim xspeed as Integer
Dim yspeed as Integer

Then instead of modifying the left and top properties of the object modify the 2 variables:
VB Code:
If keyarray(37) = True Then xspeed = xspeed - 1
If keyarray(38) = True Then yspeed = yspeed - 1
If keyarray(39) = True Then xspeed = xspeed + 1
If keyarray(40) = True Then yspeed = yspeed + 1

Then modify the top and left properties according to the speed:

VB Code:
player.left = player.left + xspeed
player.top = player.top + yspeed

Finally, the other thing this is useful for is if you have boundaries for your moving object, this makes it easier to make things bounce off the wall. First, put in a line that will make sure it doesn't leave the boundary, then all you have to do is reverse the direction, and if you want, halve it to make it more realistic.

VB Code:
If player.left < 0 then 
     player.left = 0
     xspeed = xspeed * -1 / 2
End If
If player.top < 0 then 
     player.top = 0
     yspeed = yspeed * -1 / 2
End If

Hope this is helpful, i was pretty happy with myself when i made it work.

----------


## Gamemaster1494

I cannont find the list of keys on MSDN. Where are they? What are they?

----------


## Nightwalker83

> I cannont find the list of keys on MSDN. Where are they? What are they?


Use this VB 6.0 code

----------

