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 -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)