Cvičenie 6
Nadišiel čas na vytvorenie novej hry:
Postupujte rovnako, ako pri prvom projekte. Tento raz použite novú knižnicu - MerlinCore. Táto je síce dosť podobná tomu, na čo ste už boli zvyknutí, ale je tu niekoľko zmien - niektoré veci, ktoré ste mali doteraz implementované (napr. AbstractActor) už nie sú, zostali len rozhrania. Tiež bola pridané podpora pre nové rozhrania (napr. inventár, automatické vytváranie actorov z mapy).
Vytvorte si priečinky Actors
, Commands
a Items
.
Nezabudnite si pridať priečinok Resources
- je tu ale zmena, animácie sú po novom uložené v priečinku Resources/sprites
Skopírujte si triedy Player, Enemy, Gravity
a všetky ich závislosti (nezabudnite upraviť namespaces, atď...).
6.1 AbstractActor
Vytvorte si triedu AbstractActor
v priečinku Actors
(oh, really?). Implementujte ju nasledovne:
- konštruktor:
-
AbstractActor()
- nastavte prázdny string pre meno, nech sa predíde problémom AbstractActor(string name)
-
-
string GetName()
- vráti meno actora -
int GetX(), GetY()
- vráti X-ovú a Y-ovú súradnicu (ľavý horný vrchol) -
int GetWidth(), GetHeight
- vráti rozmery actora (viete ich získať z animácie) -
void SetPosition(int x, int y)
- nastaví pozíciu -
void AddedToWorld(IWorld world)
- nastaví referenciu na svet v ktorom sa actor pohybuje - volané automaticky zGameWorld
-
IAnimation GetAnimation() & void SetAnimation(IAnimation animation)
- prístup k animácií -
bool IntersectsWithActor(IActor other)
- zistí kolíziu s iným actorom - aby bola kolízia, stačí, aby sa prekrývali v jednom bode - obidvaja actori majú tvar obdĺžnika -
void SetPhysics(bool isPhysicsEnabled) & bool IsAffectedByPhysics(void)
- informácie o fyzike (gravitácií) -
void RemoveFromWorld()
- slúži na nastavenie príznaku, či daný actor má byť zo sveta odstránený. Všetci označení actori sú na konci iterácie v hernej slučke odstránení naraz. -
boold RemovedFromWorld()
- zistí, či daný actor bol označený na odstránenie zo sveta -GameWorld
volá túto funkciu v rámci hernej slučky po zavolaníUpdate()
.
Pre lepšie zorientovanie, tu je implementácia GameWorld.Update, pridávanie a odstraňovanie actorov je robené dávkovo (batch):
//GameWorld.cs
internal void Update(long i)
{
actorsToAdd.ForEach(actor =>
{
this.actors.Add(actor);
actor.OnAddedToWorld(this);
});
actorsToAdd.Clear();
triggers.ForEach(trigger => trigger.Update());
actors.ForEach(actor => actor.Update());
actors.RemoveAll(actor => actor.RemovedFromWorld());
if (gameLevelPhysics != null)
{
gameLevelPhysics.Execute();
}
}
6.2 Lets build a factory
Návrhové vzory FactoryMethod a AbstractFactory slúžia na automatické vytváranie objektov. Vytvorte si triedu ActorFactory
, nech implementuje rozhranie IFactory
Cieľom tejto triedy je automaticky vytvárať nové objekty podľa vstupných parametrov - vieme takto zabezpečiť vytvorenie a pridanie actorov načítaných z mapy.
Implementácia je veľmi jednoduchá, jeden z parametrov je očakávaný typ - v podmienke zistite, ktorý a vytvorte zodpovedajúcu inštanciu. Keďže všetky triedy, ktoré FactoryMethod vytvára musia mať spoločný interface, môžeme na tomto mieste využiť polymorfizmus.
6.3 .tmx
Stiahnite si editor Tiled a vytvorte si mapu podľa pokynov na cvičení (prípadne si môžete pozrieť nejaký na internete). Implementácie v Merlin2d je jednoduchá, takže neumožňuje využtie komplexnejších prvkov, niekoľko obmedzení:
- 1 tileset pre mapu (ak potrebujete použiť rôzne, spojte ich do jedného obrázku)
- nefunguje render order
- Orientation: orthogonal
- custom properties nie sú (tu je to kvôli Factory, ak potrebujete nastaviť špecifické veci pre jedného actora, identifikujte ho špecifickým menom a v ďalšom bode si pridáme anonymnú funkciu (funkcie), ktorá nám takéto veci nastaví).
Mapa musí obsahovať nasledujúce vrstvy:
-
objects
- tu sú actori-
Name
: meno actora,Type
: názov triedy,X,Y
- súradnica ľavého horného rohu, rozmery sú ignorované - použité sú rozmery z animácie
-
-
walls
- vyznačené steny, všetko, čo je vymaľované je (neviditeľná) stena, zvyšok je priechodný -
background
- toto sa zobrazí ako svet v hre (nakreslite sem aj steny)
Zapojte tu svoju tvorivosť.
6.4 Initialization
V IWorld
je metóda void AddInitAction(Action<IWorld> action)
- táto očakáva anonymnú funkciu (void func(IWorld))
(môžete ju volať aj viac krát - pridať rôzne funkcie) - uložia sa a vykonajú pri inicializácií hry (na začiatku, keď sa zavolá Run()
). Pomocou takýchto anonymných funkcií viete poslať príkazy, ktoré potrebujete vykonať pri inicializácií (napr. nastavenie špecifických parametrov pre actorov)
Tiež tu viete nastaviť sledovanie actora (napr. hráča) kamerou:
world.CenterOn(actor);