#include #include #include "modules/global.h" #include "modules/camera.h" #include "modules/color.h" #include "modules/floaters.h" #include "modules/particles.h" #include "modules/world.h" #include "modules/map.h" #include "modules/menu/menuDraw.h" #include "modules/menu/menuFSM.h" /**\mainpage Leírás * \section Röviden * Egy könnyed, egyszerűen megismerhető, mégis jutalmazó játékélményt nyújtó programot szerettem volna. * \section Hosszabban * A játéktér 3D-s kockákból álló, dinamikus méretű, és véletlenszerűen generált. * A játékosnak a generált akadályok tetején található jutalmakat kell gyűjtenie. * Ezt természetesen repülő ellenségek nehezítik, akik meg is keresik a játékost. * Nem csak az ellenségeket, hanem a pályát is lehet rombolni a karakter által lőtt lövedékekkel. * A játékost segíti még az időlassítás lehetősége is. Persze egyik sincs ingyen, mindkét képesség * használata a pontszám csökkenésével jár. A pontszám nem kerülhet nulla alá. * A játék aktuális állása fájlba menthető és onnan be is tölthető. * Ezen felül a program egy toplistát is tartalmaz a legjobb eredményekről. * \section Érdekességek * - Nem triviális a térbeli megjelenítés, a pálya generálás illetve a mentés tömörítésének eljárása. * Ezeket bővebben kifejtve a megfelelő modulok függvényeinél lehet megtalálni. Röviden viszont itt is megmagyarázom őket. * A 3D-s hatást egy kamera fizikai modelljével érem el. Általában nem ez a leggyorsabb megoldás, viszont a játék egyszerű grafikájából * kifolyólag (kizárólag téglatestek vannak benne) itt nagyon jól beválik. Persze rengeteg optimalizálás kell hozzá, hogy hardveres gyorsítás nélkül, * kizárólag a processzoron futva is élvezhetően gyors legyen. Ilyen optimalizálások a nem egyesével történő rajzolás; ha hasonló tulajdonságú kockák vannak * egymás alatt, akkor azokat egy magas oszlopként rajzolja. Csak azokat az oldalakat rajzolja, amik valóban látszanak. Illetve értelemszerűen, * csak azokat a kockákat rajzolja, amelyikek látszanak. * Ezen felül a rajzolás sorrendje is igencsak érdekes kihívást tár elénk, de erről már csak a camera.c modulban kerül szó. * - A pályagenerálás nem túl bonyolult, két részből áll. Előszőr a földszintet építi, ahol random magasságú oszlopok vannak, * csak az van megszabva, hogy mekkora lehet két szomszédos oszlop közt a legnagyobb magasságkülönbség. A felső szint már érdekesebb. Ott vannak a platformok. * A pályát x irányban kisebb egységekre osztjuk, minden egységben egy "oszlopot" építünk. Az oszlop alatt olyan platformokat értünk, amik közt a távolság olyan, hogy * a játék aktuális fizikájával mindig legalább egy irányban tovább lehet haladni róluk. Igazából ennyi az egész. * - A tömörítés a három közül a legprimitívebb megoldás, viszont nincs szükségünk bonyolultabbra, ez is elégséges. Mivel a pályák nagyrésze igen repetitív, ezért * a blockok is gyakran ismétlődnek, ezt az ismétlődést a: "(ismétlődés száma)block típusa" formában rögzítjük. Erről bővebben a save.c modulban. Fontos megjegyezni, hogy * a játék nincsen felkészítve a fájljaiba való külső beavatkozásra, tehát ezt igyekezzünk elkerülni. * \section Modulok * - camera.c: minden, ami 3d-s megjelenítéssel kapcsolatos * - map.c: minden, ami a pálya generálásával és ütközésteszteléssel kapcsolatos * - floaters.c: ellenségek, lövedékek * - particles.c: hóeséssel kapcsolatos függvények és tömbök * - player.c: nagyrészt a player mozgásáért felelős * - saves.c: mentés, betöltés, mentés fájlok kezelése * - world.c: meghívja a világ létrehozásához szükséges függvényeket * - color.c: a pálya színei itt készülnek (HSL -> RGB átalakítás is van itt) * - menuFSM.c: a játékban és a menüben történő inputra reagál elsősorban, itt zajlanak az állapotátmenetek * - menuDraw.c: a menüt rajzolja le, illetve meghívja a játéktér rajzolását is, ha szükséges * - unicodePrint.c: a név sugallja, az unicode szövegek kezelése és megjelenítése a feladata * - auxSDL.c: a megfelelő sdl-es függvények meghívása, illetve az egér interakciók kezelése * - auxFunctions.c: gyakran használ inline függvények * \section Kompatibilitás * A program lefordításához szükséges az SDL.h, SDL_ttf.h, illetve SDL_gfxPrimitives.h könyvtárak. Nincs tesztelve, viszont valószínűleg * az SDL 1.2 által platformokon működőképes az alkalmazás. A játék fix FPS-sel fut, ez jelenleg 50-re van beállítva, így átlagos teljesítményű gépeken is * el kell futnia, viszont ehhez szükség van egy átlagos képességű gépre, szóval ez egy lényeges rendszerkövetelmény. * A játék működéséhez szükségesek a megfelelő ttf-fájlok. * \section Készítette * Schmelczer András, 2017. 12. 03. */ /** * \file main.c */ bool isLMBDown = false, isRMBDown = false, prematureClick; int main(int argc, char *argv[]) { srand(time(NULL)); SDL_Cursor* cursor = openWindow(); SDL_Event event; SDL_TimerID timerID; timerID = SDL_AddTimer((int)(1000.0 / FPS), timer, NULL); keys = SDL_GetKeyState(NULL); //setlocale(0, ""); Uint32 backgroundColor = SDL_MapRGB(screen -> format, 40, 0, 0); createMenuWorld(); while (getGameState() != quit) { SDL_WaitEvent(&event); switch(event.type) { case SDL_USEREVENT: SDL_FillRect(screen, NULL, backgroundColor); doStuff(isLMBDown, isRMBDown, prematureClick); SDL_UpdateRect(screen, 0, 0, 0, 0); break; case SDL_MOUSEBUTTONDOWN: if(event.button.button == SDL_BUTTON_LEFT) handleClicks(&prematureClick); if(event.button.button == SDL_BUTTON_RIGHT) isRMBDown = true; if(event.button.button == SDL_BUTTON_LEFT) isLMBDown = true; break; case SDL_MOUSEBUTTONUP: if(event.button.button == SDL_BUTTON_RIGHT) isRMBDown = false; if(event.button.button == SDL_BUTTON_LEFT) isLMBDown = prematureClick = false; break; case SDL_MOUSEMOTION: setMousePosition(event.motion.x, event.motion.y); break; case SDL_KEYDOWN: if(strcmp(SDL_GetKeyName(event.key.keysym.unicode), "escape") == 0) whatToDoOnEscape(); else processTyping(event); break; } } //Felszabadítás freeFloaterList(); freeColorMap(); freeMap(); freeRenderMap(); freeParticleList(); SDL_FreeSurface(text); freeFonts(); SDL_RemoveTimer(timerID); SDL_FreeCursor(cursor); SDL_Quit(); return 0; }