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

14. diel - MonoGame: Skrolující text (autori hry)

V minulej lekcii, MonoGame: Herné menu , sme naprogramovali herné menu. Dnes doň pridáme výber položiek a naprogramujeme obrazovku Autori sa skrolujícím textom.

Výber položky

Pri stlačení Enter sa z menu teraz presunieme vždy do levelu. Teraz ale budeme pri Enter reagovať na to, aká položka bola vybraná a podľa toho zmeníme obrazovku. Výber obrazovky urobíme podľa textu položky. Možností je samozrejme viac, ale táto je najjednoduchšie, pretože nemusíme nikde uchovávať inštancie položiek. Nevýhoda je, že pri zmene textu položky musíme zmeniť aj tento kód.

Presuňme sa do Update() v KomponentaMenu. Do reakcie na Enter vložíme switch, ktorý bude zatiaľ reagovať na položky Nová hra a Koniec:

// enter - akce podle vybrané položky
if (hra.NovaKlavesa(Keys.Enter))
{
    switch (polozkyMenu.vybranaPolozka.text)
    {
        case "StArT":
            hra.PrepniObrazovku(hra.obrazovkaLevel);
            hra.PrepniHudbu(hra.hudba_zardax);
            break;
        case "SkOrE":
            break;
        case "AuToRi":
            break;
        case "KoNeC":
            hra.Exit();
            break;

    }
}

Môžete vyskúšať.

Obrazovka autori

Poďme na obrazovku autori. Vytvoríme skrolující text, ktorý sa načíta zo súboru a bude jazdiť po obrazovke. Pridajme si novú vykreslitelnou komponent KomponentaAutori, už to iste všetci zvládnete a podrobne sme si to opisovali už niekoľkokrát :) Komponent vytvorte v priečinku Komponenty/ a namespace ponechajte na Robotris.

Ako premenné budeme okrem inštancie hry potrebovať pozadia, samotný text, štartovaciu pozíciu textu, aktuálnu pozíciu textu, výšku celého bloku textu a font. Výšku bloku potrebujeme preto, aby sme mohli spoznať, kedy celý text už vyšiel z obrazovky a vrátiť ho na štartovaciu pozíciu. Bude tak jazdiť stále dookola. Atribúty triedy budú vyzerať takto:

private Hra hra;
private Texture2D pozadi;
private string text;
private Vector2 startovniPozice;
private Vector2 pozice;
private float vyskaTextu;
private SpriteFont font;

Načítanie textu zo súboru

K projektu si pripojíme nový textový súbor, ako sme to robili so súborom pre kocky (Pravým na projekt Robotris v Solution Exploreru -> Add -> New Item -> Text File). Súbor pomenujeme autori.txt a opäť mu nastavíme v Properties Copy to Output Directory na Copy always. Do súboru si vložíme nejaký text:

.
                __
               /\ \
     _ __   ___\ \ \____    ___
    /\`'__\/ __`\ \ '__`\  / __`\  ____
    \ \ \//\ \L\ \ \ \L\ \/\ \L\ \/\___\
     \ \_\\ \____/\ \_,__/\ \____/\/___/
      \/_/ \/___/  \/___/  \/___/
     __
    /\ \__         __
    \ \ ,_\  _ __ /\_\    ____
     \ \ \/ /\`'__\/\ \  /',__\
      \ \ \_\ \ \/ \ \ \/\__, `\
       \ \__\\ \_\  \ \_\/\____/
        \/__/ \/_/   \/_/\/___/

  Ukázková hra z programátorské sociální
            sítě ITnetwork.CZ

Co je RoboTris?
===============
Ukázková hra v MonoGame se
zdrojovým kódem. Obsahuje mód
z originálního tetrisu, tzn. bodování
podle oficiálních pravidel, rozměry pole,
tvary kostiček atd. Pokud nahraješ vysoké
skóre, můžeš ho sdílet na webu
s ostatními a vyzývat je, aby se tě
pokusili překonat.

Ovládání
========
Šipka doleva - posun kostičky doleva
Šipka doprava- posun kostičky doprava
Šipka nahoru a enter - rotace kostičky
Šipka dolu   - uzemnění kostičky
Pravý CTRL   - zrychlení pádu kostičky

Poděkování
==========
StainlessSteel - hudba na pozadí
HVSC - ZeroX - píseň od neznámého autora
Vzor pro obrázky kostek - hra Supaplex

Licence
=======
RoboTris můžete volně šířit
i modifikovat, podmínkou je uvést
viditelně ve hře link na www.itnetwork.cz

(Tú bodku na začiatku som tam dal, aby miestne formátovač kódov pochopil ten ASCII ART, vy si ju vymažte :) ). V komponente pridajme na začiatok using System.IO:

using System.IO;

A poďme text zo súboru načítať do pripravenej premennej. Urobme si na to metódu NactiText():

public void NactiText()
{
    text = "";
    using (StreamReader sr = new StreamReader("autori.txt"))
    {
        text = sr.ReadToEnd();
    }
}

Tú Zavolajme v Initialize() a ešte nastavme štartovaciu pozíciu kúsok pod rámik v menu, v ktorom bude text behať. Tak bude zo začiatku celý schovaný. Aktuálnu pozíciu nastavíme tiež na štartovej:

NactiText();
startovniPozice = new Vector2(510, 550);
pozice = startovniPozice;

Načítanie obsahu

