TOC

This article is currently in the process of being translated into Portuguese (~99% 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!

Creating the game area

Para criar o nosso jogo SnakeWPF, iniciaremos com a criação de um mapa. Este mapa será como uma área confinada onde a cobra poderá se mover - o ninho da cobra, se preferir! Eu decidi que o ninho da cobra se parecerá como um tabuleiro de xadrez composto por quadrados de dimensões iguais que por sua vez terá a mesma dimensão do corpo da cobra. Iremos criar o mapa em dois momentos: Parte dele será feito em XAML, porque é mais fácil, enquanto o desenho dos quadrados do mapa será feito em Code-behind porque é um trabalho repetitivo e dinâmico.

Área do jogo em XAML

Vamos começar com o código em XAML para criar a área confinada - uma janela simples com um painel Canvas dentro de um control Border.

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

Agora o nosso jogo se parece assim:

Nós usaremos um controle Canvas como a área atual do jogo porque isto nos permitirá adicionar controles a estas posições que por sua vez nos permitirá controlá-las ao longo do jogo. Nós voltaremos à este ponto mais tarde, mas por enquanto preste atenção ao seguinte:

  • Nenhuma largura/altura é definida para a janela - ao invés disso, nós definimos estes parâmetros para a Canvas porque esta é a parte que precisamos controlar. A janela terá o seu tamanho ajustado de acordo quando definimos a propriedade SizeToContent para WidthAndHeight. Se, pelo contrário, tivéssemos definido a largura/altura para a janela diretamente, o espaço interno disponível dependeria do quanto de bordas o sistema operacional usa para a janela, que por sua vez depende do tema, etc.
  • Nós defnimos a propriedade ClipToBounds como True para a Canvas - isto é importante porque de outra maneira os controles que adcionarmos seriam capazes de se expandirem para além dos limites do painel da Canvas.

Desenhando o fundo com o Code-behind

Conforme mencionado, eu quero a área do jogo como um tabuleiro de xadrez. Isto consiste de vários quadrados similares e portanto será mais fácil adicioná-los usando Code-behind (ou uma imagem, mas isso não seria tão dinâmico!). Nós precisamos criar essa área tão logo todos os controles dentro do classe Window tenham sido inicializados/processados e para a nossa sorte Window tem um evento para isso: o evento ContentRendered. Nós faremos essa inicialização/processamento na declaração de Window:

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

Abra o Code-behind e vamos começar. Primeiramente, precisamos definir um tamanho padrão para usar no desenho da cobra, dos quadrados do tabuleiro, etc. Isto pode ser feito no topo da sua classe Window:

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

Agora, no seu evento ContentRendered faremos uma chamada do método DrawGameArea() que fará todo o trabalho pesado. Isto se parecerá como:

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;  
    }  
}

Conforme mencionado anteriormente, este artigo exige um conhecimento um pouco mais profundo de C# do que o restante dos artigos neste tutorial, dessa forma eu não iriei comentar cada linha do código. Contudo, aqui está uma descrição geral do que é feito: Dentro do comando while nós criamos continuamente instâncias do controle Rectangle e as adicionamos à Canvas (GameArea). Os retângulos são preenchidos com as cores branca ou preta e usam a contante SnakeSquareSize para a espessura e altura, dado que desejamos um quadrado. Para cada iteração, usamos os controles nextX e nextY quando desejamos nos mover para a próxima linha (quando atingimos a borda da direita) e para pararmos (quando atingimos a base E a borda da direita ao mesmo tempo).

Aqui está o resultado:

Resumo

Neste artigo, definimos o XAML para abrigar todo o conteúdo do jogo e "pintamos" a área do jogo como um tabuleiro no padrão de um jogo de damas ou xadres adicionando controles WPF Rectangle em preto ou branco. O próximo passo será adicionar a cobra bem como a comida com a qual ela irá se alimentar.


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!