TOC

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

Criando um jogo: 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!

Improving SnakeWPF: Making it look more like a game

Nos últimos artigos, construímos um jogo Snake em WPF. Implementamos todo o mecanismo do jogo e o resultado foi um jogo completamente funcional. Contudo, existe muitos melhoramentos que podemos fazer pois a implementação atual é muito simples. Portanto, nos próximos artigos vamos fazer diversos melhoramentos ao nosso jogo SnakeWPF - neste artigo vamos nos focar em melhorar o aspecto visual para que se pareça mais com um jogo!

Na sua aparência atual, com as bordas/título padrões do Windows, a nossa implementação não se parece muito com um jogo. Entretanto, foi necessário anteriormente utilizar a barra de título padrão do Windows para mostrar as informações referentes à pontuação e velocidade, e como um bônus, ganhamos automaticamente os botões de minimizar, maximizar e minimizar janela:

Até este momento, seria correto remover completamente a barra de título padrão do Windows, substituindo-a por uma customizada por nós, que deve mostrar a pontuação atual e a velocidade, além de um botão de "fechar janela" customizado. Tudo isso deve combinar com o estilo atual do jogo. Para a nossa sorte, tudo isso é fácil de ser feito utilizando o WPF.

Adicionando uma barra de título customizada

O primeiro passo é adicionar algumas propriedades e um novo evento na tag Window. Isso deve ficar da seguinte forma:

<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">

As modificações estão todas na última linha. Nos definimos a propriedade ResizeMode para NoResize e a propriedade WindowStyle para None. Isso irá remover completamente a barra de título e as bordas padrão do Windows, o que não será problema já que o nosso jogo já possui uma borda preta de 5px.

Perceba também que eu adicionei um novo evento, o MouseDown. O motivo é que ao retirar a barra de título padrão, não há mais como o usuário arrastar a janela do jogo de um ponto para outro da tela. Felizmente, há outra forma fácil de re-criar este comportamento na nossa barra de título customizada. Entretanto, ela não parece uma barra de título convencional, o que poderia causar confusão no usuário que não saberia onde arrastar a janela, então eu decidi simplificar o comportamento permitindo que toda a janela possa ser arrastada. Então, no nosso Code-behind, defina a Window_MouseDown event handler dessa forma:

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

Dessa forma, a janela pode ser arrastada independentemente de onde o ponteiro estiver na janela. O próximo passo é adicionar a nossa própria barra de título customizada, que deve mostrar a pontuação e a velocidade, além do botão de fechar a janela. A parte interna do Window XAML deve ser assim:

<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 não se esqueça de definir o evento BtnClose_Click

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

Nós anteriormente implementamos um método chamado UpdateGameStatus(), que atualizava a propriedade Titulo da nossa janela - esse método deverá ser alterado para usar os novos TextBlock's:

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

Eu irei explicar tudo o que foi feito, mas primeiro observe como jogo se parece agora:

Agora está um pouco melhor, não é mesmo? Vamos ver então o que foi feito: Como você pode ver, o controle da Border com a GameArea Canvas dentro está agora dentro de um DockPanel. Isso facilita a implementação de uma nova barra de título, no estilo de um Grid panel, no topo da Janela.

O Grid utiliza diversas técnicas interessantes do WPF que foram explicadas em outro momento neste tutorial: Nos utilizamos ColumnDefinition para dividir a área em duas áreas de mesmo tamanho (para a pontuação e a velocidade), além de uma terceira coluna de tamanho automaticamente definido para o botão de fechar a janela. Você também irá perceber que utilizamos o WPF Style para aplicar o mesmo visual para todos os controles do TextBlock, as mesmas fontes, tamanho de letra, cor e negrito foram aplicadas para todos, agradeça ao Style definido no Grid, afetando todos os TextBlock.

Perceba também como é fácil customizar o Button usado para fechar a janela, para combinar com o resto do visual do jogo, simplesmente utilizando suas propriedades padrões, WPF é muito flexível!

Resumo

Neste artigo, fizemos nossa implementação do SnakeWPF parecer muito mais com um jogo, removendo a aparência padrão do Windows e aplicando nossa própria barra de título personalizada. Nos próximos artigos, faremos muito mais melhorias!


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!