Thank you for tuning in again.  I am currently thinking of how to get the character to run.
Obviously, we are going to need another key that will be held down for running.  How about the Shift key?

Now, for the shift key, we need to edit the KeyDown and KeyUp subroutines to support the Shift key.
But, before we do that, we need to make a variable that indicates if Shift is down.

    Dim GoLeft, GoRight, GoFast As Boolean
    'Indicates which buttons are pressed.
GoFast - is true when the Shift key is pressed. I just felt like naming it GoFast, since that's actually what it does (will do) in the program. As for the keydown event, we simply set and unset the value of GoFast as we did for GoLeft and GoRight. KeyDown
        If e.KeyCode = Keys.Left Then
            GoLeft = True
        ElseIf e.KeyCode = Keys.Right Then
            GoRight = True
        ElseIf e.KeyCode = Keys.ShiftKey Then
            GoFast = True
        End If
KeyUp
        If e.KeyCode = Keys.Left Then
            GoLeft = False
        ElseIf e.KeyCode = Keys.Right Then
            GoRight = False
        ElseIf e.KeyCode = Keys.ShiftKey Then
            GoFast = False
        End If
OK, now, we actually have to make GoFast make the character gofast. I need to find where I am moving and alter that code a bit to allow the character to move faster. The code itself is in the Timer event handler (but not for long).
            PlayerLoc.Offset(-MOVESPEED, 0)
            'Move player left.
That line of code moves the character left. To support the new GoFast, we need to check GoFast with an If statement. If GoFast is pressed, he moves twice as fast... otherwise, he moves according to the line above.
            If GoFast Then
                PlayerLoc.Offset(-MOVESPEED << 1, 0)
                'When Shift is pressed the player runs.
            Else
                PlayerLoc.Offset(-MOVESPEED, 0)
                'Move player left.

            End If
Same for the GoRight block.
            If GoFast Then
                PlayerLoc.Offset(MOVESPEED << 1, 0)
                'Runs to the right.
            Else
                PlayerLoc.Offset(MOVESPEED, 0)
                'Move player right.

            End If
Now, the character should move a little faster. It would probably be more realistic with a 1.5. Also, note that if you are using .NET 2002, you need to actually multiply by 2.
Before I go into jumping, I need to do a little housekeeping. At this point, I have approximately 200 lines, and all of it is within event handlers. It is good practice to break up code into lots of subroutines (at least, it helps me). So, let's start with the biggest subroutine at the moment... which is the Clock_Tick subroutine. Let's extract the movement code and the drawing code into their own subroutines. Find the following code in the clock tick event and move it into a sub called CharacterMovement (or whatever).
    Private Sub CharacterMovement()
        If GoLeft Then
            If GoFast Then
                PlayerLoc.Offset(-MOVESPEED << 1, 0)
                'When Shift is pressed the player runs.
                'Runs to the left.
            Else
                PlayerLoc.Offset(-MOVESPEED, 0)
                'Move player left.

            End If
            If PlayerLoc.Left < 0 Then
                'If the player goes off the edge of the form, then we will move him back to the edge.
                PlayerLoc.Offset(-PlayerLoc.Left, 0)
            End If
            UpdateArtwork = True
            CharDirec = 0   'Look left.
            'Now, update the animation cycler.
            AnimCycler = (AnimCycler + 1) Mod WALKINGFRAMECOUNT
        ElseIf GoRight Then
            If GoFast Then
                PlayerLoc.Offset(MOVESPEED << 1, 0)
                'Runs to the right.
            Else
                PlayerLoc.Offset(MOVESPEED, 0)
                'Move player right.

            End If
            If PlayerLoc.Right > MAPWIDTH Then
                'If player goes off right edge... move him back.
                PlayerLoc.Offset(MAPWIDTH - PlayerLoc.Right, 0)
            End If
            UpdateArtwork = True
            CharDirec = 1   'Look right.
            'Now, update the animation cycler.
            AnimCycler = (AnimCycler + 1) Mod WALKINGFRAMECOUNT
        End If
    End Sub
