3. diel - Kreslíme a píšeme v MonoGame
V minulej lekcii, Vloženie obsahu MonoGame hry , sme si ukázali vloženie obsahu MonoGame hry. Teraz máme teda všetko pripravené na to, aby sme si prácu s obsahom vyskúšali. Poďme na to
Načítanie obsahu
Obsah musíme najprv načítať. Už vieme, že to sa robí v metóde
LoadContent()
. Než sa k metóde presunieme, vytvoríme si
potrebné premenné. Neanimované sprity sa v MonoGame ukladajú do dátového
typu Texture2D
. Pre SpriteFonty máme typ
SpriteFont
.
Pridáme teda premenné:
private Texture2D kostkyPozadi, mraky, pozadi; public SpriteFont fontCourierNew, fontBlox, fontBloxMaly;
S modifikátory prístupu si nelámte hlavu, hudba a fonty sú verejné, pretože ich budeme v budúcnosti zdieľať medzi komponentmi.
Presuňme sa konečne do metódy LoadContent()
. Za vytvorením
inštancie spriteBatch
začneme načítať obsah. Už vieme, že na
to použijeme vlastnosť Content
, presnejšie Load()
.
Metóda je generická, musíme teda špecifikovať typ obsahu, ktorý
načítame. Zaujímavé je, že nezadávame príponu súboru. Načítame
sprity:
pozadi = Content.Load<Texture2D>(@"Sprity\pozadi_level"); kostkyPozadi = Content.Load<Texture2D>(@"Sprity\pozadi_kostky"); mraky = Content.Load<Texture2D>(@"Sprity\spr_mraky");
A fonty:
fontCourierNew = Content.Load<SpriteFont>(@"Fonty\font_courier_new"); fontBlox = Content.Load<SpriteFont>(@"Fonty\font_blox"); fontBloxMaly = Content.Load<SpriteFont>(@"Fonty\font_blox_maly");
Máme načítané, nebola to žiadna veda. Poďme kresliť.
Vykresľovanie spritov
Presuňme sa do metódy Draw. Kód budeme písať za vymazanie zobrazovacieho
zariadenia. Už sme si hovorili, že vykresľovanie sprites prebieha pomocou
inštancie spriteBatch
. Vykresľovanie musíme najprv začať, to
urobíme metódou Begin()
:
spriteBatch.Begin();
Následne vykreslíme sprity. Iste ste si všimli, že sú vo formáte PNG. To preto, že PNG obsahuje tzv. Alfakanál a umožňuje urobiť rôzne časti obrázku rôzne priehľadné. Toho som využil a pozadie levelu s robotom je hore priehľadné. Pod neho vykreslíme pozadia kociek a medzi kocky a robota vykreslíme mraky.
Samotné vykreslenie Spritu prebieha pomocou metódy Draw()
:
spriteBatch.Draw(kostkyPozadi, new Vector2(0, 0), Color.White); spriteBatch.Draw(mraky, new Vector2(0, 0), Color.White); spriteBatch.Draw(pozadi, new Vector2(0, 0), Color.White);
Vidíme, že prvý parameter metódy je textúra k vykreslenie. Druhým parametrom je pozícia a tretím farba. Metóda má ďalšie preťaženie, ktoré umožňujú napr. Obrázok rozťahovať alebo rotovať, ale tá v našom kurze nevyužijeme.
Význam textúry je jasný. Pozoruhodné môže byť, že
súradnice zadávame pomocou vektora. Ešte divnejšie môže
byť, že to nie sú celé čísla, ale čísla desatinné, presnejšie typu
float
. S vektory sa v XNA pracuje preto, že umožňujú veľmi
jednoducho riešiť rôzne pohyby, smery, uhly, zrážky, zistiť vzdialenosť 2
objektov a podobne. My je v tomto seriáli budeme používať len ako
súradnice, ale aj tu je výhoda, že môžeme objektu napr. Zadať reálnu
rýchlosť pohybu miesto celočíselné a túto rýchlosť ku zložkám vektora
(súradniciam objektu) pričítať. Farba určuje zafarbenie
textúry, biela textúru nemení.
Vykresľovanie nakoniec ukončíme metódou End()
:
spriteBatch.End();
Skúsime si hru spustiť, mali by sme vidieť takýto výsledok:
Vďaka dodržanie poradie spritov pri vykreslenie sú naozaj mraky vložené
medzi 2 pozadia. Ešte u spritov chvíľku zostaneme, skúsime si totiž mraky
rozpohybovať. Založíme si novú privátne premennú pozice
typu
Vector2
. V Initialize()
ju nastavíme na počiatok
súradnicového systému (ľavý horný roh obrazovky):
pozice = new Vector2(0, 0);
Teraz zmeníme riadok s vykreslením mrakov. Ako pozíciu odovzdáme
premennú pozície a farbu vynásobíme 0.8f
, tým spôsobíme, že
mraky budú z 20% priehľadnej:
spriteBatch.Draw(mraky, pozice, Color.White * 0.8f);
Teraz sa mraky vykresľujú na pozíciu, ktorú určuje premenná. V metóde
Update()
zložku vektora X
vždy o 1
znížime:
pozice.X--;
Po posune ošetríme, či sme s mrakmi nevyšli z obrazovky. To urobíme tak,
že sa spýtame, či je X
mrakov menšia ako -šírka obrázku
mrakov. Tú získame pomocou vlastnosti Width
na textúre
mrakov:
if (pozice.X < -(mraky.Width)) pozice.X = 0;
Ak ste postupovali správne, budú mraky jazdiť doľava a akonáhle vyjdú z obrazovky, vráti sa na štartovaciu pozíciu.
Teraz zmeníme vykresľovanie tak, aby sa vykresľovali niekoľko mrakov vedľa seba:
for (int i = 0; i < 6; i++) spriteBatch.Draw(mraky, new Vector2(pozice.X + i * mraky.Width, 0), Color.White * 0.8f);
Dostaneme pekný efekt nekonečné, plaviace oblohy:
Pôsobivé, že?
Zmena farby spritov
Ešte si skúsime meniť farbu mrakov. Budeme jednoducho meniť jej jednotlivé zložky, určite vieme, že farby v počítači sú zložené z červenej, zelenej a modrej zložky. Urobiť zmenu farby tak, aby sme vystriedali celé spektrum je zložité a efekt bude veľmi podobný tomu, keď budeme striedať farieb len niekoľko. Do triedy pridáme 2 ďalšie premenné, zmenu a smer:
private int zmena; private int smer;
Premenná zmena
sa bude meniť medzi hodnotou 0
-
96
, ako kyvadlo. Premenná smer
určuje smer zmeny
tejto premennej, 1
rastúci, -1
klesajúci.
V Initialize()
nastavíme zmenu na 0
a smer na
1
, teda rastúce.
zmena = 0; smer = 1;
V Update()
teraz pripočítame smer k zmene. Tým docielime, že
sa bude s kladným smerom zvyšovať a so záporným znižovať. Tiež zmenu
pomocou 2 podmienok udržíme medzi 0
a 96
:
zmena += smer; if (zmena >= 96) smer = -1; if (zmena <= 0) smer = 1;
Hotovo. Tento kyvadlový princíp si zapamätajte, bude sa nám v hrách
hodiť, my ho ešte minimálne 2x použijeme inde. No a poďme do metódy
Draw()
. Tam si pred for
cyklom založíme premennú
barva
a zmeníme jej zložky pomocou premennej zmena
,
tie môžeme zadať jednoducho v poradí RGB (červená, zelená, modrá) do
konstruktoru farby. Potom farbu dosadíme do farby vykreslenie Mařák:
Color barva = new Color(128 + zmena, 255 - zmena, 128 + zmena); for (int i = 0; i < 6; i++) spriteBatch.Draw(mraky, new Vector2(pozice.X + i * mraky.Width, 0), barva * 0.8f);
Červená zložka bude mať základ 128
+ zmena, bude sa teda
meniť medzi 128
- 224
. Zelená medzi 255
- 159
a modrá opäť 128
- 225
. Môžete
si s tým pohrať, ale pozor, aby hodnota nebola vyššia ako 255
alebo nižšia ako 0
. Program by nespadol s chybou, ale farba by sa
menila podivne.
Pre lepší efekt by sme si v praxi uložili niekoľko pekných farieb do
poľa a potom na ne prechádzali metódou Lerp()
. Mraky by tiež
nemali byť modré, aby to do farby nezasahovala. Pre naše účely ukážky
nám to však takto stačí.
Vykreslenie textu
Vieme, že aj text vykresľujú pomocou SpriteBatch
, presnejšie
metódou DrawString()
. Tá má opäť niekoľko preťaženie pre
text orotovaný a podobne, ale tá si určite sami obhliadnete. Presuňme sa do
metódy Draw()
a pridajme pred spriteBatch.End();
nasledujúce riadky:
spriteBatch.DrawString(fontBlox, "nadpis velky", new Vector2(100, 100), Color.Yellow); spriteBatch.DrawString(fontBloxMaly, "nadpis maly", new Vector2(100, 180), Color.Yellow); spriteBatch.DrawString(fontCourierNew, "Příliš žluťoučký kůň úpěl ďábelské ódy", new Vector2(100, 240), Color.Red);
výsledok:
Parametre sú rovnaké, ako u sprites, iba je tu jeden navyše s textom. Nezabúdajte, že font Blox nevie slovenské znaky! Vo fontu Courier je to už v poriadku.
Text môže byť občas zle vidieť, pokúsime sa s tým niečo urobiť,
vykreslíme pod neho tieň. Aby sme nemuseli tieň kresliť stále znovu a
znovu, urobíme si na text s tieňom metódu. No a aby sme sa precvičili,
pridáme ju priamo do spriteBatch
, presnejšie
SpriteBatch
podědíme.
Pridajte si k projektu Robotris
novú triedu s názvom
LepsiSpriteBatch
, dedičov z SpriteBatch
. Najprv hore
pridáme potrebné using
ya triedu opatríme modifikátorom
public
:
... using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Robotris { public class LepsiSpriteBatch : SpriteBatch { ...
Pri dedení triedy musíme vytvoriť konštruktor (hoci prázdny), volajúci konštruktor triedy nadradenej:
public LepsiSpriteBatch(GraphicsDevice graphicsDevice): base(graphicsDevice) { }
Teraz pridáme našu metódu TextSeStinem()
, ktorá vykreslí
zadaný text 2x. raz čierno s trochou transparentnosti a kúsok doprava dole a
druhýkrát normálne, ako sme zvyknutí. Parametre opíšeme z pôvodnej
metódy DrawString()
.
public void TextSeStinem(SpriteFont spriteFont, string text, Vector2 position, Color color) { DrawString(spriteFont, text, new Vector2(position.X + 2, position.Y + 2), Color.Black * 0.8f); DrawString(spriteFont, text, position, color); }
Teraz sa vrátime do triedy Hra
a zmeníme typ
SpriteBatch
(hneď na začiatku v definícii atribútov triedy) na
LepsiSpriteBatch
:
LepsiSpriteBatch spriteBatch;
Podobnú zmenu urobíme ešte na začiatku metódy
LoadContent()
:
spriteBatch = new LepsiSpriteBatch(GraphicsDevice);
V metóde Draw()
zmeníme DrawString()
na
TextSeStinem()
a spustíme. Oveľa lepšie, nie?
Metódy v hre sú trochu českoanglické, ale v programovaní to inak nejde a aspoň trochu češtiny som hre chcel dodať, keď už robím českej tutoriály Tí pokročilí z vás si to môžu písať anglicky.
To by nám ku spritům stačilo.
Nabudúce, v lekcii Zvuky, hudba, klávesnica a myš v MonoGame , sa pozrieme na hudbu, zvukové efekty a reakciu na klávesy.
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é 552x (11.85 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#