diff --git a/Makefile b/Makefile index 7032595d06d847ab2cb1fb7b8e728052dd700144..738a3180ac0ea25ad2367fe9538ad6feb9822b84 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CFLAGS=$(shell pkg-config --cflags sdl2 SDL2_image SDL2_ttf) -std=c99 -Wall -Wextra -pedantic -g -O0 CPPFLAGS=-MMD -MF $*.d # Generate dependency files LDLIBS=$(shell pkg-config --libs sdl2 SDL2_image SDL2_ttf) -lm -OBJ=output.o map.o rows.o auto.o charac.o main.o init.o gameLoop.o menu.o menu2.o title_screen.o file_own.o +OBJ=output.o map.o rows.o auto.o charac.o main.o init.o gameLoop.o menu2.o title_screen.o file_own.o CC=gcc all: main diff --git a/charac.c b/charac.c index 67b3549b2b4362fc682f222739166f1cc3803fa2..518fc22a5682490794820fcde2e6e2008ada5863 100644 --- a/charac.c +++ b/charac.c @@ -87,3 +87,15 @@ int update_character(int speed, SDL_Renderer *renderer){ return(0); } + +void recenter_player(void){ + int i = 70; + for(int j = 0;j<8;j++){ + if (player->x < i + j*ROW_SIZE){ + player->x = (i-50) + j*ROW_SIZE; + return; + } + } + player->x = (i-50) + 8*ROW_SIZE; +} + diff --git a/charac.h b/charac.h index 258b5395c9f2224d6db42666eb03e0454ce30a19..f3eda58c86251e2f7b5dfa96d92dad29f6eb7a07 100644 --- a/charac.h +++ b/charac.h @@ -26,4 +26,6 @@ void jump(int); int update_character(int,SDL_Renderer*); +void recenter_player(void); + #endif \ No newline at end of file diff --git a/file_own.c b/file_own.c index b5c2c36633a6e0f5bb80080d91830068b9d96224..3ef3ac91a2bb73333388ee7f9d106c53424cfed6 100644 --- a/file_own.c +++ b/file_own.c @@ -1,21 +1,20 @@ #include "file_own.h" //V: playerhighscore exists and score.txt exists -//N if playerhighscore < current score; score gets written into score txt. Else score is rewritten into file +//N if playerhighscore > current score; playerhighscore is written into corresponding space in score.txt. The rest is rewritten into score.txt (including the theme if playerhighscore < score) int write_table (enum vehicle theme) { FILE *my_file = fopen("images/score.txt", "r+"); if (my_file == NULL ) { printf("File could be opened. file_own\n"); return -1; } - //Für jede Map ein Score + //Für jede Map ein Score, initiiert mit Null int score_normal = 0; int score_street = 0; int score_trains = 0; int score_water = 0; - //variable theme - + //liest die scores aus dem file aus if (fscanf(my_file,"%d,%d,%d,%d", &score_normal, &score_street, &score_trains, &score_water) == EOF) { printf("File could not be scanned. Error: %d file_own\n", errno); // wie ferror() ? }; @@ -25,6 +24,7 @@ int write_table (enum vehicle theme) { //truncate overwrites too much, but doesnt really matter afaik if (ftruncate(fileno(my_file), 64) == -1) printf("File couldnt be truncated\n"); + // Je nach Fall aktualisieren wir den score, wenn dieser kleiner ist als der playerhighscore switch(theme) { case coin: if (playerhighscore > score_normal) { @@ -66,6 +66,9 @@ int write_table (enum vehicle theme) { return 0; } +//V: enum vehicle exists and has 4 parameters (with the right names) for the classes +//N: my_file is the same as before or if it was empty 0,0,0,0 +//E: returns the current highscore of the theme given to the function int read_table (enum vehicle theme) { FILE *my_file = fopen("images/score.txt", "r"); if (my_file == NULL ) { @@ -82,11 +85,13 @@ int read_table (enum vehicle theme) { //Wir schließen es im read modus und öffnen es im write modus if (fclose(my_file) == EOF) printf("failed to close file. file_own 2\n"); my_file = fopen("score.txt", "w+"); + //Wir wissen, da fscanf gefailed aber fopen funktioniert hat, dass das file leer ist und schreibne deshalb 0,0,0,0 rein fprintf(my_file, "0,0,0,0"); if (fscanf(my_file,"%d,%d,%d,%d", &score_normal, &score_street, &score_trains, &score_water) == EOF) printf("Score immer noch nicht drinnen"); }; if (fclose(my_file) == EOF) printf("failed to close file. file_own 2\n"); + switch (theme) { case coin: return score_normal; case car: return score_street; @@ -99,6 +104,7 @@ int read_table (enum vehicle theme) { //V: score.txt exists //N: simply makes score.txt empty +//CURRENTLY NOT USED int reset_table (void) { FILE *my_file = fopen("images/score.txt", "w"); if (fclose(my_file) == EOF) { diff --git a/gameLoop.c b/gameLoop.c index 81e278f8b1e02ef02a2b594088f35b9216d034d3..6303bb7f02741b384795ddfc16b41ab123525319 100644 --- a/gameLoop.c +++ b/gameLoop.c @@ -5,11 +5,15 @@ SDL_Rect *player; int playerscore; int playerhighscore; +//V: enum vehicle exists with 4 correct themes, Renderer exists +//N: renderer still exists, all objects are still exist or have been correctly removed +//E: game has been played for one round, which was at least 16ms long void gameLoop(enum vehicle theme,SDL_Renderer* renderer) { SDL_Event e; int speed = 0; + // Character wird in der Mitte des vorletzten Feldes gestartet SDL_Rect character = { .x = 420, .y = 810, @@ -22,23 +26,30 @@ void gameLoop(enum vehicle theme,SDL_Renderer* renderer) { playerscore = 0; playerhighscore = 0; + //start_game prevents game start before player input has been received bool start_game = false; + //ends game if game over criteria have been met bool end_game = false; + //used to implement rows and allows to remove rows out of view struct LinkedList *map = init_map(theme); + //every at least 16ms this loop is called while (!end_game) { + //prevents overlap of menu and game SDL_RenderClear(renderer); + //used to standardize time to at least 16ms per tick Uint32 start_time = SDL_GetTicks(); while (SDL_PollEvent(&e)) { - + switch (e.type){ - + // if user closes window exit frees all used space case SDL_QUIT: exit(0); + // any key input starts game and takes player input case SDL_KEYDOWN: start_game = true; jump(e.key.keysym.scancode); @@ -64,23 +75,28 @@ void gameLoop(enum vehicle theme,SDL_Renderer* renderer) { end_game = move_map(theme,speed,map,renderer); // Wenn der Spieler nicht im Fenster zu sehen ist, dann wird das Spiel beendet - if(player->y >= SCREEN_HEIGHT){ + if(player->y >= SCREEN_HEIGHT || player->x >=SCREEN_WIDTH || player->x <= -60){ end_game = true; } //Position des Spielers wird aktualisiert und gezeichnet update_character(speed, renderer); + //Der aktuelle Score wird oben rechts angezeigt paste_score (renderer); + //Hier wird der aktuelle Stand des Spiels dem Spieler angezeigt SDL_RenderPresent(renderer); // Spiel bekommt eine feste Aktuallisierungsrate von ~60 fps + // Tick dauert mindestens 16ms Uint32 end_time = SDL_GetTicks(); while (end_time - start_time < 16) { end_time = SDL_GetTicks(); } } + //Wenn das Spiel game over ist schreiben wir den aktuellen Score in die score.txt write_table(theme); + //wir löschen die map free_map(map); return; } diff --git a/main.c b/main.c index 44d74e36a775799a2f920ad06518055af20a0ce6..56ad1bcab84c7986183d0bfc87dece39a563040c 100644 --- a/main.c +++ b/main.c @@ -58,7 +58,7 @@ int main(void) { break; } gameLoop(theme,renderer); - change_Map = end_screen(renderer,theme); + change_Map = end_screen(renderer); } diff --git a/map.c b/map.c index 9eb9310dc79f68e949ec6de1f8bc25b2b9cd2129..e404aacd9617d712804ea9089735ed874c33e52f 100644 --- a/map.c +++ b/map.c @@ -105,6 +105,13 @@ int move_map(enum vehicle theme,int delta_y,struct LinkedList *list, SDL_Rendere while(true){ cur->y_pos += delta_y; + + if (cur->y_pos <= player->y && player->y <= cur->y_pos + ROW_SIZE + && (cur->row_type == waterBrightSingle || cur->row_type == waterBrightMultiple || + cur->row_type == waterDarkSingle || cur->row_type == waterDarkMultiple)){ + player->x += cur->speed; + } + if (paste_row(renderer,cur->y_pos,cur->row_type)) return(-1); @@ -114,6 +121,11 @@ int move_map(enum vehicle theme,int delta_y,struct LinkedList *list, SDL_Rendere } } + if (cur->y_pos <= player->y && player->y <= cur->y_pos + ROW_SIZE && (cur->row_type == grassBright || + cur->row_type == grassDark || cur->row_type == finishlineBright || cur->row_type == finishlineDark)){ + recenter_player(); + } + if (cur->next == NULL){ break; } diff --git a/map.h b/map.h index 6881498dfd15c60096cf56cbc4c0d9fadd8fdab2..462344fedde8215baad25880207a60278805b5b9 100644 --- a/map.h +++ b/map.h @@ -10,6 +10,7 @@ #include "rows.h" //#include "gameLoop.h" #include "output.h" +#include "charac.h" #include "header.h" diff --git a/menu.c b/menu.c deleted file mode 100644 index 88193285afc8e6c43f4a38404c8da1986c31c401..0000000000000000000000000000000000000000 --- a/menu.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "SDL_render.h" -#include "SDL_surface.h" -# include "header.h" -# include <stdbool.h> -# include <string.h> -# include <SDL_ttf.h> -# include <SDL.h> -# include <stdio.h> -#include <SDL_ttf.h> - -/* - - -bool end_screen(SDL_Renderer* renderer) { - - if (SDL_SetRenderDrawColor(renderer,255,255,255,0) !=0) { - SDL_Log("Farbe konnte nicht gesetzt werden! SDL_Error %s\n",SDL_GetError()); - return(-1); - } - - // Hintergrund für Schrift erstellen - SDL_Rect rect = { - .x = 250, - .y = 0, - .w = 600, - .h = 200 }; - if (SDL_RenderFillRect(renderer,&rect)!=0) { - - SDL_Log("Malen des Rechtecks fehlgeschlagen! SDL_Error %s\n",SDL_GetError()); - return(-1); - } - -// Text ausgeben - SDL_Surface* surfaceMessage = TTF_RenderText_Blended_Wrapped (font, "Nochmal? (y)/(n)", (SDL_Color) {255, 255, 255, 255}, 8*200); - - if (surfaceMessage == NULL) - printf("Text Surface loading failed: %s\n", TTF_GetError()); - - SDL_Texture* Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage); - - SDL_RenderCopy(renderer, Message, NULL, &rect); - - SDL_Event e; - int input; - bool quit = false; - - SDL_RenderPresent(renderer); - - enum keys {y = 29 , n = 17}; - - while (quit == false) { - - while (SDL_PollEvent(&e)) { - switch (e.type) { - case SDL_QUIT: - exit(0); - case SDL_KEYDOWN: - input = e.key.keysym.scancode; - if (input == y) { - SDL_FreeSurface(surfaceMessage); - SDL_DestroyTexture(Message); - quit = true; - return(false); - } - - if (input == n) { - SDL_FreeSurface(surfaceMessage); - SDL_DestroyTexture(Message); - return(true); - } - } - } - } - return(true); -} - - -*/ \ No newline at end of file diff --git a/menu2.h b/menu2.h index 065fb32907cdf39011a9526fafa0df799e87d372..a7c9e28cdfbb66ce48254d404d88e8853005b0e7 100644 --- a/menu2.h +++ b/menu2.h @@ -15,7 +15,7 @@ //Declaration of functions -bool end_screen(SDL_Renderer*,enum vehicle); +bool end_screen(SDL_Renderer*); enum vehicle startscreen(SDL_Renderer*);