Snake [UPDATE 27.05.]

  • Hallo Leute,

    ich hatte heute Langeweile und habe einfach mal
    das klassische Spiel Snake nachgebaut.

    Screenshot:
    [Blockierte Grafik: http://www.abload.de/thumb/screenshot37il.jpg][Blockierte Grafik: http://www.abload.de/thumb/screenshot28ol8.jpg][Blockierte Grafik: http://www.abload.de/thumb/screenshot3ys1t.jpg]

    Code
    [autoit]


    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <misc.au3>
    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $x[1]
    Global $y[1]
    Global $End = True
    Global $up = False ;Wenn True, dann beginnt Snake in die Richtung
    Global $down = False ;Wenn True, dann beginnt Snake in die Richtung
    Global $left = False ;Wenn True, dann beginnt Snake in die Richtung
    Global $right = True ;Wenn True, dann beginnt Snake in die Richtung
    Global $CreateFood = False
    Global $Foodx[1]
    Global $Foody[1]
    Global $Food[1]
    Global $Wallx[1]
    Global $Wally[1]
    Global $Wall[1]
    Global $Snake[2]
    Global $Score = 0
    Global $Speed = 200 ;Umso höher, deso langsamer (Sleep-Zeit)
    Global $FoodScoreChange = 20 ;Wieviel Punkte es gibt, beim Fressen
    $x[0] = 170
    $y[0] = 120
    $FoodScore = $FoodScoreChange

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("SNAKE by qixx", 350, 250)
    GUICtrlCreatePic(@ScriptDir & "\images\field.jpg", 0, 0, 350, 250)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $Label_Settings = GUICtrlCreateLabel("Einstellungen", 16, 16, 200, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetColor(-1, 0xC8C8C8)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $Label_Score = GUICtrlCreateLabel("Spielstand: 0", 16, 208, 200, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetColor(-1, 0xC8C8C8)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $Label_Length = GUICtrlCreateLabel("Schlangenlänge: 1", 16, 224, 200, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetColor(-1, 0xC8C8C8)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $Snake[0] = GUICtrlCreatePic(@ScriptDir & "\images\snake.gif", $x[0], $y[0], 10, 10)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    $Button = GUICtrlCreateLabel(" Start", 288, 224, 47, 15)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetColor(-1, 0xFF0000)
    GUICtrlSetBkColor(-1, 0xFFFFFF)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateLabel("Wände:", 24, 264, 48, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    $Slider_Wall = GUICtrlCreateSlider(16, 280, 169, 25)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    $Label_Wall = GUICtrlCreateLabel("0", 72, 264, 18, 15)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlCreateLabel("Startrichtung:", 200, 264, 81, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $Radio_Up = GUICtrlCreateRadio("Hoch", 240, 280, 57, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    $Radio_Down = GUICtrlCreateRadio("Runter", 240, 328, 57, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    $Radio_Left = GUICtrlCreateRadio("Links", 200, 304, 49, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    $Radio_Right = GUICtrlCreateRadio("Rechts", 280, 304, 65, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetState(-1, $GUI_CHECKED)
    $Button_CreateWalls = GUICtrlCreateButton("Platzieren", 104, 262, 73, 17, $WS_GROUP)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlCreateLabel("Geschwindigkeit:", 24, 312, 101, 17)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
    $Slider_Speed = GUICtrlCreateSlider(16, 328, 169, 25)
    GUICtrlSetLimit(-1, 3, 0)
    GUICtrlSetData(-1, 1)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    $Label_Speed = GUICtrlCreateLabel("Mittel", 125, 312, 60, 15)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Case $Button
    If GUICtrlRead($Button) = " Start" Then
    $End = False
    _NewGame()
    GUICtrlSetData($Button, " 3")
    Sleep(1000)
    GUICtrlSetData($Button, " 2")
    Sleep(1000)
    GUICtrlSetData($Button, " 1")
    Sleep(1000)
    GUICtrlSetColor($Label_Settings, 0xFFFFFF)
    GUICtrlSetData($Button, " Stop")
    GUICtrlSetColor($Button, 0xC8C8C8)
    $pos = WinGetPos($hGui)
    MouseMove($pos[0] + $pos[2], $pos[1] + $pos[3], 0)
    Else
    $End = True
    GUICtrlSetColor($Label_Settings, 0xC8C8C8)
    GUICtrlSetData($Button, " Start")
    GUICtrlSetColor($Button, 0xFF0000)
    _EndGame()
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case $Label_Settings
    $pos = WinGetPos($hGui)
    If $pos[3] < 300 Then
    WinMove($hGui, "", $pos[0], $pos[1], 356, 385)
    Else
    WinMove($hGui, "", $pos[0], $pos[1], 356, 278)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case $Button_CreateWalls
    ;Wände erstellen

    [/autoit] [autoit][/autoit] [autoit]

    If UBound($Wall) > 1 Then
    For $i = 0 To UBound($Wall)-1
    GUICtrlDelete($Wall[$i])
    Next
    ReDim $Wall[1]
    ReDim $Wallx[1]
    ReDim $Wally[1]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState($GUI_DISABLE, $hGui)
    For $i = 0 To GUICtrlRead($Slider_Wall) -1
    ReDim $Wall[UBound($Wall)+1]
    ReDim $Wallx[UBound($Wall)+1]
    ReDim $Wally[UBound($Wall)+1]
    _CreateWall($i)
    Next
    GUISetState($GUI_ENABLE, $hGui)

    [/autoit] [autoit][/autoit] [autoit]

    Case $Slider_Wall
    GUICtrlSetData($Label_Wall, GUICtrlRead($Slider_Wall))

    [/autoit] [autoit][/autoit] [autoit]

    Case $Slider_Speed
    Switch GUICtrlRead($Slider_Speed)
    Case 0
    GUICtrlSetData($Label_Speed, "Langsam")
    $Speed = 300
    $FoodScore = $FoodScoreChange - $FoodScoreChange/2
    Case 1
    GUICtrlSetData($Label_Speed, "Mittel")
    $Speed = 200
    $FoodScore = $FoodScoreChange
    Case 2
    GUICtrlSetData($Label_Speed, "Schnell")
    $Speed = 100
    $FoodScore = $FoodScoreChange + $FoodScoreChange/2
    Case 3
    GUICtrlSetData($Label_Speed, "Sehr Schnell")
    $Speed = 50
    $FoodScore = $FoodScoreChange * 2
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    Case $Radio_Up
    If GUICtrlRead($Radio_Up) = $GUI_CHECKED Then
    $up = True
    $down = False
    $left = False
    $right = False
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case $Radio_Down
    If GUICtrlRead($Radio_Down) = $GUI_CHECKED Then
    $up = False
    $down = True
    $left = False
    $right = False
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case $Radio_Left
    If GUICtrlRead($Radio_Left) = $GUI_CHECKED Then
    $up = False
    $down = False
    $left = True
    $right = False
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case $Radio_Right
    If GUICtrlRead($Radio_Right) = $GUI_CHECKED Then
    $up = False
    $down = False
    $left = False
    $right = True
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    If $CreateFood = True Then
    Local $FoodOnWall = False
    $Foodx[0] = Random(0, 34, 1) & "0"
    $Foody[0] = Random(0, 24, 1) & "0"

    [/autoit] [autoit][/autoit] [autoit]

    If UBound($Wall) > 1 Then
    For $i = 0 To UBound($Wall)-1
    If $Foodx[0] = $Wallx[$i] And $Foody[0] = $Wally[$i] Then ;Wenn Futter auf Wand erscheint
    $FoodOnWall = True
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $FoodOnWall = False Then ;Wenn Futter nicht auf Wand, Futter setzen ; Sonst nochmal durchführen ($CreateFood = True)
    $Food[0] = GUICtrlCreatePic(@ScriptDir & "\images\food.gif", $Foodx[0], $Foody[0], 10, 10)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetState(-1, $GUI_ENABLE)
    $CreateFood = False
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $End = False Then
    If _IsPressed(26)Then
    If $down = False Then
    $up = True
    $down = False
    $left = False
    $right = False
    EndIf
    ElseIf _IsPressed(28) Then
    If $up = False Then
    $up = False
    $down = True
    $left = False
    $right = False
    EndIf
    ElseIf _IsPressed(25) Then
    If $right = False Then
    $up = False
    $down = False
    $left = True
    $right = False
    EndIf
    ElseIf _IsPressed(27) Then
    If $left = False Then
    $up = False
    $down = False
    $left = False
    $right = True
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _SetSnake()

    [/autoit] [autoit][/autoit] [autoit]

    ;Futter fressen
    For $i = 0 To UBound($Food)-1
    If $x[0] = $Foodx[$i] And $y[0] = $Foody[$i] Then
    GUICtrlDelete($Food[$i])
    $Score += $FoodScore
    GUICtrlSetData($Label_Score, "Spielstand: " & $Score)
    _LongerSnake()
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _SetSnake()
    If UBound($x) > 0 Then
    For $i = UBound($x)-1 To 1 Step -1
    $x[$i] = $x[$i-1]
    Next
    For $i = UBound($y)-1 To 1 Step -1
    $y[$i] = $y[$i-1]
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $End = False Then

    [/autoit] [autoit][/autoit] [autoit]

    If $up = True Then
    $y[0] -= 10
    ElseIf $down = True Then
    $y[0] += 10
    ElseIf $left = True Then
    $x[0] -= 10
    ElseIf $right = True Then
    $x[0] += 10
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;Rand getroffen
    If $x[0] < 0 Or $x[0] > 340 Or $y[0] < 0 Or $y[0] > 240 Then
    _EndGame()
    Return
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;Wand getroffen
    If UBound($Wall) > 1 Then
    For $i = 0 To UBound($Wall)
    If $x[0] = $Wallx[$i] And $y[0] = $Wally[$i] Then
    _EndGame()
    Return
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;Snake berührt sich selbst
    If UBound($Snake) > 2 Then
    For $i = 1 To UBound($Snake)-2
    If $x[0] = $x[$i] And $y[0] = $y[$i] Then
    _EndGame()
    Return
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $End = False
    For $i = 0 To UBound($Snake)-2
    GUICtrlSetPos($Snake[$i], $x[$i], $y[$i])
    Next
    Sleep($Speed)
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _LongerSnake()
    $CreateFood = True
    ReDim $Snake[UBound($Snake)+1]
    ReDim $x[UBound($x)+1]
    ReDim $y[UBound($y)+1]
    $Snake[UBound($Snake)-2] = GUICtrlCreatePic(@ScriptDir & "\images\snake.gif", $x[UBound($Snake)-2], $y[UBound($Snake)-2], 10, 10)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetData($Label_Length, "Schlangenlänge: " & UBound($Snake)-1)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _NewGame()
    GUICtrlSetState($Radio_Up, $GUI_DISABLE)
    GUICtrlSetState($Radio_Down, $GUI_DISABLE)
    GUICtrlSetState($Radio_Left, $GUI_DISABLE)
    GUICtrlSetState($Radio_Right, $GUI_DISABLE)
    GUICtrlSetState($Slider_Wall, $GUI_DISABLE)
    GUICtrlSetState($Button_CreateWalls, $GUI_DISABLE)
    GUICtrlSetState($Slider_Speed, $GUI_DISABLE)

    [/autoit] [autoit][/autoit] [autoit]

    _GetStartPosition()

    [/autoit] [autoit][/autoit] [autoit]

    If UBound($Snake) > 1 Then
    For $i = 1 To UBound($Snake)-1
    GUICtrlDelete($Snake[$i])
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To UBound($Food)-1
    GUICtrlDelete($Food[$i])
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Redim $Foodx[1]
    ReDim $Foody[1]
    ReDim $Food[1]
    ReDim $Snake[2]
    ReDim $x[1]
    ReDim $y[1]

    [/autoit] [autoit][/autoit] [autoit]

    $x[0] = 170
    $y[0] = 120
    GUICtrlSetPos($Snake[0], $x[0], $y[0])
    $CreateFood = True

    [/autoit] [autoit][/autoit] [autoit]

    $Score = 0
    GUICtrlSetData($Label_Score, "Spielstand: " & $Score)
    GUICtrlSetData($Label_Length, "Schlangenlänge: 1 ")
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _EndGame()
    GUICtrlSetState($Radio_Up, $GUI_ENABLE)
    GUICtrlSetState($Radio_Down, $GUI_ENABLE)
    GUICtrlSetState($Radio_Left, $GUI_ENABLE)
    GUICtrlSetState($Radio_Right, $GUI_ENABLE)
    GUICtrlSetState($Slider_Wall, $GUI_ENABLE)
    GUICtrlSetState($Button_CreateWalls, $GUI_ENABLE)
    GUICtrlSetState($Slider_Speed, $GUI_ENABLE)

    [/autoit] [autoit][/autoit] [autoit]

    $End = True
    If MsgBox(4,"Snake by qixx", "Das Spiel ist vorbei." & @CRLF & @CRLF & "Wände: " & UBound($Wall)-1 & @CRLF & "Geschwindigkeit: " & GUICtrlRead($Label_Speed) & @CRLF & "Deine Punktzahl: " & StringReplace(GUICtrlRead($Label_Score), "Spielstand: ","") & @CRLF & @CRLF & "Nochmal spielen?") = 6 Then
    GUICtrlSetColor($Label_Settings, 0xC8C8C8)
    GUICtrlSetData($Button, " Start")
    GUICtrlSetColor($Button, 0xFF0000)
    _GetStartPosition()

    [/autoit] [autoit][/autoit] [autoit]

    Else
    Exit
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _CreateWall($i)
    Local $WallAlreadyExists = False
    $Wallx[$i] = Random(0, 34, 1) & "0"
    $Wally[$i] = Random(0, 24, 1) & "0"

    [/autoit] [autoit][/autoit] [autoit]

    If UBound($Wall) > 1 Then
    For $i2 = 0 To UBound($Wall)-3
    If $Wallx[$i] = $Wallx[$i2] And $Wally[$i] = $Wally[$i2] Then
    $WallAlreadyExists = True
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If $WallAlreadyExists = False Then
    $Wall[$i] = GUICtrlCreatePic(@ScriptDir & "\images\wall.gif", $Wallx[$i], $Wally[$i], 10, 10)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetState(-1, $GUI_ENABLE)
    Else
    ConsoleWrite("Wand schon vorhanden - Neuberechnung" & @CRLF)
    _CreateWall($i)
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetStartPosition()
    If GUICtrlRead($Radio_Up) = $GUI_CHECKED Then
    $up = True
    $down = False
    $left = False
    $right = False
    EndIf
    If GUICtrlRead($Radio_Down) = $GUI_CHECKED Then
    $up = False
    $down = True
    $left = False
    $right = False
    EndIf
    If GUICtrlRead($Radio_Left) = $GUI_CHECKED Then
    $up = False
    $down = False
    $left = True
    $right = False
    EndIf
    If GUICtrlRead($Radio_Right) = $GUI_CHECKED Then
    $up = False
    $down = False
    $left = False
    $right = True
    EndIf
    EndFunc

    [/autoit]



    ToDo:

    - Levels mit Wänden
    - Schwierigkeitsstufen


    Der Code als .au3 und die Bilder sind im Anhang!
    (Aktuellste Version: 1.3)


    MfG
    qixx

  • funktioniert einwandfrei und sieht auch schön aus^^

    P.S. vielleicht könnte man noch einen pause button oder sowas einfügen, sodass man nicht immer von vorne starten muss :P

    aber sonst alles bestens

  • Aber bei mir flackert es leider :( .

    Hallo qixx, das flackern (ist mir nur für die Anzeige des Spielstandes aufgefallen) kannst du abstellen in den du ihn nur bei Änderung updates:
    :

    [autoit]

    if $Score <> $OldScore Then
    GUICtrlSetData($Label_Score, "Spielstand: " & $Score)
    $OldScore = $Score
    EndIf

    [/autoit]

    mfg (Auto)Bert

  • Danke erstmal für die Antworten. :)

    Habe einen anderen Fehler gefunden,
    warum die Score flackert. Ich hatte in der
    Funktion _SetSnake() (Zeile 152) ein
    GUICtrlSetData($Label_Score, "Spielstand: " & $Score)
    hineingeschrieben. Dieses war völlig ohne Sinn.
    Ich brauche das Skript deshalb ja nicht neu
    hochladen. ;)

    Ich würde es ja gerne in GDI+ umsetzen. Leider
    verstehe ich es aber nicht so wirklich.


    MfG
    qixx

  • Zitat

    eifach mal nach scripten von UEZ suchen und angucken

    Danke, werde ich tun! :)

    Edit:
    Gibt es auch irgendwo ein Grundlagen-Tutorial
    für GDI+, indem man Schritt für Schritt dort
    hineingebracht wird?


    MfG
    qixx