added car spawning system

This commit is contained in:
Alexandre 2025-05-15 11:16:09 +02:00
parent 8f20ebb87d
commit 435a1ae63e
16 changed files with 185 additions and 30 deletions

BIN
bin/back

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
// ------------------------------------------------------------------------------------------------------------------------- //

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;