TOC

This article has been localized into Dutch by the community.

Een Spel Creëren: 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!

Het spelgebied creëren

Om ons SnakeWPF spel te creëren, zullen we starten met het maken van het spelgebied. Het zal een afgesloten gebied zijn, waarin de slang zich kan verplaatsen: denk aan een 'slangenkuil'. Ik heb er voor gekozen om mijn 'slangenkuil' er te laten uitzien als een schaakbord; vierkantjes van gelijke grootte met dezelfde dimensies als het lichaam van de slang. Het gebied zal in twee iteraties worden opgebouwd: een deel ervan zal vorm krijgen via XAML, omdat het gemakkelijk te doen is, terwijl de achtergrond (de vierkantjes) via Code-behind zal getekend worden: het is repetitief en dynamisch.

Spelgebied - XAML

Laten we starten met het gedeelte XAML: een simpel Window met een Canvaspaneel omsloten door een Border-element, om het afgesloten gebied te creëren.

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

Ons spel ziet er nu als volgt uit:

We gebruiken een Canvas als het eigenlijke spelgebied, omdat het ons toelaat om besturingselementen toe te voegen waarbij we volledige controle hebben over hun posities op het scherm. We zullen dit later doen, maar let eerst even goed op de volgende zaken:

  • Er is geen breedte of hoogte ingegeven voor het Window; we hebben dit gedefinieerd voor het Canvas, omdat we dit element volledig moeten kunnen controleren. Om er daarnaast voor te zorgen dat het Window zich aanpast aan het Canvas, zetten we de eigenschap SizeToContent op WidthAndHeight. Hadden we daarentegen de breedte of hoogte van het Window gedefinieerd, zou de beschikbare ruimte voor het Canvas afhangen van de dikte van Window borders in het gebruikte Operating System; dit is o.a. afhankelijk van themes.
  • Voor het Canvas is de ClipToBounds eigenschap op True gezet. Dit is belangrijk, omdat de besturingselementen die we later toevoegen zich anders over de randen van het Canvas zouden kunnen uitbreiden (en we willen geen grensoverschrijdend gedrag :)).

De achtergrond tekenen vanuit Code-behind

Zoals hierboven vermeld, wil ik een dambordpatroon voor de achtergrond van het spelgebied. Het bestaat uit een heleboel vierkantjes, dus is het makkelijker om deze vanuit Code-behind toe te voegen (of we kunnen een afbeelding toevoegen, maar dat is niet dynamisch!). De achtergrond toevoegen moet gebeuren van zodra alle elementen binnen het Window geïnitialiseerd en gerenderd zijn; gelukkig heeft het Window hier een event voor: het ContentRendered event. We abonneren hierop in de Windowdeclaratie:

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

Ga naar de Code-behind en laten we beginnen. Allereerst moeten we een maat bepalen waarmee we de slang, de vierkantjes en dergelijke zullen tekenen. Dit kan je bovenaan de Window-klasse doen:

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

Nu zullen we in ons ContentRendered event de methode DrawGameArea() oproepen, die al het harde werk zal doen voor ons. Dit ziet er zo uit:

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

Zoals vermeld in de Inleiding, wordt er voor deze hoofdstukken meer C#-kennis verwacht dan in de rest van deze tutorial. Ik zal dus niet over elke regel gaan, maar hier is een algemene omschrijving van wat we net hebben neergeschreven: binnen de while loop creëren we voortdurend instanties van het Rectangle-element dat we toevoegen aan het Canvas (Spelgebied). Dit nieuwe element wordt ingevuld met ofwel een witte of een zwarte Brush, en zowel de Width als de Height worden gelijkgesteld aan de eerder gecreëerde constante waarde SnakeSquareSize zodat we een vierkant verkrijgen. Bij elke iteratie gebruiken we nextX en nextY om te bepalen wanneer we naar de volgende rij moeten bewegen (als de rechter border wordt bereikt) en wanneer we moeten stoppen (als zowel de rechter als de beneden border worden bereikt).

Hier zie je het resultaat:

Samenvatting

In dit artikel hebben we de XAML-code geschreven die al de spelinhoud organiseert en we hebben het spelgebied "beschilderd" met een dambordpatroon door WPF Rectangle-elementen in wit en zwart toe te voegen. De volgende stap is het toevoegen van de eigenlijke slang, en het voedsel.


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!