This article has been localized into Italian 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!
Creare l'area di gioco
Per creare il nostro gioco SnakeWPF, inizieremo creando la mappa. Sarà un'area confinata, dove il serpente deve muoversi all'interno. Ho deciso che la tana del serpente dovrebbe apparire come una scacchiera, composta da quadrati di uguali dimensioni, che avranno le stesse dimensioni del corpo del serpente. Creeremo la mappa in due iterazioni: alcune saranno disposte in XAML, perché è facile, mentre disegneremo i quadrati di sfondo in Code-behind, perché è ripetitiva e dinamica.
Area di gioco XAML
Quindi, iniziamo con XAML, un semplice pannello Canvas con area di disegno all'interno di un controllo Border, per creare l'area confinata:
<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>
Il nostro gioco, ora, ha questo aspetto:
Usiamo un Canvas come area di gioco reale, perché ci consentirà di aggiungere controlli avendo il pieno controllo delle posizioni. Lo useremo in seguito, ma per ora prestiamo attenzione alle seguenti cose:
- Nessuna larghezza / altezza è definita per la Window - invece, l'abbiamo definita per la Canvas, perché questa è la parte che dobbiamo controllare. Ci assicuriamo quindi che la Window adegui le sue dimensioni di conseguenza impostando la proprietà SizeToContent su WidthAndHeight . Se avessimo invece definito la larghezza / altezza della finestra, lo spazio disponibile al suo interno dipenderebbe da quanto bordo ha usato il sistema operativo per Windows, che potrebbe dipendere da temi ecc.
- Impostiamo la proprietà ClipToBounds su True per la tela: questo è importante, perché altrimenti i controlli che aggiungiamo sarebbero in grado di espandersi oltre i confini del pannello Canvas
Disegnare lo sfondo da Code-behind
Come accennato, voglio uno sfondo a scacchiera per l'area di gioco. È composto da molti quadrati, quindi è più facile aggiungerlo da Code-behind (o usare un'immagine, ma così non è dinamico!). Dobbiamo farlo non appena tutti i controlli all'interno della finestra sono stati inizializzati / renderizzati e, fortunatamente per noi, la finestra ha l'evento: ContentRendered . Ci iscriveremo a questo evento nella dichiarazione Window:
Title="SnakeWPF - Score: 0" SizeToContent="WidthAndHeight" ContentRendered="Window_ContentRendered"
Ora passiamo a Code-behind e cominciamo. Prima di tutto, dobbiamo definire una size da usare quando si disegna il serpente, i quadrati di sfondo ecc. Può essere fatto nella parte superiore della classe Window:
public partial class SnakeWPFSample : Window
{
const int SnakeSquareSize = 20;
.....
Ora, nel nostro evento ContentRendered chiameremo il metodo DrawGameArea () , che farà tutto il lavoro. Appare così:
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;
}
}
Come accennato in precedenza, questi articoli richiedono un po' più di conoscenza C# rispetto al resto degli articoli in questo tutorial, quindi non spiegherò ogni riga, ma ecco una descrizione generale di ciò che facciamo: all'interno del ciclo while, creiamo continuamente istanze del controllo Rectangle e che aggiungo al Canvas ( GameArea ). Il rettangolo sarà colorato di bianco o nero e userò la nostra costante SnakeSquareSize sia in larghezza che in altezza, poiché vogliamo che sia un quadrato. Ad ogni iterazione, utilizziamo nextX e nextY per controllare quando passare alla riga successiva (quando raggiungiamo il bordo destro) e quando fermarci (quando raggiungiamo contemporaneamente il bordo inferiore e quello destro).
Qui puoi vedere il risultato:
Riassumendo
In questo articolo, abbiamo definito tramite XAML una finestra per ospitare tutto il contenuto del gioco e abbiamo "dipinto" un motivo a scacchiera nell'area di gioco, aggiungendo ad esso i controlli WPF Rectangle in bianco e nero. Il prossimo passo sarà iniziare ad aggiungere il serpente e il cibo che mangerà.