Here we are at section 6, an introduction to Platforms.  Now, previously, we've gotten our character to jump
around a bit and walk to the edges of the screen, but we don't have anything interesting on the screen yet.  That
is about to change now.  We are going to add platforms.  This platform is only going to be the kind where you
can walk in front of it and then jump onto it.

First, we need to store the platforms into something.  The platform itself only needs to be a Rectangle for now.
If I decide on making bizarre-shaped platforms, then of course we'll have to modify the platform storage.

So, ideally, the platforms will eventually come from a file that will have all of the information necessary for
recreating a level.  But, right now, we will start off with a simple one platform that will be hard-coded in the
form class.

    Dim Platform As Rectangle
    'A platform.
Platform - is going to be a rectangle. The top property will probably be of more use, since it is where the player will walk and what the player jumps to. We need to instantiate this Platform to something. Based on our jumping, we'll initialize a platform with a Top at about 515-550. Let's say:
        Platform = Rectangle.FromLTRB(150, 515, 210, LANDHEIGHT)
        'Instantiate our platform
Next, let's get the platform drawn. Let's scroll on down to the artwork sub. Now, where should the platform be drawn in the order of things. It definitely should be in front of the sky. It should probably be behind the character. Depending on how pessimistic I am when I write this, I might want to draw the platforms after the grass to make sure that I can see them (this might come in handy when the platforms are laid out and if you want to check if any of them are too large), or I might want to draw them before the grass. Right now, I am going to draw them after the grass, because drawing before the grass might cause some of the platform to be covered up and, right now, I don't want that to happen. So, after the ForestGreen land is drawn, the brown-ish platform is drawn. (Of course, you can pick your own colors / picture to draw for the platform.)
            GFX.FillRectangle(Brushes.Maroon, Platform)
            GFX.DrawRectangle(Pens.Chocolate, Platform)
            'I'm not into interior decorating, so the only thing I can say about these colors is that 
            'they'd better be a light brown persuasion.  This draws the platform.
And now, let's see what color this turns out to be. ... Well, it looks OK. The Maroon filling was a little darker than I wanted it to be, so let's try this...
            GFX.FillRectangle(Brushes.Tan, Platform)
            GFX.DrawRectangle(Pens.RosyBrown, Platform)
            'I'm not into interior decorating, so the only thing I can say about these colors is that 
            'they'd better be a light brown persuasion.  This draws the platform.
Since Platform is a rect, it can passed to the rectangle draw as a whole... isn't that nice.
Now, we need the player to somehow interact with the platform, otherwise, it's just decoration. First, we will allow the player to jump onto the platform. If I assume that the platform extended from the left to right, then I wouldn't be concerned with the player falling off the edge or jumping in the area that the platform is not located at (on the left/right view). This simplified version will allow me to merely check the Top values of the platform with the Bottom property of my character. So, let's do that now... let's go on to the section where we check if the character is still jumping. Now, we cannot merely check if PlayerLoc.Bottom >= Platform.Top, because that would cause the player to "teleport" onto the platform while jumping... it would be more effective to check if the player is falling before we place him onto the platform. Knowing that, we also can't just make the player hop on to the platform if he is falling. If it is a tall platform, then if the character jumped at it from the side, he would fly all the way to the top once he started to fall. So, in order for this to look convincing, we need to check if the Platform top is between two points on the character, namely the feet and somewhere around the shoulder. Now, to put all of what I said into action. First, we should define a constant that determines where the shoulder is.
    Const SHOULDER As Integer = 17
    'Looked in paint to determine the distance the shoulder is from the bottom of the foot.
    'This will be used for determining if the player gets on a platform.
SHOULDER is the distance from the foot. If the platform is detected to fall in this distance (PlayerLoc.Bottom and PlayerLoc.Bottom - SHOULDER), then the player is placed on the platform. Now, to get this into good use. Let's move into the charactermovement subroutine and add this. This goes after the If PlayerLoc.Bottom >= Me.LANDHEIGHT Then block.
            ElseIf PlayerVeloc > 0 AndAlso PlayerLoc.Bottom >= Platform.Top AndAlso PlayerLoc.Bottom - SHOULDER <= Platform.Top Then
                'The player has landed on this platform.  He needs to be updated.
                'See how many advantages there are to using a Rectangle.

                IsJumping = False
                'Hit the ground, we are not jumping.
                AnimCycler = 0
                'Reset cycler.
                PlayerLoc.Offset(0, Platform.Top - PlayerLoc.Bottom)
                'Move the player onto this platform.
The player should jump onto the platform. Now, we just need to make him miss the platform.
To make the jump miss the platform, we need to check if the character is touching the platform, looking along the X-axis. This means the PlayerLoc.Left must be less than the Platform.Right and the PlayerLoc.Right must be greater than the Platform.Left. That will just be another check in the already big If statement that we just created. But, if we have to check all of this, then that's what we need to do.
            ElseIf PlayerVeloc > 0 AndAlso PlayerLoc.Bottom >= Platform.Top AndAlso PlayerLoc.Bottom - SHOULDER <= Platform.Top Then
                If PlayerLoc.Left < Platform.Right AndAlso PlayerLoc.Right > Platform.Left Then
                    'The player has landed on this platform.  He needs to be updated.
                    'See how many advantages there are to using a Rectangle.

                    IsJumping = False
                    'Hit the ground, we are not jumping.
                    AnimCycler = 0
                    'Reset cycler.
                    PlayerLoc.Offset(0, Platform.Top - PlayerLoc.Bottom)
                    'Move the player onto this platform.
                End If
