Skip to content

Commit

Permalink
Add RPG character controller
Browse files Browse the repository at this point in the history
  • Loading branch information
zyperpl committed Dec 18, 2023
1 parent b209c78 commit 630b20c
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 67 deletions.
Binary file added resources/character.aseprite
Binary file not shown.
Binary file added resources/station.aseprite
Binary file not shown.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ADD_EXECUTABLE(${PROJECT_NAME}
particle.cpp
pickable.cpp
player.cpp
player_character.cpp
player_ship.cpp
render_pass.cpp
resource.cpp
Expand Down
6 changes: 3 additions & 3 deletions src/asteroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ bool Asteroid::update()
{
life--;

if (life <= 0)
die();

for (int i = 0; i < 20; i++)
GAME.particles->push(create_asteroid_particle(position, 100));

Expand All @@ -78,7 +75,10 @@ bool Asteroid::update()
mask.position = position;

if (life <= 0)
{
die();
return false;
}

return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/asteroid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class Asteroid
[[nodiscard]] static Asteroid create(const Vector2 &position, uint8_t size);

bool update();
void die();

void draw() const noexcept;

private:
Asteroid() = default;
void die();

DECLARE_FRIEND_OBJECT_CIRCULAR_BUFFER()
};
206 changes: 148 additions & 58 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "object_circular_buffer.hpp"
#include "particle.hpp"
#include "pickable.hpp"
#include "player_character.hpp"
#include "player_ship.hpp"
#include "utils.hpp"

Expand All @@ -22,60 +23,89 @@ Game &Game::get() noexcept

void Game::init()
{
player = std::make_unique<PlayerShip>();
bullets = std::make_unique<ObjectCircularBuffer<Bullet, 128>>();
asteroids = std::make_unique<ObjectCircularBuffer<Asteroid, 1024>>();
particles = std::make_unique<ObjectCircularBuffer<Particle, 4096>>();
pickables = std::make_unique<ObjectCircularBuffer<Pickable, 1024>>();

SetTraceLogLevel(LOG_TRACE);

set_state(GameState::PLAYING_ASTEROIDS);

TraceLog(LOG_TRACE, "Size of Asteroid buffer: %zukB", sizeof(Asteroid) * asteroids->capacity / 1024);
TraceLog(LOG_TRACE, "Size of Bullet buffer: %zukB", sizeof(Bullet) * bullets->capacity / 1024);
TraceLog(LOG_TRACE, "Size of Particle buffer: %zukB", sizeof(Particle) * particles->capacity / 1024);
TraceLog(LOG_TRACE, "Size of Pickable buffer: %zukB", sizeof(Pickable) * pickables->capacity / 1024);

for (size_t i = 0; i < NUMBER_OF_ASTEROIDS; i++)
for (size_t i = 0; i < stars.size(); i++)
{
const Vector2 position = { static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
asteroids->push(Asteroid::create(position, 2));
stars[i] = Vector2{ static_cast<float>(GetRandomValue(0, width)), static_cast<float>(GetRandomValue(0, height)) };
}
}

for (size_t i = 0; i < 10; i++)
void Game::update()
{
if (state == GameState::PLAYING_ASTEROIDS)
{
Vector2 particle_position{ static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
Vector2 particle_velocity{ static_cast<float>(GetRandomValue(-100, 100)) / 100.0f,
static_cast<float>(GetRandomValue(-100, 100)) / 100.0f };
Color particle_color{ static_cast<unsigned char>(GetRandomValue(0, 255)),
static_cast<unsigned char>(GetRandomValue(0, 255)),
static_cast<unsigned char>(GetRandomValue(0, 255)),
static_cast<unsigned char>(GetRandomValue(0, 255)) };
particles->push(Particle::create(particle_position, particle_velocity, particle_color));
}
player->update();
bullets->for_each(std::bind(&Bullet::update, std::placeholders::_1));
asteroids->for_each(std::bind(&Asteroid::update, std::placeholders::_1));
particles->for_each(std::bind(&Particle::update, std::placeholders::_1));
pickables->for_each(std::bind(&Pickable::update, std::placeholders::_1));

for (size_t i = 0; i < 2; i++)
{
const Vector2 position = { static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
pickables->push(Pickable::create_ore(position, Vector2Zero()));
update_background();

if (!station)
{
if (asteroids->empty())
{
station = std::make_unique<Pickable>(Pickable::create(Vector2{ width / 2.0f, height / 2.0f },
Vector2{ 0.0f, 0.0f },
[&]() { set_state(GameState::PLAYING_STATION); }));
station->sprite = Sprite{ "resources/station.aseprite" };
station->sprite.scale = Vector2{ 0.1f, 0.1f };
}
}
else
{
station->update();
station->position = Vector2{ width / 2.0f, height / 2.0f + sin(frame * 0.001f) * 10.0f };
station->velocity = Vector2{ 0.0f, 0.0f };
if (station->sprite.scale.x < 1.0f)
{
station->sprite.scale.x += 0.01f;
station->sprite.scale.y += 0.01f;
}
}

#if defined(DEBUG)

if (IsKeyDown(KEY_LEFT_SHIFT))
{
if (IsKeyPressed(KEY_F1))
{
for (size_t i = 0; i < NUMBER_OF_ASTEROIDS; i++)
{
const Vector2 position = { static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
asteroids->push(Asteroid::create(position, 2));
}
}

if (IsKeyPressed(KEY_F2))
{
asteroids->for_each([](Asteroid &asteroid) { asteroid.life = 0; });
}
}

#endif
}

for (size_t i = 0; i < stars.size(); i++)
if (state == GameState::PLAYING_STATION)
{
stars[i] = Vector2{ static_cast<float>(GetRandomValue(0, width)), static_cast<float>(GetRandomValue(0, height)) };
player->update();
}

frame++;
}

void Game::update()
void Game::update_background() noexcept
{
player->update();
bullets->for_each(std::bind(&Bullet::update, std::placeholders::_1));
asteroids->for_each(std::bind(&Asteroid::update, std::placeholders::_1));
particles->for_each(std::bind(&Particle::update, std::placeholders::_1));
pickables->for_each(std::bind(&Pickable::update, std::placeholders::_1));

for (size_t i = 0; i < stars.size(); i++)
{
stars[i].x += 0.1f;
Expand All @@ -88,36 +118,41 @@ void Game::update()
stars[i].y = static_cast<float>(GetRandomValue(0, height));
}
}
}

#if defined(DEBUG)
void Game::draw() noexcept
{
draw_background();

if (IsKeyDown(KEY_LEFT_SHIFT))
switch (state)
{
if (IsKeyPressed(KEY_F1))
case GameState::PLAYING_ASTEROIDS:
{
for (size_t i = 0; i < NUMBER_OF_ASTEROIDS; i++)
if (station)
{
const Vector2 position = { static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
asteroids->push(Asteroid::create(position, 2));
station->sprite.position = station->position;
station->sprite.tint = ColorBrightness(BLACK, 0.7f);
station->draw();
}
}
}

#endif
particles->for_each(std::bind(&Particle::draw, std::placeholders::_1));

frame++;
}

void Game::draw() noexcept
{
draw_background();
particles->for_each(std::bind(&Particle::draw, std::placeholders::_1));

bullets->for_each(std::bind(&Bullet::draw, std::placeholders::_1));
player->draw();
asteroids->for_each(std::bind(&Asteroid::draw, std::placeholders::_1));
pickables->for_each(std::bind(&Pickable::draw, std::placeholders::_1));
bullets->for_each(std::bind(&Bullet::draw, std::placeholders::_1));
player->draw();
asteroids->for_each(std::bind(&Asteroid::draw, std::placeholders::_1));
pickables->for_each(std::bind(&Pickable::draw, std::placeholders::_1));
}
case GameState::PLAYING_STATION:
{
player->draw();
}
case GameState::PLAYING_PAUSED:
break;
case GameState::GAME_OVER:
break;
case GameState::MENU:
break;
}
}

void Game::draw_background() noexcept
Expand All @@ -131,7 +166,7 @@ void Game::draw_background() noexcept
DrawPixel(star.x, star.y, Color{ 120, 230, 100, 255 });
}

auto asteroid_sprite = Sprite{ "resources/asteroid.aseprite" };
static auto asteroid_sprite = Sprite{ "resources/asteroid.aseprite" };
asteroid_sprite.set_frame(1);
asteroid_sprite.tint = ColorBrightness(BLACK, 0.2f);
const long &w = static_cast<long>(asteroid_sprite.get_width());
Expand All @@ -152,3 +187,58 @@ void Game::draw_background() noexcept
}
}
}

