diff --git a/auto.c b/auto.c index 61e9f9582b17ac0bf7c11958c83aa9a94c10182c..21290036148affdbc76159cd02c798312cfc9c90 100644 --- a/auto.c +++ b/auto.c @@ -53,13 +53,16 @@ struct Car* init_car(int speed,int width,int height,int pred_pos,int pred_width, }else{ if (t == car || t == boat){ - min_distance = 100 * abs(speed); + min_distance = 50 * abs(speed); distance = (rand() % 300) + min_distance; } else if (t == (train)){ - min_distance = 50 * abs(speed) + 50; - distance = (rand() % 500) + min_distance; + min_distance = 40 * abs(speed) + 50; + distance = (rand() % 400) + min_distance; + }else if (t == race_car){ + min_distance = 20 * abs(speed) + 100; + distance = (rand() % 300) + min_distance; } if (speed < 0){ @@ -142,7 +145,7 @@ int move_car(SDL_Renderer* renderer,struct Row *n){ while (true){ if (n->y_pos <= player->y && player->y <= n->y_pos + ROW_SIZE && kollision(cur->x_pos,cur->width)){ - if (cur->type == car || cur->type == train){ + if (cur->type == car || cur->type == train || cur->type == race_car){ return(1); }else if (cur -> type == boat){ @@ -181,6 +184,9 @@ int move_car(SDL_Renderer* renderer,struct Row *n){ length = 150; height = 60; + }else if (n->row_type == raceStreet){ + length = 150; + height = 60; }else{ length = 200; height = 60; diff --git a/charac.c b/charac.c index 7fe9c874f5fb6436d2bf3b77dfb376e1a8148e46..91d744b573b83b67abf35299b2b2a024edf90fc5 100644 --- a/charac.c +++ b/charac.c @@ -11,17 +11,19 @@ Nachbedingung: Position des Characters hat sich je nach Tasteneingabe verändert // ROW_SIZE = 100 // SDL_SCANCODE_X = MACRO von SDL anstall "magic numbers" zu verwenden -void jump(int input){ +int jump(int input){ switch(input) { case SDL_SCANCODE_D: //right if(player->x < 770){ // Überprüfe Grenzen player->x += ROW_SIZE; + return(1); } break; case SDL_SCANCODE_A: //left if(player->x > 30){ // Überprüfe Grenzen player->x -= ROW_SIZE; + return(2); } break; @@ -29,6 +31,7 @@ void jump(int input){ if(player->y < 820){ // Überprüfe Grenzen playerscore--; player->y += ROW_SIZE; + return(3); } break; @@ -39,6 +42,7 @@ void jump(int input){ playerhighscore = playerscore; } player->y -= ROW_SIZE; + return(4); } break; @@ -50,6 +54,7 @@ void jump(int input){ } player->y -= ROW_SIZE; player->x -= ROW_SIZE; + return(5); } break; @@ -61,12 +66,14 @@ void jump(int input){ } player->y -= ROW_SIZE; player->x += ROW_SIZE; + return(6); } break; case SDL_SCANCODE_SPACE: puts("Pew Pew"); break; } + return(0); } diff --git a/gameLoop.c b/gameLoop.c index 4d277bb5c86fb7e8a8dce84583e57e368059d928..42573151d3d619c7fbd7781db40e304a39d0fb15 100644 --- a/gameLoop.c +++ b/gameLoop.c @@ -31,6 +31,7 @@ bool gameLoop(enum vehicle theme,SDL_Renderer* renderer) { //ends game if game over criteria have been met bool end_game = false; bool quit_game = false; + int last_move; //used to implement rows and allows to remove rows out of view struct LinkedList *map = init_map(theme); @@ -56,7 +57,7 @@ bool gameLoop(enum vehicle theme,SDL_Renderer* renderer) { // any key input starts game and takes player input case SDL_KEYDOWN: start_game = true; - jump(e.key.keysym.scancode); + last_move = jump(e.key.keysym.scancode); prevent_double_tipping = false; break; default: @@ -78,7 +79,7 @@ bool gameLoop(enum vehicle theme,SDL_Renderer* renderer) { // Die Map wird bewegt und gezeichnet (inklusive Fahrzeuge) // Bei einer ungültigen Kollision wird das Spiel beendet if (!end_game) - end_game = move_map(theme,speed,map,renderer); + end_game = move_map(theme,speed,map,renderer,last_move); // Wenn der Spieler nicht im Fenster zu sehen ist, dann wird das Spiel beendet if(player->y >= SCREEN_HEIGHT || player->x >=SCREEN_WIDTH || player->x <= -60){ diff --git a/hDateien/charac.h b/hDateien/charac.h index f3eda58c86251e2f7b5dfa96d92dad29f6eb7a07..d2a38b0b14c0b8e551d20cb7d754df4367ea3992 100644 --- a/hDateien/charac.h +++ b/hDateien/charac.h @@ -22,7 +22,7 @@ extern int playerscore; //Declaration of functions -void jump(int); +int jump(int); int update_character(int,SDL_Renderer*); diff --git a/hDateien/header.h b/hDateien/header.h index 37739380114eb47c190cb0b048d95849706fe036..f41ae3d073c2e620aaf89981d10a19b96bef5032 100644 --- a/hDateien/header.h +++ b/hDateien/header.h @@ -20,11 +20,12 @@ enum row{ waterBrightSingle, waterBrightMultiple, waterDarkSingle, - waterDarkMultiple + waterDarkMultiple, + raceStreet }; enum vehicle{ - car, train,boat, coin, coin_gathered + car, train,boat, coin, coin_gathered,race_car }; @@ -44,6 +45,7 @@ struct Row{ struct Row *next; int y_pos; int speed; + int stone; struct LinkedList_car *cars; }; diff --git a/hDateien/init.h b/hDateien/init.h index 42290cad922fe0904b302defa2b96f34f70cf90b..204e90a03449658fbe0ead10adb3eb510a79b814 100644 --- a/hDateien/init.h +++ b/hDateien/init.h @@ -36,5 +36,7 @@ extern SDL_Texture *img_trainL; extern SDL_Texture *img_plank; extern SDL_Texture *img_duck; extern SDL_Texture *img_3D_Duck; +extern SDL_Texture *img_stone; +extern SDL_Texture *img_race_street; #endif \ No newline at end of file diff --git a/hDateien/map.h b/hDateien/map.h index 462344fedde8215baad25880207a60278805b5b9..3618715a84cb6c52cbade8ec1e6814fead3e7add 100644 --- a/hDateien/map.h +++ b/hDateien/map.h @@ -17,7 +17,7 @@ //Declaration of functions struct LinkedList* init_map(enum vehicle); -int move_map(enum vehicle,int,struct LinkedList*,SDL_Renderer*); +int move_map(enum vehicle,int,struct LinkedList*,SDL_Renderer*,int); void free_map(struct LinkedList*); diff --git a/hDateien/output.h b/hDateien/output.h index 1a3640f27523a613076b4b9aafcbbcfe4393a722..1910ed21dbc0e46e2b2f00f8d47c95808e9733c0 100644 --- a/hDateien/output.h +++ b/hDateien/output.h @@ -17,7 +17,7 @@ //Declaration of functions - +int paste_stone(SDL_Renderer*,int,int); int paste_row(SDL_Renderer*, int , enum row); int paste_car(SDL_Renderer*, int, int, int, int,int,enum vehicle); int paste_score (SDL_Renderer*); diff --git a/hDateien/rows.h b/hDateien/rows.h index ca87072fd87fdf8c2cae946fe5a182108313bd7a..07d2a7c721a6252aebfd19eae21ea6d675d8a203 100644 --- a/hDateien/rows.h +++ b/hDateien/rows.h @@ -13,6 +13,9 @@ //Declaration of functions +int gen_stone(); + +struct Row* race(int); struct Row* init_row(struct Row*); struct Row* grass(bool,bool,int); struct Row* street(bool,int); diff --git a/images/race_street.jpg b/images/race_street.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ff744a5d95cfa0e5edfd98c58a1cf97d9adbacdc Binary files /dev/null and b/images/race_street.jpg differ diff --git a/images/stone.png b/images/stone.png new file mode 100644 index 0000000000000000000000000000000000000000..c21819e859fe7829ab19c24d1f5311b218f649dd Binary files /dev/null and b/images/stone.png differ diff --git a/init.c b/init.c index f3be29e7d1f1bf3e13e12c8bb1cc4cd40da171cd..5a416f128b0774ef5b6692143adcf6dda75f8f6e 100644 --- a/init.c +++ b/init.c @@ -21,6 +21,8 @@ SDL_Texture *img_trainR; //https://www.pinterest.com/hassanhojabri/sprite/ SDL_Texture *img_plank; //https://www.craiyon.com/image/_XEsXKthRYqpK8Vn6ZixAg SDL_Texture *img_duck; SDL_Texture *img_3D_Duck; +SDL_Texture *img_stone; +SDL_Texture *img_race_street; TTF_Font* font; SDL_Window* init_window(){ @@ -89,6 +91,8 @@ int init_images(SDL_Renderer* renderer) { img_plank = IMG_LoadTexture(renderer,"images/plank.png"); // Quelle: https://www.craiyon.com/image/_XEsXKthRYqpK8Vn6ZixAg img_duck = IMG_LoadTexture(renderer,"images/duck.png"); img_3D_Duck = IMG_LoadTexture(renderer,"images/3D_Duck.png"); + img_stone = IMG_LoadTexture(renderer,"images/stone.png"); + img_race_street = IMG_LoadTexture(renderer,"images/race_street.jpg"); //Initiierung der Bilder int flags = IMG_INIT_PNG | IMG_INIT_JPG; @@ -136,6 +140,8 @@ int exitGame(SDL_Renderer* renderer, SDL_Window* window) { SDL_DestroyTexture(img_plank); SDL_DestroyTexture(img_duck); SDL_DestroyTexture(img_3D_Duck); + SDL_DestroyTexture(img_stone); + SDL_DestroyTexture(img_race_street); TTF_CloseFont(font); SDL_Quit(); diff --git a/map.c b/map.c index 61df72abf58449352d35dd0baafdd7dcaf0223c8..a1df89b491fe9c6bafe8dcaddee24f44f4a6e68d 100644 --- a/map.c +++ b/map.c @@ -84,7 +84,7 @@ struct LinkedList* init_map(enum vehicle theme){ // Eine Reihe wurde gelöscht, wenn y_pos >= 1000 // + neue Reihe mit Typ theme wurde an das Ende der Linked Ende hinzugefügt -int move_map(enum vehicle theme,int delta_y,struct LinkedList *list, SDL_Renderer* renderer){ +int move_map(enum vehicle theme,int delta_y,struct LinkedList *list, SDL_Renderer* renderer,int last_move){ struct Row *cur = list->head; bool newRow = false; @@ -106,19 +106,45 @@ int move_map(enum vehicle theme,int delta_y,struct LinkedList *list, SDL_Rendere cur->y_pos += delta_y; + if (paste_row(renderer,cur->y_pos,cur->row_type)) + return(-1); + + if (cur->stone != -1){ + if (paste_stone(renderer,cur->stone,cur->y_pos)) + return(1); + if (cur->stone <= player->x && player->x <= cur->stone + ROW_SIZE && (cur->y_pos <= player->y && player->y <= cur->y_pos + ROW_SIZE)){ + if (last_move == 1){ + player->x -= ROW_SIZE; + }else if( last_move == 2){ + player->x += ROW_SIZE; + }else if(last_move == 3){ + player->y -= ROW_SIZE; + }else if(last_move == 4){ + player->y += ROW_SIZE; + playerscore--; + }else if(last_move == 5){ + player->y += ROW_SIZE; + player->x += ROW_SIZE; + playerscore--; + }else if(last_move == 6){ + player->y += ROW_SIZE; + player->x -= ROW_SIZE; + playerscore--; + } + + } + } + 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); - 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(); - } + } else if (cur->cars != NULL){ if (move_car(renderer,cur) && cur->y_pos <= player->y && player->y <= cur->y_pos + ROW_SIZE){ diff --git a/output.c b/output.c index 976e0d7aa6e9b89d4c9b5b1ae21bd3c946fee0df..04c584f490bbac9bb3fd244353fc7d77aebcc159 100644 --- a/output.c +++ b/output.c @@ -1,5 +1,20 @@ #include "hDateien/output.h" +int paste_stone(SDL_Renderer* renderer, int x,int y){ + SDL_Rect stone = { + .x = x + 5, + .y = y + 15, + .w = 90, + .h = 70 + }; + + if (SDL_RenderCopy(renderer,img_stone, NULL, &stone) != 0) { + SDL_Log("Bild konnte nicht kopiert werden! SDL_Error Error: %s\n",SDL_GetError()); + return(1); + } + return(0); +} + //V: renderer exists, enum row_type is correct and not renamed, correct y coordinates are transferred //N: img corresponding to row_type is set to coordinates: x: 0 to 900 y: y to y+100 and displayed via renderer int paste_row(SDL_Renderer* renderer, int y, enum row row_type){ @@ -16,6 +31,7 @@ int paste_row(SDL_Renderer* renderer, int y, enum row row_type){ .w = SCREEN_WIDTH, .h = ROW_SIZE + 9}; + SDL_Texture *picture = NULL; bool multiple = false; if (row_type == grassDark) { @@ -27,6 +43,8 @@ int paste_row(SDL_Renderer* renderer, int y, enum row row_type){ }else if(row_type == streetMultiple){ picture = img_streetMultiple; multiple = true; + }else if(row_type == raceStreet){ + picture = img_race_street; }else if(row_type == traintrack){ picture = img_traintrack; }else if(row_type == waterBrightSingle){ @@ -57,7 +75,7 @@ int paste_row(SDL_Renderer* renderer, int y, enum row row_type){ SDL_Log("Bild konnte nicht kopiert werden! SDL_Error Error: %s\n",SDL_GetError()); return(1); } - } + } return 0; } @@ -86,7 +104,7 @@ int paste_car(SDL_Renderer* renderer, int x, int y, int width, int height,int sp return(1); } return(0); - }else if(type == car){ + }else if(type == car || type == race_car){ if (speed > 0) { if (SDL_RenderCopy(renderer, img_car_trans, NULL, &rect) != 0) { SDL_Log("Bild konnte nicht kopiert werden! SDL_Error Error: %s\n",SDL_GetError()); diff --git a/rows.c b/rows.c index b9674eed2da2b7efbd7c69e9043a9ee691cb9907..c8e4c07b983d8479d16a19c6f9a7e3f81a9e5c29 100644 --- a/rows.c +++ b/rows.c @@ -1,5 +1,27 @@ #include "hDateien/rows.h" +int gen_stone(){ + int p = (rand() % 9)*ROW_SIZE; + return(p); +} + +struct Row *race(int y_pos){ + struct Row *n = malloc(sizeof(*n)); + if (n==NULL){ + perror("kein Speicherplatz"); + } + + n->row_type = raceStreet; + n->y_pos = y_pos; + int width = 150; + int height = 60; + + n->speed = (((rand()%2) * 2) -1) * 16; + n->cars = init_car_list(n->speed,width,height,(900-n->speed) % 900,race_car); + n->stone = -1; + + return(n); +} //Vorbedingung: -200<=y_pos<=1000 @@ -10,18 +32,21 @@ struct Row* grass(bool dark,bool gold,int y_pos){ perror("kein Speicherplatz"); } - if (dark){ - if (gold){ + if (gold){ + if (dark){ n->row_type = finishlineDark; }else{ - n->row_type = grassDark; + n->row_type = finishlineBright; + n->row_type = grassDark; } + n->stone = -1; }else{ - if (gold){ - n->row_type = finishlineBright; + if (dark){ + n->row_type = grassDark; }else{ n->row_type = grassBright; } + n->stone = gen_stone(); } n->y_pos = y_pos; n->cars = NULL; @@ -47,8 +72,9 @@ struct Row* street(bool first,int y_pos){ int width = 150; int height = 60; - n->speed = (((rand()%2) * 2) -1) * ((rand()%2)+1); + n->speed = (((rand()%2) * 2) -1) * ((rand()%3)+2); n->cars = init_car_list(n->speed,width,height,(900-n->speed) % 900,car); + n->stone = -1; return(n); } //Vorbedingung: -200<=y_pos<=1000 @@ -65,8 +91,9 @@ struct Row* track(int y_pos){ int width = 350; int height = 60; - n->speed = 6 *(((rand()%2)*2)-1); + n->speed = 7 *(((rand()%2)*2)-1); n->cars = init_car_list(n->speed,width,height,(SCREEN_WIDTH-n->speed) % SCREEN_WIDTH,train); + n->stone = -1; return(n); } @@ -99,6 +126,7 @@ struct Row* water(bool first,bool dark,int y_pos){ n->speed = 2 *(((rand()%2)*2)-1); n->cars = init_car_list(n->speed,width,length,(SCREEN_WIDTH-n->speed)%SCREEN_WIDTH,boat); + n->stone = -1; return(n); } @@ -135,14 +163,15 @@ struct Row* init_row(struct Row *m){ } // Nach Gras kommt mit einer Wahrscheinlichkeit von: - // 1/5 => Gras - // 1/5 => Gleis - // 1/5 => Wasser - // 2/5 => Straße + // 2/11 => Gras + // 2/11 => Gleis + // 2/11 => Wasser + // 4/11 => Straße + // 1/11 => Rennstraße }else if (m->row_type == grassDark || m->row_type == grassBright){ - p = rand() % 5; - if (p == 0){ + p = rand() % 11; + if (p <= 1){ if (m->row_type == grassDark){ n = grass(false,false,m->y_pos - ROW_SIZE); @@ -151,12 +180,12 @@ struct Row* init_row(struct Row *m){ n = grass(true,false,m->y_pos - ROW_SIZE); } - }else if (p == 1){ + }else if (p <= 3){ n = track(m->y_pos - ROW_SIZE); // Es wird verhindert, dass nur eine Flussreihe erzeugt wird, // da jedes 100. Feld durch eine goldene Grasreihe ersetzt wird - }else if (p == 2 && ((playerhighscore + (player->y/ROW_SIZE)) % 100 != 98)){ + }else if (p <=5 && ((playerhighscore + (player->y/ROW_SIZE)) % 100 != 98)){ if (m->row_type == grassDark ){ n = water(true,false,m->y_pos - ROW_SIZE); @@ -164,8 +193,10 @@ struct Row* init_row(struct Row *m){ }else{ n = water(true,true,m->y_pos - ROW_SIZE); } - }else{ + }else if(p <= 9){ n = street(true,m->y_pos - ROW_SIZE); + }else if(p == 10){ + n = race(m->y_pos - ROW_SIZE); } // Nach einem Gleis kommt mit einer Wahrscheinlichkeit von: @@ -194,6 +225,11 @@ struct Row* init_row(struct Row *m){ n = street(false,m->y_pos - ROW_SIZE); } + // Nach einer Rennstraße kommt immer Gras + }else if(m->row_type == raceStreet){ + n = grass(false,false,m->y_pos - ROW_SIZE); + + // Nach 1. Mal Wasser kommt mit einer Wahrscheinlichkeit von: // 1 => Wasser // Nach mindestens 2 mal Wasser kommt mit einer Wahrscheinlichkeit von: