12. díl - 3D bludiště v XNA - Hráčská kamera

C# .NET XNA game studio 3D bludiště 3D bludiště v XNA - Hráčská kamera

Vítejte po dva-a-dvacáté. V tomto díle si pokusnou kuličku nahradíme kamerou a poprvé si tedy vyzkoušíme bludiště projít jako hráči, tedy z pohledu 1. osoby.

Hráčská kamera

Jako kameru pro hráče nemůžeme použít tu co máme nyní. Naše kamera nerespektuje kolize a navíc s ní lze létat nahoru a dolů. Vytvoříme si tedy kameru novou, do složky na kamery si přidáme nový soubor s třídou FPSKamera. Dědit budeme od TargetKamery, stejně jako v případě volné kamery. Potřeba budou dvě proměnné pro natočení kamery, nic nového pod sluncem:

float fYaw, fPitch;

public float Yaw{
  get{
    return fYaw;
  }
  set{
    fYaw = value;
  }
}

public float Pitch{
  get{
    return fPitch;
  }
  set{
    fPitch = value;
  }
}

Novinkou je naopak kolizní koule.

BoundingSphere koule;

Kterou si v konstruktoru spolu s ostatními proměnnými nastavíme:

public FPSKamera(GameScreen okno, Vector3 pozice, Vector3 target)
  : base(okno, pozice, target){
  fYaw = 0;
  fPitch = 0;

  koule = new BoundingSphere(pozice, 5);
}

Pozice středu koule je stejná jako pozice kamery a poloměr koule je pět jednotek. Jen připomenu, že velikost kostek jsme si zvolili na 20 jednotek, takže je kolem koule dostatek místa pro pohyb. Máme vše připraveno až na to, že kamera je zatím statická. Vezmeme si metodu Update z volné kamery a tu si jen mírně upravíme. Takže jen pro úplnost jak metoda vypadá:

public override void Update(){
  fYaw -= Parent.Engine.Input.DeltaX*0.01f;
  fPitch -= Parent.Engine.Input.DeltaY * 0.01f;

  Matrix rotace = Matrix.CreateFromYawPitchRoll(fYaw, fPitch, 0);

  Vector3 posun = Vector3.Zero;
  if (Parent.Engine.Input.DrzenaKlavesa(Keys.Up)) posun += Vector3.Forward;
  if (Parent.Engine.Input.DrzenaKlavesa(Keys.Down)) posun += Vector3.Backward;
  if (Parent.Engine.Input.DrzenaKlavesa(Keys.Left)) posun += Vector3.Left;
  if (Parent.Engine.Input.DrzenaKlavesa(Keys.Right)) posun += Vector3.Right;

  posun *= 0.1f * (float)Parent.Engine.GameTime.ElapsedGameTime.TotalMilliseconds;

  Pozice += Vector3.Transform(posun,rotace);

  Target = Pozice + Vector3.Transform(Vector3.Forward,rotace);
  base.Update();
}

První věc, kterou musíme napravit, je rotační matice. Nechceme, aby bylo možné stoupat s kamerou nahoru a dolů. Proto nastavíme druhý parametr na nulu:

Matrix rotace = Matrix.CreateFromYawPitchRoll(fYaw, 0, 0);

Rychlost pohybu je moc velká, poloviční bude stačit a proto změníme konstantu z 0,1 na 0,05:

posun *= 0.05f * (float)Parent.Engine.GameTime.ElapsedGameTime.TotalMilliseconds;

Nyní je čas zohlednit kolize. Máme vypočteno o kolik se jakým směrem chceme pohnout. Stejně jako u pokusné kuličky si uložíme starou pozici:

Vector3 stara = koule.Center;

Vypočteme novou pozici koule:

Pozice += Vector3.Transform(posun, rotace);
koule.Center = Pozice;

A pokud není pohyb nulový tak zkontrolujeme kolize:

