Mehrere Kisten/Steine etc. auf Tilemap verschieben - Sokoban

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

Eyes_Only

Betreff: Mehrere Kisten/Steine etc. auf Tilemap verschieben - Sokoban

BeitragFr, Nov 07, 2014 13:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo.

Ich habe eine Tilemap auf der man Kisten in ein Ziel schieben muss. Wenn man so will á la Sokoban.
Jetzt soll es aber möglich sein, mehrere Kisten gleichzeitig verschieben zu können.

Mein bisheriger Ansatz ist der, dass ich prüfe, ob das Feld in Schieberichtung frei oder eine Kiste ist und ich dann zB code:

BlitzBasic: [AUSKLAPPEN]

If KeyHit(UP)=1 Then
If map(y-1,x)=0 Then ;wenn map frei
If objmap(y-1,x) <> 98 Then ;wenn keine Kiste
y=y-1 ;bewegen
ElseIf objmap(y-1,x)=98 And map(y-2,x)=0 Then ;wenn Kiste und Feld über Kiste = frei
objmap(y-2,x)=98 ;Kiste verschieben
Color 128,128,128
Rect x*20,(y-2)*20,20,20,1 ;Kiste zeichnen
y=y-1 ;Spieler bewegen
End If
EndIf
End If


Wenn ich mehrere bspw. drei Kisten schieben will, würde ich schreiben:

BlitzBasic: [AUSKLAPPEN]

If KeyHit(200)=1 Then
If map(y-1,x)=0 Then
If objmap(y-1,x) <> 98 Then
y=y-1
ElseIf (objmap(y-1,x)=98 And map(y-2,x)=0) Then ;wenn Kiste und Feld über Kiste = frei
If objmap(y-1,x)=98 And objmap(y-2,x)=98 And map(y-3,x)=0 Then ;wenn zwei Kisten und Feld über oberster Kiste frei
If objmap(y-1,x)=98 And objmap(y-2,x)=98 And objmap(y-3,x)=98 And map(y-4,x)=0 Then ;wenn drei Kisten und Feld über oberster Kiste frei
objmap(y-2,x)=98
objmap(y-3,x)=98
objmap(y-4,x)=98
Color 128,128,128
Rect x*20,(y-2)*20,20,20,1
Rect x*20,(y-3)*20,20,20,1
Rect x*20,(y-4)*20,20,20,1
y=y-1
Else ;Code für zwei Kisten
objmap(y-2,x)=98
objmap(y-3,x)=98
Color 128,128,128
Rect x*20,(y-2)*20,20,20,1
Rect x*20,(y-3)*20,20,20,1
y=y-1
EndIf
Else ;Code für eine Kiste
objmap(y-2,x)=98
Color 128,128,128
Rect x*20,(y-2)*20,20,20,1
y=y-1
EndIf
End If
EndIf
End If


Ich kann also immer weiter verschachteln. Wie aber kann ich darauf reagieren, dass der Spieler bspw. 10 Kisten zusammenschiebt oder 20 oder ... Ich kann das ja nicht bis ultimo weiter verschachteln.

Kennt jemand eine Lösung für dieses Problem?
 

Kruemelator

BeitragFr, Nov 07, 2014 15:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Benutze Rekursion.
Erstelle eine Funktion der du die aktuelle Position und die Richtung in die geschoben wird übergibts.
Die prüft was an der aktuellen Position ist. Ist dort eine Kiste dann wird die Funktion nochmal aufgerufen aber ein Feld in die "Schieberichtung" weiter. Wenn das Feld leer ist dann wird Wahr zurückgegeben wenn blockiert dann Falsch. Eine Kiste wird nur dann verschoben wenn Wahr zurück gegeben wurde.
 

Eyes_Only

BeitragFr, Nov 07, 2014 16:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Das klingt schonmal gut. Und damit kann ich dann mehrere Kisten gleichzeitig verschieben? Mein Vorstellungsvermögen reicht gerade noch nicht soweit, dass ich mir das praktisch vorstellen kann... Confused Obwohl das schon sinnvoll klingt mit der Funktion die sich immer wieder selbst aufruft.



EDIT:

Ich habe mir jetzt eine Funktion geschrieben mit der es erstmal läuft. Diese Funktion rufe ich bei der jeweiligen Richtungstaste auf, wenn das nächste Feld in Laufrichtung eine Kiste ist. Die Variable "checkx" setze ich vor Funktionsaufruf auf den Wert der Spielerposition. Danke für den Tipp mit der Rekursion!

BlitzBasic: [AUSKLAPPEN]
Function checknexttile(checkx)
If objmap(y,checkx-2)=0 And map(y,checkx-2)<>1 Then
objmap(y,checkx-2)=98
Color 128,128,128
Rect (checkx-2)*20,y*20,20,20,1
x=x-1
Else If objmap(y,checkx-2)=98 Then
checkx=checkx-1
checknexttile(checkx)
EndIf
End Function

Xeres

Moderator

BeitragFr, Nov 07, 2014 19:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Was ich nicht machen würde ist, in der Funktion etwas zu zeichnen. Funktionen sollten immer genau eine Sache machen, und nicht mehrere.
Du hast da auch jede Menge Magische Zahlen stehen, die in Konstanten gehören.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Eyes_Only

BeitragFr, Nov 07, 2014 19:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Xeres,

meinst du mit magischen Zahlen die "20er" mit denen ich die Größe der Zeichnung angebe? Die kommen später noch weg. Ich habe gerade erst einen ganz rudimentären Aufbau und noch keine Konstanten eingebaut, aber du hast natürlich Recht. Lieber gleich am Anfang ordentlich. Spart dann auch ne Menge Arbeit.

Würdest du das Zeichnen in eine extra Funktion stecken?

Xeres

Moderator

BeitragFr, Nov 07, 2014 22:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich meine auch den Vergleich mit "objmap". Welcher Inhalt ist 0, 1 oder gar 98?
Bei der ersten Bedingung kannst du den 2. Teil sparen; Was gleich 0 ist immer gleichzeitig ungleich 1.
Wenn das Zeichnen von der Logik entkoppelt ist, hat man zumindest die Möglichkeit hübschere Effekte zu benutzen (etwa die Kisten leicht rüttelnd über 1-2 Sekunden zu verschieben, anstatt instantan um zu schalten). Außerdem lässt sich der Code leichter warten und umschreiben, wenn Funktionen keine Nebeneffekte haben.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Eyes_Only

BeitragFr, Nov 07, 2014 23:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe zwei Ebenen, einmal map und einmal objmap. Werde das aber umstellen auf ein dreidimensionales Array(x,y,Ebene). Aufgrund der zwei Ebenen kommt auch die Bedingung mit 1 und 0 zustande. Denn in der map ist die Spielwelt drin, in der objmap nur die Objekte, wie Spieler, Kisten etc. Deswegen kann ich mir den zweiten Teil der Bedingung auch nicht sparen.

Die 0, 1, 98 etc. könnte man noch auflösen in "Wand", "Boden", "Kiste" usw. Danke für den Hinweis.

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group