commit bb5b9fb739f3b6e4691e8ffd65870e75623f62f3
parent 212bf072b743e33def9b15fc1428c767f55ed632
Author: Lou Woell <lou.woell@posteo.de>
Date:   Sat,  3 Feb 2024 02:03:53 +0100

Cleanup + Proper Scaling

Diffstat:
MREADME.md | 1-
Mmakefile | 22+++++++++++++---------
Mpong.c | 386+++++++++++++++++++++++++++++++++++++++++--------------------------------------
3 files changed, 212 insertions(+), 197 deletions(-)

diff --git a/README.md b/README.md @@ -26,4 +26,3 @@ https://www.repetitions.de/posts/pong-wars/ ## TODOs - prevent balls from getting stuck sometimes. -- make window rescalable diff --git a/makefile b/makefile @@ -1,17 +1,19 @@ CC = gcc +BIN = pong SHELL := /bin/bash - LIBS = -lraylib -lm -OBJS = pong.o -CFLAGS = -Wall -Wextra +OBJS = $(BIN).o -BIN = pong +CFLAGS = -Wall -Wextra # Only used for WASM compilation -RAYLIB_PATH = ~/Programming/raylib/ -EMSCRIPTEN_PATH = /etc/profile.d/emscripten.sh +RAYLIB_PATH = ~/Programming/raylib EMCC_FLAGS = -Wall -DPLATFORM_WEB -s GL_ENABLE_GET_PROC_ADDRESS -s USE_GLFW=3 +EMCC_SHELL_FILE = --shell-file $(RAYLIB_PATH)/src/minshell.html + +.PHONY: all +all: $(BIN) $(BIN).html $(BIN): $(OBJS) $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @@ -19,6 +21,8 @@ $(BIN): $(OBJS) %.o: %.c $(CC) -c -o $@ $< $(CFLAGS) -.PHONY: web -web: - source $(EMSCRIPTEN_PATH) && emcc -o $(BIN).html pong.c $(EMCC_FLAGS) $(RAYLIB_PATH)/src/libraylib.a -I. -I $(RAYLIB_PATH)/src -I $(RAYLIB_PATH)/src/external -L. -L $(RAYLIB_PATH)/src --shell-file $(RAYLIB_PATH)/src/minshell.html +%.html: %.c + emcc -o $@ $< $(EMCC_FLAGS) lib/libraylib.a $(EMCC_SHELL_FILE) + +%.js: %.c + emcc -o $@ $< $(EMCC_FLAGS) lib/libraylib.a diff --git a/pong.c b/pong.c @@ -2,11 +2,10 @@ #include <math.h> #include <raylib.h> +#include <sys/param.h> #if defined(PLATFORM_WEB) #include <emscripten/emscripten.h> - #include <emscripten/html5.h> - #include <sys/param.h> #endif // Color Scheme of my Website @@ -20,255 +19,268 @@ #define FONTSIZE 30 #define PAUSE_TEXT "PAUSED" -#define MAX_RECS_X 24 -#define MAX_RECS_Y 24 +#define RECS 30 +#define REC_SIZE 20 -int WIDTH = 600; -int HEIGHT = 600; - -int SQUARE_SIZE = 25; +typedef struct { + Vector2 Position; + Vector2 Direction; + float speed; -typedef struct { - Vector2 Position; - Vector2 Speed; - float Radius; - Color Color; + Color Color; + float radius; } bBall; typedef struct { - int squareSize; - Rectangle recs[MAX_RECS_X * MAX_RECS_Y]; - Color colors[MAX_RECS_X * MAX_RECS_Y]; -} Board; + // Pause related + int framesCounter; + bool pause; -typedef struct { - int framesCounter; - bool pause; - Board board; - bBall DayBall; - bBall NightBall; + int BoardDim; + RenderTexture2D target; + + // Board + Color colors[RECS][RECS]; + + // Bouncing Balls + bBall DayBall; + bBall NightBall; } Game; Game game = {0}; -int pause_text_width; +int pause_text_width = 0; -void MakeBoard(Board *board) +void MakeBoard() { - for (int y = 0; y < MAX_RECS_Y; y++) - { - for (int x = 0; x < MAX_RECS_X; x++) - { - board->recs[y * MAX_RECS_X + x].x = SQUARE_SIZE / 2.0f + SQUARE_SIZE * x; - board->recs[y * MAX_RECS_X + x].y = SQUARE_SIZE / 2.0f + SQUARE_SIZE * y; - board->recs[y * MAX_RECS_X + x].width = SQUARE_SIZE; - board->recs[y * MAX_RECS_X + x].height = SQUARE_SIZE; - if (MAX_RECS_X / 2 > x) - board->colors[y * MAX_RECS_X + x] = DAY_COLOR; - else - board->colors[y * MAX_RECS_X + x] = NIGHT_COLOR; - } - } + for (int y = 0; y < RECS; y++) + { + for (int x = 0; x < RECS; x++) + { + if (RECS / 2 > x) + game.colors[y][x] = DAY_COLOR; + else + game.colors[y][x] = NIGHT_COLOR; + } + } } -void DrawBoard(Board *board) +void DrawBoard() { - for (int i = 0; i < MAX_RECS_X * MAX_RECS_Y; i++) - { - DrawRectanglePro( - board->recs[i], - (Vector2){ - board->recs[i].width / 2, - board->recs[i].height / 2 - }, - 0, - board->colors[i]); - } + for (int j = 0; j < RECS; j++) + { + for (int i = 0; i < RECS; i++) + { + DrawRectangle(REC_SIZE * j, + REC_SIZE * i, + REC_SIZE, + REC_SIZE, + game.colors[i][j]); + } + } } int RandomOffset(int offset) { - return GetRandomValue(-(offset), (offset)); + return GetRandomValue(-(offset), (offset)); } bool coloreq(Color first, Color second) { - if (first.r == second.r && - first.g == second.g && - first.b == second.b && - first.a == second.a) return true; - return false; + if (first.r == second.r && + first.g == second.g && + first.b == second.b && + first.a == second.a) return true; + return false; } void flipColor(Color *tile) { - if (coloreq(*tile, DAY_COLOR)) - *tile = NIGHT_COLOR; - else - *tile = DAY_COLOR; + if (coloreq(*tile, DAY_COLOR)) + *tile = NIGHT_COLOR; + else + *tile = DAY_COLOR; } void MakeBouncingBall(bBall *ball, Color color, float startx, float starty) { - float xspeed = SQUARE_SIZE/2.0f - 1; - float yspeed = SQUARE_SIZE/2.0f - 1; - - if (startx > WIDTH / 2.0f) - xspeed *= -1; - else - yspeed *= -1; - - ball->Position = (Vector2){ startx, starty}; - ball->Speed = (Vector2){ xspeed, yspeed }; - ball->Radius = SQUARE_SIZE*0.5; - ball->Color = color; + float xspeed; + float yspeed; + + if (startx > game.BoardDim / 2.0f) + { + xspeed = -1; + yspeed = 1; + } + else + { + xspeed = 1; + yspeed = -1; + } + + ball->Position = (Vector2){ startx, starty}; + ball->Direction = (Vector2){ xspeed, yspeed }; + ball->Color = color; + ball->radius = REC_SIZE*0.5; + ball->speed = REC_SIZE * 0.5 - 4; } -void BouncingBallPosition(bBall *ball, Board *board) +void BouncingBallPosition(bBall *ball) { - ball->Position.x += ball->Speed.x; - ball->Position.y += ball->Speed.y; - - // Check walls collision - if ((ball->Position.x >= (WIDTH - ball->Radius)) || - (ball->Position.x <= ball->Radius)) ball->Speed.x *= -1.0f; - if ((ball->Position.y >= (HEIGHT - ball->Radius)) || - (ball->Position.y <= ball->Radius)) ball->Speed.y *= -1.0f; - - // Check Colour collision - for (double angle = 0; angle < (2 * PI); angle += (PI / 4)) - { - - int i = floor((ball->Position.x + cos(angle) * ball->Radius) / - SQUARE_SIZE); - int j = floor((ball->Position.y + sin(angle) * ball->Radius) / - SQUARE_SIZE); - - if (i >= 0 && i < MAX_RECS_X && j >= 0 && j < MAX_RECS_Y) - { - - int k = j * MAX_RECS_X + i; - - if (coloreq(board->colors[k], ball->Color)) - { - flipColor(&(board->colors[k])); - // Determine bounce direction based on the angle - if (fabs(cos(angle)) > fabs(sin(angle))) - ball->Speed.x *= -1; - else - ball->Speed.y *= -1; - } - } - } + ball->Position.x += ball->Direction.x * ball->speed; + ball->Position.y += ball->Direction.y * ball->speed; + + // Check walls collision + if ((ball->Position.x > (game.BoardDim - ball->radius)) || + (ball->Position.x < ball->radius)) + { + ball->Direction.x *= -1; + ball->Position.x += ball->Direction.x*ball->speed; + } + if ((ball->Position.y > (game.BoardDim - ball->radius)) || + (ball->Position.y < ball->radius)) + { + ball->Direction.y *= -1; + ball->Position.y += ball->Direction.y*ball->speed; + } + + // Check Colour collision + for (double angle = 0; angle < (2 * PI); angle += (PI / 4)) + { + int i = floor((ball->Position.x + cos(angle) * ball->radius) / + REC_SIZE); + int j = floor((ball->Position.y + sin(angle) * ball->radius) / + REC_SIZE); + + if (i >= 0 && i < RECS && j >= 0 && j < RECS) + { + if (coloreq(game.colors[j][i], ball->Color)) + { + flipColor(&(game.colors[j][i])); + // Determine bounce direction based on the angle + if (fabs(cos(angle)) > fabs(sin(angle))) + ball->Direction.x *= -1; + else + ball->Direction.y *= -1; + } + } + } } void DrawBouncingBall(bBall *ball) { - /* Draw Bouncing Ball */ - DrawCircleV(ball->Position, ball->Radius, ball->Color); + /* Draw Bouncing Ball */ + DrawCircleV(ball->Position, ball->radius, ball->Color); } void SetGame() { - MakeBoard(&game.board); - MakeBouncingBall(&game.DayBall, - DAY_COLOR, - (WIDTH / 4.0f) * 3 + - RandomOffset(WIDTH / 4), - HEIGHT/2.0f + RandomOffset(HEIGHT/2)); - MakeBouncingBall(&game.NightBall, - NIGHT_COLOR, - (WIDTH / 4.0f) + - RandomOffset(WIDTH / 4), - HEIGHT/2.0f + RandomOffset(HEIGHT/2)); + MakeBoard(); + MakeBouncingBall( + &game.DayBall, + DAY_COLOR, + (game.BoardDim / 4.0f) * 3 + RandomOffset(game.BoardDim / 4), + game.BoardDim/2.0f + RandomOffset(game.BoardDim/2)); + MakeBouncingBall( + &game.NightBall, + NIGHT_COLOR, + (game.BoardDim / 4.0f) + RandomOffset(game.BoardDim/ 4), + game.BoardDim/2.0f + RandomOffset(game.BoardDim/2)); } void DrawGame() { - BeginDrawing(); - - ClearBackground(RAYWHITE); - - DrawBoard(&game.board); - DrawBouncingBall(&game.DayBall); - DrawBouncingBall(&game.NightBall); - - // On pause, we draw a blinking message - if (game.pause && ((game.framesCounter/30)%2)) - { - DrawText(PAUSE_TEXT, - (WIDTH - pause_text_width)/2, - HEIGHT/3, - FONTSIZE, - WHITE); - } - - EndDrawing(); + float scale = MIN((float)GetScreenWidth()/game.BoardDim, + (float)GetScreenHeight()/game.BoardDim); + + BeginTextureMode(game.target); + + ClearBackground(RAYWHITE); + + DrawBoard(); + DrawBouncingBall(&game.DayBall); + DrawBouncingBall(&game.NightBall); + + // On pause, we draw a blinking message + if (game.pause && ((game.framesCounter/30)%2)) + { + DrawText(PAUSE_TEXT, + (game.BoardDim - pause_text_width)/2, + game.BoardDim/3, + FONTSIZE, + WHITE); + } + EndTextureMode(); + + BeginDrawing(); + ClearBackground(BLACK); + DrawTexturePro( + game.target.texture, + (Rectangle){ + 0.0f, + 0.0f, + (float)game.target.texture.width, + (float)-game.target.texture.height + }, + (Rectangle){ + (GetScreenWidth() - ((float)game.BoardDim*scale))*0.5f, + (GetScreenHeight() - ((float)game.BoardDim*scale))*0.5f, + (float)game.BoardDim*scale, + (float)game.BoardDim*scale + }, + (Vector2){0, 0}, + 0.0f, + WHITE); + EndDrawing(); } + void handleInput() { - // Press P to Pause - if (IsKeyPressed(KEY_P)) game.pause = !game.pause; - // Press R to reset - if (IsKeyPressed(KEY_R)) SetGame(); + // Press P to Pause + if (IsKeyPressed(KEY_P)) game.pause = !game.pause; + // Press R to reset + if (IsKeyPressed(KEY_R)) SetGame(); } -void UpdateDrawFrame(void) +void UpdateDrawFrame() { - handleInput(); - - if (!game.pause) - { - BouncingBallPosition(&game.DayBall, &game.board); - BouncingBallPosition(&game.NightBall, &game.board); - } - else game.framesCounter++; - - DrawGame(); + handleInput(); + /* ScaleGame(); */ + if (!game.pause) + { + BouncingBallPosition(&game.DayBall); + BouncingBallPosition(&game.NightBall); + } + else game.framesCounter++; + + DrawGame(); } int main() { + game.BoardDim = RECS*REC_SIZE; -#if defined(PLATFORM_WEB) - SetConfigFlags(FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE); -#else - SetConfigFlags(FLAG_VSYNC_HINT); -#endif - - InitWindow(WIDTH,HEIGHT, "Pong Wars"); + SetConfigFlags(FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE); + InitWindow(game.BoardDim,game.BoardDim, "Pong Wars"); -#if defined(PLATFORM_WEB) - emscripten_get_canvas_element_size("canvas", &WIDTH, &HEIGHT); - - WIDTH = MIN(WIDTH, HEIGHT); - - SQUARE_SIZE = WIDTH / MAX_RECS_X; - // avoid Gaps due to rounding - WIDTH = MAX_RECS_X * SQUARE_SIZE; - HEIGHT = WIDTH; - - emscripten_set_canvas_element_size("canvas", WIDTH, HEIGHT); - SetWindowSize( WIDTH, HEIGHT); - SetWindowMaxSize(WIDTH, HEIGHT); -#endif + game.target = LoadRenderTexture(game.BoardDim, game.BoardDim); + SetTextureFilter(game.target.texture, TEXTURE_FILTER_POINT); - // needs initialized Window - pause_text_width = MeasureText(PAUSE_TEXT, FONTSIZE); + pause_text_width = MeasureText(PAUSE_TEXT, FONTSIZE); - SetGame(); + SetGame(); #if defined(PLATFORM_WEB) - emscripten_set_main_loop(UpdateDrawFrame, 0, 1); + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); #else - SetTargetFPS(60); - while (!WindowShouldClose()) - { - UpdateDrawFrame(); - } + SetTargetFPS(60); + while (!WindowShouldClose()) + { + UpdateDrawFrame(); + } #endif - CloseWindow(); - return 0; + CloseWindow(); + return 0; }