Welcome back.  I have been running a little low on ideas to implement, but I finally thought of few.

In this episode, we will set up jumping boards, spring boards, or whatever they are being called nowadays.
The jumping board is going to be a simple block with an arrow on it, and if the player so happen to step
or fall on it, the player is launched upwards.  Aside from stepping on top of it, the jumpboard will
behave as a wall, which makes the player unable to walk into it.
The jumpboard will be capable of bouncing the player at a custom velocity defined within the board.  For
particularly big values (like -72), the player will go up quickly.  The character would also fall quickly
if it jumped from this block.  So, adding a terminal velocity wouldn't hurt.
Remember that the terminal velocity is the maximum velocity that our character will reach when falling.
Since our character starts the jump at -32 (or -16 if you are using the old one), the terminal velocity
would more than likely be bigger than this value... 50 or 45 might be good.  I will use 45.
Now, let's set up terminal velocity before we set up jumping boards.
Of course, we will first have our terminal velocity constant value.
 Const TERMINALVELOCITY As Integer = 45 'The maximum velocity that the character reaches while falling.
And then, to implement terminal velocity, we will merely check our velocity in the CharacterMovement sub. This will only be one simple check immediately after we update the velocity.
 PlayerVeloc += GRAVITY 'dV = (PlayerVeloc +=) A (GRAVITY) 'Moves the character according to its velocity, gravity, and location. If PlayerVeloc >= TERMINALVELOCITY Then 'We're in TV. PlayerVeloc = TERMINALVELOCITY 'Limit the velocity. End If
Now, climb upon a high cliff and jump off. The character will reach terminal velocity and start to fall at a constant speed until it lands on a platform or something. You'll have to watch for it carefully because terminal velocity is barely noticeable unless you've been falling for quite a bit. You should be able to tell because it looks like the player is somehow using a parachute.
Now, for the jumping board, we will use this image. Certainly a small image, but the jumping board can be resized by using a particular .DrawImage transform. This is not all we need for the jumping board. We still have to determine where it goes and what the player's velocity will be when the jumping board is stepped on. The location of the jumping board can be handled by a point, but we'd need an extra variable to hold the jumping board velocity. So, in this case, we should make a structure for the jumping board. This structure only needs a rectangle and a location, so we will specify those easily. Little else is needed - a constructor would help in getting the jumping board to and from file when we get to it, but everything else is not necessary. In the case of the Floater, we don't need an offset function, unless we want the jumping board to move (hmm idea but at the wrong time) and if we really need to move it, we can use the Offset method of the rectangle that's inside the structure. So, our jumping board structure consists of a rectangle, an integer, and a constructor.
 Public Structure JumpingBoard Public Loc As Rectangle 'Location. Public ReboundVeloc As Integer 'The velocity at which the player will jump to when he lands on this board. Public Sub New(ByVal X As Integer, ByVal Y As Integer, ByVal W As Integer, ByVal H As Integer, ByVal Rebound As Integer) 'Quickly set our jumping board. Loc = New Rectangle(X, Y, W, H) ReboundVeloc = Rebound End Sub End Structure
Of course, the size of our jumping platform will be constant, so we'll declare constants for that as well.
 Const JUMPBOARDSIZE As Integer = 16 'Size of the jumping board.
As in the case with all of our other map elements, we'll need to declare something that will hold all of the jumping boards.
 Dim Jumpboards As ArrayList 'Holds all of the jump boards in the level. Dim Jumpboard As JumpingBoard 'A board that automatically boosts the player by giving him a large jumping speed. Dim Jumpbmp As Bitmap 'Holds the picture for the jumping board.
And now, let's make some jumping boards. In the Load event, we set up our JumpBoards arraylist and the Jumpbmp bitmap.
 Jumpbmp = New Bitmap(Application.StartupPath & "\..\Uonly.jpg") 'Picture of the jumping board, an up arrow. Jumpboards = New ArrayList(10) 'Initialize the jumping board arraylist. Jumpboards.Add(New JumpingBoard(1250, 224, JUMPBOARDSIZE, JUMPBOARDSIZE, -56)) 'Add this jumping board to the level.
You may have to move it somewhere else since mine is pretty far to the right hand side. Now, for drawing this one jump board, we will go ahead and use the For Each loop to prepare for the fact that we'll have to add many more with the level editor. So, in Artwork, we'll draw the bitmap for our jumping board.
 For Each Jumpboard In Jumpboards Jumpboard.Loc.Offset(-ScreenLeft, -ScreenTop) 'We did need to move it! GFX.DrawImage(Jumpbmp, Jumpboard.Loc) Jumpboard.Loc.Offset(ScreenLeft, ScreenTop) Next
