Vianoce v ITnetwork sú tu! Dobí si teraz kredity a získaj až 80 % extra kreditov na e-learningové kurzy ZADARMO. Zisti viac.
Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.

11. diel - 3D bludisko v XNA - ČASU

Vitajte po dvadsiate prvé. Chvíľu som premýšľal, či budem aj naďalej číslovať, ale vzhľadom k tomu, že to nikto iný nerobí, tak áno, budem :-) V tomto diele si našej pokusnú guličkou skúsime prejsť bludisko na čas. Vytvoríme si komponent všeobecného časovača ak tomu ďalší časovač, ktorý pude vykresľovať na obrazovku. Tiež si ho do hry naroubujeme. Budeme teda môcť prejsť bludisko na čas :-) Pusťme sa do toho.

Timer

Časovačov a iste dokonalejších nájdeme všade hromady. Nám postačí snadňoučký, ktorý pôjde odstarovat, vynulovať a zase zastaviť. Nič moc ťažkého. V metóde Update sa bude nasčítává čas. Pridáme si teda nový súbor do nášho enginu, konkrétne do zložky s komponentmi. Triedu nazveme Timer. Urobíme ju verejnú a tak ďalej, však to poznáte. Dedíme od triedy Component. Čas budeme skladovať v premennej typu TimeSpan.

public TimeSpan Time{
  get;
  private set;
}

V konstruktoru ho vynulujeme:

public Timer(){
  Time = TimeSpan.Zero;
}

Dodáme tiež premennú pre indikáciu či je časovač aktívny:

public bool Running{
  get;
  private set;
}

Nastavovanie necháme súkromné, nechceme, aby bolo možné s premennou manipulovať mimo triedu. Nasleduje sled verejných virtuálnych metód:

public virtual void Start(){
  Running = true;
}

public virtual void Stop(){
  Running = false;
}

public virtual void Reset(){
  Time = TimeSpan.Zero;
}

Ich význam nie je snáď potreba vysvetľovať. Poslednou súčasťou je prepísaná metóda Update, kde nasčítáváme čas. Teda asi takto:

public override void Update(){
  if(Running)Time += Parent.Engine.GameTime.ElapsedGameTime;
}

Hotovo. Viac toho naozaj nie je. Základná časovač je teda hotový. My ale potrebujeme čas aj ukazovať.

Vykreslovatelný timer

Pridáme si ďalšiu triedu do zložky s komponentmi. Ja som ju nazval GameTimer, ale opäť meno ponechám na vašom uvážení. Dediť budeme od triedy Timer, ktorú sme si pripravili hore. Opäť je trieda verejná, ale to už viete lepšie ako ja. Text budeme vykresľovať skrze SpriteBatch, ako inak že. Potrebujeme poznať jeho pozíciu:

public Vector2 Pozice{
  get;
  set;
}

jeho farbu

public Color Color{
  get;
  set;
}

A akým fontom budeme vykresľovať:

private string fontName;
protected SpriteFont Font;

V Konštruktor všetky parametre nastavíme:

public GameTimer(string font, Vector2 pozice): this(font,pozice,Color.Black){
}

public GameTimer(string font, Vector2 pozice, Color color){
  fontName = font;
  Pozice = pozice;
  Color = color;
}

Tradične v metóde Load nahráme font.

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

A konečne v metóde Draw všetko vykreslíme:

public override void Draw(Microsoft.Xna.Framework.Matrix View, Microsoft.Xna.Framework.Matrix Projection, Microsoft.Xna.Framework.Vector3 CameraPosition){
  Parent.Engine.SpriteBatch.Begin();
  Parent.Engine.SpriteBatch.DrawString(Font, Time.ToString(@"mm\:ss\.ff"), Pozice, Color);
  Parent.Engine.SpriteBatch.End();
}

Vykresľovať počítanie času na hodiny snáď nebude potrebné. Skúsime si pridať nový časovač do nášho herného okna.

AddComponent(new GameTimer("Maly", new Vector2(0, 10)));

