Search code examples
.netvb.netcollision

VB.NET How to detect a collision in a maze


I'm building a maze application in visual basic. The game relies on two variables, X and Y which are integers. There's a timer which basically invalidates the whole form for a redraw. Now my question is, that there are various squares and rectangles dotted around the form. How would I create a handler, or something as such to detect if the square that the form draws is touching these objects?

Code:

Public Class Form1
    Const W As Integer = 35 'Width
    Const H As Integer = 35 'Height

    Dim X As Integer
    Dim Y As Integer

    Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        'Handles if a key is pressed
        Select Case e.KeyCode
            Case Keys.Up
                Y -= 2
            Case Keys.Down
                Y += 2
            Case Keys.Left
                X -= 2
            Case Keys.Right
                X += 2

            Case Keys.Escape
                Me.Close()
        End Select
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Text = "Maze"
        TmrRedraw.Start()
        MsgBox("Press ESC to quit")
        Cursor.Position = Me.Location
    End Sub

    Private Sub TmrRedraw_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TmrRedraw.Tick
        If CollisionDetect() = False Then
            Me.Invalidate()
            CheckForWin()
        End If
    End Sub

    Private Function CollisionDetect()
        Dim Collision As Boolean = False

        'Here is where the problem lies 


        Return Collision
    End Function

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        e.Graphics.FillRectangle(Brushes.Blue, X, Y, W, H)

    End Sub

    Private Sub CheckForWin()
        Dim WinSqX As Integer = WinSquare.Location.X
        Dim WinSqY As Integer = WinSquare.Location.Y

        If X = WinSqX And Y = WinSqY Then

            TmrRedraw.Stop()
            MsgBox("Congratulations! You won!")
            Me.Close()
        End If


    End Sub
End Class

Oh yes - the player must use the arrow keys to change the X and Y, and when it redraws, it will move.

Thanks


Solution

  • I don't see the need for the timer in your example since you just need to invalidate whenever the user is pressing the keyboard.

    For object collision, you would need a list of objects that have their rectangle coordinates, and then just test for an intersection:

    Public Class Form1
      Dim block As New Rectangle(0, 0, 35, 35)  
      Dim listOfThings As New List(Of Rectangle)
    
      Public Sub New()
        InitializeComponent()
        Me.DoubleBuffered = True
    
        listOfThings.Add(New Rectangle(40, 40, 35, 35))
      End Sub
    
      Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyDown
        Select Case e.KeyCode
          Case Keys.Up
            MoveBlock(0, -2)
          Case Keys.Down
            MoveBlock(0, 2)
          Case Keys.Left
            MoveBlock(-2, 0)
          Case Keys.Right
            MoveBlock(2, 0)
          Case Keys.Escape
            Me.Close()
        End Select
      End Sub
    
      Private Sub MoveBlock(ByVal moveX As Integer, ByVal moveY As Integer)
        block.X += moveX
        block.Y += moveY
    
        For Each r As Rectangle In listOfThings
          If r.IntersectsWith(block) Then
            MessageBox.Show("Game Over")
          End If
        Next
    
        Me.Invalidate()
      End Sub
    
      Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
        e.Graphics.Clear(Color.White)
    
        For Each r As Rectangle In listOfThings
          e.Graphics.DrawRectangle(Pens.Red, r)
        Next
    
        e.Graphics.FillRectangle(Brushes.Blue, block)
      End Sub
    End Class