| 
 | 
 | 
# 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 z `GameWorld`
 | 
| 
 | 
 | 
- `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):__
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```csharp
 | 
| 
 | 
 | 
//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)
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
 |