Our If statement is growing rapidly, like a tumor. But that's fine. Notice that this allows the player to jump off of the platform, but it still doesn't cause him to fall off of the platform, so we still have the little coyote-not-looking-down-as-it-walks-off-of-a-cliff action going on. So, now, how do we determine if the player has walked off of a cliff. We can store the endpoints of the cliff in some variables, or we can store the entire rectangle in a variable. The endpoints would only be two values, and we don't really need to know how high the character is off the ground to determine if he falls. It would have to be initialized since the player starts on the ground... otherwise, the player will be falling when we start the program. So, we'll just make two variables.
    Dim LeftEnd As Integer
    Dim RightEnd As Integer
    'This stores the locations of the end of the cliff that the character is currently on.
LeftEnd and RightEnd store numbers which represents the edge of the cliff. When the character passes these values, he will begin to fall. We'll initialize them in the Form_Load.
        LeftEnd = 0 : RightEnd = MAPWIDTH
        'Set the current end points.
We also need to set them when the character stops falling and hits ground, since he might be on a platform or he might be on the ground.
        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.
                LeftEnd = 0 : RightEnd = MAPWIDTH
                'Set the endpoints for the ground.
                AnimCycler = 0
                'Reset the animation cycler: it has been counting during the jump.
            ElseIf PlayerVeloc > 0 AndAlso PlayerLoc.Bottom >= Platform.Top AndAlso PlayerLoc.Bottom - SHOULDER <= Platform.Top Then
                If PlayerLoc.Left < Platform.Right AndAlso PlayerLoc.Right > Platform.Left Then
                    'The player has landed on this platform.  He needs to be updated.
                    'See how many advantages there are to using a Rectangle.

                    IsJumping = False
                    'Hit the ground, we are not jumping.
                    LeftEnd = Platform.Left : RightEnd = Platform.Right
                    'Set the endpoints for the platform.
                    AnimCycler = 0
                    'Reset cycler.
                    PlayerLoc.Offset(0, Platform.Top - PlayerLoc.Bottom)
                    'Move the player onto this platform.
                End If
            End If

        End If
This is all of the IsJumping code with the Endpoints added. Now, the player needs to acknowledge these end points somehow. We can do that in the walking part. (Scroll up to the walking part.) When walking left:
            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)
            ElseIf PlayerLoc.Right < LeftEnd AndAlso Not IsJumping Then
                IsJumping = True
                'We are not really jumping, but we are falling.
                PlayerVeloc = 0
                'Since we are falling from rest, the initial velocity will be zero.
            End If
You might find that, without the Not IsJumping part, the player will constantly have a velocity of zero. So, the Not IsJumping keeps this from happening, and similarly in the next part. When walking right:
            If PlayerLoc.Right > MAPWIDTH Then
                'If player goes off right edge... move him back.
                PlayerLoc.Offset(MAPWIDTH - PlayerLoc.Right, 0)
            ElseIf PlayerLoc.Left > RightEnd AndAlso Not IsJumping Then
                IsJumping = True
                'We are falling.
                PlayerVeloc = 0
                'A fall from rest.
            End If
Also, we need to modify the falling code for the platform, since I notice that I didn't do it yet.
                PlayerLoc.Offset(0, LANDHEIGHT - PlayerLoc.Bottom)
                'Move the player to stand on the land properly.
Now, the player should jump onto the platform and walk off of it. Well, that's all for this episode... next, I'll bring up multiple platform objects.
Current code for the CharacterMovement subroutine.
    Private Sub CharacterMovement()
        If GoLeft Then
            If GoFast Then
                PlayerLoc.Offset(-MOVESPEED - (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)
            ElseIf PlayerLoc.Right < LeftEnd AndAlso Not IsJumping Then
                IsJumping = True
                'We are not really jumping, but we are falling.
                PlayerVeloc = 0
                'Since we are falling from rest, the initial velocity will be zero.
            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 + (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)
            ElseIf PlayerLoc.Left > RightEnd AndAlso Not IsJumping Then
                IsJumping = True
                'We are falling.
                PlayerVeloc = 0
                'A fall from rest.
            End If
            UpdateArtwork = True
            CharDirec = 1   'Look right.
            'Now, update the animation cycler.
            AnimCycler = (AnimCycler + 1) Mod WALKINGFRAMECOUNT
        End If

        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.
                LeftEnd = 0 : RightEnd = MAPWIDTH
                'Set the endpoints for the ground.
                AnimCycler = 0
                'Reset the animation cycler: it has been counting during the jump.
                PlayerLoc.Offset(0, LANDHEIGHT - PlayerLoc.Bottom)
                'Move the player to stand on the land properly.
            ElseIf PlayerVeloc > 0 AndAlso PlayerLoc.Bottom >= Platform.Top AndAlso PlayerLoc.Bottom - SHOULDER <= Platform.Top Then
                If PlayerLoc.Left < Platform.Right AndAlso PlayerLoc.Right > Platform.Left Then
                    'The player has landed on this platform.  He needs to be updated.
                    'See how many advantages there are to using a Rectangle.

                    IsJumping = False
                    'Hit the ground, we are not jumping.
                    LeftEnd = Platform.Left : RightEnd = Platform.Right
                    'Set the endpoints for the platform.
                    AnimCycler = 0
                    'Reset cycler.
                    PlayerLoc.Offset(0, Platform.Top - PlayerLoc.Bottom)
                    'Move the player onto this platform.
                End If
            End If

        End If
    End Sub