Hi all,

I'm working my way through Deitel & Deitel's Visual Basic 2005. How to Program (please note that I'm a complete newbie to computing! ) and I'm sort of stuck with an exercise where I should create a bouncing ball application with multithreading (Ex. 15.3).

So far I've written enough code to move a ball horizontally and make it bounce. But I'm not sure I've used mutithreading correctly (this is what I'm really interested in). The ball is flickering all the time. Before going on with the exercise (i.e. moving the ball also along the y axis), I'd like to know if I've used mutithreading correctly. Can anyone help???

Thanks a million!
Beowulf Geata

Here is the code for class Ball:

Code:
Imports System.Threading

Public Class Ball

    Private colorValue As Color
    Private radiusValue As Single

    Private xValue As Single
    Private yValue As Single

    Private dxValue As Single 'x velocity
    Private dyValue As Single 'y velocity

    Private panelWidthValue As Integer
    Private panelHeightValue As Integer


    Public Sub New(ByVal BallColor As Color, ByVal BallRadius As Single, _
        ByVal BallXValue As Single, ByVal BallYValue As Single, _
        ByVal BalldX As Single, ByVal BalldY As Single, _
        ByVal BallPanelWidth As Integer, ByVal BallPanelHeight As Integer)

        Colour = BallColor
        Radius = BallRadius
        xValue = BallXValue
        yValue = BallYValue
        dX = BalldX
        dY = BalldY
        PanelWidth = BallPanelWidth
        PanelHeight = BallPanelHeight

    End Sub

    Public Property Colour() As Color
        Get
            Return colorValue
        End Get
        Set(ByVal value As Color)
            colorValue = value
        End Set
    End Property

    Public Property Radius() As Single
        Get
            Return radiusValue
        End Get
        Set(ByVal value As Single)
            radiusValue = value
        End Set
    End Property

    Public Property dX() As Single
        Get
            Return dxValue
        End Get
        Set(ByVal value As Single)
            dxValue = value
        End Set
    End Property

    Public Property dY() As Single
        Get
            Return dyValue
        End Get
        Set(ByVal value As Single)
            dyValue = value
        End Set
    End Property

    Public ReadOnly Property X() As Single
        Get
            Return xValue
        End Get
    End Property

    Public ReadOnly Property Y() As Single
        Get
            Return yValue
        End Get
    End Property

    Public Property PanelWidth() As Integer
        Get
            Return panelWidthValue
        End Get
        Set(ByVal value As Integer)
            panelWidthValue = value
        End Set
    End Property

    Public Property PanelHeight() As Integer
        Get
            Return panelHeightValue
        End Get
        Set(ByVal value As Integer)
            panelHeightValue = value
        End Set
    End Property

    Public Sub Run() 'makes ball move

        While True

            SyncLock Me

                Thread.Sleep(20)

                If (xValue + Radius >= PanelWidth) Or xValue = 0 Then
                    dX = -dX
                End If

                xValue += dX

            End SyncLock

        End While

    End Sub

End Class
Here is the code for the Form:

Code:
Imports System.Threading

Public Class FrmBallTest

    Private ball As Ball

    Delegate Sub RefreshDelegate()

    Private Sub FrmBallTest_MouseClick(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) _
        Handles pnlBall.MouseClick

        'colour, radius, x, y, x-velociy, y-velocity, panel width, panel height
        ball = New Ball(Color.Blue, 15, e.X, e.Y, 1, 1, pnlBall.Width, pnlBall.Height)

        Dim drawThread As New Thread(New ThreadStart(AddressOf Me.Draw))
        drawThread.Start()

        Dim runThread As New Thread(New ThreadStart(AddressOf ball.Run))
        runThread.Start()


    End Sub


    Private Sub FrmBallTest_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) _
        Handles MyBase.Load

        pnlBall.Width = 300
        pnlBall.Height = 300

    End Sub

    Private Sub FrmGUIThreads_FormClosing(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.FormClosingEventArgs) _
        Handles MyBase.FormClosing

        System.Environment.Exit(System.Environment.ExitCode)

    End Sub

    Private Sub Draw() 'draws ball every 20 ms

        While True

            SyncLock Me

                Thread.Sleep(20)

                Dim b As Graphics = pnlBall.CreateGraphics()
                b.FillEllipse(New SolidBrush(ball.Colour), ball.X, ball.Y, _
                    ball.Radius, ball.Radius)
                b.Dispose()

            End SyncLock


            SyncLock Me
                pnlBall.Invoke(New RefreshDelegate(AddressOf pnlBall.Refresh))
            End SyncLock


        End While

    End Sub


End Class