Powering Devices

jeden reaktor dokáže napájať jedno svetlo... zatiaľ...

Motivácia

Vitaj pri brífingu ďalšej misie, kadet! Úvodné zahrievacie kolo máš úspešne za sebou a spolu s našim taktickým a strategickým tímom predpokladáme, že si sa určite dostatočne zahrial pri ovládaní reaktora.

Pri plnení rôznych misií v teréne sa ti však určite hodí niekoľko zručností, ktoré získaš počas dnešného tréningu. Jedná sa hlavne o zručnosť používania referenčných typov ako parametrov metód. Táto nenápadná zručnosť už zachránila život nejednému objektovému programátorovi, preto ju nepodceňuj!

Veľa šťastia pri dosahovaní cieľov dnešnej misie! Z veliteľského mostíka zdraví Manager.

Upozornenie

Skôr než začnete prácu na tomto cvičení, aktualizujte si hernú knižnicu, ktorú v projekte používate, na verziu 2.0.2 podľa tohto postupu.

Ciele

  • Použitie kľúčového slova this vo vlastnom kóde.
  • Tvorba parametrických konštruktorov.
  • Referencia ako parameter metódy.

Postup

Krok 1: First tools

Ako ste si všimli, pracovať s atómovým reaktorom nie je žiadna sranda. Hlavne keď sa začne prehrievať a neexistuje spôsob, ako ho opraviť...

Diagram tried, ktorý vyjadruje vzťah tried Hammer a AbstractActor.
Obr. 1: Diagram tried, ktorý vyjadruje vzťah tried Hammer a AbstractActor.

Úloha 1.1

V balíčku sk.tuke.kpi.oop.game vytvorte triedu Hammer, ktorá bude reprezentovať kladivo.

Animácia reprezentujúca kladivo na mape je uložená v súbore hammer.png. Kladivo bude mať členskú premennú pre počet zostávajúcich použití, ktorú inicializujte prostredníctvom konštruktora na hodnotu 1. Premennej nastavte vhodnú viditeľnosť a prístup k nej zabezpečte patričnou get metódou.

Animácia hammer.png (rozmery sprite-u: _16x16_)
Obr. 2: Animácia hammer.png (rozmery sprite-u: 16x16)

Úloha 1.2

Pridajte do triedy Hammer metódu use(), ktorá bude reprezentovať použitie kladiva.

Pri každom použití je potrebné aktualizovať počet zostávajúcich použití kladiva. Keď tento počet dosiahne 0, kladivo odstráňte z hernej scény (kladivo sa zlomilo).

Poznámka

Každý actor zobrazený v hre sa nachádza v aktívnej hernej scéne, na ktorú má aj dostupnú referenciu. Scéna zas má možnosť actor-ov pridávať aj odoberať. Využite možnosti vývojového prostredia a nájdite spôsob, ako získať referenciu na hernú scénu a ako pomocou nej odstrániť použité kladivo z hry.

Krok 2: If all you have is a hammer, everything looks like a nail

V tomto kroku sa pokúsime poškodený reaktor včas opraviť vhodným nástrojom: kladivom.

Diagram tried, ktorý vyjadruje vzťah tried Reactor a Hammer.
Obr. 3: Diagram tried, ktorý vyjadruje vzťah tried Reactor a Hammer.

Úloha 2.1

Vytvorte v triede Reactor metódu repairWith(), pomocou ktorej bude možné reaktor opraviť.

Metóda nebude nič vracať, ale bude mať jeden parameter typu Hammer. Jej správanie bude nasledovné:

  • Metóda bude pracovať iba vtedy, ak hodnota parametra metódy obsahuje referenciu na inštanciu triedy Hammer (a teda nie je null) a reaktor má hodnotu poškodenia vyššiu ako 0% ale ešte nie je úplne zničený.
  • Použitie kladiva zníži poškodenie reaktora o hodnotu 50. Pozor ale na to, aby výsledná hodnota poškodenia neklesla pod 0. Teda, ak bude reaktor poškodený, povedzme, na 92%, po použití kladiva jeho poškodenie klesne na 42%. A ak bude poškodený na 35%, použitím kladiva sa úplne opraví (poškodenie 0%).

Poznámka

Keďže zvyšovaním teploty rastie poškodenie lineárne, po znížení poškodenia je potrebné odpovedajúcim spôsobom znížiť aj teplotu. K tejto časti úlohy sa vrátite neskôr v rámci doplňujúcich úloh.

Poznámka

Pri implementácii nezabudnite na to, že okrem úrovne poškodenia a teploty je potrebné zmeniť aj obrázok, ktorý vizualizuje teplotu reaktora. Predíďte však duplikovaniu kódu!