As you can see, we did need an offset function, but fortunately, one was still available in the rectangle that we used for the location. If you start the program, you should be able to see the arrow (of course, we cannot interact with it yet... that part would be in the CharacterMovement sub).
Since our jumping board is acting as a wall, we will have to do its collision checks like the ones of a wall. It may help to put all of the jumping board collision checks immediately after the wall collision checks. So, in the GoLeft block, we'd have:
 For Each Jumpboard In Jumpboards 'Check with each wall. If PlayerLoc.IntersectsWith(Jumpboard.Loc) Then PlayerLoc.Offset(Jumpboard.Loc.Right - PlayerLoc.Left, 0) 'Move the player to the edge of this jumping board. End If Next
In the GoRight block, we'd have:
 For Each Jumpboard In Jumpboards If PlayerLoc.IntersectsWith(Jumpboard.Loc) Then PlayerLoc.Offset(Jumpboard.Loc.Left - PlayerLoc.Right, 0) 'Move the player to the edge of this jumping board.. End If Next
And finally, for the biggest chunk, in the IsJumping block, we'd have:
 For Each Jumpboard In Jumpboards If PlayerLoc.IntersectsWith(Jumpboard.Loc) Then If IsJumping = False Then 'If the player has landed on a platform. IsJumping = True 'Knock the player off the platform and make the player PlayerLoc.Offset(0, Jumpboard.Loc.Bottom - PlayerLoc.Top + GRAVITYTH) 'Move the player to under the wall. We need GRAVITYTH so that the player climb up to the platform. PlayerVeloc = 0 'Make the player start falling. ElseIf PlayerVeloc > 0 Then 'If player is falling, then the player will land on the wall. PlayerVeloc = Jumpboard.ReboundVeloc 'Bounce the player off of this board. PlayerLoc.Offset(0, Jumpboard.Loc.Top - PlayerLoc.Bottom) 'Position the player to stand on this wall. Else 'The player has jumped up into the wall. PlayerLoc.Offset(0, Jumpboard.Loc.Bottom - PlayerLoc.Top) 'Move the player to under the wall. PlayerVeloc = 0 'Make the player start falling down. End If End If Next
Notice the part in the PlayerVeloc > 0 block. This is the part that is responsible for making the player automatically jump off from the jumping board, and therefore, the rebound velocity sets the player's velocity. Now, you should be able to see the player jump off of this jumping board.
Next, it's time to put these jumping boards into the file. First, we'll need to support them with the editor, so set TESTversion to 1 and let's go. The Jumping board's key would probably be better suited as "J"c, although "B"c would be fine, or "S"c, if you like "springboard". I will be using "J"c, however. So, in the KeyDown event, we'll set MDObject to J when J is pressed.
 ElseIf e.KeyCode = Keys.J Then If Not IsMouseDown Then MDObject = "J"c End If
And of course, in MouseUp, we make this happen. But, before we can make this happen, we need someway of getting a number from the user. So, we'll use the ever-useful NumericBox dialog box that I created *such a shameless advertisement* here. The numericbox is easily callable, just like this: Num = NumericBox.Show(...), and it was modeled after the MessageBox. So, this is what it would be like to use the NumericBox to set the rebound velocity.
 Case "J"c Clock.Enabled = False 'Lighten processing until we're done. Dim Jb As JumpingBoard Jb.ReboundVeloc = -NumericBox.Show(32, 100) 'Note the negative. I wouldn't trust a trackbar to be negative. 'Gets a value that was input by the user. If Jb.ReboundVeloc = 1 Then 'If the cancel returns negative 1, negative -1 would be positive 1. Jb.ReboundVeloc = -65 'Let this be the default. These could stand as declared constants as well. End If Jb.Loc = New Rectangle(Mu.X + ScreenLeft, Mu.Y + ScreenTop, JUMPBOARDSIZE, JUMPBOARDSIZE) 'Fulfill the jumping board's position. Jumpboards.Insert(0, Jb) 'And insert the newly created jumpboard at the head of the jumpboard arraylist. Clock.Enabled = True 'Re enable the processing.
The processing could probably be more efficient, but it's just the editor that will be running this. The bad details here should only be insignificantly bad details. Now, this will allow the jumping boards to be created in the editor, but they'll have to be saved to file. Therefore, we'd slap something like:
 'Jumping boards written to file. BW.Write(Jumpboards.Count) For Each Jumpboard In Jumpboards BW.Write(Jumpboard.Loc.Left) BW.Write(Jumpboard.Loc.Top) BW.Write(Jumpboard.ReboundVeloc) Next
In the SaveLevel subroutine. Ideally, this would go at the end of the save sub, after the floaters, and before the streams are closed. But, they can be placed anywhere, as you witnessed when we put the player's default location to be at the head of the file. The most important thing is that you have to resave ALL of your old files into this format with the jumping boards at the end before you write the LoadLevel procedure... otherwise, the BinaryReader will give you an error and you'd have to 'undo' the LoadLevel procedure to read your old file correctly. Now, add those jumpboards, and save all of your old files, even if they won't have jumpingboards in them (the reader will still expect to see a 0 for no jumpers).
After you have done that, the LoadLevel should be created to load your old levels. An advantage of putting the jumpboards at the end is that your new levels should be still be readable with the old version of the LoadLevel function. We'll read the level back in the exact method in how we saved it (as usual).