gists/c-moving-ball/main.c
2025-04-11 08:36:27 +03:00

137 lines
2.6 KiB
C

/*
Gist accompanying https://alloca.space/blog/c-lang.html
Build and Run
-------------
1. Install a C compiler and https://raylib.com on your system
2. Build and run with:
cc main.c -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 -o game && ./game
*/
#include <stdlib.h>
#include "raylib.h"
/* Constants */
#define FPS 60
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define BALL_SPEED 200
#define BALL_RADIUS 50
/* Data types */
typedef struct {
int x;
int y;
} V2;
typedef struct {
V2 position;
float radius;
V2 direction;
Color color;
} Ball;
/* Functions */
Ball* createBall();
void swing(int *position, int *direction, int min, int max);
void swingBall(Ball* ball);
void applyKeys(Ball* ball);
void updateBall(Ball* ball);
void initialize();
/* Main */
int main(void) {
initialize();
Ball* ball = createBall();
Color background_color = { 0x08, 0x18, 0x29, 0xff };
// Game loop
while (!WindowShouldClose()) {
// Update
updateBall(ball);
// Draw
BeginDrawing();
ClearBackground(background_color);
DrawCircle((*ball).position.x, (*ball).position.y, (*ball).radius, (*ball).color);
EndDrawing();
}
// De-Initialization
free(ball);
CloseWindow();
return 0;
}
/* Initialize window */
void initialize() {
SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "alloca.space - The C Programming Language");
SetTargetFPS(FPS);
}
/* Ball */
Ball* createBall() {
Ball ball_value = {
.position = {
.x = SCREEN_WIDTH/3,
.y = SCREEN_HEIGHT/3,
},
.radius = BALL_RADIUS,
.direction = {
.x = 1,
.y = 1,
},
.color = { 0xf9, 0x92, 0x26, 0xff },
};
Ball* ball = (Ball*)malloc(sizeof(Ball));
*ball = ball_value;
return ball;
}
void updateBall(Ball* ball) {
applyKeys(ball);
swingBall(ball);
}
void applyKeys(Ball* ball) {
if (IsKeyDown(KEY_D)) { (*ball).direction.x = 1; }
if (IsKeyDown(KEY_A)) { (*ball).direction.x = -1; }
if (IsKeyDown(KEY_S)) { (*ball).direction.y = 1; }
if (IsKeyDown(KEY_W)) { (*ball).direction.y = -1; }
}
void swingBall(Ball* ball) {
swing(&(*ball).position.x, &(*ball).direction.x, 0 + (*ball).radius, SCREEN_WIDTH - (*ball).radius);
swing(&(*ball).position.y, &(*ball).direction.y, 0 + (*ball).radius, SCREEN_HEIGHT - (*ball).radius);
}
void swing(int *position, int *direction, int min, int max) {
if (*position <= min) {
*position = min;
*direction = 1;
}
else if (*position >= max) {
*position = max;
*direction = -1;
}
float dt = GetFrameTime();
*position += *direction * (BALL_SPEED * dt);
}