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.

		Rectangle platform;
		// 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, 250, PFMain.thelandheight);
			// Instantiate the 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);
				// This draws the platform with a maroon interior and a chocolate border.
				// Try the colors out to get a good one.
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.Moccasin , platform);
				gfx.DrawRectangle(Pens.BurlyWood , platform);
				// This draws the platform with a maroon interior and a chocolate border.
				// Try the colors out to get a good one.
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 int theshoulder = 17;
		// Looked in paint to determine the shoulder distance from the bottom of the file.
		// If the platform top falls within this range above the player's feet, the player will get on the platform.
theshoulder is the distance from the foot. If the platform is detected to fall in this distance (PlayerLoc.Bottom and PlayerLoc.Bottom - theshoulder), 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 >= thelandheight) block.
				} else if (playerveloc > 0 && playerloc.Bottom >= platform.Top && playerloc.Bottom - theshoulder <= platform.Top) {
					// The player has landed on the platform.  Using a rectangle for the player made this check much easier than without.
					// We do need to set a few things to let the player know where he is.

                                        isjumping = false;
					// Not jumping
					animcycler = 0;
					// Restart the animation cycle to the first frame.
					playerloc.Offset(0, platform.Top - playerloc.Bottom);
					// Position the player so that he is standing on the 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.
				} else if (playerveloc > 0 && playerloc.Bottom >= platform.Top && playerloc.Bottom - theshoulder <= platform.Top) {
					// The player has landed on the platform.  Using a rectangle for the player made this check much easier than without.
					// We do need to set a few things to let the player know where he is.
					if (playerloc.Right >= platform.Left && platform.Right >= playerloc.Left) 
					{
						// Player is over the platform.
						isjumping = false;
						// Not jumping
						animcycler = 0;
						// Restart the animation cycle to the first frame.
						playerloc.Offset(0, platform.Top - playerloc.Bottom);
						// Position the player so that he is standing on the platform.
					}
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.
		int leftend, rightend;
		// These are the left and right ends 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 PFMain_Load.
			leftend = 0;
			rightend = themapwidth;
			// Range of the ground set as the end points for the character's current platform.
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) 
			{
				playerloc.Offset(0, playerveloc + thegravity >> 1);
				// dD (.Offset) = Vo (playerveloc) + 0.5 * A (thegravity >> 1)
				playerveloc += thegravity;
				// dV = (playerveloc +=) A (thegravity)
				// Moves the character according to its velocity, gravity, and location.
				updateartwork = true;
				// Need to update everytime during a jump.
				if (playerloc.Bottom >= PFMain.thelandheight) 
				{
					// check if we are touching ground (another rect advantage).
					isjumping = false;
					// Stop jumping... we've hit the ground.
					leftend = 0; rightend = PFMain.themapwidth;
					// Ground range.
					animcycler = 0;
					// Reset animation cycler that was counting during the jump.
				} else if (playerveloc > 0 && playerloc.Bottom >= platform.Top && playerloc.Bottom - theshoulder <= platform.Top) {
					// The player has landed on the platform.  Using a rectangle for the player made this check much easier than without.
					// We do need to set a few things to let the player know where he is.
					if (playerloc.Right >= platform.Left && platform.Right >= playerloc.Left) 
					{
						// Player is over the platform.
						isjumping = false;
						// Not jumping
						leftend = platform.Left; rightend = platform.Right;
						// Platform endpoints are now the falling endpoints.
						animcycler = 0;
						// Restart the animation cycle to the first frame.
						playerloc.Offset(0, platform.Top - playerloc.Bottom);
						// Position the player so that he is standing on the platform.
					}
				}
			}
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) 
				{
					// If the player goes off the edge of the form, then we will move him back to the edge.
					playerloc.Offset(-playerloc.Left, 0);
				} else if (playerloc.Right < leftend && !isjumping ) {
					isjumping = true;
					// Falling off the edge of a platform.
					playerveloc = 0;
					// Free-fall.
				}
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 > themapwidth) 
				{
					// If player goes off right edge... move him back.
					playerloc.Offset(themapwidth - playerloc.Right, 0);
				} else if (playerloc.Left > rightend && !isjumping ) {
					isjumping = true;
					playerveloc = 0;
					// Falling from edge of platform.
				}
