Now that we created a basic map, let's create a character and move it through our map.
Changing our sprite sheet
For this post I'll change a bit the textures from Post #3 and add a sprite sheet for player textures as shown below.
Also add a second Resource to load (which means on the declarations create another bitmap and another texturebrush)
Public TestPlayerS As Bitmap
Public TestPlayerB As TextureBrush
And on SoftRender("LOAD") added the following assign
TestDrawingS = New Bitmap(My.Resources.TileMapN) 'Resource
TestPlayerS = New Bitmap(My.Resources.PlayerSheet) 'Resource
Now on our events, we add the following code to our form for pressing keys
Private Sub F_SRender_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyCode
Case Keys.D
ScreenClicked("D")
Case Keys.A
ScreenClicked("A")
Case Keys.W
ScreenClicked("W")
Case Keys.S
ScreenClicked("S")
End Select
End Sub
Now we change our world creating sub since we changed a bit the tiles and we want to add a flag for tiles that are walkable or not.
Public Sub GridCalls(ByVal Func As String)
Dim X, Y, Z As Integer
If Func = "CREATE" Then
For X = 0 To MaxGridX
For Y = 0 To MaxGridY
GridWorld(X, Y).X = X * GridWidth
GridWorld(X, Y).Y = Y * GridWidth
GridWorld(X, Y).Z = Z * GridWidth
GridWorld(X, Y).ID = Int(Rnd() * 7) 'Assigning random values for tile ID
Next
Next
'Now we'll create a worm like algorithm to create random connected dirt through our grid world
Dim StartX As Integer = 20
Dim StartY As Integer = 12
Dim WormSteps As Integer = 360
Dim Direction As Integer = 0
Randomize()
GridWorld(StartX, StartY).ID = 7
For Z = 0 To WormSteps
Direction = Int(Rnd() * 4)
If Direction = 0 Then
StartY -= 1
ElseIf direction = 1 Then
StartX += 1
ElseIf direction = 2 Then
StartY += 1
ElseIf direction = 3 Then
StartX -= 1
End If
If StartX < 0 Then StartX = 0
If StartX > MaxGridX Then StartX = MaxGridX
If StartY < 0 Then StartY = 0
If StartY > MaxGridY Then StartY = MaxGridY
GridWorld(StartX, StartY).ID = 7
Next
For X = 0 To MaxGridX
For Y = 0 To MaxGridY
If GridWorld(X, Y).ID >= 4 And GridWorld(X, Y).ID <= 6 Then
GridWorld(X, Y).Blocked = 1
End If
Next
Next
End If
End Sub
And on our module we create the following sub
Public Sub ScreenClicked(ByVal KeyClicked As String)
Select Case KeyClicked
Case "W"
PlayerDirection = 4
PlayerTargetTy = PlayerTileY - 1
playertargettx = PlayerTileX
Case "S"
PlayerDirection = 2
PlayerTargetTy = PlayerTileY + 1
playertargettx = PlayerTileX
Case "A"
PlayerDirection = 3
PlayerTargetTx = PlayerTileX - 1
playertargetty = PlayerTileY
Case "D"
PlayerDirection = 1
PlayerTargetTx = PlayerTileX + 1
playertargetty = PlayerTileY
End Select
End Sub
And the following declarations and Sub for controlling the player
Public PlayerX As IntegerPublic PlayerY As Integer
Public PlayerTileX As Integer
Public PlayerTileY As Integer
Public PlayerTargetTX As Integer
Public PlayerTargetTY As Integer
Public PlayerFrameDouble As Integer
Public PlayerFrame As Integer
Public PlayerMoving As Integer
Public PlayerDirection As Integer
Public Sub Player(ByVal Func As String)
If Func = "LOAD" Then
GridWorld(14, 14).ID = 0
PlayerTileX = 14
PlayerTileY = 14
PlayerX = GridWorld(PlayerTileX, PlayerTileY).X
PlayerY = GridWorld(PlayerTileX, PlayerTileY).Y - 48 'Subtract the offset since we created the player sheet like out tilesheet
ElseIf func = "REFRESH" Then
If PlayerDirection = 0 Then
If PlayerFrameDouble < 14 Then
PlayerFrameDouble += 1
Else
PlayerFrameDouble = 0
End If
PlayerFrame = PlayerFrameDouble \ 4
Else
If PlayerFrameDouble < 23 Then
PlayerFrameDouble += 1
Else
PlayerFrameDouble = 0
End If
PlayerFrame = PlayerFrameDouble \ 4
End If
ElseIf func = "MOVE" Then
If GridWorld(PlayerTargetTX, PlayerTargetTY).Blocked = 0 Then
If PlayerDirection = 1 Then
PlayerX += 1
ElseIf PlayerDirection = 3 Then
PlayerX -= 1
ElseIf PlayerDirection = 2 Then
PlayerY += 1
ElseIf PlayerDirection = 4 Then
PlayerY -= 1
End If
Else
PlayerDirection = 0
End If
PlayerTileX = PlayerX / GridWidth
PlayerTileY = PlayerY / GridWidth
If PlayerX = GridWorld(PlayerTargetTX, PlayerTargetTY).X And PlayerY = GridWorld(PlayerTargetTX, PlayerTargetTY).Y Then
PlayerDirection = 0
End If
End If
End Sub
So on the above code we created an instance for our player which spawns on tile (14,14) and gets the pixel position based on our grid. (Don't forget to add Player("LOAD") on the form load events) and (Player("MOVE") on our Timer_Tick events)
Then we created a frame sequencer (different for idle and moving) and slowed it down by dividing a second variable.
And lastly we created a direction identifier which changes the pixel X,Y of the character if the next block is walkable.
For rendering the character on screen I changed the SoftRender("DRAW") code to the following.
Player("REFRESH")
For Y = 0 To MaxGridY
For X = 0 To MaxGridX
QRect = New Rectangle(GridWorld(X, Y).ID * 24, 0, 24, 72) 'We select the tile (From Tile ID - X position and Width and Height)
TestDrawingB = New TextureBrush(TestDrawingS, QRect)
TestDrawingB.TranslateTransform(GridWorld(X, Y).X, GridWorld(X, Y).Y - 48) 'Subtracting our tilemap offset
TRect = New Rectangle(GridWorld(X, Y).X, GridWorld(X, Y).Y - 48, 24, 72)
TestDrawingB.ScaleTransform(1, 1)
Gs.FillRectangle(TestDrawingB, TRect)
TestDrawingB.Dispose()
If Y = PlayerTileY And X = PlayerTileX Then
If PlayerDirection <> 0 Then
PlayerMoving = 3
Else
PlayerMoving = 0
End If
QRect = New Rectangle((PlayerMoving + PlayerFrame) * 24, 0, 24, 72) 'We select the animation frame
TestPlayerB = New TextureBrush(TestPlayerS, QRect)
TestPlayerB.TranslateTransform(PlayerX, PlayerY - 48) 'Subtracting our tilemap offset
TRect = New Rectangle(PlayerX, PlayerY - 48, 24, 72)
TestPlayerB.ScaleTransform(1, 1)
Gs.FillRectangle(TestPlayerB, TRect)
TestPlayerB.Dispose()
End If
Next
Next
Dim fontT As New Font("Arial", 12)
Gs.DrawString(PlayerTileX & "," & PlayerTileY & " | " & PlayerTargetTX & "," & PlayerTargetTY, fontT, Brushes.Black, 10, 10)
Now when pressing <WASD> the character will move till the next tile is reached, depending which key we pressed. If the next tile is a tree or a rock it won't move.
Animation of the year award |
Comments
Post a Comment