IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
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í.

5. diel - 3D bludisko v XNA - Dokončenie editoru máp

V tutoriále 3D bludisko v XNA - Editor máp sme načal tvorbu editora 3D bludisko. Dnes editor dokončíme a sprevádzkujeme. Ako prvý dokončí našu triedu Mapa, v ktorej nám chýba implementovať jej vykreslenie.

Vykreslenie mapy

Metóda k vykreslenie mapy bude teda tiež v triede Mapa.cs. V parametri metódy si odovzdáme Graphics, na ktorý sa má kresliť. Rovnako tak si odovzdáme aj veľkosť hrany políčka. Rôzne hodnoty nám umožní vykresľovať zväčšenou či zmenšenú mapu. Keďže nie sme žiadni začiatočníci, ukážme si opäť kód metódy a vzápätí si ho popíšme.

public void Vykresli(Graphics g, int hrana)
{
    // mřížka
    for (int j = 0; j <= Vyska; j++)
    {
        for (int i = 0; i <= Sirka; i++)
        {
            g.DrawLine(Pens.Gray, new Point(0, j * hrana), new Point(Sirka * hrana - 1, j * hrana)); // -
            g.DrawLine(Pens.Gray, new Point(i * hrana, 0), new Point(i * hrana, Vyska * hrana - 1)); // |
        }
    }

    // Políčka
    for (int j = 0; j < Vyska; j++)
    {
        for (int i = 0; i < Sirka; i++)
        {
            switch (policka[i, j])
            {
                // Zeď
                case 1:
                    g.FillRectangle(Brushes.CornflowerBlue, i * hrana, j * hrana, hrana, hrana);
                break;
                // Start
                case 99:
                    g.FillEllipse(Brushes.GreenYellow, i * hrana, j * hrana, hrana, hrana);
                    g.DrawString("S", new Font("Arial", hrana / 2), Brushes.Green, i * hrana + (hrana / 6), j * hrana + (hrana / 6));
                break;
                // Cíl
                case 100:
                    g.FillEllipse(Brushes.Purple, i * hrana, j * hrana, hrana, hrana);
                    g.DrawString("C", new Font("Arial", hrana / 2), Brushes.Red, i * hrana + (hrana / 6), j * hrana + (hrana / 6));
                break;
            }
        }
    }
}

Prvé 2 cykly vykreslí na daný Graphics štvorcovú sieť, aby sa nám mapa lepšie designovala. Prvý kreslí vodorovné čiary, druhý zvislé. Tu asi nie je čo vysvetľovať.

Obdobne vykresľuje v ďalších 2 cykloch aj políčka. Typ políčka rozlíšime switchom, múr je vykreslená ako štvorec, políčka štart a cieľ ako farebná kolieska s nápismi S a C. Súradnice nápisu na políčkach i veľkosť nápisu sú pronásobeny veľkostí hrany, aby pri zoomovaní mapy zostal text približne rovnako veľký a na rovnakej pozícii.

Triedu Mapa môžeme vyhlásiť za hotovú.

Vizuálnu časť

Logika je hotová, sprevádzkuje vizuálnu časť editora, teda tú formulárové.

Ako prvý si do triedy FormEditor pridajme premennú mapa, kde budeme mať uloženú inštanciu mapy, s ktorou v editore aktuálne pracujeme:

Mapa mapa;

Do konstruktoru formulára pridajme vytvorenie novej inštancie mapy veľkosti 16x16. Ak editor spustíme, bude v ňom teda pripravená táto prázdna mapa:

mapa = new Mapa(16, 16);

Vyberieme v dizajne mapaPictureBox a naklikne mu udalosť Paint (). V tej jednoducho zavoláme vykreslenie mapy, kde v parametroch odovzdáme Graphics PictureBox a šírku hrany z hranaNumericUpDown.

mapa.Vykresli(e.Graphics, Convert.ToInt32(hranaNumericUpDown.Value));

Môžeme spustiť:

Editor levelov bludisko v C# .NET - 3D bludisko v XNA

Vidíme vykreslenú prázdnu mapu, teda mriežku 16x16. PictureBox však nie je natiahnutý na veľkosť, ktorú by mal mať. Tú môžeme jednoducho spočítať, poďme pridať do formu metódu, ktorú budeme mapu obnovovať. Tá okrem prekreslenie mapy ešte zmení veľkosť PictureBox. Pridajme do FormEditor.cs metódu metódu PrekresliMapu ():

private void prekresliMapu()
{
    mapaPictureBox.Size = new Size(mapa.Sirka * Convert.ToInt32(hranaNumericUpDown.Value) + 1, mapa.Vyska * Convert.ToInt32(hranaNumericUpDown.Value) + 1);
    mapaPictureBox.Refresh();
}

Veľkosť mapy jednoducho spočítame podľa rozmerov mapy a veľkosti hrany vykreslovaného políčka. Formulári pridáme udalosť Load a v nej prekreslíme mapu:

prekresliMapu();
Editor levelov bludisko v C# .NET - 3D bludisko v XNA

PictureBox sa nám krásne roztiahol a ak je form menšia, zobrazí sa pri paneli posuvníky a môžeme mapou skrolovať. To sme presne chceli. Do udalosti Load pripíšte výber predvoleného políčka v typPolickaComboBox:

typPolickaComboBox.SelectedIndex = 0;

hraNumericUpDown naklikne udalosť ValueChanged a v nej prekreslíme mapu:

prekresliMapu();

Teraz naklikne na mapaPictureBox udalosť mouseclick. Do nej umiestnime nasledujúci kód:

