8. diel - XNA tvorba v 3D - Sprit a Text
Síce si nie som moc istý, aký má význam písať ďalší diel, keď má byť zajtra ten koniec sveta, ale aj napriek tomu vitajte po deviaty raz. V minulých dieloch sme si zostavili kostru enginu. Dnes ju prvýkrát poriadne využijeme. Vytvoríme si pár nových komponentov. Prvý bude obyčajný sprite, potom tiež obyčajný text. Aj takéto ne-3D komponenty sa budú hodiť pre rôzne menu. Text je možné využiť aj pre vypisovanie debugovacie informácií.
Predovšetkým je dôležité priznať, že sa mi podarilo urobiť pri písaní predchádzajúcich návodov celkom zásadnú chybu a prišiel som na nej až pri písaní tohto dielu. Chyba už bola v príslušnom článku opravená, ale ešte zostáva opraviť chybu u tých čo si článok čítali pred opravou. Engine musí byť Windows Game Library a nie iba Class library. Stačí keď si projekt tohto typu založíte a súbory do neho presuniete. Děkuju za pochopenie.
Ďalej bude potrebné enginu pridať projekt s obsahom. Tu som si už istý,
že je potrebné pridať projekt Empty Content. Pomenujeme si
ho menom enginu a na koniec pridajte slovko Content
. Ale opäť,
ako u všetkého, je to len na vás aké meno tomu dáte. Potreba je tiež tento
projekt pridať k enginu. Klikneme pravým tlačidlom myši na meno projektu s
enginom a vyberieme položku Add Content reference
. A v menu
vyberieme práve vytvorený projekt. Skvele, prípravy sú hotové. Môžeme
pokračovať v ďalšom písaní.
Sprite
Vytvoríme si triedu Sprite
v našej zložke
Components
. Urobíme ju verejnú a nezabudneme napraviť menný
priestor. Trieda opäť bude dediť od našej komponenty (nezabudneme pridať
using). V konstruktoru budeme ako parameter odovzdávať meno použité textúry
a polohu horného ľavého rohu Spritu na obrazovke. Vytvoríme si ho a hodnoty
si uložíme:
private string textureName; private Vector2 fPosition; public Vector2 Position{ get{ return fPosition; } set{ fPosition = value; } } public Sprite(string textureName, Vector2 position){ this.textureName = textureName; Position = position; }
Tu by mohla vzniknúť otázka: prečo odovzdávame meno textúry a nie
priamo inštanciu textúry. Tú si práve nahráme v metóde Load
,
ktorá k tomuto účelu slúži. Ďalej sa bude hodiť premenná, kde si
uložíme rozmery nášho obrázku:
public Rectangle DestinationRectangle { get; set; }
Trieda Rectangle nepredstavuje nič iné ako štvorec / obdĺžnik. Pridáme taky konštruktor kde nastavíme vlastné rozmery obrázku. Pridáme tiež druhý konštruktor, kde zo zadaných rozmerov vytvoríme inštanciu:
public Sprite(string textureName, Vector2 position, int width, int height) : this(textureName, position){ DestinationRectangle = new Rectangle((int)position.X, (int)position.Y, width, height); }
Vytvoríme si tiež chránenú premennú Texture
, kde budeme
našu textúru skladovať.
protected Texture2D Texture;
Teraz prepíšeme metódu Load
, kde nahráme textúru podľa
mena zadaného v konstruktoru. A v prípade, že premenná
DestinationRectangle
má šírku alebo výšku nulovú, tak ju
vytvoríme s rozmermi textúry:
protected override void Load(){ Texture = Parent.Engine.Content.Load<Texture2D>(textureName); if(DestinationRectangle.Width==0 || DestinationRectangle.Height==0)DestinationRectangle = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height); }
A teraz nám už stačí len metóda Draw
, ktorá nám všetko
vykreslí:
public override void Draw(){ Parent.Engine.SpriteBatch.Begin(); Parent.Engine.SpriteBatch.Draw(Texture, DestinationRectangle, Color.White); Parent.Engine.SpriteBatch.End(); }
Nie je to nič moc nového a objavného, len namiesto pozície sme odovzdali
náš štvorec / obdĺžnik, pomocou ktorého môžeme meniť veľkosti. K
dokonalosti nám tu chýba ešte jedna malá drobnosť. Ak by sme teraz zmenili
pozíciu nášho Spritu, tak by nám zostal tak by sa nič nezmenilo. Síce si
polohu ukladáme, ale nemeníme hodnoty v premennej
DestinationRectngle
. Takže to v setter napravíme:
DestinationRectangle = new Rectangle((int)Position.X, (int)Position.Y, DestinationRectangle.Width, DestinationRectangle.Height);
Šírku a výšku obrázka prevezmeme z pôvodného a iba len nandáme nové
hodnoty. Teraz je už všetko kompletne pripravené a môžeme komponent
vyskúšať. Budeme postupovať rovnako ako naposledy s farebným pozadím. Do
projektu s obsahom si pridáme náš obrázok a to obvyklým postupom, ktorý
už poznáte z predchádzajúcich dielov. Trebárs zas erb ŽvB. Tu je dobré
poznamenať, že všetko čo sa netýka enginu budeme dávať do hry. Otvoríme
si súbor s triedou nášho herného okna, ktoré sme si vytvorili minule, a do
metódy Load
POD komponentu s farebným pozadím pridáme nový
komponent:
AddComponent(new Sprite("erb",new Vector2(230,170)));
Obrázok teda bude mať textúru erbu a bude umiestnený na súradnice (230,170). Tu je asi dobré pripomenúť, že súradnice (0,0) sa nachádzajú v ľavom hornom rohu. Keď si teraz projekt spustíme, mali by sme dostať nasledujúce výsledok:
Skúsme si pridať ešte druhý erb, tentokrát ale mierne natiahnutý:
AddComponent(new Sprite("erb", new Vector2(420, 220),200,50));
Keď teraz hru spustíme a všetko sme urobili dobre tak výsledok bude nasledujúce:
So sprity sa toho dá robiť veľa. Dajú sa rôzne natáčať, meniť ich farby a alebo len zobraziť ich časť. Toto ale nechám na vás, stačí použiť inú metódu pre vykresľovanie a len pridať parametre rovnakým spôsobom, ako som to urobil ja.
Text
Ešte som neprozreteľne nasľuboval komponentu s textom. Ale keď som ju
sľúbil, tak si ju teda urobíme. Opäť si vytvoríme triedu
TextLabel
v našej zložke s komponentmi. Urobíme ju verejnú,
nasolíme tam správne menné priestory, proste všetko ako obvykle. Opäť
budeme dediť od triedy Component
. Pri texte sa nám bude hodiť
pár parametrov. Farba písma, pozície a samotný text. Bude opäť potrebné
zadať meno súboru s fontom rovnako ako u predošlej komponenty:
private string fontName; public Vector2 Position{ get; set; } public Color Color{ get; set; } public string Text{ get; set; }
Vytvoríme konštruktory, kde ako parameter všetky tieto údaje odovzdáme:
public TextLabel(string text, Vector2 position, string fontName) : this(text, position, Color.Black, fontName){ } public TextLabel(string text, Vector2 position, Color color, string fontName){ Text = text; Position = position; this.fontName = fontName; Color = color; }
Opäť ako v predchádzajúcom prípade prepíšeme metódu Load
a načítame tu font, ktorému ale najprv vytvoríme premennú:
protected SpriteFont SpriteFont; protected override void Load(){ SpriteFont = Parent.Engine.Content.Load<SpriteFont>(fontName); }
A opäť v metóde Draw
rovnako ako v predchádzajúcom prípade
vykreslíme:
public override void Draw(){ Parent.Engine.SpriteBatch.Begin(); Parent.Engine.SpriteBatch.DrawString(SpriteFont,Text,Position,Color); Parent.Engine.SpriteBatch.End(); }
Popis je teda hotový. Do projektu s obsahom pridáme nový súbor sa sprite
fontom. Rovnako ako sa to robilo v prípade Robotetris
, ak neviete,
pozrite na diel Vloženie obsahu
XNA hry. Nezabudneme editovať oblasť používaných znakov tak, aby
obsiahli aj tie s českou diakritikou a použijeme font treba
Verdanu
. Font si pomenujeme maly
. Zmeny som vykonal na
nasledujúcich riadkoch:
<FontName>verdana</FontName> <CharacterRegions> <CharacterRegion> <Start> </Start> <End>Ɔ</End> </CharacterRegion> </CharacterRegions>
Vrátime sa do nášho herného okna, kde si nový komponent pridáme rovnakým spôsobom ako vyššie:
AddComponent(new TextLabel("Vodáček zdraví Kučíře!!",new Vector2(300,350),"maly"));
Na pozícii (300,350) sa ukáže nami zadaný text a bude vykreslený fontom maly. Vyzerať to bude nasledovne:
To je pre dnešný diel všetko. Pridali sme si pár ukážkových
komponentov do nášho enginu. Rovnakým spôsobom možno urobiť aj posuvný
text, farby meniace sprite a ďalšie iné srandičky. Pre predstavu som do
vzorového kódu dole pod článkom z Robotris
ukradol a mierne
upravil posúvanie text s autormi hry. Ďakujeme zmijozelákům
za pekný návod. Tak sa na neho pozrite. Nabudúce bude potrebné vytvoriť
kameru, aby sme sa mohli opäť vydať do 3D priestoru.
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é 227x (1.67 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#