if (posun != Vector3.Zero && Parent is CollidableGameScreen){
  CollidableGameScreen okno = Parent as CollidableGameScreen;
  koule.Center = okno.CollisionManager.Collide(koule, stara, koule.Center);
  Pozice = koule.Center;
}

Musíme posunout cíl kam se kamera dívá. Ale zde budeme potřebovat oba dva úhly, umožníme hráči dívat se nahoru a dolů. Vypočteme si znovu rotační matici a výpočet cíle necháme tak jak byl:

rotace = Matrix.CreateFromYawPitchRoll(fYaw, fPitch, 0);

V herním okně pak už jen přenastavíme kameru za nově vytvořenou. Její polohu a to kam se dívá vezmeme z načtené mapy:

Kamera = new FPSKamera(this, new Vector3(mapa.Start.X, 10f, mapa.Start.Z), new Vector3(mapa.Start.X, 10f, mapa.Start.Z));

Povšimněte si, že jsem zvolil výšku 10. Pokusně jsem se k tomuto číslu dostal a zkrátka to s ním vypadalo asi nejlépe. Pro budoucí použití se nám sice moc hodit nebude a to v případě, kdy bychom chtěli aplikovat gravitaci a brát výšku z terénu. Prozatím to ale bude stačit. Pokud si nyní zkusíte hru zapnout a testovací bludiště si projít, dříve nebo později narazíte na problém. Myš se vám dostane na konec obrazovky a jednoduše už nemůžete zatáčet na jednu stranu. :-) To je celkem velký problém, avšak není neřešitelný. Do třídy Input, která se nám stará o klávesnici a myš, si přidáme novou metodu CenterMouse, která nám myš pěkně vycentruje na střed obrazovky a nikdy se nám už nestane, že by se myš dostala do pozice, ze které by nám nešlo hru ovládat. Nejsem si jist, jak přesně tento problém řeší ostatní, ale podle mě to asi ani jinak nejde. Do této třídy si předně přidáme proměnnou pro engine, skrze ní budeme získávat velikost okna a budeme moci myš vždy centrovat:

private Engine Engine;

V kontruktoru ji nastavíme:

public Input(Engine en){
  Engine = en;
}

A konečně můžeme přidat onu metodu CenterMouse, ta myš vycentruje:

public void CenterMouse(){
  Mouse.SetPosition(Engine.GraphicsDevice.PresentationParameters.BackBufferWidth / 2, Engine.GraphicsDevice.PresentationParameters.BackBufferHeight / 2);
  mysState = Mouse.GetState();
}

V konstruktoru enginu pak přidáme parametr:

fInput = new Input(this);

A máme hotovo. V naší nové kameře pak už jen tuto metodu zavoláme. A to ihned po tom, co zjistíme o kolik se myš pohnula:

Parent.Engine.Input.CenterMouse();

Hotovo. Nyní už by se mělo povést bludiště projít bez komplikací. Je pravdou že kolize nejsou optimální a že se občas stane že se postava zasekne, obzvláště když vybírá zatáčku nebo se snaží klouzat po zdi. Je to ale doufám přijatelná oběť za jednoduchost toho jak jsou kolize řešeny.

3D bludiště v C# .NET XNA

To by bylo pro dnešek vše. Příště nevím co uděláme, máme možnost udělat menu a hru tak doobalit do nějakého výsledného tvaru. Opět čekám na komentáře.


 

Stáhnout

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

 

  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ů) :
55555


 


Miniatura
Předchozí článek
3D bludiště v XNA - Časujeme
Miniatura
Všechny články v sekci
3D bludiště v XNA

 

 

Komentáře

Avatar
loob
Člen
Avatar
loob:

Předně musím pochválit autora tohoto seriálu. Je to přesně hezky lidsky srozumitelně podaný a člověku to ušetří spoustu hodin samostudia z jiných zdrojů. Takže chválím a jen tak dál.
To menu a třeba i další části hry (např. options nebo intro, outro, credits atp.) by nebylo vůbec od věci. Ať jsou každému jasné principy. Těším se na pokračování a přeju hodně sil a zdaru.

