Snake - Problem

  • VB.NET

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

    Snake - Problem

    Hi,

    jedes Mal, wenn ich das Programm starte, also die Form lade, sollten ein paar Pictureboxen generiert werden.

    Aus irgendeinem Grund klappt es nicht und nur eine Picbox wird generiert.

    Code:

    Code

    VB.NET-Quellcode

    1. Public Class frmSnake
    2. Dim Snake(Länge) As SnakePart
    3. Structure SnakePart
    4. Dim coords As Point
    5. Dim Richtung As Keys
    6. End Structure
    7. Dim zz As New Random
    8. Dim Länge As Integer = 4
    9. Dim imgSnake(Länge) As PictureBox
    10. Dim Startzeit As Date
    11. Dim Endzeit As Date
    12. Dim Zeitdiff As TimeSpan
    13. Dim verkackt As Boolean
    14. Private Sub frmSnake_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    15. timer_disable()
    16. 'Snake generieren
    17. For i As Integer = 0 To 4
    18. Snake(i).coords.X = (120 - (20 * i))
    19. Snake(i).coords.Y = 120
    20. imgSnake(i) = New PictureBox
    21. imgSnake(i).Width = 20
    22. imgSnake(i).Height = 20
    23. imgSnake(i).BackColor = Color.Black
    24. imgSnake(i).Left = Snake(i).coords.X
    25. imgSnake(i).Top = Snake(i).coords.Y
    26. Snake(i).Richtung = Keys.Down
    27. Controls.Add(imgSnake(i))
    28. Next
    29. End Sub
    30. Private Sub tmr1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr1.Tick
    31. Kopf_bewegen()
    32. Körper_bewegen()
    33. Prüfe_verloren()
    34. End Sub
    35. Private Sub frmSnake_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
    36. If e.KeyCode = Keys.Left Then
    37. Snake(0).Richtung = Keys.Left
    38. End If
    39. If e.KeyCode = Keys.Right Then
    40. Snake(0).Richtung = Keys.Right
    41. End If
    42. If e.KeyCode = Keys.Up Then
    43. Snake(0).Richtung = Keys.Up
    44. End If
    45. If e.KeyCode = Keys.Down Then
    46. Snake(0).Richtung = Keys.Down
    47. End If
    48. End Sub
    49. Private Sub lblEnde_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblEnde.Click
    50. End
    51. End Sub
    52. Private Sub lblStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblStart.Click
    53. timer_enable()
    54. Startzeit = Now
    55. End Sub
    56. Private Sub tmrZeit_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrZeit.Tick
    57. zeit_anzeigen()
    58. End Sub
    59. Private Sub timer_disable()
    60. tmr1.Enabled = False
    61. tmrZeit.Enabled = False
    62. End Sub


    *Topic verschoben*

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ct5010“ ()

    Erstell mal Dein Snake()-Feld anders:

    VB.NET-Quellcode

    1. Dim Snake() As SnakePart
    2. Private Sub frmSnake_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    3. ReDim Snake(Länge)
    4. '...
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi,
    danke, es wird aber leider immer noch nur ein Teil der Schlange generiert. Wenn ich jedoch mit den Pfeiltasten die Schlange bewege, generiert sich erst "Der Rest". Außerdem geht dieses Körper_bewegen nicht:

    VB.NET-Quellcode

    1. Private Sub tmr1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr1.Tick
    2. Kopf_bewegen()
    3. Körper_bewegen()
    4. Prüfe_verloren()
    5. End Sub
    6. Private Sub Kopf_bewegen()
    7. If Snake(0).Richtung = Keys.Left Then
    8. Snake(0).coords.X -= 20
    9. imgSnake(0).Left = Snake(0).coords.X
    10. ElseIf Snake(0).Richtung = Keys.Up Then
    11. Snake(0).coords.Y -= 20
    12. imgSnake(0).Top = Snake(0).coords.Y
    13. ElseIf Snake(0).Richtung = Keys.Right Then
    14. Snake(0).coords.X += 20
    15. imgSnake(0).Left = Snake(0).coords.X
    16. ElseIf Snake(0).Richtung = Keys.Down Then
    17. Snake(0).coords.Y += 20
    18. imgSnake(0).Top = Snake(0).coords.Y
    19. End If
    20. End Sub
    21. Private Sub Körper_bewegen()
    22. For i As Long = (x - 1) To 1 Step (-1)
    23. Snake(i).coords.X = Snake(i - 1).coords.X
    24. imgSnake(i).Left = Snake(i).coords.X
    25. Snake(i).coords.Y = Snake(i - 1).coords.Y
    26. imgSnake(i).Top = Snake(i).coords.Y
    27. Snake(i).Richtung = Snake(i - 1).Richtung
    28. Next
    29. End Sub


    Irgendwas ist außerhalb des Arraybereichs.

    EDIT: x ist jetzt die neue Variable für die Länge...
    EDIT2: Ich glaube, dass das Problem darin besteht, dass beim Laden nur ein Schlangenteil geladen wird?!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ct5010“ ()

    Check das mal, meine Variante, bzw. ein teil davon..

    VB.NET-Quellcode

    1. Public Sub OnKey(ByVal keycode As Keys)Select Case keycodeCase Keys.A die_schlange.Bewegungsrichtung.Richtung = Richtung.LinksCase Keys.S die_schlange.Bewegungsrichtung.Richtung = Richtung.RunterCase Keys.D die_schlange.Bewegungsrichtung.Richtung = Richtung.RechtsCase Keys.W die_schlange.Bewegungsrichtung.Richtung = Richtung.RaufEnd Select




    VB.NET-Quellcode

    1. Public Bewegungsrichtung As New Bewegung Public Koerper As New List(Of Feld) Public Sub Friss(ByVal sp(,) As Feld, ByVal Futterfeld As Feld)Koerper.Insert(0, Futterfeld) sp(Futterfeld.Index_X, Futterfeld.Index_Y).Status = FeldStatus.Schlange End Sub Public Sub SchwanzVor(ByVal sp(,) As Feld) If Koerper.Count > 1 Then Dim f As Feld = Koerper(Koerper.Count - 1) sp(f.Index_X, f.Index_Y).Status = FeldStatus.Frei Koerper.RemoveAt(Koerper.Count - 1) End If End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Höhlenbeisser“ ()

    Hi,

    sorry, mir ist das noch zu hoch ;) wir arbeiten an VB seit nichtmal einem Monat... habe schon sehr viel selbst gelernt. Gibt es eine Methode, wo man so arbeiten kann wie ich bisher? Ich weiß nur nicht, warum die Schlange nicht generiert wird...
    Du solltest eigentlich eher viel selbst wissen, denn dann kannst Du reagieren, wenn der Lehrer euch versucht VB6 Code auszuzwingen.

    Was Dein Problem angeht:
    Bei Zeile 18 gehst du nur von 0 bis 4, anstelle von 0 bis Länge.
    An dieser Stelle noch ein Tipp:
    Arrays werden in VB nullbasiert deklariert.
    Das bedeutet:

    VB.NET-Quellcode

    1. Dim Bla(4) As Typ

    ergibt ein Array mit 5(!) Einträgen, nämlich 0, 1, 2, 3 und 4.
    Darum solltest Du den Namen der "Länge" Variable noch mal überdenken, oder

    VB.NET-Quellcode

    1. Dim Snake(Länge - 1) As ...
    2. 'und
    3. For ... 0 To Länge - 1

    verwenden.

    Noch ein Tipp: Vermeide Umlaute in Variablennamen.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Hi, Danke, ich hab das mit dem Namen der Länge gesehen, also hier aktualisiert:

    AKTUALISIERTER Code

    VB.NET-Quellcode

    1. Public Class frmSnake
    2. Dim Snake() As SnakePart
    3. Structure SnakePart
    4. Dim coords As Point
    5. Dim Richtung As String
    6. End Structure
    7. Dim zz As New Random 'Zufallszahl
    8. Dim x As Long 'Länge der Schlange
    9. Dim imgSnake(x) As PictureBox
    10. Dim Startzeit As Date
    11. Dim Endzeit As Date
    12. Dim Zeitdiff As TimeSpan
    13. Dim v As Boolean 'Verloren
    14. Dim g As Byte 'Geschwindigkeit; 1 = langsam, 9 = schnell
    15. Private Sub frmSnake_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    16. timer_disable()
    17. ReDim Snake(x)
    18. snake_generieren()
    19. tmr1.Interval = 425
    20. End Sub
    21. Private Sub tmr1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr1.Tick
    22. Körper_bewegen()
    23. Kopf_bewegen()
    24. Prüfe_verloren()
    25. End Sub
    26. Private Sub frmSnake_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
    27. If e.KeyCode = Keys.A Then
    28. Snake(0).Richtung = "Links"
    29. End If
    30. If e.KeyCode = Keys.D Then
    31. Snake(0).Richtung = "Rechts"
    32. End If
    33. If e.KeyCode = Keys.W Then
    34. Snake(0).Richtung = "Oben"
    35. End If
    36. If e.KeyCode = Keys.S Then
    37. Snake(0).Richtung = "Unten"
    38. End If
    39. End Sub
    40. Private Sub lblEnde_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblEnde.Click
    41. End
    42. End Sub
    43. Private Sub lblStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblStart.Click
    44. timer_enable()
    45. Startzeit = Now
    46. End Sub
    47. Private Sub tmrZeit_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrZeit.Tick
    48. zeit_anzeigen()
    49. End Sub
    50. Private Sub timer_disable()
    51. tmr1.Enabled = False
    52. tmrZeit.Enabled = False
    53. End Sub
    54. Private Sub timer_enable()
    55. tmr1.Enabled = True
    56. tmrZeit.Enabled = True
    57. End Sub
    58. Private Sub zeit_anzeigen()
    59. Endzeit = Now
    60. Zeitdiff = Endzeit - Startzeit
    61. lblZeit.Text = ((Int(100 * Zeitdiff.TotalSeconds)) / 100)
    62. If Val(lblZeit.Text) < 10 Then lblZeit.Text = "0" + lblZeit.Text
    63. If Val(lblZeit.Text) < 100 Then lblZeit.Text = "0" + lblZeit.Text
    64. If Val(lblZeit.Text) < 1000 Then lblZeit.Text = "0" + lblZeit.Text
    65. End Sub
    66. Private Sub Kopf_bewegen()
    67. Select Case Snake(0).Richtung
    68. Case "Links"
    69. Snake(0).coords.X -= 20
    70. imgSnake(0).Left = Snake(0).coords.X
    71. Case "Rechts"
    72. Snake(0).coords.X += 20
    73. imgSnake(0).Left = Snake(0).coords.X
    74. Case "Oben"
    75. Snake(0).coords.Y -= 20
    76. imgSnake(0).Top = Snake(0).coords.Y
    77. Case "Unten"
    78. Snake(0).coords.Y += 20
    79. imgSnake(0).Top = Snake(0).coords.Y
    80. End Select
    81. End Sub
    82. Private Sub Prüfe_verloren()
    83. If Snake(0).coords.Y + imgSnake(0).Height <= Me.ClientRectangle.Top Then
    84. timer_disable()
    85. MsgBox("VERLOREN!!")
    86. End
    87. End If
    88. If Snake(0).coords.X + imgSnake(0).Width <= Me.ClientRectangle.Left Then
    89. timer_disable()
    90. MsgBox("VERLOREN!!")
    91. End
    92. End If
    93. If Snake(0).coords.X >= Me.ClientRectangle.Right Then
    94. timer_disable()
    95. MsgBox("VERLOREN!!")
    96. End
    97. End If
    98. If Snake(0).coords.Y >= Panel1.Top Then
    99. timer_disable()
    100. MsgBox("VERLOREN!!")
    101. End
    102. End If
    103. End Sub
    104. Private Sub Körper_bewegen()
    105. Dim i As Long
    106. For i = x - 1 To 1 Step (-1)
    107. Snake(i).coords.X = Snake(i - 1).coords.X
    108. imgSnake(i).Left = Snake(i).coords.X
    109. Snake(i).coords.Y = Snake(i - 1).coords.Y
    110. imgSnake(i).Top = Snake(i).coords.Y
    111. Snake(i).Richtung = Snake(i - 1).Richtung
    112. Next
    113. End Sub
    114. Private Sub hsbV_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles hsbV.Scroll
    115. g = hsbV.Value
    116. Select Case g
    117. Case 1
    118. tmr1.Interval = 425
    119. Case 2
    120. tmr1.Interval = 350
    121. Case 3
    122. tmr1.Interval = 275
    123. Case 4
    124. tmr1.Interval = 200
    125. Case 5
    126. tmr1.Interval = 150
    127. Case 6
    128. tmr1.Interval = 100
    129. Case 7
    130. tmr1.Interval = 75
    131. Case 8
    132. tmr1.Interval = 50
    133. Case 9
    134. tmr1.Interval = 25
    135. End Select
    136. End Sub
    137. Private Sub snake_generieren()
    138. x = 5
    139. imgSnake(0) = PictureBox1
    140. imgSnake(1) = PictureBox2
    141. imgSnake(2) = PictureBox3
    142. imgSnake(3) = PictureBox4
    143. imgSnake(4) = PictureBox5
    144. End Sub
    145. End Class

    Es wäre gut, wenn Du Deinen Code zunächst so modifizierst, dass er mit
    Option Strict On
    auf einem fremden (einem der unseren) Rechner fehlerfrei läuft.
    Schreibe darüber, wieviel und welche Controls Du benötigst, dann wäre es gut, wenn Deine Controls die von der IDE gewählte Standard-Bezeichnung hätten, da muss man nutr das Control einfügen und fertig.
    Da können wir Dir viel schneller und effizienter helfen.
    Füge einfach mal Deinen geposteten Code in ein neues Projekt ein, dann verstrehst Du, was ich meine.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So, ich habe jetzt einen komplett neuen Ansatz genommen, habe mich vorher schlau gemacht und Youtube-Vids geschaut:
    Und es klappt!

    Code

    VB.NET-Quellcode

    1. Public Class Snake
    2. Dim m As Integer = 10
    3. Dim p(m) As Point
    4. Dim k As Keys
    5. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrLoop.Tick
    6. Dim b As New Bitmap(256, 256)
    7. Dim g As Graphics = Graphics.FromImage(b)
    8. schlange_bewegen()
    9. For i As Integer = 0 To m - 1
    10. p(i) = p(i + 1)
    11. g.FillRectangle(Brushes.Black, New Rectangle(p(i), New Size(14, 14)))
    12. Next
    13. g.FillRectangle(Brushes.Red, New Rectangle(p(m), New Size(14, 14)))
    14. g.Dispose()
    15. Me.BackgroundImage = b
    16. Me.ClientSize = b.Size
    17. Me.Refresh()
    18. prüfe_verloren()
    19. End Sub
    20. Private Sub Snake_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    21. k = Keys.Right
    22. End Sub
    23. Private Sub Snake_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
    24. Select Case e.KeyCode
    25. Case Keys.Left
    26. If k = Keys.Right Then Else k = Keys.Left
    27. Case Keys.Right
    28. If k = Keys.Left Then Else k = Keys.Right
    29. Case Keys.Up
    30. If k = Keys.Down Then Else k = Keys.Up
    31. Case Keys.Down
    32. If k = Keys.Up Then Else k = Keys.Down
    33. End Select
    34. End Sub
    35. Private Sub schlange_bewegen()
    36. Select Case k
    37. Case Keys.Left
    38. p(m).X -= 16
    39. Case Keys.Right
    40. p(m).X += 16
    41. Case Keys.Up
    42. p(m).Y -= 16
    43. Case Keys.Down
    44. p(m).Y += 16
    45. End Select
    46. End Sub
    47. Private Sub prüfe_verloren()
    48. For i = 0 To m - 2
    49. If p(m) = p(i) Then
    50. tmrLoop.Enabled = False
    51. MsgBox("Verloren!")
    52. End
    53. End If
    54. Next
    55. End Sub
    56. End Class


    EDIT: @RodFromGermany
    so also hier mit dem neuen Code muss man nur den Namen der Form in Snake umändern...
    Ja ich habe verstanden warum es jetzt funktioniert, aber nicht warum der alte Code nicht funktioniert hat...
    Ist ja jetzt auch egal, ich arbeite jetzt mit dem neuen Code und es funktioniert auch gut. Es ist eigentlich gar nicht mal so kompliziert.

    Ich werd mal an einer Lösung arbeiten und wenn ich fertig bin, kann ich den Code ja auch stolz hier posten ;)

    ct5010 schrieb:

    so also hier mit dem neuen Code muss man nur den Namen der Form in Snake umändern...

    und dem Timer den Namen tmrLoop geben und außerdem den Timer im Designer aktivieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So, habe jetzt ein neues Problem... Wenn ich das generierte Essen "fresse", soll die Schlange ja länger werden. Dies klappt aber nicht, weil irgendwas außerhalb des Arraybereichs ist.

    Fehler mit > < markiert

    Code

    VB.NET-Quellcode

    1. Public Class Snake
    2. Dim m As Integer = 5 'Länge der Schlange
    3. Dim p(m) As Point 'Array von Punkten, jeder Punkt ist der Punkt eines Schlangeteils
    4. Dim pAlt(m) As Point 'speichert den Array von Punkten am Anfang
    5. Dim essen As Point 'Koordinaten des Essens
    6. Dim ev As Boolean = False 'Essen vorhanden? True = ja, False = nein
    7. Dim zz As New Random
    8. Dim k As Keys = Keys.Right 'Speichert die aktuelle Richtung der Schlange ab
    9. Dim kt As Keys 'temporäre Key-Einstellung gegenüber der Variable k
    10. Dim punkte As Integer = 0 'Punktezähler
    11. Dim geschwindigkeit As Integer = 1 'Geschwindigkeit, 1 = langsam, 9 = schnell
    12. Private Sub tmrLoop_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrLoop.Tick
    13. Dim b As New Bitmap(512, 384)
    14. Dim g As Graphics = Graphics.FromImage(b)
    15. 'Kopf bewegen
    16. Select Case k
    17. Case Keys.Left
    18. If p(m).X = 0 Then p(m).X = b.Width Else
    19. p(m).X -= 16
    20. Case Keys.Right
    21. If p(m).X = b.Width Then p(m).X = -16 Else
    22. p(m).X += 16
    23. Case Keys.Up
    24. If p(m).Y = 0 Then p(m).Y = b.Height Else
    25. p(m).Y -= 16
    26. Case Keys.Down
    27. If p(m).Y = b.Height Then p(m).Y = -16 Else
    28. p(m).Y += 16
    29. End Select
    30. 'Rest bewegen
    31. For i As Integer = 0 To m - 1
    32. p(i) = p(i + 1)
    33. g.FillRectangle(Brushes.Black, New Rectangle(p(i), New Size(15, 15)))
    34. Next
    35. g.FillRectangle(Brushes.Red, New Rectangle(p(m), New Size(15, 15)))
    36. prüfe_verloren()
    37. 'Essen generieren falls nicht vorhanden / gegessen
    38. If ev = False Then
    39. ev = True
    40. essen.X = zz.Next(1, 32) * 16
    41. essen.Y = zz.Next(1, 24) * 16
    42. End If
    43. 'Essen Abfrage
    44. If essen = p(m) Then
    45. essen.X = zz.Next(1, 32) * 16
    46. essen.Y = zz.Next(1, 24) * 16
    47. m = m + 1
    48. For i As Integer = m To 1 Step (-1)
    49. >p(i) = p(i - 1)<
    50. g.FillRectangle(Brushes.Black, New Rectangle(p(i), New Size(15, 15)))
    51. Next
    52. End If
    53. g.FillRectangle(Brushes.Green, New Rectangle(essen, New Size(15, 15)))
    54. g.Dispose()
    55. Me.BackgroundImage = b
    56. Me.Refresh()
    57. richtung_abfragen()
    58. End Sub


    EDIT: erledigt!

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ct5010“ ()