# Arkanoid Autor: Filip Chochol Predmet: Programovanie, TUKE FEI, 2026 --- ## Popis projektu Projekt je terminálová hra Arkanoid napísaná v jazyku C s využitím knižnice ncurses. Hra beží priamo v termináli bez akéhokoľvek grafického rozhrania. Všetka grafika je tvorená ASCII znakmi s farebnými atribútmi ktoré poskytuje ncurses. Hráč ovláda palku, odráža loptu a ničí tehly usporiadané do špirálového vzoru. Hra obsahuje tri levely s rastúcou rýchlosťou, systém power-upov, bossa s vlastnou logikou správania a automatické ukladanie skóre do textového súboru po každom skončení hry. --- ## Preklad a spustenie make ./game Vymazanie skompilovaných súborov: make clean Hra sa prekladá kompilátorom gcc s prepínačmi -Wall -Wextra -g a linkuje sa s knižnicami ncurses (-lncurses) a matematickou knižnicou (-lm). --- ## Architektura projektu Projekt je rozdelený do troch logických vrstiev: main.c vstupný bod, odovzdá riadenie knižnici world world.c/h engine – event loop, vykreslovanie, vstup game.c/h herná logika – všetky herné pravidlá a stav Táto separácia zabezpečuje že herná logika je úplne nezávislá od konkrétnej implementácie vykreslovania. Keby sa zmenila knižnica world, game.c by ostalo nedotknuté. --- ## Datove struktury Celý stav hry je uložený v jednej štruktúre Hra ktorá sa alokuje dynamicky pri štarte a uvoľňuje pri ukončení. ### Hra – hlavna struktura typedef struct { Palka palka; Lopta lopty[MAX_LOPT]; int pocet_lopt; Tehla tehly[MAX_RIADKOV][MAX_STLPCOV]; int zivoty; int skore; int zostatok_tehiel; int level; float rychlost; StavHry stav; int sirka, vyska; char meno[32]; PowerUp powerupy[2]; int hit_counter; int sirka_timer; int cas_tikov; int special_dostupny; Boss boss; } Hra; ### Tehla typedef struct { int ziva; int farba; char znak; } Tehla; Tehly sú uložené v dvojrozmernom poli tehly[MAX_RIADKOV][MAX_STLPCOV] teda 7x10 pozícií. Nie všetky sú obsadené – rozloženie určuje statické pole spirala[7][10] kde 1 znamená tehla existuje, 0 prázdne. Atribút ziva slúži na označenie zničených tehiel bez nutnosti preusporiadavať pole. ### Lopta typedef struct { float x, y; float dx, dy; int ziva; } Lopta; Pozícia a smer sú float aby pohyb bol plynulý a uhly presné. Hra podporuje až MAX_LOPT = 16 lôpt súčasne v jednom statickom poli. Pridávanie lôpt prechádza pole a hľadá prvý slot kde ziva == 0. ### Palka typedef struct { int x, y; int sirka; } Palka; ### PowerUp typedef struct { int ziva; float x, y; char znak; short farba; } PowerUp; ### Boss typedef struct { int ziva; float x, y; float dx; int pada; } Boss; ### StavHry – stavovy automat Hra funguje ako stavový automat s týmito stavmi: STAV_UVOD úvodná obrazovka, zadávanie mena STAV_CAKA lopta čaká na palke pred štartom STAV_HRAJE hra beží STAV_KONIEC hráč prehral STAV_VYHRAL hráč vyhral všetky 3 levely STAV_DALSI_LEVEL level dokončený, čaká na pokračovanie Každý stav určuje čo sa vykresluje a aké udalosti sa spracúvajú. --- ## Herna logika ### Event loop Knižnica world.c beží v nekonečnej slučke. Pri každom tiku (každých RYCHLOST_HRY = 120 ms) zavolá funkciu game_event() s informáciou o stlačenom klávesu alebo uplynutom čase. game_event() spracuje vstup, zavolá pohni_lopty() a vykresli_hru(). ### Fyzika lopty Každý tick sa pre každú živú loptu zavolá pohni_jednu_loptu(): 1. Vypočíta sa nová pozícia: nx = lopta.x + lopta.dx ny = lopta.y + lopta.dy 2. Kontrola narazu na steny – ak lopta dosiahne okraj, príslušná zložka smeru sa neguje: ak nx <= lavy_okraj -> dx = +|dx| ak nx >= pravy_okraj -> dx = -|dx| ak ny <= horny_okraj -> dy = +|dy| 3. Kontrola odrazu od palky – ak lopta dosiahne riadok palky a je v jej horizontálnom rozsahu: offset = (nx - stred_palky) / (sirka_palky / 2) dx = offset * rychlost Čím ďalej od stredu, tým väčší horizontálny smer. dy sa vždy nastaví na -rychlost (lopta ide hore). 4. Kontrola kolízie s tehlami – porovnanie pozície lopty s pozíciou každej živej tehly. Pri zhode sa tehla označí ziva = 0, skóre sa zvýši a dy sa neguje (odraz). 5. Ak ny >= dolna_hranica (pod palkou) – lopta zomrie, pocet_lopt sa zníži. ### Pohyb palky Palka sa pohybuje o 2 znaky na každé stlačenie klávesi. Pri pohybe myšou sa x palky nastaví priamo na pozíciu kurzora mínus polovica šírky palky, čo dáva plynulé sledovanie myši. Pohyb je ohraničený na lavy_okraj až pravy_okraj – sirka_palky. ### Boss logika Boss sa objaví po BOSS_CAS = 240 tikoch od začiatku levelu. Fáza 1 – horizontálny pohyb: boss.x += boss.dx pri náraze na okraj sa dx neguje Fáza 2 – pád (keď cas_tikov >= BOSS_CAS): boss.pada = 1 boss.y += 0.15 každý tick ak boss trafí tehlu – tehla zomrie, skore -= 50 ak boss.y >= palka.y – okamžite STAV_KONIEC Zásah bossa loptou: boss.ziva = 0, skore += 200 vystrelí 5 lôpt rôznymi smermi (vystrel_z_bossa) ### Power-upy hit_counter počíta každú zničenú tehlu. hit_counter % 3 == 0 -> power-up $ (extra lopty) hit_counter % 12 == 0 -> power-up W (siroka palka) Power-upy padajú dolu (y += 0.5 každý tick). Pri chytení palkou sa aktivuje efekt: $ – pridajú sa 2 nové lopty s mierne odchýleným smerom W – palka.sirka = PALKA_SIRKA_MAX, sirka_timer = 300 tickov po 300 tickoch sa palka vráti na PALKA_SIRKA_MIN ### Specialny vystrel Stlačením E sa vypália 2 lopty pod uhlom od stredu palky. Dostupnosť sa sleduje premennou special_dostupny (1/0). Po použití sa nastaví na 0 a už sa nedá obnoviť. ### Skore Za každú zničenú tehlu: 10 * cislo_levelu bodov. Za zničenie bossa: +200 bodov. Za tehlu zničenú bossom: -50 bodov. ### Ukladanie skore Po každom skončení hry (STAV_KONIEC aj STAV_VYHRAL) sa zavolá funkcia uloz_skore() ktorá otvorí scores.txt v append móde ("a") a pripíše formátovaný záznam s týmito údajmi: - meno hráča - dosiahnuté skóre - level na ktorom hra skončila - čas od začiatku levelu (prepočítaný z cas_tikov) - výsledok (VYHRAL / GAME OVER) - dátum a čas (zo systémovej funkcie localtime) Súbor sa nevymazáva – každá hra sa pripíše na koniec takže ostáva kompletná história všetkých hier. --- ## Vykreslovanie Celá hra sa vykresluje funkciou vykresli_hru() ktorá sa volá po každej udalosti. Funkcia najprv vymaže obrazovku (clear_screen) a potom podľa aktuálneho stavu hry vykreslí príslušné prvky. Súradnicový systém: [0,0] je ľavý horný roh obrazovky. X rastie doprava, Y rastie smerom nadol. Hracia plocha má dva rámčeky: vonkajší – ohraničuje celú obrazovku (žltý) vnútorný – ohraničuje hernú plochu (biely) Rozmery hracej plochy sa počítajú dynamicky podľa aktuálnej veľkosti terminálu (h->sirka, h->vyska) čo zabezpečuje že hra funguje správne aj pri zmene veľkosti okna. Pozície tehiel: tx = tehla_zacatek_x + stlpec * 3 ty = tehla_zac_y + riadok Každá tehla zaberá 3 znaky: [X] kde X je znak z mena hráča. --- ## Ovládanie | Kláves | Akcia | |----------------------|------------------------------| | A / sipka vlavo | Pohyb palky vlavo | | D / sipka vpravo | Pohyb palky vpravo | | Pohyb mysou | Palka sleduje kurzor | | Medzernik | Spustenie lopty | | Lavy klik mysou | Spustenie lopty | | E | Specialny vystrel | | Q | Ukoncenie hry | --- ## Bodovanie | Udalost | Body | |--------------------------|-------| | Znicenie tehly – level 1 | +10 | | Znicenie tehly – level 2 | +20 | | Znicenie tehly – level 3 | +30 | | Znicenie bossa | +200 | | Boss znici tehlu | -50 | --- ## Levely | Level | Rychlost lopty | Body za tehlu | |-------|----------------|---------------| | 1 | 0.7 | 10 | | 2 | 0.9 | 20 | | 3 | 1.1 | 30 | --- ## Subory projektu | Subor | Obsah | |------------|------------------------------------------------| | main.c | Vstupny bod, spusta hernu slucku cez world | | game.c | Cela herna logika – pohyb, kolizie, kreslenie | | game.h | Struktury, konstanty, deklaracie funkcii | | world.c | Kniźnica pre vykreslovanie v terminali | | world.h | Rozhranie kniźnice world | | Makefile | Preklad projektu prikazom make | | README.md | Tato dokumentacia | | scores.txt | Ukladanie skore (vytvori sa automaticky) | ---