Strategy game, field of view, fog of war, text sprite (Post #12 / Strategy game #3)

Now that we have created our map we can create a bit our UI and test how field of view and fog of war will work.

I'll break this post into 4 parts

  • Drawing a temporary UI Sprite Sheet and display a mini map on it
  • Applying a field of view (which will change based on explored map)
  • Creating a fog of war overlay which will change on what the player can actually see on the explored FOV 
  • Creating a separate font sheet (which we'll call for drawing text on a next post)

Drawing a temporary UI Sprite Sheet and display a mini map on it

Below you can see my temporary UI sprite sheet, pretty basic for now (just to test our mini-map projection, which will be on a square tile map (added mini tiles for it)
Since the size of the mini map box will be 264x264 (the UI sheet will be double the size), I made the tiles 8x8 pixels.

Then based on our Map size we'll resize the mini-map tiles projection.

A Call to our drawing function Draw_Calls("UI") (It's really rough since I didn't optimize my UI sheet, I just put the whole right side in the UI as a full the way you see it on the end result) You can make your UI sheet more parts, easily distinguishable and draw each one of them easier.

ElseIf func = "UI" Then

            sRect = New Rectangle(4, 8, 132, 5)
            dRect = New Rectangle(0, 0, ScreenWidth - 140 * 2, sRect.Height * 2)
            DrawTexturedQuad(sRect, dRect, 800, 548, 3, 1.0F, 1, 1, 1, 1)
            sRect = New Rectangle(4, 8, 132, 5)
            dRect = New Rectangle(0, (ScreenHeight - sRect.Height * 2), ScreenWidth - 140 * 2, sRect.Height * 2)
            DrawTexturedQuad(sRect, dRect, 800, 548, 3, 1.0F, 1, 1, 1, 1)
            sRect = New Rectangle(0, 8, 140, 540)
            dRect = New Rectangle(ScreenWidth - sRect.Width * 2, 0, sRect.Width * 2, sRect.Height * 2)
            DrawTexturedQuad(sRect, dRect, 800, 548, 3, 1.0F, 1, 1, 1, 1)
            sRect = New Rectangle(0, 8, 4, 540)
            dRect = New Rectangle(0, 0, sRect.Width * 2, sRect.Height * 2)
            DrawTexturedQuad(sRect, dRect, 800, 548, 3, 1.0F, 1, 1, 1, 1)

            For X = 0 To MaxGridX
                For Y = 0 To MaxGridY
                    sRect = New Rectangle(GridWorld(X, Y).ID * 8, 0, 8, 8)
                    dRect = New Rectangle(ScreenWidth - 140 * 2 + 4 * 2 + X * GridMiniSize, 5 * 2 + Y * GridMiniSize, GridMiniSize, GridMiniSize)
                    DrawTexturedQuad(sRect, dRect, 800, 548, 3, 1.0F, 1, 1, 1, 1)

                    If X = GridPX And Y = GridPY Then
                        DrawQuad(ScreenWidth - 140 * 2 + 4 * 2 + X * GridMiniSize, 5 * 2 + Y * GridMiniSize, GridMiniSize, GridMiniSize, 1.0F, 1.0F, 1, 0.4, 1)
                    End If
                Next
            Next

            'Rough Fix for minimap oversizing (Could debug why it's oversizing but...)
            sRect = New Rectangle(0, 8, 4, 540)
            dRect = New Rectangle(ScreenWidth - sRect.Width * 2, 0, sRect.Width * 2, sRect.Height * 2)
            DrawTexturedQuad(sRect, dRect, 800, 548, 3, 1.0F, 1, 1, 1, 1)

Declare Gridminisize and give it's value 264/MaxGrid (Our maps will be square in size, If you want them to have different width than height then you need to create GridMiniSize for X and Y and change the minimap accordingly)
 

Our end result should look like this. (The mouse tile can be shown with a different color on the map)

Applying a field of view (which will change based on explored map)

Since we haven't created our playing mechanics yet, I'll create the Field of view and the fog of war based on mouse moving.

 We add a FOV int16 on our gridworld struct and clear it to 0 when we generate our map. Based on it's value we draw our background and our mini-map (If gridworld(x,y).FOV = 1 then draw)

And now for testing purposes add the following sub to get called on a mouse move event.

    Public Sub FOVGridTemporary()
        Dim X, Y, Q As Integer
        Q = 1 'Refers to radius of Field of View to create - 1 is going to take -1 to +1 x and y around our mouse tile
        For Y = (GridPY - Q) To (GridPY + Q)
            For X = (GridPX - Q) To (GridPX + Q)
                If X > 0 And Y > 0 And X < MaxGridX And Y < MaxGridY Then
                    GridWorld(X, Y).FOV = 1
                End If
            Next
        Next
    End Sub

 This will result to the following (Yes I know my .gifs are bad)

Creating our fog of war based on our field of view and our reference point (mouse point)

Our fog of war will be a bit trickier along the way since we'll have to calculate it for all our map units, but for now we'll just calculate it based on our mouse point. Just change Q if you want a bigger field for visible radius.

    Public Sub FOVGridTemporary()
        Dim X, Y, Q As Integer
        Q = 1
        For Y = (GridPY - Q) To (GridPY + Q)
            For X = (GridPX - Q) To (GridPX + Q)
                If X > 0 And Y > 0 And X < MaxGridX And Y < MaxGridY Then
                    GridWorld(X, Y).FOV = 1
                End If
            Next
        Next
        For Y = 0 To MaxGridY
            For X = 0 To MaxGridX
                If X >= (GridPX - Q) And Y >= (GridPY - Q) And X <= (GridPX + Q) And Y <= (GridPY + Q) Then
                    GridWorld(X, Y).FOW = 1
                Else
                    GridWorld(X, Y).FOW = 0
                End If
            Next
        Next
    End Sub

And the change in our drawing code is that when we draw our tiles if they have FOW = 0

If GridWorld(X, Y).FOW = 1 Then
    DrawTexturedQuad(sRect, dRect, 1088, 160, 0, 1.0F, 1, 1, 1, 1)
Else
    DrawTexturedQuad(sRect, dRect, 1088, 160, 0, 1.0F, 0.4, 0.4, 0.4, 1)
End If

The RGB values go down for tiles in the Field of war (0) making the tiles appear darker, as shown below (have in mind that gifs are slowed down and the actual performance till now should be 60 fps even though we use immediate drawing mode - on small to medium maps that is. On the next post we'll optimize the immediate drawing mode just a bit)

Drawing a text sprite sheet to be able to draw text on our game.

In order to draw text on screen we'll create a sprite sheet like before but instead of tiles we'll have fonts that we'll call based on their ASCII code (We'll implement the code on the next post), here we'll prepare our sheet.

You can adjust your each font size maybe to 16x16 or 32x32 and change the code we'll implement if you want more nice looking fonts. Personally I like that retro feel on the fonts, that's why I used the system fonts to create my sheet.
Our algorithm will work the same way as our draw_textured_quad algorithm with the difference of auto-picking the source from ASCII code as mentioned above.

Comments