Welcome back. We are going to have vertical scrolling here. Before we get into all that, first, we are going to add editor support for platforms and walls past the old horizontal movement boundary-that-we-got-rid-of in the previous episode. So, let's go ahead and change the TESTversion to 1. Next, we'll go on down to the MouseUp event, which is responsible for placing the newly created platforms, lava, etc. In this procedure, there are eight locations where I place an object based on the X location of where the mouse was clicked. At each of these locations, we must add ScreenLeft to get the object in the right location. See if you can find all eight without looking at the solution below. OK, the solution is too close to the question for it to be difficult, but give it a try.
Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X) + ScreenLeft, Math.Min(InitialPt.Y, Mu.Y), Math.Max(InitialPt.X, Mu.X) + ScreenLeft, Math.Max(InitialPt.Y, Mu.Y)) 'For platforms. Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X) + ScreenLeft, Math.Min(InitialPt.Y, Mu.Y), Math.Max(InitialPt.X, Mu.X) + ScreenLeft, Math.Max(InitialPt.Y, Mu.Y)) 'For walls. Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X) + ScreenLeft, Math.Min(InitialPt.Y, Mu.Y), Math.Max(InitialPt.X, Mu.X) + ScreenLeft, Math.Max(InitialPt.Y, Mu.Y)) 'For lava. Coins.Insert(0, New Rectangle(Mu.X + ScreenLeft, Mu.Y, COINSIZE, COINSIZE)) 'Place a coin at the point where the mouse was released. Fltr.Loc = New Rectangle(Mu.X + ScreenLeft, Mu.Y, FLOATERSIZE, FLOATERSIZE) 'For the floater... |
'At the head of the file, we will write the player's startup location. BW.Write(PlayerLoc.Left) BW.Write(PlayerLoc.Top) 'Also, the ending points for the platform the player is on. BW.Write(LeftEnd) BW.Write(RightEnd) |
PlayerLoc = New Rectangle(BR.ReadInt32(), BR.ReadInt32(), CHARWIDTH, CHARHEIGHT) 'Read the player location. LeftEnd = BR.ReadInt32() : RightEnd = BR.ReadInt32() 'And the ending points of the current platform. |
LeftEnd = 0 : RightEnd = LEVELWIDTH 'Set the current end points. PlayerLoc = New Rectangle(100, LANDHEIGHT - CHARHEIGHT, CHARWIDTH, CHARHEIGHT) 'Instantiate the player location. |
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 = LEVELWIDTH '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. Else |
'And the remainder of the area is LAND, starting from LANDHEIGHT. GFX.FillRectangle(Brushes.ForestGreen, Rectangle.FromLTRB(0, LANDHEIGHT, MAPWIDTH, MAPHEIGHT)) |
'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)) |
'I am going to draw a lightblue rectangle for the sky. 'It will fill the whole screen. GFX.FillRectangle(Brushes.LightSkyBlue, Rectangle.FromLTRB(0, 0, MAPWIDTH, MAPHEIGHT)) |
If PlayerLoc.Bottom > MAPHEIGHT Then 'The character has fallen off the screen and can't get up. IsGoner = True 'So, the character is dead. PlayerVeloc = SBARINITIALVELOCITY End If |
Dim ScreenTop As Integer 'Where the display's top end is on the map. |
Const VERTICOFFSET As Integer = (MAPHEIGHT >> 1) - (CHARHEIGHT >> 1) 'Distance from the player's top edge to top edge of scrolling screen. |
ScreenTop = PlayerLoc.Y - VERTICOFFSET 'Same for the top end of screen. If ScreenTop > 0 Then ScreenTop = 0 'The screen top coordinate will be non-positive. End If |
If IsGoner Then If Doompause >= DOOMTIMEOUT Then GFX.TranslateTransform(Convert.ToSingle(PlayerLoc.X) + (Me.CHARWIDTH >> 1) - ScreenLeft, Convert.ToSingle(PlayerLoc.Y) + (Me.CHARWIDTH >> 1) - ScreenTop) '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 - ScreenLeft, PlayerLoc.Y - ScreenTop, New Rectangle((CHARWIDTH * WALKINGFRAMECOUNT << 1) + CharDirec * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel) 'Jumping draw only. Else GFX.DrawImage(PlayerBmp, PlayerLoc.X - ScreenLeft, PlayerLoc.Y - ScreenTop, 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 Else If IsJumping Then GFX.DrawImage(PlayerBmp, PlayerLoc.X - ScreenLeft, PlayerLoc.Y - ScreenTop, New Rectangle((CHARWIDTH * WALKINGFRAMECOUNT << 1) + CharDirec * CHARWIDTH, 0, CHARWIDTH, CHARHEIGHT), GraphicsUnit.Pixel) 'Jumping draw only. Else GFX.DrawImage(PlayerBmp, PlayerLoc.X - ScreenLeft, PlayerLoc.Y - ScreenTop, 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 |
Select Case MDObject Case "P"c Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X) + ScreenLeft, Math.Min(InitialPt.Y, Mu.Y) + ScreenTop, Math.Max(InitialPt.X, Mu.X) + ScreenLeft, Math.Max(InitialPt.Y, Mu.Y) + ScreenTop) 'For platforms. Platforms.Insert(0, Placed) 'Add a platform. Case "W"c Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X) + ScreenLeft, Math.Min(InitialPt.Y, Mu.Y) + ScreenTop, Math.Max(InitialPt.X, Mu.X) + ScreenLeft, Math.Max(InitialPt.Y, Mu.Y) + ScreenTop) 'For walls. Walls.Insert(0, Placed) 'Add a wall. Case "L"c Placed = Rectangle.FromLTRB(Math.Min(InitialPt.X, Mu.X) + ScreenLeft, Math.Min(InitialPt.Y, Mu.Y) + ScreenTop, Math.Max(InitialPt.X, Mu.X) + ScreenLeft, Math.Max(InitialPt.Y, Mu.Y) + ScreenTop) 'For lava. Lavas.Insert(0, Placed) 'Add a wall. Case "C"c Coins.Insert(0, New Rectangle(Mu.X + ScreenLeft, Mu.Y + ScreenTop, COINSIZE, COINSIZE)) 'Place a coin at the point where the mouse was released. Case "F"c Clock.Enabled = False 'Lighten the processing load while we set up our floater. Dim Fm As FloaterEd = New FloaterEd Fm.ShowDialog() 'After the showdialog, the floater's final six properties will be set. 'But, the rectangle will be empty. Dim Fltr As LevFloater = Fm.Floater 'Copy the floater to our variable. Fltr.Loc = New Rectangle(Mu.X + ScreenLeft, Mu.Y + ScreenTop, FLOATERSIZE, FLOATERSIZE) 'For the floater... 'Set the rectangle. The size is fixed, so we just make the rectangle like we did for the coin. Floaters.Insert(0, Fltr) 'And this final floater will be added. 'The movement of the floater after it is added to the form is not the exact movement that it will have 'when it is loaded from file, because the value of FloatTick is not always 0 when the floater is created, and its 'movement depends on the value of floattick with the periodic function. Clock.Enabled = True 'Continue game. End Select |