TOC

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

Creare un gioco: 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!

Migliorare SnakeWPF: renderlo più simile a un gioco

Durante gli ultimi numerosi articoli, abbiamo realizzato un fantastico gioco Snake in WPF. Abbiamo implementato tutte le meccaniche di gioco e il risultato è un gioco completamente funzionale. Tuttavia, ci sono sicuramente molti miglioramenti che potrebbero essere apportati, poiché l'implementazione attuale è minima. Quindi, nei prossimi articoli, farò diversi miglioramenti al nostro gioco SnakeWPF - in questo articolo, mi concentrerò sul rendere il nostro gioco più simile a un gioco reale!

Attualmente con la sua barra del titolo predefinita in stile Windows, la nostra applicazione non assomiglia molto a un gioco. Tuttavia, in precedenza avevamo bisogno della barra del titolo per visualizzare le informazioni su punteggio / velocità e, come bonus e abbiamo automaticamente ottenuto i pulsanti di Windows predefiniti per ridurre a icona / massimizzare / chiudere la finestra:

A questo punto, vorrei rimuovere completamente la barra del titolo di Windows predefinita e invece implementare la nostra barra di stato superiore, che dovrebbe mostrare il punteggio e la velocità attuali, nonché un pulsante di chiusura personalizzato. Tutto ciò dovrebbe corrispondere al look attuale del gioco. Fortunatamente per noi, questo è abbastanza facile da realizzare con WPF.

Aggiunta di una barra del titolo personalizzata

Il primo passo è aggiungere un paio di proprietà e un nuovo evento alla dichiarazione di Windows. Ora dovrebbe essere così:

<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" ContentRendered="Window_ContentRendered" KeyUp="Window_KeyUp"
ResizeMode="NoResize" WindowStyle="None" Background="Black" MouseDown="Window_MouseDown">

Le modifiche sono tutte nell'ultima riga. Impostiamo ResizeMode su NoResize e WindowStyle su Nessuno . Questo rimuoverà completamente la barra del titolo e tutti i bordi predefiniti intorno alla Finestra - questo non è un problema per noi, perché l'area principale del nostro gioco ha già un bordo nero di 5 px.

Noterai anche che mi sono iscritto a un nuovo evento: l'evento MouseDown . Il motivo è che poiché perdiamo la barra del titolo predefinita, l'utente non può più trascinare il gioco da un punto dello schermo all'altro. Fortunatamente per noi, è facile ricreare questo comportamento, ad es. sulla nostra barra del titolo personalizzata. Tuttavia, poiché non assomiglia alla normale barra del titolo, l'utente potrebbe essere confuso su dove trascinare, quindi ho deciso semplicemente di rendere trascinabile l'intera superficie della finestra. Quindi, nel Code-behind, definisci il gestore dell'evento Window_MouseDown in questo modo:

private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
    this.DragMove();
}

Ora la tua finestra può essere trascinata in giro, indipendentemente da dove usi il mouse. Il prossimo passo è aggiungere la nostra barra del titolo personalizzata, che dovrebbe visualizzare il punteggio e la velocità, nonché un pulsante di chiusura. La parte interna di Window XAML ora dovrebbe apparire così:

<DockPanel Background="Black">  
    <Grid DockPanel.Dock="Top" Name="pnlTitleBar">  
<Grid.ColumnDefinitions>  
    <ColumnDefinition Width="*" />  
    <ColumnDefinition Width="*" />  
    <ColumnDefinition Width="Auto" />  
</Grid.ColumnDefinitions>  

<Grid.Resources>  
    <Style TargetType="TextBlock">  
<Setter Property="FontFamily" Value="Consolas" />  
<Setter Property="Foreground" Value="White" />  
<Setter Property="FontSize" Value="24" />  
<Setter Property="FontWeight" Value="Bold" />  
    </Style>  
</Grid.Resources>  

<WrapPanel Margin="10,0,0,0">  
    <TextBlock>Score:</TextBlock>  
    <TextBlock Name="tbStatusScore">0</TextBlock>  
</WrapPanel>  
<WrapPanel Grid.Column="1">  
    <TextBlock>Speed:</TextBlock>  
    <TextBlock Name="tbStatusSpeed">0</TextBlock>  
</WrapPanel>  
<Button Grid.Column="2" DockPanel.Dock="Right" Background="Transparent" Foreground="White" FontWeight="Bold" FontSize="20" BorderThickness="0" Name="btnClose" Click="BtnClose_Click" Padding="10,0">X</Button>  
    </Grid>  
    <Border BorderBrush="Black" BorderThickness="5">  
<Canvas Name="GameArea" ClipToBounds="True" Width="400" Height="400">  

</Canvas>  
    </Border>  
</DockPanel>

E non dimenticare di definire il gestore di eventi BtnClose_Click :

private void BtnClose_Click(object sender, RoutedEventArgs e)
{
    this.Close();
}

Abbiamo precedentemente implementato un metodo chiamato UpdateGameStatus () , che ha aggiornato la proprietà Title della finestra - questo metodo dovrebbe essere modificato per usare i nuovi TextBlock:

private void UpdateGameStatus()
{    
    this.tbStatusScore.Text = currentScore.ToString();
    this.tbStatusSpeed.Text = gameTickTimer.Interval.TotalMilliseconds.ToString();
}

Ti dirò tutto su quello che abbiamo appena fatto, ma prima, vediamo come appare il gioco ora:

Sembra un po 'più bello, giusto? Ma parliamo di ciò che abbiamo appena fatto: come puoi vedere, il controllo Border originale con GameArea Canvas al suo interno è stato ora circondato da un DockPanel . Questo ci consente di collegare facilmente la nostra nuova barra del titolo, sotto forma di un pannello Grid, nella parte superiore della finestra.

la Grid utilizza diverse fantastiche tecniche WPF che sono state discusse altrove in questo tutorial: usiamo ColumnDefinition per dividere l'area in due aree di uguali dimensioni (per il punteggio e la velocità), oltre a una terza colonna di dimensione automatica per il pulsante di chiusura. Noterai anche che utilizziamo gli Style di WPF per applicare lo stesso aspetto visivo a tutti i controlli TextBlock: lo stesso carattere personalizzato, la dimensione del carattere, il colore e il peso sono applicati, grazie a uno stile definito nella griglia, destinato ai controlli TextBlock .

Nota anche come è facile personalizzare il controllo Button utilizzato per chiudere la finestra, per abbinare il resto dell'aspetto del gioco, semplicemente usando le proprietà standard: WPF è molto flessibile!

Summary

In questo articolo, abbiamo reso la nostra implementazione di SnakeWPF molto più simile a un gioco, rimuovendo l'aspetto standard di Windows e applicando la nostra barra del titolo personalizzata. Nei prossimi articoli faremo altri miglioramenti!

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!