Java týden Java týden
Pouze tento týden sleva až 80 % na celý Java e-learning!
Brno? Vypsali jsme pro vás nové termíny školení OOP v Brně!

Lekce 14 - MonoGame: Skrolující text (autoři hry)

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, MonoGame: Herní menu, 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 Enter 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 vykreslitelnou 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ě 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

(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 na začátek 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, MonoGame 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 switch 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 MonoGame (clipping)

Oříznutí dosáhneme pomocí tzv. "nůžek". V Draw() metodě komponenty 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ě, v lekci Hra tetris v MonoGame: Skóre, půjdeme na on-line skóre tabulku.


 

Stáhnout

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

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
4 hlasů
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 sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Předchozí článek
MonoGame: Herní menu
Všechny články v sekci
Od nuly k tetrisu v MonoGame
Miniatura
Následující článek
Hra tetris v MonoGame: Skóre
Aktivity (5)

 

 

Komentáře

Avatar
wazzirr
Člen
Avatar
wazzirr:24.10.2012 14:37

A co to skóre?

 
Odpovědět 24.10.2012 14:37
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na wazzirr
David Čápka:24.10.2012 14:49

No skóre bude příště, teď dělám na jiné sekci, brzy se k XNA vrátím :)

Odpovědět 24.10.2012 14:49
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
wazzirr
Člen
Avatar
wazzirr:24.10.2012 22:17

Ok :)

 
Odpovědět 24.10.2012 22:17
Avatar
minecraftgiesi:8.11.2012 17:25

Gold Game jsi borec scrado v programování

Odpovědět  +1 8.11.2012 17:25
Milujte c#/xna :)
Avatar
minecraftgiesi:10.11.2012 10:00

Ahoj sdraco dobrý tutorial ale mám problém s XNA.Když jsem založil nový projekt a spustil jsem ho tak,no nnespustilo se to napsalo to error a nějaký kódy.Pls help me.:(

Editováno 10.11.2012 10:02
Odpovědět 10.11.2012 10:00
Milujte c#/xna :)
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na minecraftgiesi
Petr Nymsa:10.11.2012 10:14

Nebylo by od věci napsat ten error sem :) Nikdo z nás nemá křišťálovou kouli a bohužel ani nikdo z nás neumí číst z karet nebo z čajových lístků. Takhle ti velmi těžko někdo pomůže

Odpovědět  +1 10.11.2012 10:14
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
minecraftgiesi:12.11.2012 17:41

nemohl by mi někdo pomoct mam problem s xna a kdyŽ si založím projekt tak mi to napíše
toto:
no suitable graphics card found

could not find a direct3D device that supports the XNA framework HIDef profile

verify that a suitable graphics devise is installed

make sure desktop is not locked,and tkat no other application is running in full screen mode

avoid running under remote desktop of as a windows service

check the display propertoes to make sure hardware acceleration is set to full

Odpovědět 12.11.2012 17:41
Milujte c#/xna :)
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na minecraftgiesi
David Čápka:12.11.2012 20:49

Máš nějakou nekompatibilní grafickou kartu, zkus dát Project -> Properties a přepni si v Game profile "Use Reach to access limited API set..."

Odpovědět  +1 12.11.2012 20:49
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Odpovídá na David Čápka
minecraftgiesi:15.11.2012 16:01

Díky sdraco už mi to díky tobě de :O :D (v)

Odpovědět 15.11.2012 16:01
Milujte c#/xna :)
Avatar
David
Redaktor
Avatar
David:31.12.2012 16:31

za jak dluho bude asi to skore

Odpovědět 31.12.2012 16:31
Nic néni nemožné!
Avatar
prxman
Člen
Avatar
prxman:24.2.2013 11:52

Behom posledneho mesiaca som videl mnoho clankov a videi o XNA... a v jednom bola ukazka, ako pridat vlastny EVENT na zachytavanie mysi. Neviem si vsak spomenut kde to bolo. :( (kazdopadne to asi ide)

Neviete, ako do XNA projektu pridat vlastny event handler pre mys? Skusal som googlit, no na nic som neprisiel.

Chcel by som vlastny event onmousemove... nechcem to riesit cez update, pretoze ten je konstantne rychly (1/60).

THX

 
Odpovědět 24.2.2013 11:52
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na prxman
David Čápka:24.2.2013 12:00

Toto se řeší v Update, tak je XNA navržené a funguje to dobře.

Odpovědět 24.2.2013 12:00
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Odpovídá na prxman
Luboš Běhounek Satik:24.2.2013 13:29

Event si můžeš napsat vlastní - já to řeším tak, že si ukládám v každém update stav klávesnice a myši a v dalším update pak podle toho házím eventy - třeba když myš byla stisknutá a teď není, tak zavolám mouseUp atd.

Odpovědět 24.2.2013 13:29
https://www.facebook.com/peasantsandcastles/
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Luboš Běhounek Satik
David Čápka:24.2.2013 13:31

Já jsem hlavně nepochopil ten argument že je Update konstantně rychlý :) I když si udělá event, stejně to bude fajrovat v Update().

Odpovědět 24.2.2013 13:31
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Michal Vašíček:4.3.2013 18:58

sdraco ty jsi kouzelník :D Tohle bych nesložil nikdy :/

Odpovědět 4.3.2013 18:58
Příspěvek může obsahovat stopy arašídů, sarkasmu a sóji.
Avatar

Člen
Avatar
:19.5.2013 7:04

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
David Čápka:19.5.2013 10:28

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

Odpovědět 19.5.2013 10:28
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar

Člen
Avatar
 
Odpovědět 19.5.2013 13:03
Avatar
Kit
Redaktor
Avatar
Odpovídá na
Kit:19.5.2013 13:36

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

Člen
Avatar
Odpovídá na Kit
:19.5.2013 14:41

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
Kit:19.5.2013 16:27

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

Člen
Avatar
Odpovídá na Kit
:20.5.2013 16:42

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
Kit:20.5.2013 17:02

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:24.6.2013 19:31

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:23.10.2014 9:23

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

Odpovědět 23.10.2014 9:23
嘿伙计在看什么
Avatar
Filip Bobovský:4.6.2018 21:10

Zdravím, mohl bych ještě poprosit o dodělání toho skóre a konce hra. Celkem bych to potřeboval. Děkuji.

 
Odpovědět 4.6.2018 21:10
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 26 zpráv z 26.