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.
Ciele
- Osvojiť si použitie kľúčového slova
this
vo vlastnom kóde. - Osvojiť si tvorbu parametrických konštruktorov.
- Porozumieť využitiu referencie na objekt ako parametra 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ť... Hádam sa nájdu nejaké užitočné nástroje.
Ú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. Obdobne, ako obrázok s animáciou reaktora, je aj obrázok kladiva dostupný vo vašom projekte. 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.
Poznámka
V prípade, že pri vytváraní animácie používate obrázok sprite-u, ktorý pozostáva len z jedného snímku animácie (tak, ako vyššie zobrazený sprite pre kladivo), môžete použiť konštruktor triedy Animation
len s jedným parametrom - názvom obrázka:
new Animation("sprites/hammer.png");
Rozmery animácie budú v takom prípade automaticky nastavené podľa rozmerov použitého obrázka.
Ú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ý aktér zobrazený v hre sa nachádza v aktívnej hernej scéne, na ktorú má aj dostupnú referenciu. Scéna zas má možnosť aktérov pridávať aj odoberať. Využite možnosti vývojového prostredia alebo si prezrite dokumentáciu rozhrania Actor
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.
Úloha 2.1
Vytvorte v triede Reactor
metódu repairWith()
, pomocou ktorej bude možné reaktor opraviť.
Metóda nebude vracať žiadnu hodnotu, ale bude mať jeden parameter typu Hammer
. Jej správanie bude nasledovné:
- Metóda bude pracovať iba vtedy, ak hodnota parametra metódy obsahuje platnú referenciu na inštanciu triedy
Hammer
(a teda nie jenull
) 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 50 percentuálnych bodov. 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 zastaviť 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úť.
To, či je reaktor zapnutý alebo vypnutý, reprezentuje jeho stav. Z minulého cvičenia už viete, ako sa reprezentuje stav objektov.
Samozrejme, reaktor môže pracovať len vtedy, keď je zapnutý. Ak nebude zapnutý, nebude možné mu zvyšovať ani znižovať teplotu pomocou jeho metód (nemali by mať efekt). Rovnako zabezpečte, aby reaktor nebol zapnutý automaticky po vytvorení jeho inštancie. Pri pokazení reaktora zabezpečte, aby bol vo vypnutom stave. Urobte 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. V prípade, že sa reaktor vypne dôsledkom zničenia, zabezpečte, aby ako jeho animácia ostal nastavený obrázok reactor_broken.
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()
.
Ú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.
Ú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. Trieda bude mať len jednu členskú premennú nazvanú 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á v parametri.
Úloha 4.2
Vytvorte v triede ovládača metódu toggle()
, ktorá zapne alebo vypne ovládaný reaktor vzhľadom na jeho aktuálny stav.
Zapnutý reaktor bude volaním metódy vypnutý, a naopak.
Ú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ý ovládač. Overte funkčnosť ovládačov.
Krok 5: Powering Light
Reaktor, ktorý ste implementovali minulý týždeň a vylepšili 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.
Ú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, ako vypínač. Svetlo však bude reálne svietiť (jeho animácia bude light_on) len v tom prípade, ak bude aj napájané elektrinou.setElectricityFlow()
- Metóda bude mať jeden parameter typuboolean
, ktorý bude udávať, či je svetlu elektrina poskytovaná alebo nie.
Ako animáciu zasvieteného svetla použite súbor light_on a pre animáciu zhasnutého svetla použite súbor light_off.
Poznámka
Nezabudnite, že svetlo sa má zasvietiť aj vtedy, ak je jeho vypínač prepnutý do polohy zapnutý a práve ho pripojíme 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 prostredníctvom parametra metódy addLight()
.
Pri volaní metód nezabudnite aktualizovať aj stav napájania spotrebiča vzhľadom na stav reaktora - ak je reaktor zapnutý a nie je pokazený, tak 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 |
Krok 6: Repository
Úloha 6.1
Nahrajte (cez commit a push) váš zdrojový kód do repozitára na GitLab-e. Spravte tak do nasledujúceho cvičenia. Zároveň si pripravte otázky, ktoré by ste na cvičení chceli vyriešiť.
Zdrojový kód nahrajte aj v prípade, ak ste nestihli dokončiť všetky úlohy. Rozpracované časti, ktoré by mohli spôsobiť kompilačné chyby, odporúčame zakomentovať.
Doplňujúce úlohy
Úloha A.1
V rámci opravy reaktora kladivom v metóde repairWith()
patrične 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.
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. Poškodenie reaktora sa uhasením nezmení.
Doplňujúce zdroje
- Java Tutoriál: What Is an Object?
- Java Tutoriál: What Is a Class?
- Java Tutoriál: What Is Inheritance?