Úloha 2.2

Overte správnosť svojej implementácie.

Vytvorte na mape inštanciu reaktora a niekoľkých kladív. Následne reaktor prehrejte a pokúste sa ho opraviť použitím kladiva.

Krok 3: Shutting Down Reactor

Výborne! Reaktor už zvládame opraviť, aj keď sa nadmieru prehreje (škoda, že v skutočnosti nestačí len to kladivo). Teraz by sa zišlo nájsť spôsob, ako reaktor v prípade potreby uviesť do nečinnosti alebo ho naopak naštartovať.

Úloha 3.1

V triede reaktora vytvorte metódy turnOn() a turnOff(), pomocou ktorých bude možné reaktor zapnúť a vypnúť.

Pri implementácii nezabudnite na fakt, že reaktor vie pracovať len vtedy, ak je zapnutý (ak nebude zapnutý, nebude možné mu zvyšovať ani znižovať teplotu pomocou jeho metód). Rovnako zabezpečte, aby reaktor nebol zapnutý automaticky po vytvorení jeho inštancie. Po pokazení reaktora, zabezpečte, aby bol vo vypnutom stave. Urobte teda všetky potrebné úpravy, aby ste tieto skutočnosti zohľadnili.

Úloha 3.2

Pre reprezentáciu reaktora vo vypnutom stave použite obrázok animácie reactor.png.

Potrebný objekt animácie si pripravte v konštruktore reaktora, patrične upravte metódu nastavujúcu aktuálnu animáciu a práve vytvorené metódy turnOn() a turnOff().

Poznámka

V prípade, že sa reaktor vypne dôsledkom zničenia, zabezpečte, aby ako jeho animácia ostal nastavený obrázok reactor_broken.png.

Úloha 3.3

V triede Reactor vytvorte metódu isRunning(), ktorá zistí, či je reaktor zapnutý (vráti hodnotu true) alebo vypnutý (vráti hodnotu false).

Krok 4: Gaining Control

Ovládanie rozhorúčeného reaktora môže byť poriadne nebezpečná záležitosť. Preto sa teraz pokúsime vytvoriť diaľkový ovládač, ktorý nám umožní reaktor zapnúť alebo vypnúť bez priameho fyzického kontaktu s ním.

Diagram tried, ktorý vyjadruje vzťah tried Reactor a Controller.
Obr. 4: Diagram tried, ktorý vyjadruje vzťah tried Reactor a Controller.

Úloha 4.1

Vytvorte triedu Controller, ktorá bude reprezentovať ovládač pre príslušný reaktor.

Obrázok ovládača sa nachádza v súbore switch.png. Trieda bude mať len jednu členskú premennú reactor, ktorá bude predstavovať referenciu na ovládaný reaktor. Jej hodnotu nastavte pri volaní konštruktora, ktorému bude referencia na príslušný reaktor odovzdaná.

Animácia switch.png (rozmery sprite-u: _16x16_)
Obr. 5: Animácia switch.png (rozmery sprite-u: 16x16)

Úloha 4.2

Vytvorte vo vypínači metódu toggle(), ktorá zapne/vypne ovládaný reaktor.

Úloha 4.3

Overte správnosť svojej implementácie.

Pomocou nástroja Inšpektor vytvorte niekoľko inštancií reaktorov a ku každému potrebný vypínač. Overte funkčnosť vypínačov.

Štyri bloky reaktorov ovládané štyrmi vypínačmi. Ktorý však ovláda ktorý?
Obr. 6: Štyri bloky reaktorov ovládané štyrmi vypínačmi. Ktorý však ovláda ktorý?

Krok 5: Powering Light

Reaktor, ktorý ste implementovali minulý týždeň a opravili dnes, vyrába elektrinu. V tomto kroku vytvoríme spotrebič, ktorý ku reaktoru pripojíme. Samozrejme - bude fungovať len vtedy, ak bude reaktor vyrábať elektrinu.

Diagram tried, ktorý vyjadruje vzťah tried Light, Reactor a AbstractActor.
Obr. 7: Diagram tried, ktorý vyjadruje vzťah tried Light, Reactor a AbstractActor.

Úloha 5.1

Podľa diagramu tried vyššie, vytvorte v balíčku sk.tuke.kpi.oop.game triedu Light, ktorá bude reprezentovať svetlo a otestujte svoju implementáciu.