void Game::set_state(GameState new_state) noexcept
{
state = new_state;

bullets.reset();
asteroids.reset();
particles.reset();
pickables.reset();

switch (state)
{
case GameState::PLAYING_ASTEROIDS:
player = std::make_unique<PlayerShip>();
bullets = std::make_unique<ObjectCircularBuffer<Bullet, 128>>();
asteroids = std::make_unique<ObjectCircularBuffer<Asteroid, 1024>>();
particles = std::make_unique<ObjectCircularBuffer<Particle, 4096>>();
pickables = std::make_unique<ObjectCircularBuffer<Pickable, 1024>>();

for (size_t i = 0; i < NUMBER_OF_ASTEROIDS; i++)
{
const Vector2 position = { static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
asteroids->push(Asteroid::create(position, 2));
}

for (size_t i = 0; i < 10; i++)
{
Vector2 particle_position{ static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
Vector2 particle_velocity{ static_cast<float>(GetRandomValue(-100, 100)) / 100.0f,
static_cast<float>(GetRandomValue(-100, 100)) / 100.0f };
Color particle_color{ static_cast<unsigned char>(GetRandomValue(0, 255)),
static_cast<unsigned char>(GetRandomValue(0, 255)),
static_cast<unsigned char>(GetRandomValue(0, 255)),
static_cast<unsigned char>(GetRandomValue(0, 255)) };
particles->push(Particle::create(particle_position, particle_velocity, particle_color));
}

for (size_t i = 0; i < 2; i++)
{
const Vector2 position = { static_cast<float>(GetRandomValue(0, width)),
static_cast<float>(GetRandomValue(0, height)) };
pickables->push(Pickable::create_ore(position, Vector2Zero()));
}
break;
case GameState::PLAYING_STATION:
player = std::make_unique<PlayerCharacter>();
break;
case GameState::GAME_OVER:
break;
default:
break;
}
}
18 changes: 15 additions & 3 deletions src/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <raymath.h>

#define CONFIG(Option) Game::config.Option
#define GAME Game::get()
#define GAME Game::get()

class Player;
class Bullet;
Expand All @@ -26,6 +26,15 @@ struct Config
bool debug_bullets{ false };
};

enum class GameState
{
MENU,
PLAYING_PAUSED,
PLAYING_ASTEROIDS,
PLAYING_STATION,
GAME_OVER
};

class Game
{
public:
Expand All @@ -45,17 +54,20 @@ class Game
static uint64_t frame;

void init();

void update();

void draw() noexcept;

size_t coins{ 0 };
size_t score{ 0 };

GameState state { GameState::MENU };

private:
[[nodiscard]] Game() noexcept = default;

std::array<Vector2, 100> stars;
std::unique_ptr<Pickable> station;
void update_background() noexcept;
void draw_background() noexcept;
void set_state(GameState new_state) noexcept;
};
4 changes: 2 additions & 2 deletions src/pickable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ bool Pickable::update()
velocity.x += dir.x * 0.1f;
velocity.y += dir.y * 0.1f;

position.x += dir.x * 0.4f;
position.y += dir.y * 0.4f;
position.x += dir.x * 0.5f;
position.y += dir.y * 0.5f;
}

return true;
Expand Down
Loading

0 comments on commit 630b20c

Please sign in to comment.