1. Computing & Technology

Discuss in my forum

GDI+ Graphics in Visual Basic 2005 .NET

Peter's Solution

By , About.com Guide

As promised, Peter's solution is a step up, and there are some important improvements, including:

  • the use of a structure to contain the parameters for each ring the program draws
    (Peter wanted more control than a loop provides)
  • more sophisticated trigonometry
  • the use of a Panel component to contain the graphics

Peter's solution is also integrated into a larger program so it won't run without the rest of his design, and there are a few undefined terms in it. But it's still very worth studying to understand GDI+. Here's his solution in his own words ...

First I defined a structure ...

Public Structure MapStructure
  Dim PenColor As Color   ' Color to draw the circle
  Dim PenWidth As Integer   ' Width of pen
  Dim CenterX As Single   ' X coordinate of center
  Dim CenterY As Single   ' Y coordinate of center
  Dim CircleSize As Integer ' Size of circle
  Dim Visible As Boolean   ' True if this circle is to be plotted, False if not
  Dim Fill As Boolean     ' True if this circle is to be filled, False if not
End Structure

... and a suitably global variable ...

Private ShowLines As Boolean
' True if show the non-adjacent connections
' False otherwise

Then I declared an array

Public MapArray(MaxRoom) _
  As MapStructure

I computed the semi-constant stuff once, in the following loop. (Note the use of an old FORTRAN trick: 4*Atan(1) = PI, so I can reduce your computation of SegAngle to a much simpler expression)

  SegAngle = Math.Atan(1) / 4
  Radius = ((panMap.Height + panMap.Width) / 4) - 80
  For I = 0 To MaxRoom
    RadAngle = I * SegAngle

    With MapArray(I)
      .PenWidth = 3
      .CenterX = Radius * (1 + Math.Sin(RadAngle)) + 60
      .CenterY = Radius * (1 - Math.Cos(RadAngle)) + 60
      .CircleSize = 46
    End With
  Next I

The "variable" information in MapArray is computed here:

Private Sub ReadMap()
  Dim I As Integer
  Dim J As Integer
  Dim LocalColorNumber As Integer
  Dim LowerLimit As Integer
  Dim Upperlimit As Integer
  panMap.Visible = True

  If GameObject(Nou.Map, Obj.Value) > 0 Then
    For I = 0 To MaxRoom
      With MapArray(I)
        .PenColor = ColorList(2 + FNRanNr(13)).Value
        .Visible = True
        .Fill = ((I Mod 2) = 0)
      End With
    Next I
    ShowLines = False
  Else
    If GameObject(Nou.Chxlrth, Obj.Location) = Obj.Carried Then
      LowerLimit = 0
      Upperlimit = MaxRoom
    Else
      LowerLimit = CurLocation - 3 * (Magic + 1)
      If LowerLimit < 0 Then LowerLimit = 0
      Upperlimit = CurLocation + 3 * (Magic + 1)
      If Upperlimit > MaxRoom Then Upperlimit = MaxRoom
    End If
    For I = 0 To MaxRoom
      With MapArray(I)
        If ((I >= LowerLimit) AndAlso (I <= Upperlimit)) Then
          .Visible = True

          If I = CurLocation Then
            LocalColorNumber = 12
            ' Bright red for present location
          Else
            LocalColorNumber = 4
            ' Otherwise, dark red
          End If

          For J = 0 To MaxWall
            If Math.Abs( _
              Room(I, J, Roo.RoomNr)) = CurLocation Then
              LocalColorNumber -= 2
              ' Make color green if connection in
              ' some dimension to current location
              Exit For
            End If
          Next J

          .PenColor = ColorList(LocalColorNumber).Value
          .Fill = (I <= (-1 - TruePath))
        Else
          .Visible = False
        End If
      End With
    Next I
    ShowLines = True
  End If
  Call panMap.Refresh()
End Sub

©2012 About.com. All rights reserved.

A part of The New York Times Company.