Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
P PVJCs2021
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Ing. Lukáš Hruška
  • PVJCs2021
  • Wiki
  • cv5

cv5 · Changes

Page history
Create cv5 authored Oct 18, 2021 by Ing. Lukáš Hruška's avatar Ing. Lukáš Hruška
Show whitespace changes
Inline Side-by-side
Showing with 114 additions and 0 deletions
+114 -0
  • cv5.md cv5.md +114 -0
  • No files found.
cv5.md 0 → 100644
View page @ 35e3532c
# 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.
__Nezabudnite si pridať do sveta gravitáciu - `container.GetWorld().SetGravity(new Gravity())`!__
## 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));
```
Viac o lambda výrazoch nájdete tu: [Microsoft dokumentácia](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions)
## 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
Clone repository
  • assignment 1
  • assignment 2
  • cv10
  • cv2
  • cv3
  • cv4
  • cv5
  • cv7
  • cv8
  • cv9
  • exam 0
  • exam 1
  • exam 2
  • exam 3
  • exam 4
View All Pages