C# DeltaEngine Snake

Guten Morgen,

ich arbeite derzeit fleißig daran, mich mit der Spieleprogrammierung auseinanderzusetzen und sitze derzeit vor einem Snake Klon. Derzeit lässt sich die Schlange steuern…und das wars im Moment auch schon.

Das Problem besteht darin, dass ich beim Bewegen der Schlange ja nichtnur einen ‚neuen‘ Kopf bauen, sondern auch das letzte Stück der Schlange entfernen muss. Und letzteres bereitet mir Schwierigkeiten.

Das gesamte Spielfeld wird in einem 2D-Array gespeichert. Den Array habe ich gewählt, da ich plane, später eine Art „Levelbuilder“ zu schreiben, der eine Textdatei ausliest und bestimmte Zeichen in Spielelemente umwandelt (Items, Wände etc). Zum Beispiel:

##########
#000100###
#00020000#
##000000##
##00000###
#0000000##
##00##000#
#000##0#0#
#00000003#
##########

- Wand, 0 - leer, 1 - Körper, 2 - Kopf, 3 - Item

Die eigentliche Frage: Wie finde ich das Schwanzteil? Gibt es einen einfacheren Weg, um das Spielfeld zu zeichnen?

Die Board.cs:

class Board
{
#region Variablen
Rectangle drawArea = ScreenSpace.DrawArea;

Material2D mBackground = new Material2D(„SpaceBackground“);
Material2D mHead = Material2D.Default;

int iHeadPositionX = 0;
int iHeadPositionY = 49;

float fSpeed = 0.25f;
float fTime = 0.0f;

public static int[,] boardArray = new int[100, 100];

string sDirection = „r“;
#endregion

#region Constructor
public Board()
{
//Spielbrett mit 0’en füllen
fillBoard();
}
#endregion

#region Run
public void Run()
{
#region Input
//Auf Tastatureingaben reagieren
if (Input.Keyboard.CursorUpIsPressed && sDirection != „d“)
sDirection = „u“;
if (Input.Keyboard.CursorDownIsPressed && sDirection != „u“)
sDirection = „d“;
if (Input.Keyboard.CursorLeftIsPressed && sDirection != „r“)
sDirection = „l“;
if (Input.Keyboard.CursorRightIsPressed && sDirection != „l“)
sDirection = „r“;
#endregion

#region UpdateSnake
//Snake bewegen
move(sDirection);
#endregion

#region Draw
mBackground.Draw(Rectangle.One);
Font.Default.DrawTopLeft("FPS: " + Time.Fps);

//Das Spielbrett zeichnen
//0 - leer; 1 - Körper; 2 - Kopf;
for (int i = 0; i = fSpeed)
{
if (Direction == „u“)
{
//Kopf im boardArray verschieben
boardArray[iHeadPositionX, iHeadPositionY - 1] = 2;
//‚alten Kopf‘ zum Körper machen
boardArray[iHeadPositionX, iHeadPositionY] = 1;
//Variable mit der Kopfposition updaten
iHeadPositionY–;
//TODO: Letztes Stück der Schlange entfernen
}
else if (Direction == „d“)
{
boardArray[iHeadPositionX, iHeadPositionY + 1] = 2;
boardArray[iHeadPositionX, iHeadPositionY] = 1;
iHeadPositionY++;
}
else if (Direction == „r“)
{
boardArray[iHeadPositionX + 1, iHeadPositionY] = 2;
boardArray[iHeadPositionX, iHeadPositionY] = 1;
iHeadPositionX++;
}
else if (Direction == „l“)
{
boardArray[iHeadPositionX - 1, iHeadPositionY] = 2;
boardArray[iHeadPositionX, iHeadPositionY] = 1;
iHeadPositionX–;
}

//reseten des Timers
fTime = 0.0f;
}
}
}

Hi,
für dein Problem habe ich zwar keine wirkliche Lösung aber eine Frage zu der Umsetzung. Womit hast du das gemacht? Weil XNA sieht anders aus.
Lg Knerd

Hallo,

ich habe mir Deinen Code nicht angeschaut, jedoch würde ich die Schlange über eine Liste von Elementen verwalten.
Jedes Element beinhaltet seine eigenen Koordinaten für die Spielfeldposition. Das erste Element der Liste ist der Kopf, das letzte entsprechend der Schwanz. Beim Vorrücken der Schlange fügst Du an die nullte Position der Liste ein neues Element ein, was dann der neue Kopf ist, und das letzte Element wird gelöscht, sodass das vorletzte den neuen Schwanz bildet.

Gruß
Thomas

Der Titel verrät es :smiley:
deltaengine.net

http://msdn.microsoft.com/de-de/library/7977ey2c.aspx

Eine Queue ist dafür nicht geeignet, da auch auf die Elemente innerhalb der Schlange zugegriffen werden muss. Besser eignet sich eine List oder eine LinkedList.

Nico

Hi

Auch ich habe deinen code nicht gelesen :wink: Aber ich erzähl dir wie ichs gemacht hatte bei meinen Snakeclone damals:

Auf dem Spielfeld sind die Schlangenteile mit fortlaufenden Nummern gespeichert, beginnend beim Schwanz. Dort wo der Schwanz ist steht eine 1, das darausfolgende Teil hat die 2, usw. bis zum Kopf, derhat die Nummer n.
Zusätzlich speicher ich die Position vom Kopf und vom Schwanz. In jedem Spielschritt lösche ich nun das Schwanzende (die Position habe ich ja) und suche die 4 umgebenden Felder nach der kleinsten Ziffer ab. Dort liegt dann entsprechend das nächste Schwanzende und du kannst es speichern. Das hat für mich gegenüber der Methode mit der Liste aller Schlangenteile den Vorteil, dass du nicht in jedem Schritt die Liste umsortieren musst (ist zwar rechentechnsich kein Aufwand aber doch irgendwie unschön). Logischerweise wird die Nummer des Schwanzendes im Verlauf des Spiels immer größere Zahlen annehmen.

Für diese Methode reicht es natürlich nicht die Map aus char’s aufzubauen. Du solltest dann int oder so nehmen. Das Einlesen aus einer Datei is dann aber trotzdem problemlos möglich. Objekte wie Luft oder Wände können dann mit Zahlen