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