3. díl - 3D bludiště v XNA - Editor map

C# .NET XNA game studio 3D bludiště 3D bludiště v XNA - Editor map

V dnešním díle si uděláme editor map pro naše 3D bludiště. Editor nebude v XNA, ale jednoduše ve Windows Forms. To je z toho důvodu, že nás u editoru nezajímá rychlost vykreslování, ale vyžadujeme dialogy a další klikátka, které by byly v XNA zbytečně pracné.

Návrh formulářů

Založme si tedy nový projekt, Windows Forms aplikaci. Pojmenujme ho "EditorBludiste". Jako tomu bylo doteď, stále je předpokladem, že umíte základy .NETu a tedy i Windows Forms, pokud ne, podívejte se do sekce Okenní aplikace v C#.

Zezačátku si vytvoříme potřebné formuláře aplikace, bude mít dva.

Formulář editoru

Formuláři nastavíme Text na "Editor bludiště" a StartPosition na CenterScreen. Přejmenujeme ho z Form1 na FormEditor. Vložíme do něj MenuStrip, pojmenovaný jednoduše menuStrip. Naklikáme do něj 2 položky: Mapa a O programu. Do Mapa ještě vložíme 3 položky: Nová, Načíst a Uložit. Vzniklé MenuItemy přejmenujeme tak, aby neměly v názvu diakritiku. Do O programu vložíme stejnojmnenný item O programu.

Form trochu roztáhneme a umístíme na něj Panel (pojmenujeme ho mapaPanel). Ten roztáhneme po celém formu, jen dole necháme pruh volného místa. Nastavíme mu všechny 4 Anchor a AutoScroll na True. Do levého horního rohu panelu vložíme PictureBox pojmenovaný "mapaPictureBox". Důležité je, aby byl PictureBox opravdu v Panelu a ne jen na něm. Na PictureBox budeme vykreslovat naši mapu, Panel nám poté umožní mapou posouvat v případě, kdy se nevejde do okna.

Do dolního volného pruhu ve formu vložíme doleva Label typPolickaLabel s textem "Typ políčka" a ComboBox typPolickaComboBox s Itemy: "Zeď", "Start", "Cíl", "Prázdno". Oběma kontrolkám nastavíme Anchor na Left Bottom. Do pruhu vložíme ještě doprava Label hranaLabel s textem "Délka hrany" a Archor na Bottom Right. Vedle něj přidáme NumericUpDown s názvem hranaNumericUpdown. Tím se bude nastavovat délka hrany mapy, budeme tedy moci mapu zvětšovat či zmenšovat. NumericUpDown nastavíme také Anchor na Bottom Right, Minimum na 8 a Value na 32.

Měli byste dospět k podobnému výsledku:

Formulář pro editor bludiště v C# .NET

Formulář pro novou mapu

Druhým formulářem je dialog pro vytvoření nové mapy. Je velmi jednoduchý, obsahuje pouze zadání rozměrů mapy a tlačítko vytvořit.

Přidáme si k projektu tedy další formulář (pravým na projekt v Solution Exploreru -> Add -> New Item -> Windows Form) a pojmenujeme ho FormNovaMapa.cs. Nastavíme mu Text na "Nová mapa", position na CenterScreen a zakážeme změnu jeho velikosti nastavením FormBorderStyle na FixedDialog. Do formu vložíme 2 labely pojmenované sirkaLabel a vyskaLabel. Texty labelů jsou vám asi jasné, budou "Šířka" a "Výška". Pro hodnoty si přidáme 2x NumericUpDown, pojmenované sirkaNumericUpDown a vyskaNumericUpDown. Minimum nastavíme oběma na 8. Formulář dokončíme přidáním tlačítka pojmenovaného vytvoritButton s textem Vytvořit.

Form by měl vypadat asi takto:

Formulář pro novou mapu v C# .NET

Mapa

Tím máme formuláře hotové. Jak víme, logika aplikace do formuláře nepatří. Proto si nejprve vytvoříme třídu Mapa, která bude reprezentovat herní mapu a obsluhovat vše potřebné. Teprve poté s ní budeme ve formu pracovat.

Přidejme si tedy k projektu třídu Mapa.cs a přidejme jí modifikátor public.

public class Mapa
{

}

Třída bude spravovat políčka mapy, která jsou v paměti reprezentována jako dvourozměrné pole intů. Tento atribut dáme třídě jako veřejný:

public int[,] policka;

Pro lepší manipulaci přidáme vlastnosti pro přístup k šířce a výšce mapy. U vícerozměrných polí se na velikosti (dimenze) ptáme pomocí parametrizované metody GetLength():

 public int Sirka
{
        get { return policka.GetLength(0); }
}

public int Vyska
{
        get { return policka.GetLength(1); }
}

Třídě vytvoříme jednoduchý konstruktor, který založí novou mapu (inicializuje proměnnou policka). V C# se můžeme spolehnout na to, že jsou v poli samé nuly (ty označují ve hře prázdé políčko).

public Mapa(int sirka, int vyska)
{
        policka = new int[sirka, vyska];
}

Datovou strukturu s mapou tedy třída již ovládá dobře. Teď zbývá implementovat 3 věci: uložení mapy do souboru, načtení mapy ze souboru a vykreslení mapy na Graphics nějaké komponenty.

Uložení

Mapa bude uložena v textovém souboru, jednotlivé hodnoty budou oddělené čárkou, řádek v poli odpovídá řádku v souboru. Soubor s mapou tedy vypadá např. takto:

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0
0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0
0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0
0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0
0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0
0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0
0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0
0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0
0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0
0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

Přidejme si metodu Uloz(), jako parametr jí dáme cestu k souboru, kam se má mapa vytvořit. Ukažme si kompletní kód metody a záhy si jej popišme:

public void Uloz(string cesta)
{
        using (StreamWriter sw = new StreamWriter(cesta))
        {
                for (int j = 0; j < Vyska; j++)
                {
                        // vytvoření pole z řádku
                        int[] radek = new int[Sirka];
                        for (int i = 0; i < Sirka; i++)
                                radek[i] = policka[i, j];
                        // spojení pole do řetězce pomocí separátorů
                        string spojenyRadek = String.Join(",", radek);
                        // zapsání řetězce
                        sw.WriteLine(spojenyRadek);
                }
                sw.Flush();
        }
}

V using bloku si vytvoříme instanci StreamWriteru nasměrovanou na příslušnou cestu. For cyklem projedeme řádky pole policka a každý řádek si překopírujeme do pomocného jednorozměrného pole. Budeme používat právě cyklus for, jelikož nám řídící proměnná bude zároveň sloužit jako index do našeho pole policka. Tato pole pomocí funkce Join() převedeme na textový řetězec, kde jsou prvky z pole oddělené čárkou. Není už nic jednoduššího, než vzniklý řádek zapsat do souboru. Nakonec zavoláme metodu Flush() pro vyprázdnění bufferu a máme uloženo.

Načtení

Přidejme si metodu Nacti(), také bude mít parametr s cestou k souboru a bude vypadat takto:

public void Nacti(string cesta)
{
        string[] radky = File.ReadAllLines(cesta);
        for (int j = 0; j < radky.Length; j++)
        {
                // rozbití řádku podle separátoru
                string[] radek = radky[j].Split(',');
                // založení nového pole pro mapu podle délky 1. řádku
                if (j == 0)
                        policka = new int[radek.Length, radky.Length];
                // naparsování hodnot v řádku
                for (int i = 0; i < radek.Length; i++)
                        policka[i, j] = int.Parse(radek[i]);
        }
}

Pro pohodlnější manipulaci s řádky si je načteme všechny najednou. Uděláme to pomocí statické metody ReadAllLines() na třídě File.

Jednotlivé řádky proiterujeme opět for cyklem. Každý řádek si metodou Split() rozbijeme podle čárky na pole podřetězců, obsahující dané hodnoty. Pokud jsme v první iteraci cyklu, tak pole policka inicializujeme. Nemohli jsme to udělat dříve, jelikož teprve zde známe počet políček na řádku, tedy šířku mapy. Nakonec v každém běhu cyklu převedeme rozbitý řádek postupně na čísla a dosadíme je na příslušná místa v poli policka. Máme hotovo.

Vykreslení a dokončení editoru si necháme na příště.


 

Stáhnout

Staženo 170x (59.38 kB)
Aplikace je včetně zdrojových kódů v jazyce C# XNA

 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (3 hlasů) :
4.666674.666674.666674.666674.66667


 


Miniatura
Všechny články v sekci
3D bludiště v XNA

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!