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
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)
-
-
void 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 -GameWorldvolá 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)