5. díl - XNA tvorba ve 3D - Engine poprvé

C# .NET XNA game studio 3D grafika XNA tvorba ve 3D - Engine poprvé

Je to již pošesté, co píši úvod k nějakému článku. V tomto díle se podíváme na úvod do napsání enginu. Bylo to celkem nevyhnutné, nemá smysl to moc natahovat. Čím dříve si jej napíšete, tím lépe. Zjednoduší nám to práci a psaní kódu bude snadnější a dosažené výsledky budou lepší. Budeme moci velmi snadno zavést pohyblivou kameru a další pokročilejší věci. Je sice pravdou, že se na internetu povaluje hodně více-či méně hotových a funkčních enginů. Pokud je ale budete při učení se využívat (a to samé platí i pro frameworky, a teď se chytám do pastičky, protože XNA je také framework), tak se může snadno stát, že na daném prostředí zůstanete závislí. Nedovede si představit jiné řešení než za použití dané věci. Uznávám, že pro větší projekty nemá asi smysl psát si vlastní engine, ale použít už něco hotového, co dané vlastnosti už má, ale pro naučení se základních principů je napsání si vlastního podle mého názoru nutné. Dále je také dobré mít na paměti poučku, kterou jsem našel někde na internetu, ale už si nejsem jistý kde to bylo, takže zatím bez zdroje:

Nepište engine, ale hru.

Chytil jsem se také :) Nicméně abychom hru napsat mohli, nějaký základ potřebujeme a ten se pokusím v následujících dvou dílech provést. Není vše z mé hlavy. Za prvotní impulz vděčím Seanu Jamesovi (http://www.innovativegames.net/) a taky jeho knize, odkud sem načerpal spoustu zajímavých věcí, které tu budu prezentovat později. Sean provedl myslím do té doby nevídanou věc, udělal z psaní enginu tutoriál. Jistě lze předložit holou kostru a tím si to odbýt (pro mě jako autora nejlepší, co si budeme namlouvat :-) Dovolil jsem si tedy vzít jeho práci, upravit ji podle sebe a potřeb, které vzešly dalším vývojem, a tu se vám tady pokusím předložit. Zároveň hodlám jít ještě o krůček dále a zároveň s tvorbou jednotlivých komponent paralelně pracovat i na editoru, který umožní plné využití enginu jako takového. Jak takový editor vypadá v akci se může podívat v tomto mém videu:

Není to nic moc (oblíbený kravský obraz nesmí chybět), ale základ je to slušný. Zanechme ale úvodních řečí a pusťme se do díla. Engine samotný se skládá ze tří hlavních tříd. Základem enginu jsou takzvané komponenty. Vyjadřuje je třída Component. Jedná se kupříkladu o model, text nebo třeba fyzikální systém. Až takto daleko lze zajít. Nepotřebujeme fyzikální systém? Nepřidáme komponentu. Jak snadné. Komponenta obsahuje metody Draw, Load a Update, stejně jako jsme měli doposud. Komponenty se sdružují do herních oken reprezentovaných třídou GameScreen. Tato třída řídí pořadí vykreslování jednotlivých komponent. Stará se také o volání správných metod v komponentách. A na závěr třída Engine. Ta sdružuje herní okna a určuje které bude vykresleno. Umožňuje herní okno přidat, odebrat a podobně. Celý systém je snadný jak na pochopení tak na implementaci. Určitě připomíná velmi nápadně systém, který je v XNA již vestavěn. Není potřeba nějak zastírat, že tomu tak opravdu je. Přesto si myslím, že když si jej napíšeme sami, tak to bude lepší.

Jako základ použiji obsah z předcházející lekce, pouze jsem odstranil vše, co souviselo s modelem. Vložíme nový a čistý projekt typu Windows Game Library (knihovna). Zkontrolujte si, že používáte .NET Framework 4. Jméno projektu nechám jen a jen na vás. Já jsme zvolil sobecky VodacekEngine, jelikož se mi stejně už jmenuje to co mám vytvořeno a bude pro mě pohodlnější mít stejný název. Vytvoříme si v něm tři soubory s třídami Engine, GameScreen a Component. Nezapomeňte je učinit veřejně přístupné (public před class). Přidáme reference na knihovny XNA. Klikneme na reference, v menu vybereme Add refenrece, záložka .NET, sjedeme ukazatelem úplně dolů (zde pozor, chvíli to trvá než se seznam načte) a vybereme všechny s názvem Microsoft.Xna.Framework. Je jich celkem 9.

V projektu s naší hrou učiníme podobný krok, ale namísto knihoven XNA přidáme knihovnu s naším enginem. (záložka Projects). Nyní máme vše připraveno a můžeme se pustit do samotného psaní. Do všech tří tříd vložíme potřebné jmenné prostory:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

Začneme třídou Engine. Vytvoříme si metody Update a Draw, netřeba snad říkat, k čemu tyto metody budou sloužit. Pokaždé si v nich uložíme současný herní čas (proměnná v parametru).

private GameTime gameTime;

public GameTime GameTime{
  get { return gameTime; }
}

public void Update(GameTime time){
  this.gameTime = time;
}

public void Draw(GameTime time){
  this.gameTime = time;
}

Vytvoříme si také konstruktor enginu, jako parametr předáme instanci na naši současnou hru. Bude se nám posléze hodit kupříkladu na nastavování titulku okna. Instanci si také uložíme do proměnné:

private Game parent;

public Game Parent {
  get { return parent; }
}

public Engine(Game parent){
  this.parent = parent;
}

Dále budeme potřebovat GraphicsDevice, abychom skrze něj mohli vykreslovat. Uděláme si tedy pro něj proměnnou:

private GraphicsDevice graphics;

public GraphicsDevice GraphicsDevice{
  get { return graphics; }
}

a v konstruktoru ji naplníme:

this.graphics = parent.GraphicsDevice;

Hodit se určitě bude také SpriteBatch. Tak si ji vytvoříme také:

private SpriteBatch spriteBatch;

public SpriteBatch SpriteBatch{
  get { return spriteBatch; }
}

a opět v konstruktoru ji vytvoříme:

this.spriteBatch = new SpriteBatch(graphics);

Dále nám chybí prostředník pro načítání modelů, textur a jiných věcí. Jedná se o třídu ContentManager, časem bude možná potřeba napsat si vlastní stejně jako to udělal Sean ve svém enginu, ale pro začátek bych to nekomplikoval, takže pouze takto:

private ContentManager content;

public ContentManager Content{
  get { return content; }
}

a opět do konstruktoru:

this.content = parent.Content;

Nyní máme všechny důležité proměnné hotové. Zbývá nám jen pole pro herní okna:

public List<GameScreen> Screens;

které opět inicializujeme v konstruktoru:

Screens = new List<GameScreen>();

U tohoto pole pro herní obrazovky bude vhodné se více zastavit. Má totiž fungovat jako takzvaný zásobník. Ten si můžeme představit jako takovou věž. Na vrchol dáváme jednotlivá okna, ale když je chceme vybrat, tak je odebíráme opět ze shora. Někdy se tomu také říká LIFO (last in first out – poslední dovnitř a první ven). Pro práci s tímto zásobníkem budeme používat metodu PushGameScreen, která herní okno na zásobník položí a provede jeho načtení. Dále také metodu PopGameScreen, která herní okno ze zásobníku vyzvedne. Toto řešení nám umožní později mít najednou vykreslované více než jedno herní okno.

public void PushGameScreen(GameScreen okno){
  Screens.Add(okno);
}

public GameScreen PopGameScreen(){
  if (Screens.Count == 0) return null;

  GameScreen ret=Screens[Screens.Count-1];
  Screens.Remove(ret);
  return ret;
}

Nyní přidáme do třídy naší GameScreen virtuální metody Draw a Update. Tentokráte již bez parametrů:

public virtual void Update(){

}

public virtual void Draw(){

}

V třídě s Enginu je na příslušných místech zavoláme. Po úpravě budou tedy vypadat následovně:

public void Update(GameTime time){
  this.gameTime = time;

  foreach (GameScreen okno in Screens){
    okno.Update();
  }
}

public void Draw(GameTime time){
  this.gameTime = time;

  foreach (GameScreen okno in Screens){
    okno.Draw();
  }
}

Gratuluji. Máme třídu s enginem připravenu. Do dalších tříd se pustíme zase příště. Jen doufám, že to nikoho z vás neodradilo a pokud přecijen ano, tak nezoufejte. Dole pod článkem jako vždy naleznete kompletní zdrojový kód, ovšem stále si myslím, že pokud si jej napíšete sami a pochopíte tak jak funguje, že to bude lepší než jen přeložit hotový kód a teď s tím budeme dělat. Co se děje vevnitř vás nemusí zajímat, něco se tam stane a tady je takovej výsledek. Těším se také na komentáře, hlavně abych si o ně nemusel říkat :-)


 