Also, we need to modify the falling code for the platform, since I notice that I didn't do it yet.
					playerloc.Offset(0, thelandheight - playerloc.Bottom);
					// Move the player so he stands properly on the bottom.
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 void charactermovement() 
		{
			if (goleft)
			{
				if (gofast) 
				{
					playerloc.Offset(-themovespeed - (themovespeed >> 1), 0);
					// When shift is pressed, the player runs.
				} 
				else 
				{
					playerloc.Offset(-themovespeed, 0);
					// Move player left.
				}
				if (playerloc.Left < 0) 
				{
					// If the player goes off the edge of the form, then we will move him back to the edge.
					playerloc.Offset(-playerloc.Left, 0);
				} else if (playerloc.Right < leftend && !isjumping ) {
					isjumping = true;
					// Falling off the edge of a platform.
					playerveloc = 0;
					// Free-fall.
				}
				updateartwork = true;
				chardirec = 0;  // Look left.
				// Now update the animation cycler.
				animcycler = (animcycler + 1) % thewalkingframecount;
			} 
			else if (goright) 
			{
				if (gofast) 
				{
					playerloc.Offset(themovespeed + (themovespeed >> 1), 0);
					// When Shift is pressed, the player runs.
				} 
				else 
				{
					playerloc.Offset(themovespeed, 0);
					// Move player right.
				}
				if (playerloc.Right > themapwidth) 
				{
					// If player goes off right edge... move him back.
					playerloc.Offset(themapwidth - playerloc.Right, 0);
				} else if (playerloc.Left > rightend && !isjumping ) {
					isjumping = true;
					playerveloc = 0;
					// Falling from edge of platform.
				}
				updateartwork = true; 
				chardirec = 1;  // Look right.
				// Now update the animation cycler.
				animcycler = (animcycler + 1) % thewalkingframecount;
			}

			if (isjumping) 
			{
				playerloc.Offset(0, playerveloc + thegravity >> 1);
				// dD (.Offset) = Vo (playerveloc) + 0.5 * A (thegravity >> 1)
				playerveloc += thegravity;
				// dV = (playerveloc +=) A (thegravity)
				// Moves the character according to its velocity, gravity, and location.
				updateartwork = true;
				// Need to update everytime during a jump.
				if (playerloc.Bottom >= PFMain.thelandheight) 
				{
					// check if we are touching ground (another rect advantage).
					isjumping = false;
					// Stop jumping... we've hit the ground.
					leftend = 0; rightend = PFMain.themapwidth;
					// Ground range.
					animcycler = 0;
					// Reset animation cycler that was counting during the jump.
					playerloc.Offset(0, thelandheight - playerloc.Bottom);
					// Move the player so he stands properly on the bottom.

				} else if (playerveloc > 0 && playerloc.Bottom >= platform.Top && playerloc.Bottom - theshoulder <= platform.Top) {
					// The player has landed on the platform.  Using a rectangle for the player made this check much easier than without.
					// We do need to set a few things to let the player know where he is.
					if (playerloc.Right >= platform.Left && platform.Right >= playerloc.Left) 
					{
						// Player is over the platform.
						isjumping = false;
						// Not jumping
						leftend = platform.Left; rightend = platform.Right;
						// Platform endpoints are now the falling endpoints.
						animcycler = 0;
						// Restart the animation cycle to the first frame.
						playerloc.Offset(0, platform.Top - playerloc.Bottom);
						// Position the player so that he is standing on the platform.
					}
				}
			}
		}