And find the artwork code that goes into the new Artwork (etc) subroutine: (Which is just the remainder of the code in the clock_tick event handler)
    Private Sub Artwork()

        If UpdateArtwork Then
            'I am going to draw a lightblue rectangle for the sky.
            'It will go down until it reaches the land, so therefore the bottom of the rectangle has to be
            'the LANDHEIGHT.
            GFX.FillRectangle(Brushes.LightSkyBlue, Rectangle.FromLTRB(0, 0, MAPWIDTH, LANDHEIGHT))
            'And the remainder of the area is LAND, starting from LANDHEIGHT.
            GFX.FillRectangle(Brushes.ForestGreen, Rectangle.FromLTRB(0, LANDHEIGHT, MAPWIDTH, MAPHEIGHT))
            'I use LTRB instead of New so that I don't have to calculate the height.
            'These two will make the 'background' for the form.
            GFX.DrawImage(PlayerBmp, PlayerLoc.X, PlayerLoc.Y, New Rectangle(CHARWIDTH * CharDirec * WALKINGFRAMECOUNT + AnimCycler * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel)
            'This draws the character to the display, based on the current character location.

            UpdateArtwork = False
            'Set it back to false.
        End If
        Me.DrawOnForm()
        'Me.Invalidate(New Rectangle(0, 0, 1, 1))
    End Sub
Don't forget to call these subs from the Clock Tick.
    Private Sub Clock_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Clock.Tick

        Me.CharacterMovement()
        'Handles the character movement.
        Me.Artwork()
        'Draws the information to the backbuffer, and then, to the form.

    End Sub
So, now it should do the same thing as it did before. Also, if you get a chance, change that multiply by 2 to a multiply by 1.5. It looks realer, although it does make you move at a lower mean speed in the end:
                PlayerLoc.Offset(-MOVESPEED - (MOVESPEED >> 1), 0)
                'When Shift is pressed the player runs.
                'Runs to the left.

                PlayerLoc.Offset(MOVESPEED + (MOVESPEED >> 1), 0)
                'Runs to the right.
Again, if you are using 2002, you actually need to divide by 2 (but use Integer division).
                PlayerLoc.Offset(-MOVESPEED - MOVESPEED \ 2, 0)
                'When Shift is pressed the player runs.
                'Runs to the left.

                PlayerLoc.Offset(MOVESPEED + MOVESPEED \ 2, 0)
                'Runs to the right.
And there's more realistic movement.
Now, for jumping, there's a lot that needs to be done. Of course, we need to assign a key (how's the Space bar?) for jumping. I am going to choose to make a fixed jump with Spacebar. By fixed-jump, I mean the jump is going to be the same regardless of how long the space bar is held. I'll probably add another key combination for a smaller jump. But for now, we'll just have the spacebar for a regular jump. Now, with the space bar as the key, we'll need to declare a Boolean for it. But, this one will behave a little differently than the other keys. When the spacebar is pressed, we are just going to start a jump. We don't set our boolean to false in the KeyUp event because this Boolean is going to denote if we are jumping. Let's go ahead and declare our Jumping Boolean
    Dim IsJumping As Boolean
    'While this is true, the character will be jumping.
IsJumping - set to true when the space bar is pressed. Set to False when the character lands on ground. Now, when the jump begins, we have to store the character's vertical velocity. Since the jump is going to have a fixed initial velocity, we can declare a constant for it. We also need to declare a constant for gravity.
    Dim PlayerVeloc As Integer
    'This is the velocity of the player in the Y direction.
    'Positive values point down.
    'To jump up, PlayerVeloc must be initialized to a negative value.

    Const SBARINITIALVELOCITY As Integer = -16
    'The initial velocity for the player's jump using space bar.
    Const GRAVITY As Integer = 1
    'Gravitational acceleration constant... how much the speed changes at each tick.
PlayerVeloc - the velocity of the player for the jump. (Reaches 0 at the top of the jump) SBARINITIALVELOCITY - initial velocity of the jump when the user presses the spacebar. Remember that there might be other key combinations for other jumps. GRAVITY - gravitational acceleration... decreases the velocity, which eventally causes the player to move downward toward the ground. Remember that the Jumping variable needs to be set to False when the player touches ground. It's positive because gravity points in the down direction (which is positive). Well, SBARINITIALVELOCITY is quite a long constant name... fortunately, I can use Intellisense to get SBARINITIALVELOCITY for me. Now, we have all of the variables and constants. Let's put them into action. First stop, the KeyDown event is where we receive notice that the spacebar is pressed. Not only do I need to set IsJumping to True, I need to initialize the velocity. The code in the KeyDown event now looks like this:
        If e.KeyCode = Keys.Left Then
            GoLeft = True
        ElseIf e.KeyCode = Keys.Right Then
            GoRight = True
        ElseIf e.KeyCode = Keys.ShiftKey Then
            GoFast = True
        ElseIf e.KeyCode = Keys.Space Then
            IsJumping = True
            'The jump is initialized.
            PlayerVeloc = Me.SBARINITIALVELOCITY
            'Use space bar initial velocity.
        End If
