| 
 | 
 | 
# Cvičenie 5
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
__BREAKING CHANGES: PREMENOVANÉ ROZHRANIA - PRIDANÁ PREDPONA `I` (`ICommand, IWorld, IPhysics`)__ aby boli dodržané C# naming conventions
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 5.1 There are no ghosts here
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Pri implementácií `Move` ste zatiaľ neriešili kolíziu s prostredím. Napriek tomu, že už od nepamäti poznáme spôsob, ako prechádzať cez steny (nazvali ho dvere), v hre by bolo implementovať funkcionalitu, ako postavičke zabrániť v pohybe cez stenu.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Každý actor v sebe udržuje referenciu na svet, v ktorom existuje. Viete sa k nej dostať cez `GetWorld()`. Svet má v sebe uložených všetkých actorov a takiež pozná rozloženie mapy - máte dostupnú metódu `bool IntersectsWithWall(IActor)`. Použite ju a doplňte implementáciu tak, aby sa pomocou Move nedalo chodiť cez stenu.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 5.2 Newton's legacy
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Píše sa rok 1687 a sir Isaac Newton práve publikoval dielo, ktoré zmenilo svet, s názvom _Principia_. Zažite tento slávny moment a objavte gravitáciu:
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Vytvorte si triedu `Gravity` v priečinku `Commands`. Nech implementuje rozhranie `IPhysics` - jedná sa o okrášlený `ICommand` - je tu navyše metóda `SetWorld` - táto sa volá automaticky v rámci frameworku pri nastavení fyziky sveta a dostanete v nej referenciu na `IWorld` - uložte si ju, budete ju potrebovať.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
`IPhysics.Execute()` sa automaticky volá stále v hernej slučke - viete teda v `Gravity` implementovať postupné padanie predmetov:
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
- Každý actor implementuje 2 metódy - `bool IsPhysicsEnabled()` a `void SetPhysics(bool isPhysicsEnabled)` - pomocou nich dokážeme regulovať, či bude daný actor ovplyvnený fyzikou alebo nie - môžeme takto nechať nejaký predmet lietať vo vzduchu.
 | 
| 
 | 
 | 
- `IWorld` má v sebe metódu `GetActors()` - táto vráti zoznam všetkých actorov vo svete.
 | 
| 
 | 
 | 
- Zatiaľ využite `Move` na pád, ale musíte stále vytvárať nové inštancie (dočasne zakomentujte typovú kontrolu pre `IMovable` v `Move` (a upravte ho, nech akceptuje `IActor` nie `IMovable`) - za chvíľu sa k tomu vrátime a ukážeme si niečo viac o práci s typovými parametrami a Action design pattern) - nevýhoda je zvytočné vytváranie množstva objektov.
 | 
| 
 | 
 | 
- v cykle, napríklad `foreach` si implementujte pád, nezabudnite zohľadniť či je daný predmet ovplyvnený gravitáciou.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 5.3 Aaaand `Action<T>`
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
V priečinku commands si vytvorte `Interface IAction`:
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```csharp
 | 
| 
 | 
 | 
public interface IAction<T>
 | 
| 
 | 
 | 
{
 | 
| 
 | 
 | 
    public void Execute(T t);
 | 
| 
 | 
 | 
}
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
ako už deklarácia napovedá, jedná sa o niečo podobné ako `ICommand` ale je tu jeden rozdiel - v rámci execute vieme poslať nejaký parameter. Toto vieme využiť pri našej implementácií pádu - nepotrebujeme vytvárať nový objekt pre každého actora ale použijeme stále ten istý.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Pridajte si do Commands triedu `Fall`, nech implementuje `IAction` - máme tu dva spôsoby implementácie (použite druhý):
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```csharp
 | 
| 
 | 
 | 
public class Fall : IAction<IActor>
 | 
| 
 | 
 | 
{
 | 
| 
 | 
 | 
    public void Execute(IActor t)
 | 
| 
 | 
 | 
    {
 | 
| 
 | 
 | 
        //magic with actor
 | 
| 
 | 
 | 
    }
 | 
| 
 | 
 | 
}
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
public class Fall<T> : IAction<T> where T : IActor
 | 
| 
 | 
 | 
{
 | 
| 
 | 
 | 
    public void Execute(T t)
 | 
| 
 | 
 | 
    {
 | 
| 
 | 
 | 
        //magic with something, that implements IActor
 | 
| 
 | 
 | 
    }
 | 
| 
 | 
 | 
}
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Takýmto spôsobom sa vyhneme unboxingu a samozrejme aj zbytočnému vytváraniu množstva objektov - to však neznamená, že Command je zlý, ešte sa nám bude hodiť.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Implementujte pád (nezabudnite odstrániť komentáre).
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 5.4 LINQ and Lambdas
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Stále prechádzať zoznamy je často nutné a nie veľmi praktické. Našťastie máme funkcionalitu, ktorá nám toto vie zjednodušiť. V C# vieme aplikovať rôzne filtre na kolekcie pomocou fukcií, ktoré dostanú ako vstupný parameter filter (lambda výraz alebo referenciu na funkciu).
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Najprv potrebujeme pridať zodpovedajúci namespace (`using System.Linq`) - následne vieme aplikovať tzv. extension methods na rôzne kolekcie, napríklad:
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```csharp
 | 
| 
 | 
 | 
List<int> values;
 | 
| 
 | 
 | 
//add some values into the list
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
List<int> negativeValues = values.Where(x => x < 0).ToList(); //select values smaller than 0, the result is then converted into a list (it is IEnumerable by default)
 | 
| 
 | 
 | 
int smallestValue = values.OrderBy(x => x).First(); //select the smalest value (order them and select the first one)
 | 
| 
 | 
 | 
int firstPositive = values.First(x => x > 0); //select the first positive value from the list
 | 
| 
 | 
 | 
int numberOfPositiveValues = values.Where(x => x > 0).Count(); //count the number of positive values
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
List<IActor> actors//init and stuff...
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
IActor actor = actors.Find(a => a.GetName().Equals("player")); //select single entry
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Samozrejme, dostupných metód je oveľa viac, ako sme tu ukázali, môžete si ich pozrieť napr. cez dopĺňanie kódu alebo na internete.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Modifikujte `foreach` tak, aby prechádzal iba actorov, na ktorých vplýva gravitácia.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
_tip: ak trošku predbehneme, existuje aj `foreach` verzia, ktorá akceptuje lambda výraz, tu by to fungovalo nasledovne:_
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```csharp
 | 
| 
 | 
 | 
//void DoStuff(IActor actor);
 | 
| 
 | 
 | 
actors.ForEach(a => DoStuff(a));
 | 
| 
 | 
 | 
```
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 5.5 Jump
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Vytvorte triedu Jump, ktorá umožní hráčovi skákať, zvážte použité rozhranie.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
## 5.6 My very own enemy
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Vytvorte triedu `Enemy` (rozširuje `AbstractActor`).
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
Použite `enemy.png` ako animáciu.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
V `Update` implementujte funkcionalitu, že ak sa hráč k nepriateľovi priblíži na vzdialenosť N pixelov, začne ho prenasledovať. Pokiaľ je obeť v nedohľadne, nech sa nepriateľ náhodne prechádza po mape.
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
```csharp
 | 
| 
 | 
 | 
Random _random = new Random(); //initialize pseudorandom number generator, do this only once
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
//some awesome code...
 | 
| 
 | 
 | 
 | 
| 
 | 
 | 
int x = random.Next(min,max); //get random number from the given range
 | 
| 
 | 
 | 
``` | 
 | 
 | 
\ No newline at end of file |