Strategy game, handling openGL calls, displaying text (Post #14 / Strategy game #5)

Before we dive further into the strategy game we need to optimize our UI, by lowering our openGL calls. On this post after performance we'll cover map resizing and displaying text on screen (in order to fill that nice new user interface from last post).

 Optimizing performance

I'll add some lines of code in order to optimize performance (by only drawing tiles that are visible to the screen). Now with our UI (I created mine to be 140 pixels and drawn x2 so my screen visible tiles will be the ones that are inside X values (0 to Screen_width - 140x2) and Y values (0 to Screen_height). And in order to test this we'll add the same clause in the mini-map where we'll draw all of the tiles but tint the ones that don't show.

Doing so should give us steady fps even in extra large maps with 500x500 tiles.

If (GridWorld(X, Y).SX + OffSetX) > -GridWidth And (GridWorld(X, Y).SX + OffSetX) < (ScreenWidth - 240) And (GridWorld(X, Y).SY + OffSetY) >= -GridHeight And (GridWorld(X, Y).SY + OffSetY) < ScreenHeight + 40 Then

'Drawing

End if

Tinting the ones outside the screen should show on our mini-map like this.

Zooming in and out

In order to add zoom in/out functionality we need to create a new sub which will change our map array X,Y values (only for our isometric projection) and of course add a scaling float variable which will resize the end result for our drawing calls.

Let's do some math for this.

In order to add this functionality we declare a Scaling float, (Public ZoomVar As Single = 1.0F), and create a sub to call when we press to zoom in/out.

 Public Sub Grid_Resize(ByVal Func As String)
        If Func = "Minus" Then 'When we zoom out
            If ZoomVar > 0.6F Then
                ZoomVar -= 0.2F
            End If
        ElseIf Func = "Plus" Then 'When we zoom in
            If ZoomVar < 2.4F Then
                ZoomVar += 0.2F
            End If
        End If

'Re-arrange our grid based on our isometric math and multiply it by our zoom float  

      For X = 0 To MaxGridX
            For Y = 0 To MaxGridY
                GridWorld(X, Y).SX = ((X - Y) * GridWidth / 2) * ZoomVar
                GridWorld(X, Y).SY = ((X + Y) * GridHeight / 2) * ZoomVar
            Next
        Next
    End Sub

And on our projection drawing we'll change the target rectangle to the following

dRect = New Rectangle(GridWorld(X, Y).SX + OffSetX, GridWorld(X, Y).SY + OffSetY - 8, 64 * ZoomVar, 40 * ZoomVar) 'we just multiply the projection width and height with our float

And the last but hardest part of our code is the mouse over tile detection math which again is found by reversing the equations we used when we created our tile-map.

    Public Sub GLMouseMove(ByVal X1 As Integer, ByVal Y1 As Integer)
        Dim X, Y As Integer
        X = (X1 - OffSetX)
        Y = (Y1 - OffSetY)
        GridPX = (Y + X / 2) / (GridHeight * ZoomVar)
        GridPY = GridPX - (X) / (GridHeight * ZoomVar)
        FOVGridTemporary()
    End Sub

Just call Grid_Resize (with Plus or Minus) to zoom in/out and you'll see that your mouse moving will identify the tile when resizing. You will also notice a visible change when you zoom in/out on our X,Y coordinates. I tweaked my code like this to make it smoother

    'Tweaking Offset on Minus
    OffSetX += 50
    OffSetY += 220

    'Tweaking Offset on Plus
    OffSetX -= 50
    OffSetY -= 220

 Displaying text on openGL

Now that we created our fonts sprite sheet (see post #12 about the way to create it), we need a way to display a text since we can't call all fonts one by one whenever we want to write something on screen.

Our system-y fonts sprite sheet

The rendering call is the following, which I will explain right under

    Public Sub DrawText(ByVal Text As String, ByVal X As Integer, ByVal Y As Integer, ByVal Size As Single, ByVal OffsZ As Single, ByVal R As Single, ByVal G As Single, ByVal B As Single, ByVal A As Single)
        Dim MaxTextArrLng As Integer = Text.Length
        If Text.Length = 0 Then 'Debug just in case the sub gets called with no text
            Text = " "
            MaxTextArrLng = 1
        End If
        Dim TextARR(MaxTextArrLng) As Point
        Dim TextARRLength As Integer
        Dim I As Integer
        Dim ILength As Integer
        ILength = MaxTextArrLng
        For I = 0 To (ILength - 1)
            TextARR(I).X = Asc(Text(I)) Mod 10
            TextARR(I).Y = (Asc(Text(I)) \ 10) - 3
        Next
        TextARRLength = ILength
        For I = 0 To TextARRLength
            sRect = New Rectangle(TextARR(I).X * 8, TextARR(I).Y * 8, 8, 8)
            dRect = New Rectangle(X + (8 * Size * I), Y, 8 * Size, 8 * Size)
            DrawTexturedQuad(sRect, dRect, 80, 80, 4, OffsZ, R, G, B, A)
        Next
    End Sub

As you can see it's the same process we use to draw a tile, only now it's getting automated for the characters in our string to draw, while using Asc to get the position of our char.
Now let's test our new drawing text sub. (I'll make a call to it while drawing our mouse over tile for testing reasons)

That was it! Now we can draw text on our map too. It's a pretty easy process and you can easily (Not as easy as picking fonts to be honest..) modify your text sheet depending on how you want your text to look.

Size when you call the sub refers to font size, and RGBA (Red, Green, Blue, Alpha) is included on the call.

With this last code part, I think we finished our basic drawing calls and we can dive deeper into the game's more complex and more fun aspects.


Comments