14. díl - XNA: Skrolující text (autoři hry)

C# .NET XNA game studio Robotris XNA: Skrolující text (autoři hry)

V minulém dílu seriálu XNA tutoriálů jsme naprogramovali herní menu. Dnes do něj přidáme výběr položek a naprogramujeme obrazovku Autoři se skrolujícím textem.

Výběr položky

Při stisknutí Enter se z menu nyní přesuneme vždy do levelu. Teď ale budeme při enteru reagovat na to, jaká položka byla vybrána a podle toho změníme obrazovku. Výběr obrazovky uděláme podle textu položky. Možností je samozřejmě více, ale tato je nejjednodušší, protože nemusíme nikde uchovávat instance položek. Nevýhoda je, že při změně textu položky musíme změnit i tento kód.

Přesuňme se do Update() v KomponentaMenu. Do reakce na enter vložíme switch, který bude zatím reagovat na položky Nová hra a Konec:

// 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 vyzkoušet.

Obrazovka autoři

Pojďme na obrazovku autoři. Vytvoříme skrolující text, který se načte ze souboru a bude jezdit po obrazovce. Přidejme si novou vykreslovatelnou komponentu KomponentaAutori, již to jistě všichni zvládnete a podrobně jsme si to popisovali již několikrát :) Komponentu vytvořte ve složce Komponenty a namespace ponechte na Robotris.

Jako proměnné budeme kromě instance hry potřebovat pozadí, samotný text, startovní pozici textu, aktuální pozici textu, výšku celého bloku textu a font. Výšku bloku potřebujeme proto, abychom mohli poznat, kdy celý text již vyjel z obrazovky a vrátit ho na startovní pozici. Bude tak jezdit stále dokola. Atributy třídy budou vypadat takto:

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

Načtení textu ze souboru

K projektu si připojíme nový textový soubor, jako jsme to dělali se souborem pro kostky (Pravým na projekt Robotris v Solution Exploreru -> Add -> New Item -> Text File). Soubor pojmenujeme autori.txt a opět mu nastavíme v Properties Copy to Output Directory na Copy always. Do souboru si vložíme nějaký text:

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

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

Co je RoboTris?
===============
Ukázková hra v XNA Game Studio 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.devbook.cz

(Tu tečku na začátku jsem tam dal, aby místní formátovač kódů pochopil ten ASCII ART, vy si ji vymažte :) ). V komponentě přidejme do usingů System.IO:

using System.IO;

A pojďme text ze souboru načíst do připravené proměnné. Udělejme si na to metodu NactiText():

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

Tu zavolejme v Initialize() a ještě nastavme startovní pozici kousek pod rámeček v menu, ve kterém bude text běhat. Tak bude ze začátku celý schovaný. Aktuální pozici nastavíme také na startovní:

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

Načtení obsahu

S fontem máme opět problém, potřebujeme se zeptat na jeho výšku, ale ještě není načtený. Vyřešíme to jednoduše, prostě ho v této komponentě načteme znovu. Nebojte, XNA v Hra.cs pozná, že byl již načtený zde a pouze ho předá jako instanci. Můžeme si to tedy dovolit bez zpomalení aplikace, to samé platí i u dalších součástí obsahu. Zde mimo font načteme podobně i pozadí, které by teoreticky mohlo být jiné, než u menu, i když v tomto případě není. Přesuňme se do LoadContent a dodejme následující řádky:

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 jsme nastavili pomocí metody MeasureString() na fontu, která nám vrátí přímo výšku a šířku textu v pixelech, pokud je napsaný tímto fontem. Další možností by bylo použít vlastnost LineSpacing a tu vynásobit počtem řádků.

Logika

Logika v Update() bude triviální. Návrat do menu je pouze reakce na klávesu escape:

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

Pohybu textu směrem nahoru dosáhneme jednoduše posunem jeho pozice. Zde se ukáže jedna z výhod vektorových souřadnic, můžeme posouvat o desetinná čísla:

pozice.Y -= 0.3F;

Zbývá snad jen zjistit, zda text vyjel z obrazovky a tehdy resetovat jeho pozici. Podiváme se, zda je jeho pozice menší, než startovní pozice snížená o výšku textu a ještě výšku oblasti, ve které text běží.

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

Vykreslení