int hrana = Convert.ToInt32(hranaNumericUpDown.Value);
int x = e.X / hrana;
int y = e.Y / hrana;
// Hodnoty v pořadí, jako jsou popisky políček v ComboBoxu
int[] hodnoty = {1, 99, 100, 0};

// Kontrola správnosti souřadnic
if ((x >= 0) && (y >= 0) && (x < mapa.Sirka) && (y < mapa.Vyska))
{
    // Levé myšítko přidá zeď
    if (e.Button == MouseButtons.Left)
        mapa.policka[x, y] = hodnoty[typPolickaComboBox.SelectedIndex];
    // Pravé myšítko vymaže zeď
    if (e.Button == MouseButtons.Right)
        mapa.policka[x, y] = 0;
    prekresliMapu();
}

Najprv si zistíme zo súradníc myši políčko na mape, na ktoré sa kliklo. To je jednoduché, stačí ich len vydeliť veľkosťou políčka. Ďalej si pripravíme pole hodnôt, ktoré bude predstavovať hodnoty pre jednotlivé políčka v typPolickaComboBox. Je dôležité, aby hodnoty mali to isté poradí, ako majú itemy v ComboBox. Vidíme, že múr má hodnotu 1, štart 99, cieľ 100 a prázdno 0. Vypočítané súradnice treba otestovať, pretože užívateľ mohol kliknúť mimo mapu a siahali by sme tak za hranice poľa. Teraz len otestujeme, ktoré tlačidlo bolo stlačené. Ak ľavej, vložíme na vhodnej políčko na mape hodnotu podľa vybraného item v ComboBox. Ak bolo stlačené pravé tlačidlo, vložíme prázdne políčko (pravým tlačidlom teda natierame). Nakoniec mapu prekreslíme a máme hotovo. Mouseclick sme použili z dôvodu možnosti odlíšenie tlačidiel narozdiel od udalosti Click.

Môžete vyskúšať. Bolo by skvelé, keby sme mohli na mapu pokladať políčka aj ťahaním myši, nielen klikaním. Stačí len, keď metódu mapaPictureBox_Mou­seClick () vyberieme aj u udalosti MouseMove. Teraz sa mapa vytvára naozaj jednoducho:

Editor levelov bludisko v C# .NET - 3D bludisko v XNA

Vytvorenie novej mapy

Prejdime k formuláru pre vytvorenie novej mapy. Do jeho triedy si pridáme verejný atribút s inštanciou mapy.

public Mapa mapa;

Pri kliknutí na tlačidlo "Vytvoriť" do atribútu vytvoríme novú inštanciu mapy požadovanej veľkosti a formulár zatvoríme:

mapa = new Mapa(Convert.ToInt32(sirkaUpDown.Value), Convert.ToInt32(vyskaUpDown.Value));
Close();

Formu naklikne udalosť Shown, kde vždy nastavíme túto inštanciu na null:

mapa = null;

Pri každom zobrazení dialógu sa nám teda mapa vymaže. Vďaka tomu spoznáme, či sme formulár opustili kliknutím na tlačidlo "Vytvoriť" (v mape je inštancia mapy) alebo len zavreli krížikom (v mape je null).

Vytvorenie formu a následné vytvorenie mapy nakoniec naklikne do položky Nová v MenuStrip:

FormNovaMapa formNovaMapa = new FormNovaMapa();
formNovaMapa.ShowDialog();
if (formNovaMapa.mapa != null)
{
    mapa = formNovaMapa.mapa;
    prekresliMapu();
}

Môžete si skúsiť založiť novú mapu.

Ukladanie a načítanie

Dokončenie editora vrcholí. Pridajme si z Toolbox dialógy pre otvorenie a uloženie súboru. Najprv pridajme SaveFileDialog pomenovaný mapaSaveFileDialog. Nastavíme mu DefaultExt (predvolené príponu) na máp. To bude prípona našich súborov s mapou. Ďalej nastavíme Filter na:

Mapy (*.map)|*.map

Rovnako pridáme aj nastavíme mapaOpenFileDialog. U neho ešte vymažeme vlastnosť FileName (necháme prázdnu hodnotu).

V MenuStrip rozkliknite položku Otvoriť a vložíme logiku pre zobrazenie dialógu a načítanie mapy:

if (mapaOpenFileDialog.ShowDialog() == DialogResult.OK)
{
    mapa.Nacti(mapaOpenFileDialog.FileName);
    prekresliMapu();
}

Obdebně to urobíme aj u položky Uložiť:

if (mapaSaveFileDialog.ShowDialog() == DialogResult.OK)
{
    mapa.Uloz(mapaSaveFileDialog.FileName);
    prekresliMapu();
}

Ako symbolickú čerešničku na torte pridáme vyvolanie MessageBox pri kliknutí na položku "O programe":

MessageBox.Show("Editor k tutoriálu na 3D bludiště v C# XNA z programátorské sociální sítě www.itnetwork.cz");

Editor levelov pre bludisko je hotový :) Za domácu úlohu si môžete obmedziť, aby šlo vložiť iba jedno štartové a cieľové pole, aj keď táto ochrana nie je nevyhnutne potrebné. Nabudúce si s somárikom načítate vašou krásnu mapu do enginu a môžete sa v nej prejsť.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 193x (70.49 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
3D bludisko v XNA - Mapy, múry a podlaha
Všetky články v sekcii
3D bludisko v XNA
Preskočiť článok
(neodporúčame)
3D bludisko v XNA - Podlahy druhýkrát a kolízie
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
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 sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity