2013-12-08 36 views
0

這是一個非常簡單的代碼。我剛開始使用VB。我正在製作一個遊戲,您可以按照正確的順序對混洗號碼進行重新排序。您嘗試用最少的時間和最少的點擊次數來解決這個難題,並且在下次玩遊戲時,您會嘗試獲得較低的分數(或擊敗該記錄)。你有十六個按鈕(4x4)和十五個數字。有一個checkbutton函數來查看這個謎題是否解決了。每次我調試該程序時,它都會突出顯示Clicks和FinalTime,並說Null引用異常是未處理的。下面是一些代碼。空引用異常未處理

Public Class Form1 
Dim Clicks As Integer = 0 'The variable that counts the number of times you clicked 
Dim Time As Integer 'The vairable that holds the time 
Dim TimeMin As Integer 'The variable that holds the minutes 
Dim TimeSec As Integer 'The variable that holds the seconds 
Dim FinalTime As String 'The variable that holds the final time (minutes and seconds) 
Dim lngArray() As String = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", ""} {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", ""}  
Dim NumArray() As Integer 
Dim NumArray1() As String 

Private Sub CheckButton(ByRef Butt1 As Button, ByRef Butt2 As Button) 
    If Butt2.Text = "" Then 'Checks if the button around the clicked number is empty "" It's the location of the empty square that you want the number in Butt1 to move to. 
     Butt2.Text = Butt1.Text 'If it is, the value from Butt2 will "copy and paste" into Butt1 
     Butt1.Text = "" 'Butt1 will keep the value and the value in Butt2 will clear "" 
     Clicks += 1 'Incrementing Each click by only 1. It's a counter. In addition, the code above only allows the click to increment by 1 if the number has moved. If you just click on a number that can't move, the click would not count. 
    End If 
    If Clicks > 1 Then 
     lblTotal.Text = Clicks & " Clicks" 'Shows the total amount of clicks when it is greater than one 
    Else 
     lblTotal.Text = Clicks & " Click" 'Shows the total amount of clicks when it is one 
    End If 

End Sub 

Private Sub CheckSolved() 'A private sub that checks if the puzzle is solved ,restarts the count, and stops the time 
    Dim strName As String = "" 'The variable that has the string of the winners name 
    If Me.Button1.Text = "1" And Me.Button2.Text = "2" And Me.Button3.Text = "3" And Me.Button4.Text = "4" And Me.Button5.Text = "5" And Me.Button6.Text = "6" And Me.Button7.Text = "7" And Me.Button8.Text = "8" And Me.Button9.Text = "9" And Me.Button10.Text = "10" And Me.Button11.Text = "11" And Me.Button12.Text = "12" And Me.Button13.Text = "13" And Me.Button14.Text = "14" And Me.Button15.Text = "15" Then 'Checks if the numbers are in the correct buttons 
     Timer1.Enabled = False 'Stops the time 
     strName = InputBox("What is your name", "Name of winner") 'Get's the winners name 
     MessageBox.Show("In " & FinalTime & " , you solved the puzzle in " & Me.Clicks & " clicks! Congratulations " & strName) 'Messagebox showing how many times you clicked to solve the puzzle. It gets the name you typed into the inputbox (strname) and displays it 
     Call Restart() 'Shuffles the buttons and restarts the game when you win 
     Call Record(NumArray, NumArray1) 
    End If 
End Sub 
Private Sub Record(ByVal NumArray() As Integer, ByVal NumArray1() As String) 
    'Make timemin array and then make time array. Then make click array 
    For i As Integer = 0 To 1000 
     NumArray(i) = Clicks 'This is where the Null Reference error occured 
     i = +1 
     Array.Sort(NumArray) 'sorting the array values from least to greatest 
    Next i 

    lblRecordClicks.Text = NumArray(0) & " Clicks" 'displaying the lowest number of clicks in the label 
    For k As Integer = 0 To 1000 'Making an integer that captures 1000 values 
     NumArray1(k) = FinalTime 'This is where the Null Reference error occured 
     k = +1 
     Array.Sort(NumArray1) 'sorting the array values from least to greatest 
    Next k 

    lblRecordTime.Text = NumArray1(0) 'displaying the lowest time in the label 
End Sub 

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

Private Sub Shuffle(ByVal lngArray As Object) 'Shuffles the values of the Array 
    Dim i As Long 
    Dim iMin As Long 
    Dim iMax As Long 
    Dim lngReplace As Long 
    Dim varSwap As Object 
    iMin = LBound(lngArray) 
    iMax = UBound(lngArray) 
    For i = iMax To iMin + 1 Step -1 
     lngReplace = Int((i - iMin + 1) * Rnd() + iMin) 
     varSwap = lngArray(i) 
     lngArray(i) = lngArray(lngReplace) 
     lngArray(lngReplace) = varSwap 
    Next 
    Button1.Text = lngArray(0) 
    Button2.Text = lngArray(1) 
    Button3.Text = lngArray(2) 
    Button4.Text = lngArray(3) 
    Button5.Text = lngArray(4) 
    Button6.Text = lngArray(5) 
    Button7.Text = lngArray(6) 
    Button8.Text = lngArray(7) 
    Button9.Text = lngArray(8) 
    Button10.Text = lngArray(9) 
    Button11.Text = lngArray(10) 
    Button12.Text = lngArray(11) 
    Button13.Text = lngArray(12) 
    Button14.Text = lngArray(13) 
    Button15.Text = lngArray(14) 
    Button16.Text = lngArray(15) 
End Sub 

Private Sub RestartToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RestartToolStripMenuItem.Click 
    Call Restart() 
    Call Me.btnStart_Click(sender, e) 'Call the button click to enable all buttons 
End Sub 
Private Sub Times() 
    Time = Time + 1 'Increase the time by 1 second every interval 
    TimeSec = TimeSec + 1 'Increase the time by 1 second every interval 
    TimeMin = Convert.ToInt32(TimeSec \ 60) 'Takes the whole number of the amount of seconds divided by 60 and leaves out the remainder 
    If Time >= 60 Then 
     Time = 0 
    End If 
    'If the seconds pass 59 (and they do), it restarts to 0 
    FinalTime = TimeMin & " min " & Time & " seconds" 'Final time is the string displayed showing the final time 
    lblTime.Text = FinalTime 'The label displays the final time 
End Sub 
Private Sub Restart() 
    Time = 0 'Resets the time 
    Clicks = 0 'Resets the amount of clicks 
    lblTotal.Text = "" 'Clears the label 
    lblCheat.Visible = False 
    lblTotal.Visible = True 
    lblClicks.Visible = True 
    lblQuote.Visible = True 
    lblRecordClicks.Visible = True 
    lblRecordTime.Visible = True 
    'If the user cheated and hit the solve button and wants to restart and solve the puzzle on their own, then he can. Turning these label settings to true allows you to see them again 
    Call Shuffle(lngArray) 'Shuffles the numbers 
    Timer1.Enabled = True 'Continues the time when it resets to 0 

End Sub 

Public Sub RefreshEverythingToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshEverythingToolStripMenuItem.Click 
    Timer1.Enabled = False 'Pauses the timer 
    If MessageBox.Show("Do you want to restart everything?", "Restart Game", MessageBoxButtons.YesNo, MessageBoxIcon.Information) = DialogResult.Yes Then 
     Time = 0 
     TimeSec = 0 
     'Resets the time 
     Clicks = 0 'Resets the amount of clicks 
     lblTotal.Text = "" 'Clears the label 
     lblRecordClicks.Text = "" 'Resets the record click 
     lblRecordTime.Text = "" 'Resets the record time 
    End If 
    Call Shuffle(lngArray) 'Shuffles the numbers 
    Timer1.Enabled = True 'Continues the timer if no is selected 
    ReDim NumArray(1000) 'Clears the array data that was captured 
    ReDim NumArray1(1000) 'Clears the array data that was captured 
End Sub 

End Class 

如果你決定幫助(我希望你這樣做),你可以儘量避免使用「計算機」交談,並嘗試「啞下來我。」就像我之前說過的,我是這個新手。謝謝你的時間。

+0

哪條線發生異常? – Szymon

+1

Theres對發生這種情況的行發表評論......'這是Null引用錯誤發生的位置 – user3078445

回答

0

您正試圖將值保存到數組。當您定義像Dim NumArray() As Integer這樣的數組時,沒有爲數組設置邊界(數組基本上是Nothing),並且如果您嘗試訪問數組項,則會遇到Null引用異常。 您只能在Public Sub RefreshEverythingToolStripMenuItem_Click中設置數組邊界。現在我不知道所有的代碼,但如果遊戲開始時沒有用戶專門點擊這個按鈕,那麼你的數組將是Nothing。 您必須確保在遊戲開始之前總是設置數組邊界。

你也可以在.NET中查看更抽象的類數類型。例如,你可以嘗試一個列表。 List實際上是一個具有任意邊界的數組。您可以使用關鍵字與特定類型的定義列表,然後你可以添加項目與列表添加方法,刪除項目,排序列表等

定義爲一個全局變量:

Dim FinalTimes as New List(Of Integer) 
Dim FinalClicks as New List(Of Integer) 

請確保您在這裏使用New關鍵字。這意味着將創建一個List類的新對象。否則,您將再次遇到下面幾行中的空引用異常。 當用戶解決了困擾你然後做:

FinalTimes.Add(FinalTime) 
FinalClicks.Add(Clicks) 
FinalTimes.Sort 
FinalClicks.Sort 

這將基本上由一個增加了列表的長度,FinalTime /點擊次數值寫入的最後一個項目,然後再打兩個列表。想法:爲獲得高分,您可能希望將FinalTime,Clicks和Player Name連接到結構中,並使用IComparer界面讓用戶按名稱/時間/點擊對高分列表進行排序。

PS:我忘記之前:對於其中的異常在你的代碼發生循環毫無現實意義。第一個問題是,在它們當前的形式中,它們將是無限循環,因爲當循環結束時,我總是將i設置爲1,當i = 1000時(顯然這絕不會發生)。我想你的意思是i=i+1或更短的i += 1那裏。但他們仍然沒有意義。我試了一下,看看究竟發生了什麼(這是不明顯的:-)),你的高分的一半被新值覆蓋等。我認爲上述方法會更容易。 :-)

+0

如何在標籤中顯示排序的FinalTimes和FinalClicks?我並沒有完全理解你對排序變量FinalClicks和Final Times的代碼下面的段落的解釋。 – user3078445

+0

'FinalTimes。Sort'只會對列表中的值進行排序,而不會顯示它們。爲了顯示值,你可以把你自己的'Function ListToString(ByVal l as List(Of Integer))作爲String'。在那裏:'Dim res as string =「」',然後'對於每個我都是l'中的整數,然後是'res&= i.tostring',然後是'Next',然後'Return res','End Function'。在你的代碼中:'lblTimes.Text = ListToString(FinalTimes)' – Jens