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.
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#