Ciele
- Implementovať vlastný herný level.
- Implementovať vlastných aktérov.
- Navrhnúť a implementovať vlastnú funkcionalitu objektovo orientovaným spôsobom.
- Identifikovať a použiť návrhové vzory vo vlastnom riešení.
Znenie zadania
Vytvorte jeden hrateľný level hry s využitím knižnice GameLib (verzia 2.6.1
) v jazyku Java. Pre jej grafickú reprezentáciu môžete použiť sprity z počítačovej hry Alien Breed. Mapu levelu vytvorte pomocou editora Tiled. Základnú funkcionalitu hry implementujte podľa úloh z cvičení 7 až 10. Vlastný level hry musí byť dohrateľný a pre jeho riešenie musí byť potrebné využiť sadu adventúrnych krokov. To znamená, že level nemôže byť lineárne dohrateľný napr. len streľbou do nepriateľov alebo pozbieraním nejakých premetov, ale musí obsahovať aktérov, s ktorými je potrebné interagovať.
Požiadavky na riešenie sú detailne opísané nižšie.
Pri práci na zadaní dodržiavajte etický kódex!
Dôležité termíny
- Zadanie je potrebné odovzdať (obe časti) do systému GitLab najneskôr do soboty 14. decembra 2024, 23:59.
- Hodnotenia projektov systémom Arena budú prebiehať denne každé 3 hodiny. Posledné hodnotenie prebehne v sobotu 14. decembra 2024 o polnoci.
- Po úspešnom automatizovanom testovaní sa dostavíte na ústnu obhajobu vlastnej hernej časti vášho riešenia (ktorá nemôže byť pokrytá testami v Arene). Termín obhajob je na cvičeniach v 12. a 13. týždni semestra.
Upozornenie
Ústna obhajoba je nutná na možnosť získania plného počtu bodov za zadanie. V prípade, že nespravíte vlastnú hernú časť a vyriešite len základné úlohy pokryté testami v systéme Arena, nemá zmysel, aby ste na túto obhajobu prišli. Na obhajobe je možné získať len body vyhradené pre vlastnú hernú časť zadania.
Poznámka
- Testovanie v systéme Arena je spustené.
- Testovanie v systéme Arena prebieha každé 2 hodiny (00:00, 02:00, 04:00 atď.).
- Testovanie v systéme Arena bude prerušené v stredu 11.12. a štvrtok 12.12. od 08:00 do 14:00.
1. Základná časť implementácie (hodnotená testami)
Nasledovné triedy (signatúry ich konštruktorov) a rozhrania s definovanými metódami reprezentujú stav základnej implemetácie po vypracovaní všetkých úloh cvičení 7 - 10 a budú sa hodnotiť testami v Arene:
- actions:
- trieda
Drop<K extends Keeper>
(rozširujeAbstractAction
)- konštruktor
public Drop()
- konštruktor
- trieda
Fire<A extends Armed>
(rozširujeAbstractAction
)- konštruktor
public Fire()
- konštruktor
- trieda
Move<A extends Movable>
(implementujeAction
)- konštruktor
public Move(Direction direction, float duration)
- metóda
public void stop()
- konštruktor
- trieda
Shift<K extends Keeper>
(rozširujeAbstractAction
)- konštruktor
public Shift()
- konštruktor
- trieda
Take<K extends Keeper>
(rozširujeAbstractAction
)- konštruktor
public Take()
- konštruktor
- trieda
Use<A extends Actor>
(rozširujeAbstractAction
)- konštruktor
public Use(Usable<A> usable)
- metóda
public Disposable scheduleForIntersectingWith(Actor mediatingActor)
- konštruktor
- trieda
- behaviours:
- rozhranie
Behaviour<A extends Actor>
- metóda
void setUp(A actor)
- metóda
- trieda
Observing<T, A extends Actor>
(implementujeBehaviour
)- konštruktor
public Observing(Topic<T> topic, Predicate<T> predicate, Behaviour<A> delegate)
- konštruktor
- trieda
RandomlyMoving
(implementujeBehaviour
)- konštruktor
public RandomlyMoving()
- konštruktor
- rozhranie
- characters
- trieda
Alien
(rozširujeAbstractActor
; implementujeMovable
,Alive
aEnemy
)- konštruktor
public Alien()
- konštruktor
public Alien(int healthValue, Behaviour<? super Alien> behaviour)
- konštruktor
- rozhranie
Alive
(rozširujeActor
)- metóda
Health getHealth()
- metóda
- rozhranie
Armed
(rozširujeActor
)- metóda
Firearm getFirearm()
- metóda
void setFirearm(Firearm firearm)
- metóda
- rozhranie
Enemy
(rozširujeActor
) - trieda
Health
- konštruktor
public Health(int initHealth, int maxHealth)
- konštruktor
public Health(int initHealth)
- metóda
public int getValue()
- metóda
public void refill(int amount)
- metóda
public void restore()
- metóda
public void drain(int amount)
- metóda
public void exhaust()
- metóda
public void onFatigued(FatigueEffect effect)
- rozhranie
FatigueEffect
- metóda
void apply()
- metóda
- konštruktor
- trieda
Ripley
(rozširujeAbstractActor
; implementujeAlive
,Armed
,Keeper
aMovable
)- konštruktor
public Ripley()
- statická premenná
public static Topic<Ripley> RIPLEY_DIED
- konštruktor
- trieda
- controllers:
- trieda
KeeperController
(implementujeKeyboardListener
)- konštruktor
public KeeperController(Keeper keeper)
- konštruktor
- trieda
MovableController
(implementujeKeyboardListener
)- konštruktor
public MovableController(Movable actor)
- konštruktor
- trieda
ShooterController
(implementujeKeyboardListener
)- konštruktor
public ShooterController(Armed shooter)
- konštruktor
- trieda
- items:
- trieda
Ammo
(rozširujeAbstractActor
, implementujeUsable
)- konštruktor
public Ammo()
- konštruktor
- trieda
Backpack
(implementujeActorContainer
)- konštruktor
public Backpack(String name, int capacity)
- konštruktor
- rozhranie
Collectible
(rozširujeActor
) - trieda
Energy
(rozširujeAbstractActor
, implementujeUsable
)- konštruktor
public Energy()
- konštruktor
- rozhranie
Usable<A extends Actor>
- metóda
void useWith(A actor)
- metóda
Class<A> getUsingActorClass()
- metóda
- trieda
- openables:
- trieda
Door
(rozširujeAbstractActor
, implementujeOpenable
aUsable
)- enumerácia
Orientation { VERTICAL, HORIZONTAL }
- konštruktor
public Door(String name, Orientation orientation)
- statická premenná
public static Topic<Door> DOOR_OPENED
- statická premenná
public static Topic<Door> DOOR_CLOSED
- enumerácia
- rozhranie
Openable
(rozširujeActor
)- metóda
void open()
- metóda
void close()
- metóda
boolean isOpen()
- metóda
- trieda
- weapons:
- trieda
Bullet
(rozširujeAbstractActor
, implementujeFireable
)- konštruktor
public Bullet()
- konštruktor
- rozhranie
Fireable
(rozširujeMovable
) - abstraktná trieda
Firearm
- konštruktor
public Firearm(int initAmmo, int maxAmmo)
- konštruktor
public Firearm(int initAmmo)
- metóda
public int getAmmo()
- metóda
public void reload(int amount)
- metóda
public Fireable fire()
- abstraktná metóda
protected Fireable createBullet()
- konštruktor
- trieda
Gun
(rozširujeFirearm
)- konštruktor
public Gun(int initAmmo, int maxAmmo)
- konštruktor
- trieda
- enumerácia
Direction
- hodnoty
NORTH
,EAST
,SOUTH
,WEST
- konštruktor
Direction(int dx, int dy)
- metóda
public int getDx()
- metóda
public int getDy()
- metóda
public float getAngle()
- statická metóda
public static Direction fromAngle(float angle)
- hodnoty
- rozhranie
Keeper
(rozširujeActor
)- metóda
Backpack getBackpack()
- metóda
- trieda
Main
- statická metóda
public static void main(String[] args)
- statická metóda
- rozhranie
Movable
(rozširujeActor
)- metóda
int getSpeed()
- metóda
default void startedMoving(Direction direction) {}
- metóda
default void stoppedMoving() {}
- metóda
default void collidedWithWall() {}
- metóda
- trieda
SpawnPoint
(rozširujeAbstractActor
)- konštruktor
public SpawnPoint(int spawnAliens)
- konštruktor
Poznámka
Vaša implementácia má byť postavená na tomto základe, aj keď nie je nevyhnutné, aby ste z neho vo vlastnej hre využívali úplne všetko. V prípade potreby môžete uvedené triedy rozšíriť o vlastné metódy, ak zachováte funkcionalitu tých existujúcich.
Upozornenie
Uvedené povinné rozhrania nesmiete vo svojom riešení nijako modifikovať! Testy v Arene sú kompilované voči tu popísaným podobám rozhraní a v prípade, že vaše rozhrania im nebudú zodpovedať, môže sa stať, že testy, ktoré testujú alebo nejako využívajú dané rozhranie, sa nepodarí inicializovať.
Upozornenie
Kvôli testovaniu požadovaných troch ovládačov v balíku sk.tuke.kpi.oop.game.controllers
je potrebné, aby ste zachovali priradenie kláves pre jednotlivé akcie tak, ako je to opísané v cvičeniach. V prípade, že si chcete priradenie kláves prispôsobiť, spravte to len pridaním ďalšej akceptovanej klávesy pre určitú akciu, aby ostali akceptované aj tie klávesy z cvičení.
2. Požiadavky na vlastnú hernú časť zadania
Pre možnosť získať plný počet bodov za zadanie je potrebné vytvoriť už spomínaný hrateľný level. Pri obhajobe zadania sa bude kontrolovať splnenie nasledovných požiadaviek.
2.1 Funkčnosť a hrateľnosť
Projekt odovzdaný na GitLab-e musí byť kompletný a spustiteľný príkazom ./gradlew run
(Linux, Mac OS) respektíve gradlew.bat run
(Windows).
Poznámka
Projekt musí byť uvedeným spôsobom spustiteľný aj na inom ako vašom počítači. Myslite preto aj na zahrnutie všetkých obrázkov spritov a máp do projektu na GitLab-e.
Hra musí byť úspešne dohrateľná. Samotný koniec (záverečný, no nie jediný krok hry) však môže byť dosiahnuteľný rôznym spôsobom, ako napríklad: zničenie všetkých nepriateľov (alebo finálneho boss-a), opustenie úrovne konkrétnymi dverami alebo výťahom, stlačenie spínača alebo množiny spínačov, a podobne.
2.2 Vlastná mapa levelu
Je potrebné vytvoriť vlastnú mapu herného levelu s názvom map.tmx
, ktorej plocha bude minimálne 500 dlaždíc - tiles (napríklad 20 x 25) ale nie väčšia ako 6400 dlaždíc (napr. 80 x 80). Viac o mape úrovne nižšie.
Mapu levelu vytvorte podľa tutoriálu pre integráciu s knižnicou GameLib.
2.3 Vlastní aktéri
V hre vytvorte minimálne 7 vlastných tried, ktoré budú implementovať rozhranie Actor
, resp. rozširovať abstraktnú triedu AbstractActor
. Dodržujte pri tom nasledovné požiadavky:
- Tieto triedy a z nich vytvorené inštancie budú potrebné pre úspešné dosiahnutie cieľa hry, t.j. budú aktívne zapojené do scenára hry. Príkladom aktívneho zapojenia do scenára je použitie skrinky, otvorenie dverí, presunutie tehly na spínač v podlahe a podobne.
- Nesmie sa jednať o prázdnych aktérov - nesmú obsahovať len animáciu (konštruktor) bez žiadneho ďalšieho kódu (bez metód).
- Do stanoveného počtu sa nezarátajú aktéri, ktorých implementácia bola úlohou prvého zadania (napríklad reaktor, chladič, kladivo, atď) a ktorí sú povinnou súčasťou hry (ich zoznam je uvedený vyššie). Taktiež sa nezarátajú aktéri s rovnakým správaním a vlastnosťami, ako boli uvedení v rámci úloh cvičení.
2.4 Použitie návrhových vzorov
V hre použite minimálne 4 návrhové vzory. Vyberajte si vzory prednostne zo skupín štrukturálnych a behaviorálnych návrhových vzorov. Takisto je možné využiť vzory Builder a Prototype zo skupiny vytváracích (creational) návrhových vzorov.
Upozornenie
K potrebným štyrom sa budú počítať len vaše vlastné implementácie návrhových vzorov, nie tie implementované na základe úloh v cvičeniach.
2.5 Programátorský štýl
Pri programovaní dodržujte nasledovné zásady:
- Na predmete Objektovo orientované programovanie je vyžadované riešenie, ktoré je písané objektovo - využívajte zapuzdrenie údajov, hierarchiu tried, rozhrania, kompozíciu, polymorfizmus. Bonusom sú vhodne použité vlastné typové parametre zovšeobecňujúce vaše riešenie.
- Vytvárajte triedy s čo najmenším počtom členských premenných (členské premenné by mali byť len tie, ktoré sú nevyhnutné pre zaznamenanie stavu objektov!) s užitočným a zrozumiteľným API vo forme verejných metód. Metódy, ktoré riešia implementačné detaily, definujte ako privátne.
- Predchádzajte duplikovaniu funkcionality.
- Formátujte svoj kód podľa zaužívaných pravidiel pre jazyk Java.
- Dbajte na pomenovanie identifikátorov (názvy tried, metód, premenných ...). Pomenovania majú byť zmysluplné a majú dodržiavať konvencie pre jazyk Java.
3. Testovanie
Pri testovaní vašeho riešenia v Arene bude vyžadované:
- Nepoužívanie unchecked operácií alebo raw typov.
- Používanie len privátnych členských premenných (s výnimkou statických premenných).
- Dodržiavanie pravidiel kontrolovaných PMD nástrojom, ktoré sú definované v tomto súbore pmd-ruleset.xml (návod na nastavenie lokálneho spúšťania).
Upozornenie
Váš kód bude na Arene kompilovaný s prepínačmi -Xlint:unchecked,rawtypes -Werror
, ktoré varovania ohľadom použitia unchecked operácii alebo raw typov skonvertujú na chyby a ich výskyt tak spôsobí zlyhanie kompilácie.
Tieto prepínače si viete nastaviť aj pre lokálnu kompiláciu kódu upravením existujúcej konfigurácie JavaCompile
úloh v súbore build.gradle.kts
do nasledovnej podoby:
tasks {
withType<JavaCompile> {
options.compilerArgs.addAll(listOf("-parameters", "-Xlint:unchecked,rawtypes", "-Werror"))
}
}
4. Odovzdávanie
Zadanie sa odovzdáva prostredníctvom systému na správu verzií Git na školskom GitLab serveri https://git.kpi.fei.tuke.sk.
Používajte ten istý projekt, ktorý ste si vytvorili prostredníctvom aplikácie OOP Gitlab Classroom na začiatku semestra, a ktorý ste používali aj pri prvom zadaní. Triedy požadované v rámci prvého testovania už testované nebudú. Podmienkou je len to, aby projekt ako celok bol skompilovateľný pomocou vyššie spomínaných prepínačov kompilátora, a aby všetky nestatické členské premenné boli privátne.
4.1 Štruktúra projektu
Štruktúra vášho projektu s uvedeným umiestnením povinných častí implementácie musí vyzerať nasledovne:
. // root adresar repozitara
├── gradle // obsahuje subory nastroja gradle
├── src
│ ├── main
│ │ ├── java
│ │ │ └── sk
│ │ │ └── tuke
│ │ │ └── kpi
│ │ │ └── oop
│ │ │ └── game
│ │ │ ├── actions
│ │ │ │ ├── Drop.java
│ │ │ │ ├── Fire.java
│ │ │ │ ├── Move.java
│ │ │ │ ├── Shift.java
│ │ │ │ ├── Take.java
│ │ │ │ └── Use.java
│ │ │ ├── behaviours
│ │ │ │ ├── Behaviour.java
│ │ │ │ ├── Observing.java
│ │ │ │ └── RandomlyMoving.java
│ │ │ ├── characters
│ │ │ │ ├── Alien.java
│ │ │ │ ├── Alive.java
│ │ │ │ ├── Armed.java
│ │ │ │ ├── Enemy.java
│ │ │ │ ├── Health.java
│ │ │ │ └── Ripley.java
│ │ │ ├── controllers
│ │ │ │ ├── KeeperController.java
│ │ │ │ ├── MovableController.java
│ │ │ │ └── ShooterController.java
│ │ │ ├── items
│ │ │ │ ├── Ammo.java
│ │ │ │ ├── Backpack.java
│ │ │ │ ├── Collectible.java
│ │ │ │ ├── Energy.java
│ │ │ │ └── Usable.java
│ │ │ ├── openables
│ │ │ │ ├── Door.java
│ │ │ │ └── Openable.java
│ │ │ ├── scenarios // obsahuje triedy scenarov
│ │ │ ├── weapons
│ │ │ │ ├── Bullet.java
│ │ │ │ ├── Fireable.java
│ │ │ │ ├── Firearm.java
│ │ │ │ └── Gun.java
│ │ │ ├── Direction.java
│ │ │ ├── Keeper.java
│ │ │ ├── Main.java
│ │ │ ├── Movable.java
│ │ │ └── SpawnPoint.java
│ │ └── resources
│ │ ├── maps
│ │ │ ├── tilesets // obsahuje pouzite tilesety z mapy
│ │ │ └── map.tmx // mapa vasho levelu hry
│ │ └── sprites // obsahuje pouzite sprity akterov
├── .editorconfig
├── .gitignore
├── build.gradle.kts
├── gradlew
├── gradlew.bat
├── README.md
└── settings.gradle.kts
Poznámka
Súbory vytvorené v rámci vašeho vlastného levelu hry umiestňujte podľa potreby buď do niektorého z uvedených balíkov, alebo vytvorte vhodne pomenované a organizované nové balíky. Zachovajte však balík sk.tuke.kpi.oop.game
ako rodičovský balík všetkých tried a rozhraní v projekte.
Upozornenie
Kódovanie všetkých odovzdávaných súborov musí byť UTF-8
. Pri názvoch vytváraných súborov a priečinkov záleží na veľkosti písmen! Je dôležité, aby sa povinné súbory nachádzali na uvedených miestach v projekte, inak dôjde k zlyhaniu testov pre konkrétne súbory, ktoré sa nenájdu.
4.2 Závislosti projektu
Pri preklade a testovaní projektu budú predpokladané nasledovné nastavenia závislostí v súbore build.gradle.kts
:
val gamelibVersion = "2.6.1"
dependencies {
implementation("sk.tuke.kpi.gamelib:gamelib-framework:$gamelibVersion")
}
5. Hodnotenie
Za zadanie môžete získať max. 30 bodov. Z toho je 15 bodov vyhradených na hodnotenie základnej časti automatickými testami a 15 bodov na obhajobu vlastnej hernej časti zadania.
Automatickými testami (15 bodov) bude v systéme Arena hodnotená základná časť funkcionality hry.
Pri obhajobe zadania (15 bodov) sa bude vaša implementácia hodnotiť:
- z pohľadu používateľa-hráča (max. 5 bodov)
- funkčnosť a hrateľnosť
- prítomnosť adventúrnych krokov
- počet aktérov zapojených do hry
- vizuálna stránka (bonus)
- z programátorského pohľadu (max. 10 bodov)
- programátorský štýl (~4 bodov)
- použitie návrhových vzorov (~6 bodov)
Samozrejmosťou je, že študent vie odpovedať na otázky týkajúce sa odovzdávaného projektu. V prípade hraničného hodnotenia je možné očakávať doplnkové programátorské úlohy na rozšírenie alebo modifikáciu hry ako súčasť obhajoby.
Vaše riešenia prejdú kontrolou originality. Preto sa pri práci na vašom zadaní správajte podľa pravidiel etického kódexu! V prípade, že odovzdáte zadanie, ktoré nie je vaše, budete vylúčení z predmetu!