Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

6. diel - 3D bludisko v XNA - Podlahy druhýkrát a kolízie

Vitajte po šestnástej. V tomto diele si vytvoríme cieľovú a štartové podlahu, ktoré budú inak farebné než zvyšné podlahy. Vytvorenie oných podláh nie je tak triviálne ako u podlahy normálne, ale to sa hnedle ukáže. Ďalej sa pozrieme na možnosti kolízií a celý systém premyslíme. Na záver si napíšeme pomocné triedy pre vykreslenie krabice a gule.

Štartovej a cieľová podlaha

Vytvoríme si rovnako ako posledne súbor v priečinku na komponenty. Triedu opäť nazvite tak ako je vám libo, ja som zvolil StartovniPodlaha. Konštruktor zostane rovnaký ako minule:

public StartovniPodlaha(int x, int z): base(new Vector3(x*20+10,0,z*20+10),Matrix.Identity,new Vector3(1.34f),"podlaha") {

}

Zatiaľ nie je žiadna podivnosť na obzore. Teraz má ale podlaha rovnaký vzhľad ako podlahy ostatní. Ale my chceme dlaždicu zvýrazniť inou farbou. Máme v zásade dve možnosti. Buď si v modelovacím programu dlaždicu nafarbíme a urobíme si tak nový model a máme po problémoch a alebo si farbu pri vykreslenie upravíme. Prvá možnosť je pre srab a tak si farbu jednoducho zmeníme pri vykreslenie.

Prepíšeme si metódu Draw s našimi parametrami:

public override void Draw(Matrix View, Matrix Projection, Vector3 CameraPosition)

A nakopírujeme vlastne celý obsah pôvodnej metódy, takže pre prehľad ju tu uvádzam:

Matrix world = Utility.CreateWorld(Pozice, Rotace, Meritko);
foreach (ModelMesh mesh in Model.Meshes){
  foreach (ModelMeshPart part in mesh.MeshParts){
    if (part.Effect is BasicEffect){
      BasicEffect efekt = part.Effect as BasicEffect;
      efekt.View = View;
      efekt.Projection = Projection;
      efekt.World = transformace[mesh.ParentBone.Index] * world;
      efekt.EnableDefaultLighting();
    }
  }
  mesh.Draw();
}

A pol práca je hneď hotovo. Ešte nezabudnúť nastaviť poli s transformáciami modifikátor na protected, rovnako ako som urobil ja:

protected Matrix[] transformace;

Farbu vykresľovanie plochy zmeníme veľmi ľahko. BasicEffect na to má priamo premennú DiffuseColor. Ale tá nie je napodiv typu Color ako by sa čakalo, ale Vector3. Grafická karta totiž nepracuje s farbami vo formáte 0-255 ale 0-1 a na ich uloženie sa hodí práve Vector3. Vector4 sa potom hodia pre farby s alfa kanálom, ale tým sa zatiaľ nebudeme zaťažovať. Trieda vektora tak dostáva už tretí význam. Pripomeňme, že prvé bolo určenie pozície a druhý bol vektor potrebné pre pohyb. Ako ich navzájom previesť nemusíme riešiť. Štruktúra Color na to má metódu ToVector3, ktorú použijeme. Vector3 ani Color už ale spätnú metódu nemá. Do efektu teda priradíme treba svetlomodrou farbu:

efekt.DiffuseColor = Color.Aqua.ToVector3();

Nájdeme si triedu s mapou a do switch e si pridáme ďalšiu vetvu s novou podlahou:

case 99:{
  c = new StartovniPodlaha(i, j);
  break;
}

Skúsime si výsledok spustiť aby sme videli novú tyrkysovú pohromu, ktorá je rozlezlá po všetkých podlahách.

Podlahy v 3D bludisku v C# XNA - 3D bludisko v XNA

Dôvod je jasný. XNA sa snaží šetriť a tak zakaždým, keď sa pokúsime o nahranie modelu alebo čohokoľvek, tak sa pozrie, či ak sme tak už neurobili a v prípade že áno nám vráti uloženú inštanciu. To sa nám veľmi nehodí, celú vec to mierne komplikuje, ale nie je to nič neprekonateľného. Úplne bude stačiť, keď pri vykreslenie vrátime pôvodnú farbu. Takže hneď za vykreslenie danej meshe modelu pridáme ďalšie foreach cyklus, kde farbu navrátime:

foreach (ModelMeshPart part in mesh.MeshParts){
  if (part.Effect is BasicEffect){
    BasicEffect efekt = part.Effect as BasicEffect;
    efekt.DiffuseColor = Color.Blue.ToVector3();
  }
}

To je všetko. Ak teraz hru spustíme, tyrkysové zostalo len jedno pole a to je to, čo chceme. Úplne rovnako budeme postupovať aj v prípade cieľovej podlahy, iba zvolíme inú výraznú farbu (ja som dal červenú), iné číslo poľa, v tomto prípade 100, a iný názov súboru a triedy.

Podlahy v 3D bludisku v C# XNA - 3D bludisko v XNA

Kolízie

Vôbec najväčší oriešok, ktorému budeme čeliť, sú kolízie. Ak sa nad tým zamyslíte, tak je možné vyriešiť aj celkom intuitívne. Máme k dispozícii polia s priechodnými a neprůchozími políčkami. Možno tak pohyb hráča vymedziť len a len skrze súradnice. Je to funkčný, je to ľahké. Avšak pri tvorbe enginu, o ktorý sa tak trochu stále viac skryto pokúšam, to nie je moc taktický krok. V akej inej hre toto použijete? Obávam sa, že asi už v žiadnej inej. Má preto asi väčšiu cenu pokúsiť sa o pokročilejšie systém, ktorý na tomto jednoduchom prípadu môžeme vyskúšať, vytvoriť a potom ho len na zložitejšie veci aplikovať a prípadne ho len kvapku rozšíriť.

Základom sú kolízne objekty, ktoré akoby obaľujú naše modely a kolízie zjednodušujú a robia je matematicky uskutočniteľnými v reálnom čase. Zatiaľ sú naše modely veľmi jednoduché, ako do počtu hrán a vrcholov, tak pre kolízie, ale nie vždy to tak s modelmi je. Práve preto sa obaľujú tvarovo a výpočtovo jednoduchšími objekty. Trpíme tým síce na presnosti kolízie, ale za to dostávame kratší výpočtový čas. A to je poväčšinou to hlavné, o čo nám ide, aby hra bežala čo najsvižnejšie. Používajú sa dva zásadné tvary: gule a kocky alebo ak chcete kváder. Pre výpočty je najrýchlejší kolízie gule s guľou. Len sa spočíta vzdialenosť ich stredov. Kvádre, ktorým budem pre istotu hovoriť krabice, už majú výpočet zložitejšie, ale je tu zavedených niekoľko zjednodušujúcich pravidiel.

Krabica používané v XNA sú osovo orientované. Anglicky možno hľadať návody a algoritmy pod názvom axis aligned bounding box alebo len so skratkou AABB. Čo to ale znamená osovo orientované? Slovensky možno povedať že s nimi nejde rotovať. Ich hrany stále zostávajú rovnobežné s osami herného sveta. Ako to vyzerá keď sa objekt otáča môžete vidieť na tomto mojom videu:

Krabice sa nám zväčšuje a opäť zmenšuje. Nie je to moc dobré, ale čo narobíme. Máme tu ešte guľu, ktorá sa pre rotujúce objekty hodí viac, pri rotácii je totiž stále rovnaká :-) ale nie zas na všetky druhy objektov sa hodí. Naše múru by neboli príliš dobre obalitelné gulí. Naopak pre hráčov sa guľa hodí myslím pomerne dobre. XNA obsahuje tiež lúč Ray, ten sa hodí pre strieľanie a klikanie myšou na objekty za použitia takzvaného ray castingu. Máme tiež tiež plochu Plane. Plocha nie je ničím obmedzená je teda nekonečne veľká. Ale aj tak ju možno použiť napríklad k ukončeniu sveta.

Hráča si teda obalíme gulí, múry zas krabicami. Stále je ale počet výpočtov, ktoré musíme vykonať pri každom volanie metódy Update u hracieho okna (tu totiž budeme kolízie počítať), veľmi veľký. Vezmite si, že máme bludisko 10x10 políčok. To máme celkom v najhoršom prípade 100 kusov múrov. Hráč môže kolidovať so 100 objektmi, krabice okolo múru s ďalšími 100 a tak ďalej. To je nepredstaviteľne veľký počet výpočtov. Preto označíme krabica pre múry za statické a tým tiež ušetríme veľa výpočtového času. Počítať sa bude teda iba 100 kolízií, ale aj to je pomerne dosť. Existujú metódy, ktoré nám to môžu razantne zmenšiť, ale tie zatiaľ ponechajme stranou.

Súvahu ako to to pôjdeme máme teda hotovú. Dosť mi chýba že v návodoch na internete sa zvyčajne len dočítate ako to riešiť, ale prečo takto a nie inak sa už nedozviete. Jednoducho preto. Snažím sa byť v tomto smere iný a svoje myšlienkové pochody (často realizované v posteli pred spaním) v tomto texte prezentovať. Mnohokrát som so svojimi riešeniami narazil na nepochopenie, naposledy výraznejšie na Socci, ale tým že sem bol v štátnom kole sa tu nebudem vyťahovať. Ak vás skôr zaujíma, ako si okopírovať bezmyšlienkovite tých pár riadkov kódu, tak to si budete musieť počkať na inokedy. Nemám tu ešte stále moc jasno ako presne to urobíme, ale už sa obloha protrhávat. Čo viem iste je že bude potreba je krabica a gule, na tie sa pozrieme nabudúce.


 

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

 

Predchádzajúci článok
3D bludisko v XNA - Dokončenie editoru máp
Všetky články v sekcii
3D bludisko v XNA
Preskočiť článok
(neodporúčame)
3D bludisko v XNA - Škatule a guľa
Č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