Welcome back.  After a long break, I've decided to continue the .NET Platform Game Tour.  Here, I'm going to add some hazards.  This is just going to be stuff that kills the main character and that you should avoid.  I'm only going to make two types of hazards: a lava trap, which will just be a stationary rectangle of doom, and a floater, which will be a moving object of pain.

First, we'll start off with the lava, since it will be easy.  To get the most of where I place hazards, here's the map that I have created (don't forget to rename it to level.dat) and it's quite odd-looking.  Since the lava will just be a rectangle, we can use the Graphics class Rectangle drawing methods.  Since we've done this so many times, let's spice it up a little.
Instead of using the regular old brushes provided by the Brushes class (yes, it is a class, despite its behavior), let's make our own brush.
It will just be a translucent color of red and it isn't that easy.  We'll do the brush alongside the lava rectangle setup which is covered next.

The declarations come first.
    Dim Lava As Rectangle
    'A deadly rectangle of lava that will kill the character.
    Dim LavaBrsh As Brush
    'This will be the brush that draws the lava onto the display.
Lava - defines a rectangle of lava. LavaBrsh - defines a brush that has been dipped into the bucket of paint that has the color that I will draw this lava with. And then, the initialization. Right now, the lava is going to be hard-coded, but eventually, we'll move it into the level file.
        Lava = Rectangle.FromLTRB(210, 520, 270, LANDHEIGHT)
        'Initialize the lava location.
        LavaBrsh = New SolidBrush(Color.FromArgb(192, 255, 32, 32))
        'Translucent hot looking red brush color.
Next, we draw the spiced-up lava in the Artwork() subroutine after we draw the coins. It is a good idea to draw these from back to front at all times regardless if they may never overlap. I want the lava to appear last since it is translucent and shouldn't appear behind many other objects.
        GFX.FillRectangle(LavaBrsh, Lava)
        GFX.DrawRectangle(Pens.Red, Lava)
        'The translucent lava will be drawn with a red box around the border.
If you run the project, you can walk in the lava, but not for long.
Let's declare another variable to indicate if the player has been defeated by something.
    Dim IsGoner As Boolean
    'If this variable is true, then the character is dead.
IsGoner - will be set to True when the character steps into lava or whatnot and is killed. This will be used for some defeat animation. Now, to detect if the character has stepped into lava, we need to do a simple collision detection in the CharacterMovement sub again using Rectangle.IntersectsWith().
        If Lava.IntersectsWith(PlayerLoc) Then
            IsGoner = True
            'The player steps into lava.  Lose a life.
                PlayerVeloc = SBARINITIALVELOCITY
        End If
This goes after the check for Coins, although it probably doesn't matter if you put it before the coins or before the IsJumping if block. It should generally come after the PlayerLoc has been changed. Now, when the player has been defeated, we do not want the user to be able to move freely while we do our defeated animation. So, in the CharacterMovement, add:
        If Not IsGoner Then
            'Do this only if the player has not been killed.
To the beginning, and then add another End If as the last line of the subroutine. If you run the project now, you'll see the player come to a complete stop when it touches the lava, as if it is frozen in time (it looks really neat if you jump).
Now, for our defeated animation, let's try to make the player fall off to the bottom of the form, kind of like what Mario does in the classic Super Mario Bros. except we don't have a frame for the character to look at us and instead, we'll just have the character spin while he is falling... we can do this with a Graphics transform. Well, let's try it. First, we need to make the character fall to the bottom of the form. We can use the regular falling formulas that we have for the player during regular gameplay. So, in CharacterMovement, after we set IsGoner to True, notice that we added
                PlayerVeloc = SBARINITIALVELOCITY
Now, we need to spin the player. We'll need to declare a variable that indicates what angle to go to to cause the player to appear to be spinning. So, in Artwork(), we'll declare another static variable:
        Static RotateAngle As Single
        'Holds the current rotation angle for our character.
And this variable will be incremented everytime we enter the Artwork Subroutine while the player is defeated. The amount that we increment can be determined by another constant, so let's declare it.
    Const SPINOUTSPEED As Single = 50.0F
    'How fast the character spins when he has been killed.
And now, I change the entire section of code that draws the main character in the Artwork subroutine to:
        If IsGoner Then
            GFX.TranslateTransform(Convert.ToSingle(PlayerLoc.X) + (Me.CHARWIDTH >> 1), Convert.ToSingle(PlayerLoc.Y) + (Me.CHARWIDTH >> 1))
            'Move the center point to the center of the character's midpoint.
            GFX.RotateTransform(RotateAngle)
            'Spin the character clockwise.
            RotateAngle += SPINOUTSPEED

            If IsJumping Then
                GFX.DrawImage(PlayerBmp, -Me.CHARWIDTH >> 1, -Me.CHARHEIGHT >> 1, New Rectangle((CHARWIDTH * WALKINGFRAMECOUNT << 1) + CharDirec * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel)
                'Draw the character centered on the point 0, 0
            Else
                GFX.DrawImage(PlayerBmp, -Me.CHARWIDTH >> 1, -Me.CHARHEIGHT >> 1, 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

            PlayerLoc.Offset(0, PlayerVeloc + GRAVITY >> 1)
            'Gravity-based calculations that we have already done in CharacterMovement.
            PlayerVeloc += GRAVITY

            GFX.ResetTransform()

        Else
            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

        End If
If you run the project, the spinning character looks a bit scary, which should convey the fact that the user doesn't want this to happen. If you pick a good value for SPINOUTSPEED, you'll get different results.
The delay was kind of nice. To make the character delay for a while before tumbling off to the bottom of the screen, let's add another static variable to the Artwork sub in order to cause a delay.
        Static Doompause As Integer
        'After this hits a certain value, the character will begin tumbling because he has been killed.
Of course, we need a constant to determine how long to wait before starting the tumble.
    Const DOOMTIMEOUT As Integer = 15
    'Wait this many frames until the character begins tumbling to the bottom of the screen.
I have changed the timer interval to 50 at some point during my development, so if your timer interval is still 100, you should change it to 50 so that the game runs faster, or you can halve the number that I have there. Now, my IsGoner if section in my Artwork sub looks like this:
        If IsGoner Then

            If Doompause >= DOOMTIMEOUT Then
                GFX.TranslateTransform(Convert.ToSingle(PlayerLoc.X) + (Me.CHARWIDTH >> 1), Convert.ToSingle(PlayerLoc.Y) + (Me.CHARWIDTH >> 1))
                'Move the center point to the center of the character's midpoint.
                GFX.RotateTransform(RotateAngle)
                'Spin the character clockwise.
                RotateAngle += SPINOUTSPEED

                If IsJumping Then
                    GFX.DrawImage(PlayerBmp, -Me.CHARWIDTH >> 1, -Me.CHARHEIGHT >> 1, New Rectangle((CHARWIDTH * WALKINGFRAMECOUNT << 1) + CharDirec * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel)
                    'Draw the character centered on the point 0, 0
                Else
                    GFX.DrawImage(PlayerBmp, -Me.CHARWIDTH >> 1, -Me.CHARHEIGHT >> 1, 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

                PlayerLoc.Offset(0, PlayerVeloc + GRAVITY >> 1)
                'Gravity-based calculations that we have already done in CharacterMovement.
                PlayerVeloc += GRAVITY

                GFX.ResetTransform()
            Else

                RotateAngle = 0.0F
                'Reset the rotateangle for our tumbling-spinning character.

                Doompause += 1
                'Increment the delay counter.
                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

            End If

And now the character stops for a little while, and then falls down off the bottom of the form.
Now, for the floaters. The floater is going to be a really small critter that moves back and forth via periodic functions. Here is the floater picture. Don't forget to put it in the same folder as the .vb files for this project. Here are the declarations.
    Dim FloatBmp As Bitmap
    'THe bitmap that will hold the picture of the floater.
    Dim Floater As Rectangle
    'This is the floater's location on the field.
    Dim FloatTick As Integer
    'This is the time variable that indicates what part of the periodic floater function.
The constants: we just need the size of the floater.
    Const FLOATERSIZE As Integer = 16
    'The width and height of floater.
A lot of the information about the floater is going to be held back, because, for now, we are just going to have the Floater move in a circle. Later on, we'll develop some structures that will greatly expand the features of the Floater. Next, the initialization:
        FloatBmp = New Bitmap(Application.StartupPath & "\..\iorb.gif")
        'Picture of the floater.
        Floater = New Rectangle(420, 400, FLOATERSIZE, FLOATERSIZE)
        'Location of the floater.  The width and height are all determined by the floatersize constant.
        FloatTick = 0
        'Init the float counter.
Then, we draw the floater.
        GFX.DrawImage(FloatBmp, Floater.X, Floater.Y)
        'Draw the floater to the display.  There's only one frame, so no selection involved.
If you run the project now, you can see the floater on the screen, but it doesn't move and it doesn't kill. It does look quite harmless, though. First, let's do the collision detection to determine if the floater hits the character. You may not be surprised that it looks exactly like the lava collision detection code.
            If Floater.IntersectsWith(PlayerLoc) Then
                IsGoner = True
                'The player has touched the floater.  Lose a life.
                PlayerVeloc = SBARINITIALVELOCITY
            End If
And that is done. Now, all we need to do is move the floater in a circle. We can have the floater move regardless of whether the player has been killed or not, so that means it can go outside of the big IsGoner If block that we just added. So, our circular movement section will look like this:
        Floater.Offset(Convert.ToInt32(5 * Math.Cos(Convert.ToDouble(FloatTick) / 8)), Convert.ToInt32(5 * Math.Sin(Convert.ToDouble(FloatTick) / 8)))
        'The Floater moves in a circle.
        'I am not using constants right now, because I am going to update the lava and floater eventually.
        FloatTick += 1
And that comes right before the End Sub of the CharacterMovement subroutine. Now, the floater is a formidable opponent (or pest). Next, we work over the code so that things should be easier.