Question Display Issue

james_h

Member
Joined
Aug 21, 2012
Messages
15
Programming Experience
Beginner
Hi Guys,

I am trying to make a dice roller that generates a random number which is all good.

The problem I am having is at the start of the code the picturebox should display a series of images

before finishing on the random number. I have a half second delay between displayed images, the delay is working

but the images are not displayed between each half second delay. After the delay time then the random number is displayed correctly???

Public Class frmDiceRoll

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRollDice.Click


        Dim diceroll As Integer
        Dim DiceNumber As System.Random


        'scroll through several different images with a half second delay between each image
        picRollDice.BackgroundImage = My.Resources.dice_3
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_6
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_4
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_1
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_2
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_1
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_5
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_6
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_1
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_4
        System.Threading.Thread.Sleep(500)
        picRollDice.BackgroundImage = My.Resources.dice_5


        'generate a random number between 1-6 and store in diceroll
        DiceNumber = New System.Random(My.Computer.Clock.TickCount)
        diceroll = CInt(DiceNumber.Next(1, 7))


        'display image based on dicerolls value
        Select Case diceroll
            Case 1
                picRollDice.BackgroundImage = My.Resources.dice_1
            Case 2
                picRollDice.BackgroundImage = My.Resources.dice_2
            Case 3
                picRollDice.BackgroundImage = My.Resources.dice_3
            Case 4
                picRollDice.BackgroundImage = My.Resources.dice_4
            Case 5
                picRollDice.BackgroundImage = My.Resources.dice_5
            Case 6
                picRollDice.BackgroundImage = My.Resources.dice_6
        End Select


    End Sub


End Class




Thanks for looking.
 
You should pretty much NEVER be calling Thread.Sleep on the UI thread. By doing so you are telling the UI thread to stop all processing, which includes responding to user input and updating the UI. Displaying your Images is part of updating the UI. If you want to change the Image in a PictureBox once every 500 ms then you should be using a Timer with its Interval set to 500 and making the change in the Tick event handler.

Other issues with your code include that fact that you are still creating the Random object inside a method, which you have been told more than once not to do. Also, don't access the same property of My.Resources more than once. In your code you are accessing My.Resources.dice_1 four times, which means that you are creating four Image objects that are all exactly the same. You should access the property once and once only, assigning the value to a variable and then using that variable over and over. It's exactly the same principle as the Random object. Create one object only and place it in a common location, then access it from that location multiple times.
 
You should pretty much NEVER be calling Thread.Sleep on the UI thread. By doing so you are telling the UI thread to stop all processing, which includes responding to user input and updating the UI. Displaying your Images is part of updating the UI. If you want to change the Image in a PictureBox once every 500 ms then you should be using a Timer with its Interval set to 500 and making the change in the Tick event handler.

Other issues with your code include that fact that you are still creating the Random object inside a method, which you have been told more than once not to do. Also, don't access the same property of My.Resources more than once. In your code you are accessing My.Resources.dice_1 four times, which means that you are creating four Image objects that are all exactly the same. You should access the property once and once only, assigning the value to a variable and then using that variable over and over. It's exactly the same principle as the Random object. Create one object only and place it in a common location, then access it from that location multiple times.

Yep fair call on the Random object :embarrassed: My Bad!!!


Public Class frmDiceRoll

    Private DiceNumber As System.Random

Correct? :nevreness:

Ok I shall work on getting the rest right. I'll be back!
 
That's the declaration but you're not creating the Random object. You have to make sure that you create only one Random object, so it makes sense to create that object where you declare the variable you want to assign it to.
 
That's the declaration but you're not creating the Random object. You have to make sure that you create only one Random object, so it makes sense to create that object where you declare the variable you want to assign it to.

mmmmm I really am not sure what you mean sorry?

Can you possibly show me the code as it should be written then I will be able to workout what it is you mean by that!!!

Very much appreciated
Kind Regards
 
I am sure that I am doing something completely wrong which i hope is obvious to you guys.

I have revised the code and it will step through the loop 5 times then stop displaying a message box each loop.
But while the message box is displaying the dice image is continuing to scroll through in the background.
If I comment out the message box it appears to just display 1 image only?

