Results 1 to 4 of 4

Thread: [VB6 & VB 5]Hex Grid Auto-Navigation

Threaded View

  1. #1

    Thread Starter
    Fanatic Member technorobbo's Avatar
    Join Date
    Dec 2008
    Location
    Chicago
    Posts
    864

    [VB6 & VB 5]Hex Grid Auto-Navigation

    Goes from Point A to Point B in a Hex Lattice and avoid obstacles.

    1 form - paste code and run.

    Code:
    Option Explicit
    Private Type COORD
        x As Long
        y As Long
    End Type
    Private Declare Function GetTickCount& Lib "kernel32" ()
    Private Declare Function GetRgnBox Lib "gdi32" (ByVal hRgn As Long, lpRect As RECT) As Long
    Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
    Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
    Private Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long
    Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As Any, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
    Private Declare Function Polygon Lib "gdi32" (ByVal hdc As Long, lpPoint As Any, ByVal nCount As Long) As Long
    Private Declare Function FillRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long, ByVal hbrush As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Const ALTERNATE = 1
    Const WINDING = 2
    Const BLACKBRUSH = 4
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Enum Logic
        Origin = 1
        Target = 2
        Victory = 3
        Idle = 4
        Init = 5
        quit = 6
        Defeat = 7
        Lattice = 8
    End Enum
    Dim hRgn() As Long, Think As Logic, FindPath As RECT, GameOn As Boolean
    Dim LastPath() As Boolean, TailCount As Integer, Tailend As COORD
    Dim DeadEnds() As Boolean
    Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyEscape Then Think = quit
    If KeyCode = vbKeyR Then Think = Init
    If KeyCode = vbKeyL Then Think = Lattice
    End Sub
    Private Sub Form_Load()
    Randomize
    Me.KeyPreview = True
    Me.WindowState = vbMaximized
    Me.ScaleMode = vbPixels
    Me.FillStyle = 0
    Me.Show
    DoEvents
    Me.AutoRedraw = True
    MakeLattice
    Me.Refresh
    Me.AutoRedraw = False
    Think = Init
    GameOn = True
    GameLoop
    Unload Me
    End Sub
    Private Sub MakeLattice()
    Dim poly(1 To 6) As COORD, NumCoords As Long
    Dim pi As Double, i As Double, j As Integer, latX As Double, x As Integer
    Dim hexrad As Double, INC As Double, latY As Double, y As Integer
    pi = Atn(1) * 4
    NumCoords = 6
    'PRECOMP
    hexrad = Me.ScaleWidth / 40
    INC = pi / 3
    latX = Cos(INC) * hexrad
    latY = Sin(INC) * hexrad
    ReDim hRgn(0 To Me.ScaleWidth / (hexrad + latX * 0.75), 0 To Me.ScaleHeight / (hexrad + latY * 0.75))
    For y = 0 To UBound(hRgn, 2) 'Me.ScaleHeight / hexrad
        For x = 0 To UBound(hRgn, 1) 'Me.ScaleWidth / 50
            For j = 1 To 6
                i = j * INC
                poly(j).x = Cos(i) * hexrad + latX * x + hexrad * x
                poly(j).y = Sin(i) * hexrad + latY * (x And 1) + y * latY * 2
            Next
    
                Me.FillColor = Choose(Int(Rnd() * 4) + 1, RGB(192, 192, 0), _
                    RGB(64, 255, 64), RGB(192, 192, 0), RGB(192, 192, 0))
    
            Polygon Me.hdc, poly(1), NumCoords
            hRgn(x, y) = CreatePolygonRgn(poly(1), NumCoords, ALTERNATE)
        Next
    Next
    End Sub
    Sub DeleteLattice()
    Dim x As Integer, y As Integer
    
    For y = 0 To UBound(hRgn, 2)
        For x = 0 To UBound(hRgn, 1)
            DeleteObject hRgn(x, y)
        Next
    Next
    End Sub
    Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim x1 As Integer, y1 As Integer, found As Boolean
    Dim fx As Integer, fy As Integer, hbrush As Long
    If Think = Idle Or Think = Origin Then
        If GetPixel(Me.hdc, x, y) <> RGB(192, 192, 0) Then Exit Sub
            found = False
            For y1 = 0 To UBound(hRgn, 2)
                For x1 = 0 To UBound(hRgn, 1)
                    If PtInRegion(hRgn(x1, y1), x, y) <> 0 Then
                        found = True
                        fy = y1
                        fx = x1
                        Exit For
                    End If
                    If found Then Exit For
                Next
            Next
        If Think = Idle Then
            FindPath.Left = fx
            FindPath.Top = fy
            Me.Cls
            hbrush = CreateSolidBrush(RGB(255, 0, 0))
            FillRgn Me.hdc, hRgn(fx, fy), hbrush
            DeleteObject hbrush
            Think = Origin
            Me.Caption = "Origin Set"
        ElseIf Think = Origin Then
            FindPath.Right = fx
            FindPath.Bottom = fy
            Think = Target
            Me.Caption = "Destination Set, Navigating - Press R to reset."
        End If
    End If
    End Sub
    Sub GameLoop()
    Do While GameOn
        Select Case Think
            Case Origin
                DoEvents
            Case Target
                plotpath
                DoEvents
            Case Victory
                MsgBox "I'm There."
                Me.Caption = "Found Target!!!!!"
                Think = Idle
            Case Idle
                DoEvents
            Case Init
                Me.Cls
                Me.Caption = "Pick a Starting Brown Hex - Or L to for new lattice"
                Think = Idle
            Case quit
                GameOn = False
            Case Defeat
                MsgBox "stuck"
                Me.Caption = "I'm Lost"
                Think = Idle
            Case Lattice
                DoEvents
                DeleteLattice
                Me.AutoRedraw = True
                MakeLattice
                Me.Refresh
                Me.AutoRedraw = False
                Think = Init
        End Select
    Loop
    End Sub
    Function CheckBlock(ByVal x1 As Integer, ByVal y1 As Integer) As Boolean
    Dim box As RECT, color As Long
    If x1 < 0 Or x1 > UBound(hRgn, 1) Then
        CheckBlock = False
        Exit Function
    ElseIf y1 < 0 Or y1 > UBound(hRgn, 2) Then
        CheckBlock = False
        Exit Function
    ElseIf DeadEnds(x1, y1) Then
        CheckBlock = False
        Exit Function
    ElseIf LastPath(x1, y1) Then
        CheckBlock = False
        Exit Function
    End If
    GetRgnBox hRgn(x1, y1), box
    color = GetPixel(Me.hdc, (box.Left + box.Right) / 2, (box.Top + box.Bottom) / 2)
    If color = RGB(192, 192, 0) Then
        CheckBlock = True
    Else
        CheckBlock = False
    End If
    End Function
    Sub plotpath()
    Dim DONE As Boolean, PlotX As Integer, Ploty As Integer
    Dim hbrush As Long, pause As Long, x1 As Integer, y1 As Integer
    Dim x As Single, OE As Integer, i As Integer, lost As Boolean
    Dim Sort(1 To 6, 0 To 1) As Single, sTmp As COORD, tmp As Single
    
    Const Index = 0
    Const Dist = 1
    
    Erase LastPath
    ReDim LastPath(0 To UBound(hRgn, 1), 0 To UBound(hRgn, 2))
    Erase DeadEnds
    ReDim DeadEnds(0 To UBound(hRgn, 1), 0 To UBound(hRgn, 2))
    
    LastPath(FindPath.Left, FindPath.Top) = True
    TailCount = 0
    Tailend.x = FindPath.Left
    Tailend.y = FindPath.Top
    
    Do While Not DONE
        'sell the drama -LET'S SLOW IT DOWN
        pause = GetTickCount + 50
        While pause > GetTickCount
            DoEvents
        Wend
        'get bearings
        PlotX = Sgn(FindPath.Right - FindPath.Left)
        Ploty = Sgn(FindPath.Bottom - FindPath.Top)
        OE = FindPath.Left And 1
        'think
        'Check Arrive
        If PlotX = 0 And Ploty = 0 Then
            Think = Victory
            DONE = True
        Else
            lost = True
            For i = 1 To 6
               If CheckBlock(NPair(OE, i).x + FindPath.Left, _
                   NPair(OE, i).y + FindPath.Top) Then
                   sTmp.x = FindPath.Left + NPair(OE, i).x
                   sTmp.y = FindPath.Top + NPair(OE, i).y
                   x = Sqr((FindPath.Right - sTmp.x) ^ 2 + (FindPath.Bottom - sTmp.y) ^ 2)
                   Sort(i, Index) = i
                   Sort(i, Dist) = x
                   lost = False
               Else
                   Sort(i, Index) = i
                   Sort(i, Dist) = 65535
               End If
            Next
            If lost Then
                Erase LastPath
                ReDim LastPath(0 To UBound(hRgn, 1), 0 To UBound(hRgn, 2))
                LastPath(FindPath.Left, FindPath.Top) = True
                DeadEnds(FindPath.Left, FindPath.Top) = True
            Else
                'sort
                i = 1
                While i < 7
                    If i = 1 Then
                        i = i + 1
                    ElseIf Sort(i - 1, Dist) <= Sort(i, Dist) Then
                        i = i + 1
                    Else
                        tmp = Sort(i, Dist): Sort(i, Dist) = Sort(i - 1, Dist): Sort(i - 1, Dist) = tmp
                        tmp = Sort(i, Index): Sort(i, Index) = Sort(i - 1, Index): Sort(i - 1, Index) = tmp
                        i = i - 1
                    End If
                Wend
                'use closest
                FindPath.Left = FindPath.Left + NPair(OE, Sort(1, Index)).x
                FindPath.Top = FindPath.Top + NPair(OE, Sort(1, Index)).y
                
                LastPath(FindPath.Left, FindPath.Top) = True
                TailCount = (TailCount + 1) Mod 100
                If TailCount = 0 Then
                    LastPath(Tailend.x, Tailend.y) = False
                    Tailend.x = FindPath.Right
                    Tailend.y = FindPath.Bottom
                End If
            End If
        End If
        If Not DONE Then
            Me.Cls
            hbrush = CreateSolidBrush(RGB(255, 0, 0))
            x1 = FindPath.Left
            y1 = FindPath.Top
            FillRgn Me.hdc, hRgn(x1, y1), hbrush
            DeleteObject hbrush
        End If
        If Think = quit Or Think = Init Then DONE = True
    Loop
    End Sub
    Private Function NPair(OE As Integer, ByVal nav As Integer) As COORD
    'LATTICE lOGIC
            NPair.x = Choose(nav, -1, 0, -1, 1, 0, 1)
            NPair.y = Choose(nav, -1 + OE, -1, 0 + OE, -1 + OE, 1, 0 + OE)
    End Function
    Private Sub Form_Unload(Cancel As Integer)
    GameOn = False
    DeleteLattice
    End Sub

    Post Edit - fixed some transposed numbers on the logic table.
    Last edited by technorobbo; Apr 22nd, 2009 at 08:28 PM.
    Have Fun,

    TR
    _____________________________
    Check out my Alpha DogFighter2D Game Demo and Source code. Direct Download:http://home.comcast.net/~technorobbo/Alpha.zip or Read about it in the forum:http://www.vbforums.com/showthread.php?t=551700. Now in 3D!!! http://home.comcast.net/~technorobbo/AlPha3D.zip or read about it in the forum: http://www.vbforums.com/showthread.php?goto=newpost&t=552560 and IChessChat3D internet chess game

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width