Trieda bude mať dve metódy:

  • toggle() - Metóda bude vedieť zmeniť stav svetla zo zapnutého na vypnuté a naopak. Svetlo však bude reálne svietiť (jeho animácia bude light_on.png) len v tom prípade, ak bude napájané elektrinou.
  • setElectricityFlow() - Metóda bude mať jeden parameter typu boolean, ktorý bude udávať, či je svetlu elektrika poskytovaná alebo nie.

Ako animáciu zasvieteného svetla použite súbor light_on.png a animáciu zhasnutého svetla použite súbor light_off.png.

Animácia light_on.png (rozmery obrázka: _16x16_).
Obr. 8: Animácia light_on.png (rozmery obrázka: 16x16).
Animácia light_off.png (rozmery obrázka: _16x16_).
Obr. 9: Animácia light_off.png (rozmery obrázka: 16x16).

Poznámka

Nezabudnite, že svetlo sa má zasvietiť aj vtedy, ak je vypínač prepnutý do polohy zapnutý a práve ho pripojím k dodávke elektriny!

Úloha 5.2

V triede reaktora vytvorte metódy addLight() a removeLight(), pomocou ktorých budete vedieť k reaktoru pripojiť a odpojiť svetlo.

Aktuálny model reaktora bude vedieť súčasne napájať práve jeden spotrebič - v našom prípade to bude práve jedno svetlo. Referenciu naň dostanete ako parameter v metóde addLight().

Pri volaní metód nezabudnite aktualizovať aj stav napájania spotrebiča vzhľadom na stav reaktora - ak je zapnutý a nie je pokazený, tak reaktor elektrinu vyrába. Nezabudnite rovnako aktualizovať aj všetky ostatné potrebné metódy, ktoré sa podieľajú na uvedenej zmene stavu.

Úloha 5.3

Overte správnosť svojej implementácie vytvorením dvoch inštancií reaktorov a k nim pripojte dve inštancie svetiel.

Pri overovaní činnosti sa môžete riadiť nasledovnou pravdivostnou tabuľkou, ktorá ilustruje správanie svetla:

isOn isPowered stav svetla
true true svieti
true false nesvieti
false true nesvieti
false false nesvieti
Každý reaktor napája jedno svetlo (jeden už zrejme donapájal).
Obr. 10: Každý reaktor napája jedno svetlo (jeden už zrejme donapájal).

Doplňujúce úlohy

Úloha A.1

V rámci opravy reaktora kladivom v metóde repairWith() zodpovedajúco upravte aj teplotu reaktora.

Vráťte sa k úlohe 4.1 minulého cvičenia a všimnite si uvedený graf závislosti poškodenia od teploty. Ak ho invertujeme pre získanie závislosti teploty od poškodenia, tak jeho správanie v oblasti 0% poškodenia nie je pre výpočet teploty jednoznačné (nie je to funkcia). Preto výpočet teploty pri oprave reaktora upravte nasledovne:

  • najskôr určte vzťah teploty od poškodenia na základe časti grafu, kde je ich závislosť lineárna.
  • určte pomocnú hodnotu poškodenia (zníženú o 50 oproti hodnote pred opravou) bez ohľadu na to, či výsledok bude kladné alebo záporné číslo.
  • získanú hodnotu dosaďte do pripraveného vzťahu a výsledok nastavte ako teplotu reaktora po oprave, avšak len ak by nová teplota reaktora bola nižšia ako tá pred opravou.

Úloha A.2

Vytvorte triedu pre Thorovo kladivo s názvom Mjolnir, odvodenú od triedy Hammer.

Mjolnir Vydrží 4 použitia (úplná oprava dvoch reaktorov), po ktorých sa, tak ako pôvodné kladivo, tiež zlomí.

Úloha A.3

Vytvorte triedu FireExtinguisher pre hasiaci prístroj, ktorým bude možné uhasiť horiaci zničený reaktor.

Trieda bude potomkom triedy AbstractActor a bude mať členskú premennú pre počet použití, ktorej nastavte vhodnú viditeľnosť, a implementujte aj patričnú get metódu. Trieda nech má aj metódu use() na odrátavanie zostávajúceho počtu použití. Keď sa hasiaci prístroj spotrebuje, zmizne z hernej mapy. Animácia reprezentujúca hasiaci prístroj na mape je uložená v súbore extinguisher.png.

Na uhasenie implementujte v triede Reactor metódu extinguishWith(), ktorá bude ako parameter vyžadovať objekt typu FireExtinguisher, ktorý sa na hasenie použije. Hasiaci prístroj vydrží jedno použitie, pri ktorom sa teplota reaktora zníži na 4000 stupňov a animácia reaktora sa zmení na obrázok reactor_extinguished.png. Poškodenie reaktora sa uhasením nezmení.

Doplňujúce zdroje