Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - 3D bludiště v XNA - Editor map

V minulé lekci, 3D bludiště v XNA - Kamera a mřížka, jsme si vytvořili kameru a mřížku.

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 - 3D bludiště v XNA

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 - 3D bludiště v XNA

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ě, 3D bludiště v XNA - Mapy, zdi a podlaha.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

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

 

Předchozí článek
3D bludiště v XNA - Kamera a mřížka
Všechny články v sekci
3D bludiště v XNA
Přeskočit článek
(nedoporučujeme)
3D bludiště v XNA - Mapy, zdi a podlaha
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
3 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity