diff --git a/bin/back b/bin/back index 3a2daf0..c554c1c 100755 Binary files a/bin/back and b/bin/back differ diff --git a/obj/base.o b/obj/base.o index 1e40980..bf82826 100644 Binary files a/obj/base.o and b/obj/base.o differ diff --git a/obj/cars.o b/obj/cars.o index 7b2fd51..51b433c 100644 Binary files a/obj/cars.o and b/obj/cars.o differ diff --git a/obj/display.o b/obj/display.o index b3e9699..16e98fd 100644 Binary files a/obj/display.o and b/obj/display.o differ diff --git a/obj/main.o b/obj/main.o index 369ef42..90fde72 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/obj/rooms.o b/obj/rooms.o index 7ef8db7..ae6c694 100644 Binary files a/obj/rooms.o and b/obj/rooms.o differ diff --git a/obj/structure.o b/obj/structure.o index 54ce4d2..c16ecee 100644 Binary files a/obj/structure.o and b/obj/structure.o differ diff --git a/src/base.c b/src/base.c index 80bf439..83e760f 100644 --- a/src/base.c +++ b/src/base.c @@ -24,7 +24,8 @@ void init_all(int nPl) { currentTurn = 0; players = malloc(sizeof(carData)*nPlayers); for(int p = 0; p < nPlayers; p++) { - players[p].c = init_car("player"); + players[p].rgb = (color){.red = 255, .green = 255, .blue = 255}; + players[p].c = init_car(p, nPlayers); } } diff --git a/src/cars.c b/src/cars.c index 0841f90..2beddfe 100644 --- a/src/cars.c +++ b/src/cars.c @@ -15,11 +15,24 @@ #include "base.h" #include "cars.h" -car* init_car() { +const double PI = 3.14159; + +ptf get_position(int nPl, int nTotPl) { + double theta = (2.0*MAX_THETA_SPAWN*nPl/((nTotPl-1==0)?(1):(nTotPl-1)) - 1.0*MAX_THETA_SPAWN); + //printf("%d --> %lf", nPl, theta); + return (ptf){ + .fx = ROOM_SIZE/2.0+cos(theta*PI/180.0 - PI/2.0*(START_DIR))*ROOM_SIZE/4.0, + .fy = ROOM_SIZE/2.0+sin(theta*PI/180.0 - PI/2.0*(START_DIR))*ROOM_SIZE/4.0 + }; +} + +car* init_car(int nPl, int nTotPl) { car* res = malloc(sizeof(car)); res->itm = NULL; res->nCoins = 0; - res->pos = (ptf){.fx = 0.0, .fy = 0.0}; + res->pos = get_position(nPl, nTotPl); + res->chx = START_CHX; + res->chy = START_CHY; res->vel = (ptf){.fx = 0.0, .fy = 0.0}; return res; } diff --git a/src/cars.h b/src/cars.h index 2102df7..a1885f6 100644 --- a/src/cars.h +++ b/src/cars.h @@ -1,7 +1,7 @@ #ifndef CARS_H #define CARS_H -car* init_car(); +car* init_car(int nPl, int nTotPl); void destroy_car(car* c); void place_car(car* c, double x, double y); diff --git a/src/display.c b/src/display.c index 657b6d8..406c02b 100644 --- a/src/display.c +++ b/src/display.c @@ -24,7 +24,7 @@ void updateRenderer(SDL_Renderer* renderer) { } void resetRenderer(SDL_Renderer* renderer) { - SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255); + SDL_SetRenderDrawColor(renderer, 64, 64, 64, 255); SDL_RenderClear(renderer); } @@ -210,7 +210,7 @@ void draw7SegNumberToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W } } //---------------------------------------------------------------------------------------------------------------------// -// circle functions by @Gumichan01 at https://gist.github.com/Gumichan01/332c26f6197a432db91cc4327fcabb1c (not native) // +// circle functions by @Gumichan01 at https://gist.github.com/Gumichan01/364c26f6197a464db91cc4647fcabb1c (not native) // //---------------------------------------------------------------------------------------------------------------------// void SDL_RenderDrawCircle(SDL_Renderer * renderer, int x, int y, int radius, int r, int g, int b, int a) { SDL_SetRenderDrawColor(renderer, r, g, b, a); @@ -295,6 +295,86 @@ void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius, int //return status; } +void drawCircleToRenderer(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius, int r, int g, int b, int a) { + SDL_SetRenderDrawColor(renderer, r, g, b, a); + const int32_t diameter = (radius * 2); + + int32_t x = (radius - 1); + int32_t y = 0; + int32_t tx = 1; + int32_t ty = 1; + int32_t error = (tx - diameter); + + while(x >= y){ + SDL_RenderDrawLine(renderer, centreX + x, centreY - y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX + x, centreY + y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX - x, centreY - y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX - x, centreY + y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX + y, centreY - x, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX + y, centreY + x, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX - y, centreY - x, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX - y, centreY + x, centreX, centreY); + + if(error <= 0){ + ++y; + error += ty; + ty += 2; + } + + if(error > 0) { + --x; + tx += 2; + error += (tx - diameter); + } + } +} + +void drawQuarterCircleToRenderer(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius, bool TL, bool TR, bool BL, bool BR, int r, int g, int b, int a) { + SDL_SetRenderDrawColor(renderer, r, g, b, a); + const int32_t diameter = (radius * 2); + + int32_t x = (radius - 1); + int32_t y = 0; + int32_t tx = 1; + int32_t ty = 1; + int32_t error = (tx - diameter); + + while(x >= y){ + + if(TL) { + SDL_RenderDrawLine(renderer, centreX - x, centreY - y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX - y, centreY - x, centreX, centreY); + } + + if(TR) { + SDL_RenderDrawLine(renderer, centreX + x, centreY - y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX + y, centreY - x, centreX, centreY); + } + + if(BL) { + SDL_RenderDrawLine(renderer, centreX - x, centreY + y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX - y, centreY + x, centreX, centreY); + } + + if(BR) { + SDL_RenderDrawLine(renderer, centreX + x, centreY + y, centreX, centreY); + SDL_RenderDrawLine(renderer, centreX + y, centreY + x, centreX, centreY); + } + + if(error <= 0){ + ++y; + error += ty; + ty += 2; + } + + if(error > 0) { + --x; + tx += 2; + error += (tx - diameter); + } + } +} + // ------------------------------------------------------------------------------------------------------------------------- // void renderStraights(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, int rsize) { @@ -314,13 +394,13 @@ void renderStraights(SDL_Renderer* renderer, level* lvl, int cx, int cy, int ran (HEIGHT-rsize)/2+rsize*x, rsize-(int)(2*START_EDGE*rsize), rsize, - 32, 32, 32, 255); + 64, 64, 64, 255); placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x+(int)(START_EDGE*rsize), rsize, rsize-(int)(2*START_EDGE*rsize), - 32, 32, 32, 255); + 64, 64, 64, 255); break; case STR_H: @@ -330,7 +410,7 @@ void renderStraights(SDL_Renderer* renderer, level* lvl, int cx, int cy, int ran (HEIGHT-rsize)/2+rsize*x+(int)(DIST_EDGE*rsize), rsize, rsize-(int)(2*DIST_EDGE*rsize), - 32, 32, 32, 255); + 64, 64, 64, 255); break; case STR_V: @@ -340,7 +420,7 @@ void renderStraights(SDL_Renderer* renderer, level* lvl, int cx, int cy, int ran (HEIGHT-rsize)/2+rsize*x, rsize-(int)(2*DIST_EDGE*rsize), rsize, - 32, 32, 32, 255); + 64, 64, 64, 255); break; case TURN_NE: @@ -382,27 +462,35 @@ void renderCircles(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range break; case TURN_NE: - placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x , (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x , (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + drawQuarterCircleToRenderer(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x , (int)(rsize*(1-DIST_EDGE)), + false, false, true, false, + 64, 64, 64, 192); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x , (int)(rsize*DIST_EDGE), 0, 0, 0, 255); break; case TURN_SE: - placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + drawQuarterCircleToRenderer(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*(1-DIST_EDGE)), + true, false, false, false, + 64, 64, 64, 192); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y+rsize, (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*DIST_EDGE), 0, 0, 0, 255); break; case TURN_SW: - placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + drawQuarterCircleToRenderer(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*(1-DIST_EDGE)), + false, true, false, false, + 64, 64, 64, 192); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x+rsize, (int)(rsize*DIST_EDGE), 0, 0, 0, 255); break; case TURN_NW: - placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x , (int)(rsize*(1-DIST_EDGE)), 32, 32, 32, 255); - SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x , (int)(rsize*DIST_EDGE), 0, 0, 0, 255); + placeRectToRenderer(renderer, (WIDTH-rsize)/2+rsize*y, (HEIGHT-rsize)/2+rsize*x, rsize, rsize, 0, 0, 0, 255); + drawQuarterCircleToRenderer(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x , (int)(rsize*(1-DIST_EDGE)), + false, false, false, true, + 64, 64, 64, 192); + SDL_RenderFillCircle(renderer, (WIDTH-rsize)/2+rsize*y , (HEIGHT-rsize)/2+rsize*x , (int)(rsize*DIST_EDGE), 0, 0, 0, 255); break; default: @@ -413,9 +501,24 @@ void renderCircles(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range } } +void renderPlayers(SDL_Renderer* renderer, int cx, int cy, int range, int rsize) { + for(int p = 0; p < nPlayers; p++) { + if(players[p].c->chx >= cx-range && players[p].c->chx <= cx+range && players[p].c->chy >= cy-range && players[p].c->chy <= cy+range) { + int plchx = players[p].c->chx; + int plchy = players[p].c->chy; + int cox = (WIDTH-rsize)/2+rsize*(plchx-cx) + (int)((players[p].c->pos.fx*1.0)/ROOM_SIZE*rsize); + int coy = (HEIGHT-rsize)/2+rsize*(plchy-cy) + (int)((players[p].c->pos.fy*1.0)/ROOM_SIZE*rsize); + SDL_RenderFillCircle(renderer, cox, coy, PLAYER_R, players[p].rgb.red, players[p].rgb.green, players[p].rgb.blue, 255); + } else { + // + } + } +} + void renderMap(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, int rsize) { renderCircles(renderer, lvl, cx, cy, range, rsize); renderStraights(renderer, lvl, cx, cy, range, rsize); + renderPlayers(renderer, cx, cy, range, rsize); } // ------------------------------------------------------------------------------------------------------------------------- // diff --git a/src/display.h b/src/display.h index 1518086..b91b307 100644 --- a/src/display.h +++ b/src/display.h @@ -14,6 +14,8 @@ void draw7SegDigitToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W, void draw7SegNumberToRenderer(SDL_Renderer* renderer, int n, int X, int Y, int W, int H, int thicc, int R, int G, int B, int A, int side, int dot); void SDL_RenderDrawCircle(SDL_Renderer * renderer, int x, int y, int radius, int r, int g, int b, int a); void SDL_RenderFillCircle(SDL_Renderer * renderer, int x, int y, int radius, int r, int g, int b, int a); +void drawCircleToRenderer(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius, int r, int g, int b, int a); +void drawQuarterCircleToRenderer(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius, bool TL, bool TR, bool BL, bool BR, int r, int g, int b, int a); void renderMap(SDL_Renderer* renderer, level* lvl, int cx, int cy, int range, int rsize); diff --git a/src/main.c b/src/main.c index 2e59d3c..6ed88aa 100644 --- a/src/main.c +++ b/src/main.c @@ -35,10 +35,14 @@ int main() { import_letters(rend); import_digits(rend); - init_all(N_PLAYERS); // ---------------------------- // //test_file("levels/test.txt"); level* test = parse_level("levels/test.txt"); + init_all(N_PLAYERS); + + //for(int p = 0; p < N_PLAYERS; p++) { + // printf("[%d], (at [%d %d] (%lf %lf))\n", p, players[p].c->chx, players[p].c->chy, players[p].c->pos.fx, players[p].c->pos.fy); + //} renderMap(rend, test, 1, 1, 2, 250); updateRenderer(rend); diff --git a/src/rooms.c b/src/rooms.c index 751030a..b069358 100644 --- a/src/rooms.c +++ b/src/rooms.c @@ -15,6 +15,10 @@ #include "base.h" #include "rooms.h" +int START_CHX; +int START_CHY; +int START_DIR; + bool is_digit(char c) { return ((int)c >= 48 && (int)c <= 57); } @@ -101,9 +105,26 @@ level* parse_level(char* path) { if(ch == '\n') {ch = fgetc(ptr); printf("\n");} printf("%c", ch); lvl->map[l][c] = get_type(ch); - //printf("(%d %d -> %c)", l, c, ch); + if(ch == 'S') { + START_CHX = l; + START_CHY = c; + } } } + printf("\n"); + + if(START_CHX-1 >= 0 && lvl->map[START_CHX-1][START_CHY] != NONE) { + START_DIR = 3; + } + if(START_CHX+1 < lvl->lines && lvl->map[START_CHX+1][START_CHY] != NONE) { + START_DIR = 1; + } + if(START_CHY-1 >= 0 && lvl->map[START_CHX][START_CHY-1] != NONE) { + START_DIR = 0; + } + if(START_CHY+1 < lvl->cols && lvl->map[START_CHX][START_CHY+1] != NONE) { + START_DIR = 2; + } return lvl; } diff --git a/src/structure.c b/src/structure.c index 95d2c3a..6e634ad 100644 --- a/src/structure.c +++ b/src/structure.c @@ -11,9 +11,14 @@ const int MAX_SPEED = 66; const double DIST_EDGE = 0.2; const double START_EDGE = 0.05; -const int BARRIERS = 1; const int RESTITUTION_WALL = 0.8; const int RESTITUTION_PLAYER = 0.8; +const int PLAYER_R = 10; +const int MAX_THETA_SPAWN = 60; // degrees + +const int BARRIERS = 1; +const double BARRIER_WIDTH = 0.05; + const double FRICTION = 0.75; const double DV = 0.01; diff --git a/src/structure.h b/src/structure.h index 0b842c3..d3bc5c6 100644 --- a/src/structure.h +++ b/src/structure.h @@ -26,6 +26,8 @@ typedef struct item_t { typedef struct car_t { ptf pos; // remains in [0, ROOM_SIZE[ + int chx; + int chy; ptf vel; int nCoins; item* itm; // either NULL or a pointer to an item @@ -43,8 +45,6 @@ typedef struct color_t { typedef enum road_t {NONE, START, END, STR_V, STR_H, TURN_NE, TURN_SE, TURN_SW, TURN_NW} road; typedef struct level_t { - pt start; - pt end; int lines; int cols; road** map; @@ -54,8 +54,6 @@ typedef struct level_t { typedef struct carData_t { car* c; color rgb; - int chx; - int chy; } carData; // ------------------------------------------------------------------------ // @@ -74,11 +72,19 @@ extern const int HEIGHT; extern const int ROOM_SIZE; extern const int MAX_SPEED; +extern int START_CHX; +extern int START_CHY; +extern int START_DIR; // (0, 1, 2, 3) = (N, E, S, W) +extern const int MAX_THETA_SPAWN; + +extern const int PLAYER_R; // radius + extern const double DIST_EDGE; extern const double START_EDGE; -extern const int BARRIERS; extern const int RESTITUTION_WALL; extern const int RESTITUTION_PLAYER; +extern const int BARRIERS; +extern const double BARRIER_WIDTH; extern const double FRICTION; extern const double DV;