VB.net вопрос о тиковом таймере - PullRequest
3 голосов
/ 17 марта 2011

Я написал следующий код, чтобы построить базовую игру, в которой участвуют гонщики на двух автомобилях (randomgenerator) и позволяющие пользователю выбирать свои ставки на конечные результаты. Я где-то ошибся, потому что мои машины только мчатся на полпути, а затем застряли за линией старта, и программа продолжает повторять звуковой сигнал и messsagebox.show и добавляет результаты в поле «неверно». Я провел последние три дня, пытаясь выяснить, где я ошибся, и мне просто не хватает этого. Спасибо, что нашли время посмотреть на это. Я действительно ценю любые советы.

Единственный способ завершить приложение - нажать «Остановить отладку».

Screen shot of application

Option Explicit On
Option Strict On

Public Class MainForm

    Private Sub exitButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles exitButton.Click
        Me.Close()
    End Sub


    Private Sub MainForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'fills the list box with items, then selects the first item
        resultListBox.Items.Add("No guess")
        resultListBox.Items.Add("Tie")
        resultListBox.Items.Add("Red Car wins")
        resultListBox.Items.Add("White car wins")
        resultListBox.SelectedIndex = 0
    End Sub

    Private Sub startButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles startButton.Click
        raceTimer.Enabled = True

    End Sub

    Private Sub raceTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceTimer.Tick
        ' moves two cars from a starting line to a finish line on the form
        ' displays a message indicating the race results
        ' calculates and displays the number of times the user selects the
        ' correct race result from the resultlistbox, and the number
        ' of times the user selects an incorrect race result

        Dim randomgenerator As New Random
        Dim whitenewlocation As Integer
        Dim rednewlocation As Integer
        Dim raceresult As String
        Dim userchoice As String
        Dim finishline As Integer = finishTextBox.Left + 1
        Static numbercorrect As Integer
        Static numberincorrect As Integer

        ' save the user's list box selection, then disable the list box
        userchoice = resultListBox.SelectedItem.ToString
        resultListBox.Enabled = False

        'calculate the new location of each picture box's right border
        ' don't allow the right border to go beyond the finish line
        whitenewlocation = whitePictureBox.Right + randomgenerator.Next(0, 11)
        If whitenewlocation > finishline Then
            whitenewlocation = finishline
        End If
        rednewlocation = redPictureBox.Right + randomgenerator.Next(0, 11)
        If rednewlocation > finishline Then
            rednewlocation = finishline
        End If

        'move each picture box toward the finish line
        whitePictureBox.SetBounds(whitenewlocation - whitePictureBox.Width, 0, 0, 0, BoundsSpecified.X)
        redPictureBox.SetBounds(rednewlocation - redPictureBox.Width, 0, 0, 0, BoundsSpecified.X)

        'the following selection structure is processed only when at least
        ' one of the picture boxes is at the finish line
        If whitePictureBox.Right = finishline _
            OrElse redPictureBox.Right = finishline Then
            'disable the timer
            raceTimer.Enabled = False
        End If

        'sound a beep to indicate the end of the race
        For x As Integer = 1 To 5
            Console.Beep(100, 100)
        Next x

        'store the result of the race in a variable
        If whitenewlocation = rednewlocation Then
            raceresult = "Tie"
        ElseIf whitenewlocation > rednewlocation Then
            raceresult = "White car wins"
        Else
            raceresult = "red car wins"
        End If

        'display the race results
        MessageBox.Show("Race Over!" & ControlChars.NewLine & raceresult, _
        "Car Race", MessageBoxButtons.OK, MessageBoxIcon.Information)

        'move the picture boxes back to the starting line
        whitePictureBox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)
        redPictureBox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)


        'if the user did not want to guess the race results, then
        'don't update or display the counter values; otherwise,
        'compare the race results to the user's selection and update
        ' the appropriate counter, then display both counter values
        If userchoice <> "no guess" Then
            If raceresult = userchoice Then
                numbercorrect = numbercorrect + 1
            Else
                numberincorrect = numberincorrect + 1
            End If
            correctLabel.Text = Convert.ToString(numbercorrect)
            incorrectLabel.Text = Convert.ToString(numberincorrect)
        End If

        'enable the list box
        resultListBox.Enabled = True
    End Sub
