TOC

This article is currently in the process of being translated into Spanish (~95% done).

Creating a Game: SnakeWPF:
Chapter introduction:

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!

Creating the game area

Para comenzar con nuestro juego SnakeWPF (juego de la serpiente), vamos a empezar creando un mapa, va a ser un área cerrada, por la cual se moverá la serpiente - podríamos llamarlo un nido de serpientes. He decidido que mi nido se va a parecer a un tablero de ajedrez, con cuadrados iguales, que van a tener el mismo tamaño que el cuerpo de la serpiente. Vamos a crear el mapa de dos formas: una de ellas será desde el XAML, porque es fácil, mientras que los cuadrados del fondo los dibujaremos desde el código, porque es algo repetitivo y dinámico.

XAML para el área del juego

Empecemos con el XAML – usaremos una ventana simple con un Canvas (lienzo) dentro de un Border (borde) para crear el área cerrada:

<Window x:Class="WpfTutorialSamples.Games.SnakeWPFSample"  
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
xmlns:local="clr-namespace:WpfTutorialSamples.Games"  
mc:Ignorable="d"  
Title="SnakeWPF - Score: 0" SizeToContent="WidthAndHeight">  
    <Border BorderBrush="Black" BorderThickness="5">  
<Canvas Name="GameArea" ClipToBounds="True" Width="400" Height="400">  

</Canvas>  
    </Border>  
</Window>

Nuestro juego ser vería así:

Usamos un Canvas como el área del juego porque nos permite añadir controles en la posición que queramos dentro de él. Lo haremos mas tarde, pero de momento presta atención a las siguientes cosas:

  • Ningún alto ni ancho ha sido definido para la ventana – en su lugar, las hemos definido para el Canvas ya que es la parte de la que necesitamos tener el control. Más tarde nos ocuparemos de que la ventana se ajuste al tamaño del Canvas con el valor SizeToContent en las propiedades WidthAndHeight de la ventana.
  • Ponemos a True la propiedad ClipToBounds del Canvas – esto es importante ya que, de otra forma, los controles que añadamos se expandirían más allá de los límites del panel Canvas.

Dibujando el fondo desde el código.

Como ya mencioné, quiero un tablero de damas como fondo del área del juego. Consiste en muchos cuadrados, así que es mas fácil añadirlos desde el código de la aplicación (o usar una imagen, ¡pero eso no es tan dinámico!). Necesitamos hacer este en el momento en el que los controles dentro de la ventana han sido inicializados/renderizados, y por suerte para nosotros, la ventana tiene un evento para eso: El evento ContentRendered. Lo añadiremos en la declaración de la ventana.

Title="SnakeWPF - Score: 0" SizeToContent="WidthAndHeight" ContentRendered="Window_ContentRendered"

Ahora vayamos al código y empecemos. Lo primero que haremos será definir el tamaño que usaremos para dibujar a la serpiente, los cuadrados del fondo, etc. Lo podemos escribir al inicio de la clase:

public partial class SnakeWPFSample : Window
{
    const int SnakeSquareSize = 20;
    .....

Ahora, en nuestro evento ContentRendered vamos a llamar al método DrawGameArea(), que será el que realice todo el trabajo. Debería de quedar así:

private void Window_ContentRendered(object sender, EventArgs e)  
{  
    DrawGameArea();  
}  

private void DrawGameArea()  
{  
    bool doneDrawingBackground = false;  
    int nextX = 0, nextY = 0;  
    int rowCounter = 0;  
    bool nextIsOdd = false;  

    while(doneDrawingBackground == false)  
    {  
Rectangle rect = new Rectangle  
{  
    Width = SnakeSquareSize,  
    Height = SnakeSquareSize,  
    Fill = nextIsOdd ? Brushes.White : Brushes.Black  
};  
GameArea.Children.Add(rect);  
Canvas.SetTop(rect, nextY);  
Canvas.SetLeft(rect, nextX);  

nextIsOdd = !nextIsOdd;  
nextX += SnakeSquareSize;  
if(nextX >= GameArea.ActualWidth)  
{  
    nextX = 0;  
    nextY += SnakeSquareSize;  
    rowCounter++;  
    nextIsOdd = (rowCounter % 2 != 0);  
}  

if(nextY >= GameArea.ActualHeight)  
    doneDrawingBackground = true;  
    }  
}

Como he mencionado anteriormente, estos artículos requieren de algo más de conocimiento de C# que en el resto de este tutorial, así que no voy a ir línea por línea, pero aquí os doy una descripción general de lo que hemos hecho: Dentro del blucle while, creo constantemente instancias del control Rectangle y las añadimos al Canvas (El área del juego). Llenamos el rectángulo con el color blanco o negro, y usamos nuestra constante SnakeSquareSize como valor para la anchura y la altura ya que queremos cuadrados. En cada iteración del bucle, usamos nextX y nextY para controlar cuando movernos a la siguiente línea (es decir, cuando llegamos al borde derecho) y para cuando detener el bucle (que será cuando lleguemos abajo y a la derecho al mismo tiempo).

Here's the result:

Resumen

En este artículo hemos definido el XAML con la finalidad de alojar todo el contenido del juego, y hemos “pintado” el área del juego siguiendo el patrón de un tablero de damas, añadiendo el control de WPF Rectangle de color blanco o negro. El siguiente pasó será empezar con la serpiente, a la vez que con la comida que ésta ira comiendo.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!