S fontom máme opäť problém, potrebujeme sa opýtať na jeho výšku, ale ešte nie je načítaný. Vyriešime to jednoducho, proste ho v tejto komponente načítame znova. Nebojte, MonoGame v Hra.cs spozná, že bol už načítaný tu a iba ho odovzdá ako inštanciu. Môžeme si to teda dovoliť bez spomalenia aplikácie, to isté platí aj u ďalších súčastí obsahu. Tu mimo font načítame podobne aj pozadie, ktoré by teoreticky mohlo byť iné, ako u menu, aj keď v tomto prípade nie je. Presuňme sa do LoadContent a dodajme nasledujúce riadky:

pozadi = hra.Content.Load<Texture2D>(@"Sprity\pozadi_menu");
font = hra.Content.Load<SpriteFont>(@"Fonty\font_courier_new");
vyskaTextu = font.MeasureString(text).Y;

Výšku textu sme nastavili pomocou metódy MeasureString() na fontu, ktorá nám vráti priamo výšku a šírku textu v pixeloch, ak je napísaný týmto fontom. Ďalšou možnosťou by bolo použiť vlastnosť LineSpacing a tú vynásobiť počtom riadkov.

Logika

Logika v Update() bude triviálne. Návrat do menu je len reakcia na klávesu Escape:

if (hra.NovaKlavesa(Keys.Escape))
    hra.PrepniObrazovku(hra.obrazovkaMenu);

Pohybu textu smerom nahor dosiahneme jednoducho posunom jeho pozície. Tu sa ukáže jedna z výhod vektorových súradníc, môžeme posúvať o desatinné čísla:

pozice.Y -= 0.3F;

Zostáva snáď len zistiť, či text vyšiel z obrazovky a vtedy resetovať jeho pozíciu. Pozriem sa, či je jeho pozícia menšia, než štartovej pozície znížená o výšku textu a ešte výšku oblasti, v ktorej text beží.

if (pozice.Y < startovniPozice.Y - (vyskaTextu + 320))
    pozice = startovniPozice;

Vykreslenie

V Draw() vykreslíme pozadia a zatiaľ celý text bez orezania:

hra.spriteBatch.Begin();
hra.spriteBatch.Draw(pozadi, new Vector2(0, 0), Color.White);
hra.spriteBatch.TextSeStinem(font, text, pozice, Color.Red);
hra.spriteBatch.End();

To by zatiaľ stačilo, presuňme sa do Hra.cs a do atribútov triedy pridajme obrazovku s autormi:

public HerniObrazovka obrazovkaAutori;

V Initialize() vytvorme komponent:

KomponentaAutori autori = new KomponentaAutori(this);

A nižšie aj obrazovku, zas v nej budú mraky a naše komponenta autori:

obrazovkaAutori = new HerniObrazovka(this, mraky, autori);

V KomponetaMenu doplníme v Update() do switch prepnutie obrazovky:

case "AuToRi":
    hra.PrepniObrazovku(hra.obrazovkaAutori);
    break;

Spustíme.

Ukážkový Tetris v XNA Game Studio - Od nuly k tetrisu v MonoGame

Až na to, že by sa text mal orezať, je výsledok dobrý.

Orezanie vykresľovanie v MonoGame (clipping)

Orezanie dosiahneme pomocou tzv. "Nožníc". V Draw() metóde komponenty KomponentaAutori vyberieme vykreslenie textu a vložíme ho do ďalšieho vykreslovacího bloku, tentoraz s iným preťažením metódy Begin(). Najprv uvediem kód, ktorý vysvetlím. Metódu Draw() si pozmeňte takto:

public override void Draw(GameTime gameTime)
{
    // vykreslení pozadí
    hra.spriteBatch.Begin();
    hra.spriteBatch.Draw(pozadi, new Vector2(0, 0), Color.White);
    hra.spriteBatch.End();

    // vyklreslení skrolujícího textu pomocí clippingu (nůžek):
    // zapnutí clippingu
    RasterizerState rs = new RasterizerState();
    rs.ScissorTestEnable = true;
    hra.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, rs);
    // uložení současných nůžek
    Rectangle currentRect = hra.spriteBatch.GraphicsDevice.ScissorRectangle;
    // nastavení nůžek
    hra.spriteBatch.GraphicsDevice.ScissorRectangle = new Rectangle(488, 240, 570, 335);
    // vykreslení textu
    hra.spriteBatch.TextSeStinem(font, text, pozice, Color.Red);
    // reset původních nůžek
    hra.spriteBatch.GraphicsDevice.ScissorRectangle = currentRect;
    hra.spriteBatch.End();

    base.Draw(gameTime);
}

Pomocou RasterizerState zapneme nožnice. Toto nastavenie potom odovzdáme metóde Begin(). Uložíme si súčasné nožnice (nastavenej na celú obrazovku) a potom nastavíme nožnice vlastné, nastavené na obdĺžnik, kde má text skrolovať. Vykreslíme text a nožnice vrátime späť. Výsledný efekt:

Ukážkový Tetris v XNA Game Studio - Od nuly k tetrisu v MonoGame

K dokonalosti by sme mohli výtvor doviesť tak, že by sme si uložili obdĺžniky horného a spodného okraja poľa, v ktorom text jede. Tie v grafickom editore postupne sprehľadnila a vykreslili cez text. Text by sa potom takto neusekával, ale postupne mizol. Môžete si doplniť. Niektoré veci v menu ešte necháme rozrobenej. Nabudúce, v lekcii Hra tetris v MonoGame: Skóre , pôjdeme na on-line skóre tabuľku.


 

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é 581x (13.22 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
MonoGame: Herné menu
Všetky články v sekcii
Od nuly k tetrisu v MonoGame
Preskočiť článok
(neodporúčame)
Hra tetris v MonoGame: Skóre
Č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