# Visual Basic > Games and Graphics Programming > Game Demos >  [VB.Net]Plinko

## dday9

This is the source code and the .exe

*Features:*
Allows you to play the game Plinko

*Drawbacks:*
The collision against irregular objects is a little off.

*Notes:*
I plan on tweaking the drawback listed above, but I'm not going to lie... Detecting collision between two irregular objects is tough. You can't just use the objects bounds because bounds are of type 'rectangle' which just doesn't work.

*Project:*
plinko.zip

*Source Code:*
In order for the source to compile you'll need to add:
Three(3) panels. Named Panel1, pnl_Wall1, and pnl_Wall2One(1) timer. Named Timer1


vb.net Code:
Option Strict On
Option Explicit On
 Imports System.Drawing.Drawing2D
Public Class Form1
    Private bottom_container As New List(Of Panel)
    Private peg_conatiner As New List(Of Circle_Panel)
    Private coin As New Circle_Panel
    Private moving As Boolean = False
    Private move_x, move_y As Integer
    Private r As New Random
     Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If moving = False Then
            'I check for the coin.left/right -/+ 10 to make sure that the coin is in sight
            If e.KeyCode = Keys.Left AndAlso coin.Left - 10 > 0 Then
                coin.Left -= 10
            ElseIf e.KeyCode = Keys.Right AndAlso coin.Right + 10 < Panel1.Width Then
                coin.Left += 10
            ElseIf e.KeyCode = Keys.Space Then
                move_y = 5
                'Get if the current millisecond is even/odd to set if the coin falls left/right
                If CBool(DateTime.Now.Millisecond Mod 2) Then
                    move_x = 5
                Else
                    move_x = -5
                End If
                Timer1.Start()
                moving = True
            End If
        End If
    End Sub
     Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        'Set up the containers at the bottom
        'There's a couple of things I've done differently:
        '1)Loop from 1 - 5, reason is for the pnl.Left property. I didn't want to do 0 * 66 because that'd be 0
        '2)Set the pnl.Left = x * 66. The reason I did 66 is because I took the panel1.width(400) and divided it by 6. The reason for 6
        '             Is because if I did it by 5, the fifth pnl.Left would = Panel1.Width so it wouldn't show.
        For x As Integer = 1 To 5
            Dim pnl As New Panel
            With pnl
                .Size = New Size(10, 50)
                .BackColor = Color.SaddleBrown
                .Left = x * 66
                .Top = Panel1.Bottom - 50
            End With
             bottom_container.Add(pnl)
            Panel1.Controls.Add(pnl)
        Next
         'Set up the pegs
        'I loop from 1 -5 & 2 - 9 for the same reason as reason #1 for the containers at the bottom
        For x As Integer = 1 To 5
            For y As Integer = 2 To 9
                Dim peg As New Circle_Panel
                With peg
                    .Size = New Size(15, 15)
                    .BackColor = Color.Gainsboro
                     'I check if y is divisible by 2 to create a staggering effect
                    If CBool(y Mod 2) Then
                        .Left = CInt((x - 0.5) * 66)
                         If x = 5 Then
                            'Extra peg
                            'The reason we use an extra peg is so that the far right side isn't just a straight shot down
                            Dim newpeg As New Circle_Panel
                            With newpeg
                                .Size = New Size(15, 15)
                                .BackColor = Color.Gainsboro
                                .Left = CInt((6 - 0.5) * 66)
                                .Top = y * 38
                            End With
                            peg_conatiner.Add(newpeg)
                            Panel1.Controls.Add(newpeg)
                        End If
                    Else
                        .Left = x * 66
                    End If
                     .Top = y * 38
                End With
                 'Add to the list and to the panel's controls
                peg_conatiner.Add(peg)
                Panel1.Controls.Add(peg)
            Next
        Next
         'Set up the coin
        With coin
            .BackColor = Color.Gold
            .Size = New Size(25, 25)
            .Location = New Point(10, 5)
        End With
         Panel1.Controls.Add(coin)
     End Sub
     Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
         'Loop through each peg and check if the coin hits the peg
        For Each peg As Circle_Panel In peg_conatiner
            Dim gp As New GraphicsPath
            gp.AddEllipse(coin.Bounds)
            Dim gp2 As New GraphicsPath
            gp2.AddEllipse(peg.Bounds)
            If gp2.PathPoints.Any(Function(pt) gp.IsVisible(pt)) Then
                 move_x = -move_x
             End If
        Next
         'Loop through each 'border' at the bottom and check if the coin hits one of those
        For Each border As Panel In bottom_container
            If coin.Bounds.IntersectsWith(border.Bounds) Then
                move_x = -move_x
            End If
        Next
         'Check if the coin hits one of the walls docked to the left/right of Panel1
        If coin.Bounds.IntersectsWith(pnl_Wall1.Bounds) OrElse coin.Bounds.IntersectsWith(pnl_Wall2.Bounds) Then
            move_x = -move_x
        End If
         'If the coin is still above ground
        If coin.Bottom < Panel1.Bottom Then
             'Keep moving
            coin.Left += move_x
            coin.Top += move_y
        Else
             'Stop!
            Timer1.Stop()
            moving = False
            coin.Location = New Point(10, 5)
            'Random score from 0 - 5
            MessageBox.Show(r.Next(0, 6).ToString)
        End If
    End Sub
End Class
 Public Class Circle_Panel
    Inherits Panel
     Private Sub Circle_Panel_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        'Declare graphics path and set a rectangle
        Dim gPath As New GraphicsPath
        Dim rect As Rectangle = Me.ClientRectangle
         'Draw the border
        e.Graphics.DrawEllipse(New Pen(Brushes.Black, 3), rect)
         'Add the circle to the graphics path & set the region
        gPath.AddEllipse(rect)
        Me.Region = New System.Drawing.Region(gPath)
     End Sub
 End Class

----------


## Jacob Roman

When it comes to game programming, you should never use a Timer, especially in collision. Timers are bad. Instead use a managed game loop locked at 60 frames per second. The problem with timers is that the entire timer must fire every bit of code in them before another timer or another execution could be executed. Thats probably one reason why your collision is off.

----------