Public Class frmDiceRoll


    Private DiceNumber As System.Random
    Private dice1 As Image = My.Resources.dice_1
    Private dice2 As Image = My.Resources.dice_2
    Private dice3 As Image = My.Resources.dice_3
    Private dice4 As Image = My.Resources.dice_4
    Private dice5 As Image = My.Resources.dice_5
    Private dice6 As Image = My.Resources.dice_6




    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRollDice.Click




        Dim index As Integer


        'Start timer so that it runs this process every .2 of a second
        Timer1.Start()


        'Run through this process 5 times then stop
        For index = 1 To 5
            
            'Messagebox put in to test loop is working ok
            MsgBox("Message Box Shows " & index & " Times ")

            'Call Timer1_Tick
            Timer1_Tick(sender, e)
            
        Next


        'Stop the timer
        Timer1.Stop()


    End Sub


    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick


        Dim diceroll As Integer






            'generate a random number between 1-6 and store in diceroll
            DiceNumber = New System.Random(My.Computer.Clock.TickCount)
            diceroll = CInt(DiceNumber.Next(1, 7))


            'display image based on dicerolls value
            Select Case diceroll
                Case 1
                    picRollDice.BackgroundImage = dice1
                Case 2
                    picRollDice.BackgroundImage = dice2
                Case 3
                    picRollDice.BackgroundImage = dice3
                Case 4
                    picRollDice.BackgroundImage = dice4
                Case 5
                    picRollDice.BackgroundImage = dice5
                Case 6
                    picRollDice.BackgroundImage = dice6
        End Select
       
    End Sub
End Class


Thanks for the guidance
 
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

DiceNumber = New System.Random(My.Computer.Clock.TickCount)
This is no better than your first code. You are still creating a new Random instance each time Tick event is raised.
Timer1_Tick(sender, e)
DON'T do this! Event handlers are there for one reason only, to be called by the event owner object when the event is raised. If you want to call the same code from different places put that code in a method and call that method from each place. Don't mess with the event handlers.
 
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

DiceNumber = New System.Random(My.Computer.Clock.TickCount)

This is no better than your first code. You are still creating a new Random instance each time Tick event is raised.


I am happy to do this but I don't know how to go about doing this. Do I just put that up with the DiceNumber variable?

Private DiceNumber As System.Random = New System.Random(My.Computer.Clock.TickCount)

Is this what you mean???

Ok and don't mess with event handlers!!! Got it!!!
 
That is one way to do it, you can also use the short version, open both links in post 6 and read them this time.
 
Ok I am pretty sure I have got it right this time around.

Thankyou for your guidance, I think I am probably frustrating for you guys that get it, but I really appreciate your help and guidance.
Public Class frmDiceRoll
    'declare new random so only needs to be created once
    Public DiceNumber As New System.Random(My.Computer.Clock.TickCount) 'Please tell me this is right :o)
    Public diceroll As Integer
    Public ImageCount As Integer
    'Load Images into a variable so they only need to be loaded once
    Private dice1 As Image = My.Resources.dice_1
    Private dice2 As Image = My.Resources.dice_2
    Private dice3 As Image = My.Resources.dice_3
    Private dice4 As Image = My.Resources.dice_4
    Private dice5 As Image = My.Resources.dice_5
    Private dice6 As Image = My.Resources.dice_6


    Sub selectImage()


        'Add 1 to the ImageCount variable each time code ran
        ImageCount = ImageCount + 1
        'Create a random number from 1-6 and store in diceroll variable
        diceroll = CInt(DiceNumber.Next(1, 7))
        'Display a random image based on the case selection
        Select Case diceroll
            Case 1
                picRollDice.BackgroundImage = dice1
            Case 2
                picRollDice.BackgroundImage = dice2
            Case 3
                picRollDice.BackgroundImage = dice3
            Case 4
                picRollDice.BackgroundImage = dice4
            Case 5
                picRollDice.BackgroundImage = dice5
            Case 6
                picRollDice.BackgroundImage = dice6
        End Select
        'Stop the timer and reset ImageCount variable
        If ImageCount = 10 Then
            Timer1.Stop()
            ImageCount = 0
        End If




    End Sub




    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRollDice.Click


        'Start timer
        Timer1.Start()


        


    End Sub




    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick


        'call the selectImage sub
        selectImage()


    End Sub


End Class


One problem with the GUI is that it shows whitespace to the right hand side even though I have set teh form size to the same as the picturebox.
How would I go about fixing this???
ScreenShot.gif
 
Last edited:
Any help here with this issue guys?
 
Any help on the display issue guys??????
 
Back
Top