initial commit
This commit is contained in:
commit
8c61e53dcd
13
.clang-format
Normal file
13
.clang-format
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
BasedOnStyle: Microsoft
|
||||||
|
|
||||||
|
# Specify column limit of 80, this way you can squize more terminals on screen
|
||||||
|
ColumnLimit: 80
|
||||||
|
|
||||||
|
# Pointers are part of the type not the variable name
|
||||||
|
PointerAlignment: Left
|
||||||
|
|
||||||
|
# Consecutive macros are more readable
|
||||||
|
AlignConsecutiveMacros: true
|
||||||
|
|
||||||
|
# It is more readable to have short {} statements on the same line
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Do not include compiled object files into git
|
||||||
|
*.o
|
||||||
|
# Do not include the built binary into git
|
||||||
|
pong
|
45
Makefile
Normal file
45
Makefile
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
CC=gcc
|
||||||
|
LD=gcc
|
||||||
|
|
||||||
|
# I'm using GCC to link code. This is prefered over using LD directly since
|
||||||
|
# it will handle all the GLIBC linkage for you.
|
||||||
|
|
||||||
|
SRCS = $(wildcard src/*.c)
|
||||||
|
OBJS = ${SRCS:.c=.o}
|
||||||
|
|
||||||
|
DEST = pong
|
||||||
|
|
||||||
|
CC_FLAGS = -I include/ -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -O3
|
||||||
|
LD_FLAGS =
|
||||||
|
LIBS = -lSDL2
|
||||||
|
|
||||||
|
# This is to let make know these are not actually file targets but rather
|
||||||
|
# command targets.
|
||||||
|
.PHONY = all clean format debug run
|
||||||
|
|
||||||
|
all: $(DEST)
|
||||||
|
|
||||||
|
# Link all objects together into one binary
|
||||||
|
$(DEST): ${OBJS}
|
||||||
|
$(LD) ${LD_FLAGS} $^ $(LIBS) -o $(DEST)
|
||||||
|
|
||||||
|
# For every c file, compile it to an object file
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) ${CC_FLAGS} -c $< -o $@
|
||||||
|
|
||||||
|
# Run the formatter
|
||||||
|
format:
|
||||||
|
clang-format -i src/*.c include/*.h
|
||||||
|
|
||||||
|
# Run the created binary
|
||||||
|
run: $(DEST)
|
||||||
|
./$(DEST)
|
||||||
|
|
||||||
|
# Run the created binary using the debugger
|
||||||
|
debug: $(DEST)
|
||||||
|
gdb ./$(DEST) -ex "set disassembly-flavor intel"
|
||||||
|
|
||||||
|
# Clean the project of all build files
|
||||||
|
clean:
|
||||||
|
$(info [INFO] Cleaning directory)
|
||||||
|
rm -rf ${OBJS} $(DEST)
|
20
README.md
Normal file
20
README.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# This is an example project to test if SDL2 is working on WSL2
|
||||||
|
|
||||||
|
## Required software
|
||||||
|
You need to install the SDL2 development library. On Debian
|
||||||
|
based systems such as Ubuntu or Linux Mint, you can run
|
||||||
|
|
||||||
|
sudo apt install libsdl2-dev
|
||||||
|
|
||||||
|
You will also need gcc and make to build the project and gdb
|
||||||
|
if you want to debug the project. Further clang-formatt can
|
||||||
|
be used to format the project.
|
||||||
|
|
||||||
|
These can all be installed using
|
||||||
|
|
||||||
|
sudo apt install build-essential gdb clang-format
|
||||||
|
|
||||||
|
## Building the project
|
||||||
|
In the main directory, simply run `make` with no arguments to
|
||||||
|
build the project. You can run `make run` to run the built project
|
||||||
|
and you can run `make debug` to debug the project using gdb.
|
21
include/ball.h
Normal file
21
include/ball.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef BALL_H
|
||||||
|
#define BALL_H
|
||||||
|
|
||||||
|
#define BALL_WIDTH 15
|
||||||
|
#define BALL_SPEED 1000
|
||||||
|
|
||||||
|
struct ball
|
||||||
|
{
|
||||||
|
int x_location;
|
||||||
|
int y_location;
|
||||||
|
int width;
|
||||||
|
int speed;
|
||||||
|
float x_direction;
|
||||||
|
float y_direction;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ball* ball_init(int x_location, int y_location, int width, int speed);
|
||||||
|
struct game_data;
|
||||||
|
void ball_update(struct game_data* data, struct ball* ball, float dt);
|
||||||
|
|
||||||
|
#endif /* BALL_H */
|
19
include/game.h
Normal file
19
include/game.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
|
||||||
|
struct game_data
|
||||||
|
{
|
||||||
|
int is_running;
|
||||||
|
struct render_data* render_data;
|
||||||
|
|
||||||
|
struct player* player1;
|
||||||
|
struct player* player2;
|
||||||
|
struct ball* ball;
|
||||||
|
|
||||||
|
int window_width;
|
||||||
|
int window_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
void game_start(int window_width, int window_height);
|
||||||
|
|
||||||
|
#endif /* GAME_H */
|
25
include/player.h
Normal file
25
include/player.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef PLAYER_H
|
||||||
|
#define PLAYER_H
|
||||||
|
|
||||||
|
#define PLAYER_WIDTH 25
|
||||||
|
#define PLAYER_HEIGHT 250
|
||||||
|
#define PLAYER_SPEED 6000.0
|
||||||
|
|
||||||
|
struct player
|
||||||
|
{
|
||||||
|
int x_location;
|
||||||
|
int y_location;
|
||||||
|
int speed;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum player_move_dir
|
||||||
|
{
|
||||||
|
PLAYER_MOVE_UP,
|
||||||
|
PLAYER_MOVE_DOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
void player_move(struct player* player, float dt, enum player_move_dir dir);
|
||||||
|
void player_update(struct game_data* data, struct player* player, float dt);
|
||||||
|
struct player* player_init(int x_location, int move_limit, int speed);
|
||||||
|
|
||||||
|
#endif /* PLAYER_H */
|
6
include/pong_ai.h
Normal file
6
include/pong_ai.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef PONG_AI_H
|
||||||
|
#define PONG_AI_H
|
||||||
|
|
||||||
|
void pong_ai_update(struct game_data* game, struct player* player, float dt);
|
||||||
|
|
||||||
|
#endif /* PONG_AI_H */
|
8
include/render.h
Normal file
8
include/render.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef RENDER_H
|
||||||
|
#define RENDER_H
|
||||||
|
|
||||||
|
struct render_data;
|
||||||
|
struct render_data* render_init(int width, int height);
|
||||||
|
void render(struct game_data* data);
|
||||||
|
|
||||||
|
#endif /* RENDER_H */
|
100
src/ball.c
Normal file
100
src/ball.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include <ball.h>
|
||||||
|
#include <game.h>
|
||||||
|
#include <player.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct ball* ball_init(int x_location, int y_location, int width, int speed)
|
||||||
|
{
|
||||||
|
struct ball* ball = malloc(sizeof(struct ball));
|
||||||
|
memset(ball, 0, sizeof(struct ball));
|
||||||
|
|
||||||
|
ball->x_location = x_location;
|
||||||
|
ball->y_location = y_location;
|
||||||
|
ball->width = width;
|
||||||
|
ball->speed = speed;
|
||||||
|
ball->x_direction = 1.0;
|
||||||
|
ball->y_direction = 1.0;
|
||||||
|
|
||||||
|
return ball;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_collision(int x1, int y1, int w1, int h1, int x2, int y2,
|
||||||
|
int w2, int h2)
|
||||||
|
{
|
||||||
|
// Simple AABB collision
|
||||||
|
return (x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void collide_with_player(struct player* player, struct ball* ball)
|
||||||
|
{
|
||||||
|
ball->x_direction = -ball->x_direction;
|
||||||
|
// Calculate how much drift this hit should add to the ball
|
||||||
|
//
|
||||||
|
// _ player->y_location
|
||||||
|
// ¦ ¦
|
||||||
|
// ¦ ¦ ball->y_location
|
||||||
|
// ¦ ¦ O
|
||||||
|
// ¦ ¦ ----- player->y_location / 2
|
||||||
|
// ¦ ¦
|
||||||
|
// ¦ ¦
|
||||||
|
// ¦_¦
|
||||||
|
//
|
||||||
|
// The following equation will create a float between -1.0 and 1.0 where
|
||||||
|
// 0 means the ball hit the player paddle straight on, -1.0 means the ball
|
||||||
|
// hit the topmost point of the paddle and 1.0 means the bottommost point.
|
||||||
|
float drift = (float)((ball->y_location + (ball->width / 2)) -
|
||||||
|
(player->y_location + PLAYER_HEIGHT / 2)) /
|
||||||
|
((float)PLAYER_HEIGHT / 2.0f);
|
||||||
|
ball->y_direction += drift;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ball_update(struct game_data* game, struct ball* ball, float dt)
|
||||||
|
{
|
||||||
|
ball->x_location += ball->x_direction * (float) ball->speed * dt;
|
||||||
|
ball->y_location += ball->y_direction * (float) ball->speed * dt;
|
||||||
|
|
||||||
|
// Check collisions with the top and bottom of the frame
|
||||||
|
if (ball->y_location < 0)
|
||||||
|
{
|
||||||
|
// collide with top of the frame
|
||||||
|
ball->y_direction = -ball->y_direction;
|
||||||
|
ball->y_location = 0;
|
||||||
|
}
|
||||||
|
else if (ball->y_location + ball->width > game->window_height)
|
||||||
|
{
|
||||||
|
// collide with bottom of the frame
|
||||||
|
ball->y_direction = -ball->y_direction;
|
||||||
|
ball->y_location = game->window_height - ball->width;
|
||||||
|
}
|
||||||
|
// Check collisions with the left and right of the frame
|
||||||
|
if (ball->x_location < 0)
|
||||||
|
{
|
||||||
|
// end game on the left
|
||||||
|
game->is_running = 0;
|
||||||
|
}
|
||||||
|
else if (ball->x_location + ball->width > game->window_width)
|
||||||
|
{
|
||||||
|
// end game on the right
|
||||||
|
game->is_running = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check collision with players
|
||||||
|
struct player* p1 = game->player1;
|
||||||
|
struct player* p2 = game->player2;
|
||||||
|
if (check_collision(ball->x_location, ball->y_location, ball->width,
|
||||||
|
ball->width, p1->x_location, p1->y_location,
|
||||||
|
PLAYER_WIDTH, PLAYER_HEIGHT))
|
||||||
|
{
|
||||||
|
ball->x_location = p1->x_location + PLAYER_WIDTH;
|
||||||
|
collide_with_player(p1, ball);
|
||||||
|
}
|
||||||
|
else if (check_collision(ball->x_location, ball->y_location, ball->width,
|
||||||
|
ball->width, p2->x_location, p2->y_location,
|
||||||
|
PLAYER_WIDTH, PLAYER_HEIGHT))
|
||||||
|
{
|
||||||
|
ball->x_location = p2->x_location - ball->width;
|
||||||
|
collide_with_player(p2, ball);
|
||||||
|
}
|
||||||
|
}
|
104
src/game.c
Normal file
104
src/game.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
#include <ball.h>
|
||||||
|
#include <game.h>
|
||||||
|
#include <player.h>
|
||||||
|
#include <pong_ai.h>
|
||||||
|
#include <render.h>
|
||||||
|
|
||||||
|
static void check_events(struct game_data* data, float dt)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
printf("Exit requested\n");
|
||||||
|
data->is_running = 0;
|
||||||
|
break;
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t* state = SDL_GetKeyboardState(NULL);
|
||||||
|
if (state[SDL_SCANCODE_UP])
|
||||||
|
{
|
||||||
|
player_move(data->player1, dt, PLAYER_MOVE_DOWN);
|
||||||
|
}
|
||||||
|
else if (state[SDL_SCANCODE_DOWN])
|
||||||
|
{
|
||||||
|
player_move(data->player1, dt, PLAYER_MOVE_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void game_update(struct game_data* data, float dt)
|
||||||
|
{
|
||||||
|
// Check and act on events
|
||||||
|
check_events(data, dt);
|
||||||
|
|
||||||
|
// Update the AI
|
||||||
|
pong_ai_update(data, data->player2, dt);
|
||||||
|
|
||||||
|
// Update all players and the ball
|
||||||
|
player_update(data, data->player1, dt);
|
||||||
|
player_update(data, data->player2, dt);
|
||||||
|
ball_update(data, data->ball, dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void game_loop(struct game_data* data)
|
||||||
|
{
|
||||||
|
printf("Starting game loop\n");
|
||||||
|
|
||||||
|
float dt = 0;
|
||||||
|
while (data->is_running)
|
||||||
|
{
|
||||||
|
unsigned long long start = SDL_GetPerformanceCounter();
|
||||||
|
|
||||||
|
// Update the game and render
|
||||||
|
game_update(data, dt);
|
||||||
|
render(data);
|
||||||
|
|
||||||
|
// Calculate the frame time
|
||||||
|
unsigned long long end = SDL_GetPerformanceCounter();
|
||||||
|
dt = (end - start) / (float)SDL_GetPerformanceFrequency();
|
||||||
|
|
||||||
|
// Keep the framrate at 60 Fps
|
||||||
|
long long delay = 16.666f - (dt * 1000.0f);
|
||||||
|
if (delay > 0)
|
||||||
|
SDL_Delay(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Goodbye\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void game_start(int window_width, int window_height)
|
||||||
|
{
|
||||||
|
printf("Starting game\n");
|
||||||
|
|
||||||
|
// Create a structure to hold all the information about the game
|
||||||
|
struct game_data* data = malloc(sizeof(struct game_data));
|
||||||
|
memset(data, 0, sizeof(struct game_data));
|
||||||
|
|
||||||
|
// Fill the game data structure with the correct values
|
||||||
|
data->is_running = 1;
|
||||||
|
data->window_width = window_width;
|
||||||
|
data->window_height = window_height;
|
||||||
|
|
||||||
|
// Initialize SDL2
|
||||||
|
data->render_data = render_init(window_width, window_height);
|
||||||
|
|
||||||
|
// Create the players and the ball
|
||||||
|
data->player1 = player_init(15, window_height, PLAYER_SPEED);
|
||||||
|
data->player2 = player_init(window_width - PLAYER_WIDTH - 15, window_height,
|
||||||
|
PLAYER_SPEED);
|
||||||
|
data->ball =
|
||||||
|
ball_init(window_width / 2 - BALL_WIDTH,
|
||||||
|
window_height / 2 - BALL_WIDTH, BALL_WIDTH, BALL_SPEED);
|
||||||
|
|
||||||
|
game_loop(data);
|
||||||
|
}
|
40
src/main.c
Normal file
40
src/main.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <game.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
int window_width = 500;
|
||||||
|
int window_height = 500;
|
||||||
|
|
||||||
|
const char* help =
|
||||||
|
" -w <width> Set the width of the window, default 500\n"
|
||||||
|
" -h <height> Set the height of the window, default 500\n";
|
||||||
|
|
||||||
|
int opt;
|
||||||
|
while ((opt = getopt(argc, argv, "w:h:")) != -1)
|
||||||
|
{
|
||||||
|
switch (opt)
|
||||||
|
{
|
||||||
|
case 'w':
|
||||||
|
/* Set the window width */
|
||||||
|
window_width = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
/* Set the window height */
|
||||||
|
window_height = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown argument '%s'\n%s", argv[optind], help);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
game_start(window_width, window_height);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
42
src/player.c
Normal file
42
src/player.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <game.h>
|
||||||
|
#include <player.h>
|
||||||
|
|
||||||
|
void player_move(struct player* player, float dt, enum player_move_dir dir)
|
||||||
|
{
|
||||||
|
if (dir == PLAYER_MOVE_DOWN)
|
||||||
|
{
|
||||||
|
player->y_location -= (int)(player->speed * dt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->y_location += (int)(player->speed * dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void player_update(struct game_data* game, struct player* player, float dt)
|
||||||
|
{
|
||||||
|
// Constrain the players location
|
||||||
|
if (player->y_location < 0)
|
||||||
|
{
|
||||||
|
player->y_location = 0;
|
||||||
|
}
|
||||||
|
else if (player->y_location + PLAYER_HEIGHT > game->window_height)
|
||||||
|
{
|
||||||
|
player->y_location = game->window_height - PLAYER_HEIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct player* player_init(int x_location, int move_limit, int speed)
|
||||||
|
{
|
||||||
|
struct player* player = malloc(sizeof(struct player));
|
||||||
|
memset(player, 0, sizeof(struct player));
|
||||||
|
|
||||||
|
player->x_location = x_location;
|
||||||
|
player->y_location = (move_limit - PLAYER_HEIGHT) / 2;
|
||||||
|
player->speed = speed;
|
||||||
|
|
||||||
|
return player;
|
||||||
|
}
|
16
src/pong_ai.c
Normal file
16
src/pong_ai.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include <ball.h>
|
||||||
|
#include <game.h>
|
||||||
|
#include <player.h>
|
||||||
|
|
||||||
|
void pong_ai_update(struct game_data* game, struct player* player, float dt)
|
||||||
|
{
|
||||||
|
int distance = game->ball->y_location - (player->y_location + PLAYER_HEIGHT / 2);
|
||||||
|
if (distance < -1)
|
||||||
|
{
|
||||||
|
player_move(player, dt, PLAYER_MOVE_DOWN);
|
||||||
|
}
|
||||||
|
else if (distance > 1)
|
||||||
|
{
|
||||||
|
player_move(player, dt, PLAYER_MOVE_UP);
|
||||||
|
}
|
||||||
|
}
|
70
src/render.c
Normal file
70
src/render.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <ball.h>
|
||||||
|
#include <game.h>
|
||||||
|
#include <player.h>
|
||||||
|
|
||||||
|
struct render_data
|
||||||
|
{
|
||||||
|
SDL_Renderer* renderer;
|
||||||
|
SDL_Window* window;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct render_data* render_init(int width, int height)
|
||||||
|
{
|
||||||
|
// Initialize SDL2
|
||||||
|
struct render_data* data = malloc(sizeof(struct render_data));
|
||||||
|
memset(data, 0, sizeof(struct render_data));
|
||||||
|
|
||||||
|
printf("Start initializing SDL2\n");
|
||||||
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
||||||
|
fprintf(stderr, "Could not initialize SDL2: '%s'\n", SDL_GetError());
|
||||||
|
|
||||||
|
data->window =
|
||||||
|
SDL_CreateWindow("Pong", 50, 50, width, height, SDL_WINDOW_SHOWN);
|
||||||
|
if (!data->window)
|
||||||
|
fprintf(stderr, "Could not create window: '%s'\n", SDL_GetError());
|
||||||
|
|
||||||
|
data->renderer =
|
||||||
|
SDL_CreateRenderer(data->window, -1, SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
|
||||||
|
printf("Finished initializing SDL2\n");
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void player_render(struct player* player, struct render_data* data)
|
||||||
|
{
|
||||||
|
SDL_Rect rect;
|
||||||
|
rect.x = player->x_location;
|
||||||
|
rect.y = player->y_location;
|
||||||
|
rect.w = PLAYER_WIDTH;
|
||||||
|
rect.h = PLAYER_HEIGHT;
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(data->renderer, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
|
SDL_RenderDrawRect(data->renderer, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ball_render(struct ball* ball, struct render_data* data)
|
||||||
|
{
|
||||||
|
SDL_Rect rect;
|
||||||
|
rect.x = ball->x_location;
|
||||||
|
rect.y = ball->y_location;
|
||||||
|
rect.w = ball->width;
|
||||||
|
rect.h = ball->width;
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(data->renderer, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
|
SDL_RenderDrawRect(data->renderer, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(struct game_data* game)
|
||||||
|
{
|
||||||
|
// Clear the screen of the game
|
||||||
|
SDL_SetRenderDrawColor(game->render_data->renderer, 0, 0, 0, 0xFF);
|
||||||
|
SDL_RenderClear(game->render_data->renderer);
|
||||||
|
|
||||||
|
player_render(game->player1, game->render_data);
|
||||||
|
player_render(game->player2, game->render_data);
|
||||||
|
ball_render(game->ball, game->render_data);
|
||||||
|
|
||||||
|
// Show the newly rendered screen
|
||||||
|
SDL_RenderPresent(game->render_data->renderer);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user