End Class

1 Ответ

1 голос
/ 17 марта 2011

Ваш таймер делает все на каждом тике. Код, который обрабатывает конец гонки, обрабатывается каждый тик таймера. Он должен быть заключен в if-логику, которая обрабатывает конец гонки.

Все, что после комментария «прозвучит звуковой сигнал, указывающий на конец гонки», должно быть в проверке конца гонки:

If whitePictureBox.Right = finishline  OrElse redPictureBox.Right = finishline Then
    'put all logic of the "ending" of the race here
end if

Таким образом, этот код будет работать так, как вы ожидали:

Private Sub raceTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RaceTimer.Tick
    ' moves two cars from a starting line to a finish line on the form
    ' displays a message indicating the race results
    ' calculates and displays the number of times the user selects the
    ' correct race result from the resultlistbox, and the number
    ' of times the user selects an incorrect race result

    Dim randomgenerator As New Random
    Dim whitenewlocation As Integer
    Dim rednewlocation As Integer
    Dim raceresult As String
    Dim userchoice As String
    Dim finishline As Integer = finishTextBox.Left + 1
    Static numbercorrect As Integer
    Static numberincorrect As Integer

    ' save the user's list box selection, then disable the list box
    userchoice = resultListBox.SelectedItem.ToString
    resultListBox.Enabled = False

    'calculate the new location of each picture box's right border
    ' don't allow the right border to go beyond the finish line
    whitenewlocation = whitePictureBox.Right + randomgenerator.Next(0, 11)
    If whitenewlocation > finishline Then
        whitenewlocation = finishline
    End If
    rednewlocation = redPictureBox.Right + randomgenerator.Next(0, 11)
    If rednewlocation > finishline Then
        rednewlocation = finishline
    End If

    'move each picture box toward the finish line
    whitePictureBox.SetBounds(whitenewlocation - whitePictureBox.Width, 0, 0, 0, BoundsSpecified.X)
    redPictureBox.SetBounds(rednewlocation - redPictureBox.Width, 0, 0, 0, BoundsSpecified.X)

    'the following selection structure is processed only when at least
    ' one of the picture boxes is at the finish line
    If whitePictureBox.Right = finishline _
        OrElse redPictureBox.Right = finishline Then
        'disable the timer
        RaceTimer.Enabled = False
        'sound a beep to indicate the end of the race
        For x As Integer = 1 To 5
            Console.Beep(100, 100)
        Next x

        'store the result of the race in a variable
        If whitenewlocation = rednewlocation Then
            raceresult = "Tie"
        ElseIf whitenewlocation > rednewlocation Then
            raceresult = "White car wins"
        Else
            raceresult = "red car wins"
        End If

        'display the race results
        MessageBox.Show("Race Over!" & ControlChars.NewLine & raceresult, _
        "Car Race", MessageBoxButtons.OK, MessageBoxIcon.Information)

        'move the picture boxes back to the starting line
        whitepicturebox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)
        redpicturebox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)


        'if the user did not want to guess the race results, then
        'don't update or display the counter values; otherwise,
        'compare the race results to the user's selection and update
        ' the appropriate counter, then display both counter values
        If userchoice <> "no guess" Then
            If raceresult = userchoice Then
                numbercorrect = numbercorrect + 1
            Else
                numberincorrect = numberincorrect + 1
            End If
            correctlabel.Text = Convert.ToString(numbercorrect)
            incorrectlabel.Text = Convert.ToString(numberincorrect)
        End If

        'enable the list box
        Resultlistbox.Enabled = True
    End If


End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...