Stáhnout

Staženo 282x (1.57 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 (5 hlasů) :
55555


 


Miniatura
Předchozí článek
XNA tvorba ve 3D - Modely
Miniatura
Všechny články v sekci
Základy 3D grafiky a tvorba enginu

 

 

Komentáře

Avatar
user
Redaktor
Avatar
user:

Myslím, že by tou poučkou mohl být tento článek:
http://scientificninja.com/…-not-engines
Stojí za to se nad ním zamyslet :)

 
Odpovědět 26.1.2013 19:21
Avatar
magic44
Redaktor
Avatar
magic44:

Proč, když chci přidat engine do hry, tak v Projects nic nemám?

Odpovědět 24.4.2013 19:10
Moudrý člověk nechce být lepší než ostatní, ale lepší, než byl sám včera.
Avatar
vodacek
Redaktor
Avatar
 
Odpovědět 24.4.2013 20:19
Avatar
Zdeněk Pavlátka
Tým ITnetwork
Avatar
Odpovídá na vodacek
Zdeněk Pavlátka:

Proč používáš na obrazovky List a metody pro chování zásobníku, když můžeš použít kolekci zásobník?

Odpovědět 16.2.2014 19:12
Kolik jazyků umíš, tolikrát jsi programátor.
Avatar
vodacek
Redaktor
Avatar
Odpovídá na Zdeněk Pavlátka
vodacek:

pravda, asi to je tím že ho dávám všade

 
Odpovědět 16.2.2014 19:41
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 5 zpráv z 5.