Hru si pustíme a vidíme náš nádherný čas a tiež vidíme prúser.

Chyba v časovači v 3D bludisku v C# .NET XNA - 3D bludisko v XNA

Je dôležité si uvedomiť, že zakaždým, keď pracujeme so SpriteBatch, je potrebné vrátiť stav grafickej karty do normálu. Takže po vykreslenie je navrátime.

Parent.Engine.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
Parent.Engine.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
Parent.Engine.GraphicsDevice.BlendState = BlendState.Opaque;

Hotovo. Teraz je všetko ako má byť. Chýba nám už len časovač odštartovať.

Štartovej a cieľová podlaha

To sa bude diať na týchto našich špeciálnych podlahách. Začneme sa štartové podlahou, ktorú až gulička / hráč opustí, tak sa časovač spustí. Otvoríme si teda triedu sa štartové podlahou. Zmeníme triedu od ktorej dedíme na CollidableModel3D. Rovnako ako sme urobili pri stene. Prepíšeme metódu Load. Necháme zavolať metódu Load u predka. Naši kolízne krabicu ale musíme na osi Y zväčšiť, pretože model len len placka a my potrebujeme plnú krabicu.

this.CollisionSkin.ZakladniKrabice.Max.Y = 15;

Skúsime si hru spustiť, či je všetko v poriadku. Je snáď jasné, že keď na to tak upozorňujem, niečo v poriadku nebude. Vôbec sa nám nepodarí odísť preč. Nečakane. Systém nám detekuje kolíziu a guľôčku nepustí ani o pixel. V našom systéme chýba možnosť urobiť kožu priechodná. Pýtate sa prečo ju teda potrebujeme, keď sa skrze nej dá prejsť, ale práve o to nám ide. Aby sa zavolala udalosť a aby všetko bolo na jednom mieste. Pozrieme sa teda do našej kože a do nej pridáme parameter Solid:

public bool Solid{
  get;
  set;
}

V konstruktoru ho nastavíme na true. Všetko bude pevné len na výnimky, ktoré si stanovíme. Jednou takou je práve urobíme u štartové podlahy, takže nastavíme Solid na false.

this.CollisionSkin.Solid = false;

Ešte ho potrebujeme zohľadniť v kolíznom manažérovi. Do metódy Collide pridáme pred pridanie kože do zoznamu podmienku, či je pevná:

if (skin.CheckCollision(sphere) && skin.Solid) colliding.Add(skin);

Ak teraz hru spustíme, tak už sa nám podarí odísť. To bol onen zádrhel, ktorý som avizoval minule. Viac sa ich snáď už nenaskytne. Dúfajme.

Poslednou vecou, ktorú potrebujeme, je odchytiť udalosť, že gulička pole opustila. Pridáme si ju teda:

this.CollisionSkin.UnCollided += new CollisionEnd(CollisionSkin_Collided);

Zároveň nám to vytvorí aj obslužnú metódu. Vnútri nej nájdeme medzi komponentmi časovač a spustíme ho:

void CollisionSkin_Collided(BoundingSphere koule){
  GameTimer t = null;
  foreach (Component c in Parent.Components){
    if (c is GameTimer){
      t = c as GameTimer;
      break;
    }
  }

  if (t != null){
    t.Start();
  }
}

Ak teraz hru spustíme a odídeme zo štartovacieho poľa, vualáá, časovač jede. Rovnaký postup aplikujeme u cieľovej podlahy, len časovač zastavíme a reagujeme na vstup do políčka nie na výstup. Ak by mal niekto s týmto problém, tak vás odkazujem na celý kód pod článkom.

Nabudúce si urobíme kameru a nahradíme jej tak guľôčku. Prvýkrát si bludisko prejdeme ako hráči.


 

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

 

Predchádzajúci článok
3D bludisko v XNA - Kolízia tretíkrát a snáď naposledy
Všetky články v sekcii
3D bludisko v XNA
Preskočiť článok
(neodporúčame)
3D bludisko v XNA - Hráčska kamera
Článok pre vás napísal vodacek
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
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.
Aktivity