Setup
-
Install clang :
-
Get the latest RayLib release :
-
File system :
๎ฟ . โโโ ๎ main.cpp // the main file where the game is โโโ ๎ฟ raylib // folder where I put the downloaded raylib โโโ ๓ฐบ README.md โโโ ๏ญ LICENSE โโโ ๏ CHANGELOG โโโ ๎ฟ lib โ โโโ ๎ฎ raylib.dll โ โโโ ๏ ผ libraylibdll.a โ โโโ ๏ ผ libraylib.a โโโ ๎ผ include โโโ ๎ rlgl.h โโโ ๎ raymath.h โโโ ๎ raylib.h -
Compile :
-
clang++ main.cpp -o main.exe -Lraylib/lib -lraylib -lopengl32 -lgdi32 -lwinmm-
clang++-
Invokes the Clang C++ compiler.
-
clanguses the the C compiler driver, not the C++ one, so it does not link the C++ standard library. Useclang++instead.
-
-
main.cpp-
Source file to compile.
-
-
-o main.exe-
Sets the output executable name.
-
-
-Lraylib/lib-
Adds this directory to the linkerโs search paths.
-
Clang will look here when resolving
-l...flags.
-
-
-lraylib-
Links against:
-
raylib/lib/libraylib.a(static) -
or
-
raylib/lib/libraylibdll.a(import lib for DLL)
-
-
The linker automatically resolves:
-
-lraylibโlibraylib.a
-
-
-
-lopengl32-
Windows system library, required for raylib.
-
Links OpenGL (graphics backend)
-
-
-lgdi32-
Windows system library, required for raylib.
-
Windows GDI (window/context handling pieces)
-
-
-lwinmm-
Windows system library, required for raylib.
-
Windows multimedia (timing, audio support)
-
-
-
-
Execute :
-
.\main.exe
-
Moving Ball
/*
clang++ main.cpp -o main.exe -L../raylib/lib -lraylib -lopengl32 -lgdi32 -lwinmm
*/
#include "../raylib/include/raylib.h"
int main() { // <- this is the only difference from C
constexpr int SCREEN_WIDTH = 800;
constexpr int SCREEN_HEIGHT = 450;
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Raylib in C++ | 1_moving_ball");
SetTargetFPS(60);
// Initialize ball
Vector2 ball_position = { SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0 };
while (!WindowShouldClose()) {
// Update ball position
if (IsKeyDown(KEY_RIGHT)) ball_position.x += 2.0f;
if (IsKeyDown(KEY_LEFT)) ball_position.x -= 2.0f;
if (IsKeyDown(KEY_UP)) ball_position.y -= 2.0f;
if (IsKeyDown(KEY_DOWN)) ball_position.y += 2.0f;
// Draw
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("move the ball with arrow keys", 10, 10, 20, DARKGRAY);
DrawCircleV(ball_position, 50.0, MAROON);
EndDrawing();
}
CloseWindow();
return 0;
}
Collect The Coins
/*
clang++ main.cpp -o main.exe -L../raylib/lib -lraylib -lopengl32 -lgdi32 -lwinmm
Only for C++11 or newer.
*/
#include "../raylib/include/raylib.h"
#include "../raylib/include/raymath.h"
#include <array>
constexpr int MAX_COINS = 20; // Comparing to C: Real language construction with type-checking
constexpr float PLAYER_SPEED = 4.0;
struct Player {
Vector2 position{}; // Zero-initialized by default.
float radius{};
int score{};
};
struct Coin {
Vector2 position{};
float radius{};
bool active{};
};
int main() {
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Raylib in C++ | 2_collect_the_coins");
SetTargetFPS(60);
// Initialize player
Player player{};
player.position = {400.0, 300.0};
player.radius = 20.0;
player.score = 0;
// Initialize coins
std::array<Coin, MAX_COINS> coins{};
for (auto& coin : coins) {
coin.position = {
static_cast<float>(GetRandomValue(20, SCREEN_WIDTH - 20)),
static_cast<float>(GetRandomValue(20, SCREEN_HEIGHT - 20))
};
coin.radius = 8.0;
coin.active = true;
}
while (!WindowShouldClose()) {
// Update player
if (IsKeyDown(KEY_W)) player.position.y -= PLAYER_SPEED;
if (IsKeyDown(KEY_S)) player.position.y += PLAYER_SPEED;
if (IsKeyDown(KEY_A)) player.position.x -= PLAYER_SPEED;
if (IsKeyDown(KEY_D)) player.position.x += PLAYER_SPEED;
// Check collisions
for (auto& coin : coins) {
if (coin.active) {
float dist = Vector2Distance(player.position, coin.position);
if (dist < player.radius + coin.radius) {
coin.active = false;
player.score += 1;
}
}
}
// Draw
BeginDrawing();
ClearBackground(DARKGREEN);
DrawCircleV(player.position, player.radius, BLUE);
for (const auto& coin : coins) {
if (coin.active) {
DrawCircleV(coin.position, coin.radius, GOLD);
}
}
DrawText(TextFormat("Score: %d", player.score), 10, 10, 20, WHITE);
EndDrawing();
}
CloseWindow();
return 0;
}
Space Invaders
/*
clang++ main.cpp -o main.exe -L../raylib/lib -lraylib -lopengl32 -lgdi32 -lwinmm
Only for C++11 or newer.
*/
#include "../raylib/include/raylib.h"
#include "../raylib/include/raymath.h"
#include <array>
#include <vector>
constexpr int MAX_BULLETS = 64; // Comparing to C: Real language construction with type-checking
constexpr float BULLET_SPEED = 6.0f;
struct Player {
Vector2 position{};
float radius{};
};
struct Bullet {
Vector2 position{};
Vector2 velocity{};
float radius{};
bool active{};
};
struct Enemy {
Vector2 position{};
float radius{};
bool active{};
Color color{};
};
void spawn_bullet(std::array<Bullet, MAX_BULLETS>& bullets, Vector2 pos);
void spawn_inactive_enemies(std::vector<Enemy>& enemies);
int main() {
constexpr int SCREEN_WIDTH = 800;
constexpr int SCREEN_HEIGHT = 600;
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Raylib in C++ | 3_space_invaders");
SetTargetFPS(60);
// Initialize player
Player player{{400.0f, 500.0f}, 20.0f};
std::array<Bullet, MAX_BULLETS> bullets{}; // Stack allocation
// Initialize enemies
std::vector<Enemy> enemies(20); // Heap allocation
int enemies_destroyed_count = 0;
spawn_inactive_enemies(enemies);
while (!WindowShouldClose()) {
// Update player
if (IsKeyDown(KEY_A)) player.position.x -= 4.0f;
if (IsKeyDown(KEY_D)) player.position.x += 4.0f;
if (IsKeyDown(KEY_W)) player.position.y -= 4.0f;
if (IsKeyDown(KEY_S)) player.position.y += 4.0f;
if (IsKeyPressed(KEY_SPACE)) {
spawn_bullet(bullets, player.position);
}
// Update bullets
for (auto& b : bullets) {
if (b.active) {
b.position.x += b.velocity.x;
b.position.y += b.velocity.y;
if (b.position.y < 0) {
b.active = false;
}
}
}
// Update enemies
int active_enemies = 0;
for (auto& e : enemies) {
if (e.active) {
e.position.y += 0.5f;
active_enemies += 1;
}
}
// Respawn
if (active_enemies < 5) {
spawn_inactive_enemies(enemies);
}
// Collisions
for (auto& b : bullets) {
if (!b.active) continue;
for (auto& e : enemies) {
if (!e.active) continue;
float d = Vector2Distance(b.position, e.position);
float r = b.radius + e.radius;
if (d < r) {
b.active = false;
e.active = false;
enemies_destroyed_count += 1;
}
}
}
// Draw
BeginDrawing();
ClearBackground(BLACK);
DrawCircleV(player.position, player.radius, BLUE);
for (const auto& b : bullets) {
if (b.active) {
DrawCircleV(b.position, b.radius, YELLOW);
}
}
for (const auto& e : enemies) {
if (e.active) {
DrawCircleV(e.position, e.radius, e.color);
}
}
DrawText("Space Invaders: WASD move | SPACE shoot", 10, 10, 20, WHITE);
DrawText(TextFormat("Enemies destroyed: %d", enemies_destroyed_count),
10, 40, 20, YELLOW);
EndDrawing();
}
CloseWindow();
return 0;
}
// Spawn first inactive bullet
void spawn_bullet(std::array<Bullet, MAX_BULLETS>& bullets, Vector2 pos) {
for (auto& b : bullets) {
if (!b.active) {
b.active = true;
b.position = pos;
b.velocity = {0.0f, -BULLET_SPEED};
b.radius = 5.0f;
return;
}
}
}
// Activate all inactive enemies
void spawn_inactive_enemies(std::vector<Enemy>& enemies) {
for (auto& e : enemies) {
if (!e.active) {
e.position = {
static_cast<float>(GetRandomValue(50, 750)),
static_cast<float>(GetRandomValue(50, 300))
};
e.radius = 15.0f;
e.active = true;
e.color = {
static_cast<unsigned char>(GetRandomValue(100, 255)),
static_cast<unsigned char>(GetRandomValue(100, 255)),
static_cast<unsigned char>(GetRandomValue(100, 255)),
255
};
}
}
}