V Draw() vykreslíme pozadí a zatím celý text bez oříznutí:

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 prozatím stačilo, přesuňme se do Hra.cs a do atributů třídy přidejme obrazovku s Autory:

public HerniObrazovka obrazovkaAutori;

V Initialize() vytvořme komponentu:

KomponentaAutori autori = new KomponentaAutori(this);

A níže i obrazovku, zas v ní budou mraky a naše komponenta autori:

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

V KomponetaMenu doplníme v Update() do switche přepnutí obrazovky:

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

Spustíme.

Ukázkový Tetris v XNA Game Studio

Až na to, že by se text měl oříznout, je výsledek dobrý.

Oříznutí vykreslování v XNA (clipping)

Oříznutí dosáhneme pomocí tzv. "nůžek". V Draw() KomponentaAutori vyjmeme vykreslení textu a vložíme ho do dalšího vykreslovacího bloku, tentokrát s jiným přetížením metody Begin(). Nejprve uvedu kód, který vysvětlím. Metodu Draw() si pozměň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);
}

Pomocí RasterizerState zapneme nůžky. Toto nastavení poté předáme metodě Begin(). Uložíme si současné nůžky (nastavené na celou obrazovku) a poté nastavíme nůžky vlastní, nastavené na obdélník, kde má text skrolovat. Vykreslíme text a nůžky vrátíme zpět. Výsledný efekt:

Ukázkový Tetris v XNA Game Studio

K dokonalosti bychom mohli výtvor dovést tak, že bychom si uložili obdélníky horního a spodního okraje pole, ve kterém text jede. Ty v grafickém editoru postupně zprůhlednili a vykreslili přes text. Text by se poté takto neusekával, ale postupně mizel. Můžete si doplnit. Některé věci v menu ještě necháme rozdělané. Příště půjdeme na on-line skóre tabulku.


 

Stáhnout

Staženo 538x (6.67 MB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  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 (4 hlasů) :
55555


 


Miniatura
Předchozí článek
XNA: Herní menu
Miniatura
Všechny články v sekci
Od nuly k tetrisu v XNA game studio

 

 

Komentáře
Zobrazit starší komentáře (15)

Avatar
exyi
Redaktor
Avatar
exyi:

Udělal jsem si z těchto článků e-book, tak jsem si říkal že vám to sem dám, třeba někomu ušetřím práci. xxx

Editováno 19.5.2013 10:28
 
Odpovědět 19.5.2013 7:04
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na exyi
David Čápka:

Opravdu si myslíš, že je legální tohle dělat s mojí prací?

Odpovědět 19.5.2013 10:28
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
exyi
Redaktor
Avatar
Avatar
Kit
Redaktor
Avatar
Odpovídá na exyi
Kit:

Dokud to děláš pro vlastní potřebu, je to OK. Dělám to podobně. Šířit bez povolení autora to však nesmíš.

Editováno 19.5.2013 13:38
Odpovědět 19.5.2013 13:36
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
exyi
Redaktor
Avatar
Odpovídá na Kit
exyi:

Obcas me to nebavi to vyrabet, tak jsem si rikal ze treba nekomu usetrim praci. Tak ne :(

 
Odpovědět 19.5.2013 14:41
Avatar
Kit
Redaktor
Avatar
Odpovídá na exyi
Kit:

Snad to neděláš ručně?

Odpovědět 19.5.2013 16:27
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
exyi
Redaktor
Avatar
Odpovídá na Kit
exyi:

NE to opravdu ne. Mam na to takovy osklivy script.

 
Odpovědět 20.5.2013 16:42
Avatar
Kit
Redaktor
Avatar
Odpovídá na exyi
Kit:

Ošklivé skripty bývají nejlepší. Nesnaží se být dokonalé, jejich základem bývá jednoduchost.

Odpovědět  +2 20.5.2013 17:02
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Hudson_Hawk
Člen
Avatar
Hudson_Hawk:

Super tutoriál, děkuji za něj ;) a klobouk dolů ...

 
Odpovědět  +1 24.6.2013 19:31
Avatar
borec.peta
Člen
Avatar
borec.peta:

Davide,
uděláš ještě to skore moc bych to potreboval:)

Odpovědět 23.10.2014 9:23
嘿伙计在看什么
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.

Zobrazeno 10 zpráv z 25. Zobrazit vše