8. díl - XNA tvorba ve 3D - Sprity a Text

C# .NET XNA game studio 3D grafika XNA tvorba ve 3D - Sprity a Text

Sice si nejsem moc jist, jaký má význam psát další díl, když má být zítra ten konec světa, ale i přesto vítejte podeváté. V minulých dílech jsme si sestavili kostru enginu. Dnes ji poprvé pořádně využijeme. Vytvoříme si pár nových komponent. První bude obyčejný sprite, potom také obyčejný text. I takové ne-3D komponenty se budou hodit pro různá menu. Text lze využít také pro vypisování debugovacích informací.

Předně je důležité přiznat, že se mi povedlo udělat při psaní předchozích návodů docela zásadní chybu a přišel jsem na ní až při psaní tohoto dílu. Chyba už byla v příslušném článku opravena, ale ještě zbývá opravit chybu u těch co si článek četli před opravou. Engine musí být Windows Game Library a ne pouze Class library. Stačí když si projekt tohoto typu založíte a soubory do něj přesunete. Děkuju za pochopení.

Dále bude potřeba enginu přidat projekt s obsahem. Tady jsem si už jist, že je potřeba přidat projekt Empty Content. Pojmenujeme si jej jménem enginu a na konec přidejte slůvko Content. Ale opět, jako u všeho, je to jen na vás jaké jméno tomu dáte. Potřeba je také tento projekt přidat k enginu. Klepneme pravým tlačítkem myši na jméno projektu s enginem a vybereme položku Add Content reference. A v menu vybereme právě vytvořený projekt. Skvěle, přípravy jsou hotové. Můžeme pokračovat v dalším psaní.

Sprite

Vytvoříme si třídu Sprite v naší složce Components. Učiníme ji veřejnou a nezapomeneme napravit jmenný prostor. Třída opět bude dědit od naší komponenty (nezapomeneme přidat using). V konstruktoru budeme jako parametr předávat jméno použité textury a polohu horního levého rohu spritu na obrazovce. Vytvoříme si jej 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;
}

Tady by mohla vyvstat otázka: proč předáváme jméno textury a ne přímo instanci textury. Tu si právě nahrajeme v metodě Load, která k tomuto účelu slouží. Dále se bude hodit proměnná, kde si uložíme rozměry našeho obrázku:

public Rectangle DestinationRectangle { get; set; }

Třída Rectangle nepředstavuje nic jiného než čtverec/obdélník. Přidáme taky konstruktor kde nastavíme vlastní rozměry obrázku. Přidáme také druhý konstruktor, kde ze zadaných rozměrů vytvoříme instanci:

public Sprite(string textureName, Vector2 position, int width, int height)
  : this(textureName, position){
     DestinationRectangle = new Rectangle((int)position.X, (int)position.Y, width, height);
}

Vytvoříme si také chráněnou proměnnou Texture, kde budeme naši texturu skladovat.

protected Texture2D Texture;

Nyní přepíšeme metodu Load, kde nahrajeme texturu podle jména zadaného v konstruktoru. A v případě, že proměnná DestinationRectangle má šířku nebo výšku nulovou, tak ji vytvoříme s rozměry textury:

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 nyní nám už stačí pouze metoda Draw, která nám vše vykreslí:

public override void Draw(){
  Parent.Engine.SpriteBatch.Begin();
  Parent.Engine.SpriteBatch.Draw(Texture, DestinationRectangle, Color.White);
  Parent.Engine.SpriteBatch.End();
}

Není to nic moc nového a objevného, pouze namísto pozice jsme předali náš čtverec/obdélník, pomocí kterého můžeme měnit velikosti. K dokonalosti nám tu chybí ještě jedna malá drobnost. Pokud bysme nyní změnili pozici našeho spritu, tak by nám zůstal tak by se nic nezměnilo. Sice si polohu ukládáme, ale neměníme hodnoty v proměnné DestinationRectngle. Takže to v setteru napravíme:

DestinationRectangle = new Rectangle((int)Position.X, (int)Position.Y, DestinationRectangle.Width, DestinationRectangle.Height);

Šířku a výšku obrázku převezmeme z původního a pouze jen nandáme nové hodnoty. Nyní je již vše kompletně připraveno a můžeme komponentu vyzkoušet. Budeme postupovat stejně jako posledně s barevným pozadím. Do projektu s obsahem si přidáme náš obrázek a to obvyklým postupem, který již znáte z předchozích dílů. Třeba zas erb ŽvB. Tady je dobré poznamenat, že vše co se netýká enginu budeme dávat do hry. Otevřeme si soubor s třídou našeho herního okna, které jsme si vytvořili minule, a do metody Load POD komponentu s barevným pozadím přidáme novou komponentu:

AddComponent(new Sprite("erb",new Vector2(230,170)));

Obrázek tedy bude mít texturu erbu a bude umístěn na souřadnice (230,170). Zde je asi dobré připomenout, že souřadnice (0,0) se nalézají v levém horním rohu. Když si nyní projekt spustíme, měli bychom dostat následující výsledek:

Zobrazení spritu v XNA 3d hře

Zkusme si přidat ještě druhý erb, tentokráte ale mírně natáhnutý:

AddComponent(new Sprite("erb", new Vector2(420, 220),200,50));

Když nyní hru spustíme a vše jsme udělali dobře tak výsledek bude následující:

Zobrazení spritu v XNA 3d hře

Se sprity se toho dá dělat mnoho. Dají se různě natáčet, měnit jejich barvy a nebo jen zobrazit jejich část. Toto ale nechám na vás, stačí použít jinou metodu pro vykreslování a jen přidat parametry stejným způsobem, jako jsem to udělal já.

Text

Ještě jsem neprozřetelně nasliboval komponentu s textem. Ale když jsem ji slíbil, tak si ji tedy uděláme. Opět si vytvoříme třídu TextLabel v naší složce s komponentami. Učiníme ji veřejnou, nasolíme tam správné jmenné prostory, prostě vše jako obvykle. Opět budeme dědit od třídy Component. U textu se nám bude hodit pár parametrů. Barva písma, pozice a samotný text. Bude opět potřeba zadat jméno souboru s fontem stejně jako u předešlé komponenty:

private string fontName;

public Vector2 Position{
  get;
  set;
}

public Color Color{
  get;
  set;
}

public string Text{
  get;
  set;
}

Vytvoříme konstruktory, kde jako parametr všechny tyto údaje předá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ět jako v předchozím případě přepíšeme metodu Load a načteme zde font, kterému ale nejdřív vytvoříme proměnnou:

protected SpriteFont SpriteFont;

protected override void Load(){
  SpriteFont = Parent.Engine.Content.Load<SpriteFont>(fontName);
}

A opět v metodě Draw stejně jako v předchozím případě vykreslíme:

public override void Draw(){
  Parent.Engine.SpriteBatch.Begin();
  Parent.Engine.SpriteBatch.DrawString(SpriteFont,Text,Position,Color);
  Parent.Engine.SpriteBatch.End();
}

Popisek je tedy hotový. Do projektu s obsahem přidáme nový soubor se sprite fontem. Stejně jako se to dělalo v případě Robotetris, pokud nevíte, koukněte na díl Vložení obsahu XNA hry. Nezapomeneme editovat oblast používaných znaků tak, aby obsáhly i ty s českou diakritikou a použijeme font třeba Verdanu. Font si pojmenujeme maly. Změny jsem provedl na následujících řádkách:

<FontName>verdana</FontName>

<CharacterRegions>
   <CharacterRegion>
      <Start>&#32;</Start>
      <End>&#390;</End>
   </CharacterRegion>
</CharacterRegions>

Vrátíme se do našeho herního okna, kde si novou komponentu přidáme stejným způsobem jako výše:

AddComponent(new TextLabel("Vodáček zdraví Kučíře!!",new Vector2(300,350),"maly"));

Na pozici (300,350) se ukáže námi zadaný text a bude vykreslen fontem maly. Vypadat to bude následovně:

Vykreslení textu v XNA 3D enginu

To je pro dnešní díl vše. Přidali jsme si pár ukázkových komponent do našeho enginu. Stejným způsobem lze udělat i posuvný text, barvy měnící sprite a další jiné legrácky. Pro představu jsem do ukázkového kódu dole pod článkem z Robotris ukradl a mírně poupravil posouvaný text s autory hry. Děkujeme zmijozelákům za pěkný návod. Tak se na něj koukněte. Příště bude potřeba vytvořit kameru, abychom se mohli opět vydat do 3D prostoru.


 

Stáhnout

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

 

  Aktivity (1)

Článek pro vás napsal vodacek
Avatar
Vodáček dělá že umí C#, naplno se již pět let angažuje v projektu ŽvB. Nyní studuje na FEI Upa informatiku, ikdyž si připadá spíš na ekonomice. Není mu také cizí PHP a SQL. Naopak cizí mu je Java a Python.

Jak se ti líbí článek?
Celkem (3 hlasů) :
4.666674.666674.666674.666674.66667


 


Miniatura
Všechny články v sekci
Základy 3D grafiky a tvorba enginu
Miniatura
Následující článek
XNA tvorba ve 3D - Kamera

 

 

Komentáře

Avatar
magic44
Redaktor
Avatar
magic44:

Můžu se zeptat, proč v MojeHerniOkno nevidím třídy Sprite a TextLabel? Ostatní (Pozadi, Engine...) tam vidím.
Takhle vypadá Sprite. Jmený prostor je správný a třída veřejná.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Engine
{
    public class Sprite:Component
    {
    }
}
Editováno 30.4.2013 16:36
Odpovědět 30.4.2013 16:32
Moudrý člověk nechce být lepší než ostatní, ale lepší, než byl sám včera.
Avatar
vodacek
Redaktor
Avatar
Odpovídá na magic44
vodacek:

tak to nedovedu takhle na dálku posoudit

 
Odpovědět 30.4.2013 22:50
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 2 zpráv z 2.