Odpovědět 29.1.2013 19:30
Beskyde, Beskyde, kdo po tobě SCSI
Avatar
vodacek
Redaktor
Avatar
Odpovídá na loob
vodacek:

děkuji, hodně sem toho přečetl a tak nějak si to vždycky přežvejknu pro sebe tak, abych věděl jak to funguje. Už se mi hodněkrát stalo že to bylo úplně vedle ale většinou mi to projde :-) Jakýsi splash screen mám taky připravenej, jenže se tam používá shader a moc nechci aby tam byla používaná nějaká černá krabice do který by čtenář neviděl...

 
Odpovědět 29.1.2013 21:44
Avatar
Odpovídá na vodacek
Luboš Běhounek (Satik):

Pokud ten shader používáš při zobrazení splashe na zmtavování, tak to můžeš jednoduše (pro začátečníky) obejít tím, že přes obraz vykreslíš černý čtverec přes celou obrazovku s měnící se alphou.

Odpovědět 29.1.2013 23:17
:)
Avatar
vodacek
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
vodacek:

ano to mohu a nebo měnit barvu při vykreslování sprite batchem, ovšem ten shader je tak snadnej že mi připadne že je docela na vysvětlení funkce, uvidíme

 
Odpovědět 30.1.2013 8:00
Avatar
prxman
Člen
Avatar
prxman:

Devbook je super projekt... a aj clanky o XNA su velmi dobre. Rozoberaju tvorbu hier "profesionalnej­sie". Ine tutorialy ukazu len zaklad a ked clovek zacne pracovat na dakom vecsom projekte zisti, ze ma odzakladu zlu koncepciu (orientovanie programu).

Viem, ze keby ste mali viac casu (vodacek a sdraco), tak by ste pisali dalsie clanky... Ale i tak, by som chcel povedat svoju prozbu:

MOHLI BY STE SPRAVIT PAR CLANKOV (alebo aspon 1 taky vseobecny) O TVORBE MULTIPLAYER HRY? Sietova hra (LAN / online ) nie je casta tema v XNA svete (a obecne praca so sietou)

Dakujem za odpoved a este viac za clanok, ak by ste daky zbuchli ;))))

 
Odpovědět 31.1.2013 17:06
Avatar
Odpovídá na prxman
Luboš Běhounek (Satik):

Obecný článek o tvorbě multiplayeru bych sepsat mohl, zkusím se k tomu nějak dokopat.

Odpovědět  +4 31.1.2013 17:14
:)
Avatar
prxman
Člen
Avatar
 
Odpovědět 31.1.2013 17:38
Avatar
Darken141
Člen
Avatar
Darken141:

Je to uplne super spravene a spisane vsetko pokial clovek pozorne cita nikde sa nestrati. mal by som mensiu otazku a ta sa tyka vykreslovanie 3D charakteru skusal som to sam podla predoslich tutorialov ale akosik mi to zlyhalo tak ci by bolo mozne niekde popisat navod ako nato :)

 
Odpovědět 31.1.2013 18:31
Avatar
magic44
Redaktor
Avatar
magic44:

Hezký článek. Jen jedna věc, když je myš vycentrovaná na střed, tak se ze středu nehne, dokud bude hra spuštěnná a to podstatně ztíží její vypnutí. Dalo by se to odstranit tak, že do Input přidáme (třeba od Esc), že se po jeho stisknutí hra ukončí?

private Game hra;
if (Parent.Engine.Input.StisknutaKlavesa(Keys.Escape))
                hra.Exit();
Odpovědět 27.5.2013 14:19
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:

nepochybně, hotové bludiště má na ESC pauzu která myš odblokne prozatím atl+f4 postačuje :)

 
Odpovědět 27.5.2013 14:56
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 10 zpráv z 10.