The rest of the code goes into the timer, since that is what all movement relies on (the timer)... specifically, the CharacterMovement sub that we just created. Now, this sub currently has stuff that executes when the Left and Right buttons are pressed for walking. We can use most of it even while jumping. We aren't necessarily using the AnimCycler, and since that's the only thing that we don't need, we'll just keep everything there unchanged. For the AnimCycler, we'll just need to make an If statement for IsJumping... when we are walking, we will use the walking frames, and while jumping, we will use the Jumping frames (the two at the end). However, we do have to add something that makes the player move vertically if the player is jumping, which, of course, goes into an If IsJumping Then block. Inside this block, we apply two decent physics formulae: dD = Vo * dT + 0.5 * A * (dT)^2 ; dV = A * T. Except, I am going to approximate T to be 1. (dD is the change of distance, dT is the change of time, and dV is the change of velocity.) dD = Vo + 0.5 * A ; dV = A For the * 0.5, we can just do a left shift... but since A is 1, this might not be too effective. Still, I have the gravity as a constant. At a later time in programming, I/you might want to change the Gravity, and this will allow you to just change the constant value with no worry. (Note that dD relies on the initial velocity (Vo), so the dD term should come first) Now, the If IsJumping Then block looks like this.
        If IsJumping Then
            PlayerLoc.Offset(0, PlayerVeloc + GRAVITY >> 1)
            'dD (.OffSet) = Vo (PlayerVeloc) + 0.5 * A (GRAVITY >> 1)
            PlayerVeloc += GRAVITY
            'dV = (PlayerVeloc +=) A (GRAVITY)
            'Moves the character according to its velocity, gravity, and location.
            UpdateArtwork = True
            'Need to update everytime during a jump.
        End If
And that should appear at the bottom of the CharacterMovement sub. Now, we're not finished yet. We still need to check if the player has touched ground. The IsJumping block now becomes something like:
        If IsJumping Then
            PlayerLoc.Offset(0, PlayerVeloc + GRAVITY >> 1)
            'dD (.OffSet) = Vo (PlayerVeloc) + 0.5 * A (GRAVITY >> 1)
            PlayerVeloc += GRAVITY
            'dV = (PlayerVeloc +=) A (GRAVITY)
            'Moves the character according to its velocity, gravity, and location.
            UpdateArtwork = True
            'Need to update everytime during a jump.
            If PlayerLoc.Bottom >= Me.LANDHEIGHT Then
                'Check if we are touching the ground (another RECT advantage).

                IsJumping = False
                'Stop the jump: we have hit the ground.
                AnimCycler = 0
                'Reset the animation cycler: it has been counting during the jump.

            End If

        End If
Notice that we check the bottom of the player rectangle to see if it is touching the ground. If so, then the jump is disabled. The AnimCycler = 0 is there for housekeeping, since it was still possibly executed in the GoRight and GoLeft blocks above. Now that that is done, we need to fix the frame drawing rectangle, which is quite simple. So:
            GFX.DrawImage(PlayerBmp, PlayerLoc.X, PlayerLoc.Y, New Rectangle(CHARWIDTH * CharDirec * WALKINGFRAMECOUNT + AnimCycler * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel)
            'This draws the character to the display, based on the current character location, frame, and state.
becomes:
            If IsJumping Then
                GFX.DrawImage(PlayerBmp, PlayerLoc.X, PlayerLoc.Y, New Rectangle((CHARWIDTH * WALKINGFRAMECOUNT << 1) + CharDirec * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel)
                'Jumping draw only.
            Else
                GFX.DrawImage(PlayerBmp, PlayerLoc.X, PlayerLoc.Y, New Rectangle(CHARWIDTH * CharDirec * WALKINGFRAMECOUNT + AnimCycler * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel)
                'This draws the character to the display, based on the current character location, frame, and state.
            End If
The original .DrawImage has moved into the Else part of this If block (which is in the Artwork sub). The only change to the top call was in the left parameter of the new rectangle (constructor) sub.
New Rectangle((CHARWIDTH * WALKINGFRAMECOUNT << 1) + CharDirec * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT)
The first part, (CHARWIDTH * WALKINGFRAMECOUNT << 1), is skipping over the 8 frames at the start of the bitmap. The CHARWIDTH is the frame width, and the WALKINGFRAMECOUNT is the number of frames in each walking cycle. As you can see, it is multiplied by 2 (shifted left by 1). This will return the first jumping frame (the one where the picture is looking left). Which is fine if the character is looking left, but if he is looking right, you see the extra CharDirec * CHARWIDTH term. When the character is looking left, CharDirect is 0, so this term does not contribute to the result. But, when the character is looking right, CharDirec is 1, and this causes an extra CHARWIDTH to be added to the left parameter of the rectangle constructor, moving it to the right facing jump frame. Now, if you run the project, the character should jump when the space bar is pressed. Hmm... it's quite a long jump. The hangtime of the jump can be calculated by dT = 2 * | InitialVelocity | * Clock.Interval / Gravity (that's something for us, not the computer)... and the jump height can be calculated from dD = (1.5 * InitialVelocity * InitialVelocity) / Gravity you can use this to tweak the jump a bit. If you want a long hangtime, you can either make the initialvelocity or the interval larger. Additionally, decreasing the gravity makes the hang time larger as well. Play around with the SBARINITIALVELOCITY and GRAVITY constants until you find something that looks good. (Although, when I discuss platforms, I will be using the 16 initialvelocity and 1 gravity.) Good luck! Next time, I think I'm going to go ahead and get those other jump key combinations out of the way.