This article has been localized into German by the community.
In this article series, we're building a complete Snake game from scratch. It makes sense to start with the Introduction and then work your way through the articles one by one, to get the full understanding.
If you want to get the complete source code for the game at once, to get started modifying and learning from it right now, consider downloading all our samples!
Kontinuierliche Bewegung mit dem DispatcherTimer
In den vorherigen Artikeln haben wir ein ansprechendes Spielfeld für unser Snake erstellt und Code für die Anzeige, bzw. Bewegung der Schlange hinzugefügt. Jedoch soll der Code nicht nur einmal sondern immer wieder aufgerufen werden, um die Schlange solange in Bewegung zu halten wie das Spiel läuft. Mit anderen Worten - wir benötigen einen Timer.
Generell ermöglicht der Timer-Mechanismus die mehrmalige Wiederholung eines Aufgabenschritts abhängig von einem Intervall. In anderen Worten, bei jedem Tick des Timer wird ein Teil des Programmcodes ausgeführt, basierend auf einem definierten Intervall. Auf diese Art können wir unsere Snake kontinuierlich bewegen. Somit fügen wir einen DispatcherTimer hinzu:
public partial class SnakeWPFSample : Window
{
private System.Windows.Threading.DispatcherTimer gameTickTimer = new System.Windows.Threading.DispatcherTimer();
....
Nun fügen wir im Window-Konstruktor das einzige Event hinzu, das Tick-Event.
public SnakeWPFSample()
{
InitializeComponent();
gameTickTimer.Tick += GameTickTimer_Tick;
}
Hier wird das Event implementiert:
private void GameTickTimer_Tick(object sender, EventArgs e)
{
MoveSnake();
}
Bei jedem Tick wird das Tick-Event aufgerufen, welches wiederum die vorher implementierte MoveSnake()-Methode aufruft. Schließlich waren für das Ergebnis der angezeigten, sich bewegenden Snake nur die Erstellung der Snake-Teile und der Start des Timers nötig. Wir werden noch eine Methode StartNewGame() erstellen, um sowohl das erste als auch alle zusätzlichen Spielrunden nach einem Game Over zu starten. Wir starten jedoch mit einer sehr einfachen Version. Später werden wir weitere Funktionen einbauen. Lass uns die Snake starten!
Als erstes werden weitere Konstanten für das Starten eines neuen Spiels hinzugefügt.
public partial class SnakeWPFSample : Window
{
const int SnakeSquareSize = 20;
const int SnakeStartLength = 3;
const int SnakeStartSpeed = 400;
const int SnakeSpeedThreshold = 100;
......
Hier werden nur die ersten drei Konstanten genutzt. Diese bestimmen die Größe, die Länge und die Geschwindigkeit der Snake. Wir setzen das SnakeSpeedThreshold später ein, aber nun folgt zuerst eine einfache Implementierung der StartNewGame()-Methode.
private void StartNewGame()
{
snakeLength = SnakeStartLength;
snakeDirection = SnakeDirection.Right;
snakeParts.Add(new SnakePart() { Position = new Point(SnakeSquareSize * 5, SnakeSquareSize * 5) });
gameTickTimer.Interval = TimeSpan.FromMilliseconds(SnakeStartSpeed);
// Draw the snake
DrawSnake();
// Go!
gameTickTimer.IsEnabled = true;
}
Als erstes setzen wir - basierend auf den Ausgangswerten - die Konstanten snakeLength und snakeDirection. Dann fügen wir einen Teil der snakeParts-List hinzu (mehr dazu später). Wir legen eine gute Startposition fest und nutzen nochmal die Konstante SnakeSquareSize-Konstante um eine optimale Position zu berechnen. Somit können wir die Snake durch den Aufruf der DrawSnake()-Methode zeichnen und den Timer und dadurch die Bewegung der Snake starten.
Wir sind jetzt endlich an dem Punkt angelangt, an dem wir uns fast zurücklehnen und die allererste Version von etwas genießen können, das tatsächlich wie ein Spiel aussieht. Tatsächlich müssen wir jetzt nur noch die StartNewGame() Methode aufrufen. Dies sollte natürlich gemacht werden, wenn der Benutzer bereit ist, aber um zu überprüfen, ob alles funktioniert, machen wir es einfach, sobald alles andere initialisiert ist - wir verlassen uns wieder auf das ContentRendered Ereignis des Fensters, das wir in einem der ersten Artikel hinzugefügt haben. Fügen Sie einfach einen Aufruf zu unserer StartNewGame() -Methode hinzu und wir sind endlich bereit zum Kompilieren und Ausführen:
private void Window_ContentRendered(object sender, EventArgs e)
{
DrawGameArea();
StartNewGame();
}
Wenn Sie alles wie beschrieben gemacht haben, sollten Sie nun in der Lage sein, das Spiel zu starten und zu sehen, wie die Schlange erstellt wird, und sofort damit beginnt sich zu bewegen:
Beachten Sie, wie die Schlange aus dem Nichts als einzelnes Quadrat erscheint und dann auf eine Länge von drei Quadraten wächst. Das passiert, weil wir nur einen Teil zur Liste snakeParts hinzufügen, aber jedes Mal, wenn die Methode MoveSnake() vom Timer aufgerufen wird, wird ein neuer Teil hinzugefügt (um sie wachsen zu lassen), während nur Schwanzteile entfernt werden, wenn die aktuelle Länge im Begriff ist, die gewünschte Länge der Schlange zu überschreiten, die bei 3 beginnt (bestimmt durch die SnakeStartLength -Konstante).
Zusammenfassung
Nun haben wir eine Snake, die sich bewegt. Das ist toll! Aber wie man an der Animation oben erkennen kann, sind immer noch Dinge zu tun. Es gibt kein Futter für die Snake und wenn die Snake an die Mauer stößt passiert nichts. In den folgenden Artikeln kümmern wir uns um diese Aspekte.