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