Skip to content

Commit

Permalink
A playable tech demo! No powerups but as souls are collected, orb upg…
Browse files Browse the repository at this point in the history
…rades massively. At the end, the black-hole-orb consumes the world and it's really cool.
  • Loading branch information
harrand committed Sep 9, 2018
1 parent a3adf01 commit 654a702
Show file tree
Hide file tree
Showing 23 changed files with 356 additions and 79 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ include_directories(RedNightmare ${PROJECT_SOURCE_DIR}/src)
link_directories(${PROJECT_SOURCE_DIR}/lib)

add_executable(RedNightmare
src/main.cpp src/player.cpp src/player.hpp src/sprite_collection.cpp src/sprite_collection.hpp src/entity_manager.cpp src/entity_manager.hpp src/audio_manager.cpp src/audio_manager.hpp src/game_sprite.cpp src/game_sprite.hpp src/entity.cpp src/entity.hpp src/ghost.cpp src/ghost.hpp src/cursor.cpp src/cursor.hpp src/fireball.cpp src/fireball.hpp)
src/main.cpp src/player.cpp src/player.hpp src/sprite_collection.cpp src/sprite_collection.hpp src/entity_manager.cpp src/entity_manager.hpp src/audio_manager.cpp src/audio_manager.hpp src/game_sprite.cpp src/game_sprite.hpp src/entity.cpp src/entity.hpp src/enemies/ghost.cpp src/enemies/ghost.hpp src/cursor.cpp src/cursor.hpp src/orbs/fireball.cpp src/orbs/fireball.hpp src/orbs/frostball.cpp src/orbs/frostball.hpp src/orbs/blackball.cpp src/orbs/blackball.hpp)
target_link_libraries(RedNightmare OpenGL32 SDL2 SDL2_ttf topaz)
Binary file added res/textures/missile_black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file added res/textures/missile_frost.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/textures/powerups/missile_growth.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void Cursor::update(EntityManager& manager, float delta_time)
{
this->position_screenspace = manager.get_mouse_listener().get_mouse_position();
Player* closest = this->get_closest_player(manager);
if(manager.get_mouse_listener().is_left_clicked() && closest != nullptr && !closest->is_moving())
if(manager.get_mouse_listener().is_left_clicked() && closest != nullptr && (!closest->is_moving() || closest->net_force().length() > 0.0f) && manager.has_any_alive_player())
{
this->set_texture(&manager.get_sprite_collection().get_on_rune());
this->active = true;
Expand All @@ -26,7 +26,7 @@ void Cursor::update(EntityManager& manager, float delta_time)
}
for(Ghost* ghost : manager.get_ghosts())
{
if(ghost->get_boundary().has_value() && ghost->get_boundary().value().intersects({this->position_screenspace, 0.0f}) && this->is_activated() && !ghost->is_dead())
if(ghost->get_boundary().has_value() && ghost->get_boundary().value().intersects({this->position_screenspace, 0.0f}) && this->is_activated() && !ghost->is_dead() && manager.has_any_alive_player())
{
ghost->set_kinematic(true);
this->held_entities.emplace(ghost, ghost->position_screenspace - this->position_screenspace);
Expand Down
22 changes: 16 additions & 6 deletions src/ghost.cpp → src/enemies/ghost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,24 @@ Ghost::Ghost(Vector2F position, float rotation, Vector2F scale, const Texture* g

void Ghost::update(EntityManager& manager, float delta_time)
{
if(this->is_dead())
{
this->velocity = {};
return;
}
Player* closest = this->get_closest_player(manager);
if(closest != nullptr)
{
this->set_target(closest->position_screenspace);
if(this->get_boundary().value().intersects(Vector3F{closest->position_screenspace, 0.0f}))
{
if(this->is_dead())
{
closest->add_health(manager, 10);
closest->add_souls(1);
manager.remove_sprite(*this);
}
else
closest->remove_health(manager, 1);
}
}
if(this->is_dead())
return;
if(this->velocity.x > 0.0f)
this->set_animation(&manager.get_sprite_collection().get_ghost_right());
else if(this->velocity.x < 0.0f)
Expand All @@ -31,6 +41,6 @@ void Ghost::update(EntityManager& manager, float delta_time)

void Ghost::on_death(EntityManager& manager)
{
std::cout << "owie owie ouchies! you killed me!\n";
this->set_texture(&manager.get_sprite_collection().get_ghost_dead());
this->velocity = {};
}
2 changes: 1 addition & 1 deletion src/ghost.hpp → src/enemies/ghost.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Ghost : public Entity
Ghost(Vector2F position, float rotation, Vector2F scale, const Texture* ghost_texture);
virtual void update(EntityManager& manager, float delta_time) override;
virtual void on_death(EntityManager& manager) override;
static constexpr unsigned int default_health = 1;
static constexpr unsigned int default_health = 5;
static constexpr float default_speed = 50.0f;
};

Expand Down
14 changes: 12 additions & 2 deletions src/entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "player.hpp"
#include "entity_manager.hpp"

Entity::Entity(Vector2F position, float rotation, Vector2F scale, const Texture* texture) : GameSprite(position, rotation, scale, texture), health(Entity::default_health), target(std::nullopt), kinematic(false){}
Entity::Entity(Vector2F position, float rotation, Vector2F scale, const Texture* texture, unsigned int health, float speed) : GameSprite(position, rotation, scale, texture), health(health), speed(speed), target(std::nullopt), kinematic(false){}

Vector2F Entity::forward() const
{
Expand All @@ -17,7 +17,7 @@ void Entity::update([[maybe_unused]] EntityManager& manager, float delta_time)
if(!this->is_kinematic())
{
if(this->has_target())
this->velocity = {(*this->get_target() - this->position_screenspace).normalised() * Entity::default_speed, 0.0f};
this->velocity = {(*this->get_target() - this->position_screenspace).normalised() * this->speed, 0.0f};
}
else
this->velocity = {};
Expand Down Expand Up @@ -66,6 +66,16 @@ void Entity::remove_health(EntityManager& manager, unsigned int health)
this->health -= health;
}

float Entity::get_speed() const
{
return this->speed;
}

void Entity::set_speed(float speed)
{
this->speed = speed;
}

const Vector2F* Entity::get_target() const
{
if(this->has_target())
Expand Down
5 changes: 4 additions & 1 deletion src/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class EntityManager;
class Entity : public GameSprite
{
public:
Entity(Vector2F position, float rotation, Vector2F scale, const Texture* texture);
Entity(Vector2F position, float rotation, Vector2F scale, const Texture* texture, unsigned int health = Entity::default_health, float speed = Entity::default_speed);
virtual void update(EntityManager& manager, float delta_time);
virtual void on_death([[maybe_unused]] EntityManager& manager){}
Vector2F forward() const;
Expand All @@ -23,6 +23,8 @@ class Entity : public GameSprite
void set_health(EntityManager& manager, unsigned int health);
void add_health(EntityManager& manager, unsigned int health);
void remove_health(EntityManager& manager, unsigned int health);
float get_speed() const;
void set_speed(float speed);
const Vector2F* get_target() const;
bool has_target() const;
void set_target(Vector2F target);
Expand All @@ -34,6 +36,7 @@ class Entity : public GameSprite
protected:
Player* get_closest_player(EntityManager& manager);
unsigned int health;
float speed;
std::optional<Vector2F> target;
bool kinematic;
};
Expand Down
120 changes: 87 additions & 33 deletions src/entity_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
#include "entity_manager.hpp"

EntityManager::EntityManager(Window& wnd): Scene(), key_listener(wnd), mouse_listener(wnd), sprite_collection(), quad(tz::util::gui::gui_quad()), screen_wrapping_bounds(std::nullopt){}
EntityManager::EntityManager(Window& wnd): Scene(), window(wnd), default_font("../res/fonts/comfortaa.ttf", 24), key_listener(wnd), mouse_listener(wnd), sprite_collection(), quad(tz::util::gui::gui_quad()), screen_wrapping_bounds(std::nullopt){}

const Window& EntityManager::get_window() const
{
return this->window;
}

const Font& EntityManager::get_default_font() const
{
return this->default_font;
}

bool EntityManager::has_player() const
{
bool contains = false;
for(const auto& sprite_ptr : this->heap_sprites)
if(dynamic_cast<Player*>(sprite_ptr.get()) != nullptr)
contains = true;
return contains;
return !this->get_players().empty();
}

bool EntityManager::has_any_alive_player() const
{
for(const Player* player : this->get_players())
if(!player->is_dead())
return true;
return false;
}

Cursor& EntityManager::spawn_cursor()
Expand All @@ -21,6 +35,16 @@ Fireball& EntityManager::spawn_fireball(Vector2F position, float rotation, Vecto
return this->emplace<Fireball>(position, rotation, scale, &this->sprite_collection.get_fireball());
}

Frostball& EntityManager::spawn_frostball(Vector2F position, float rotation, Vector2F scale)
{
return this->emplace<Frostball>(position, rotation, scale, &this->sprite_collection.get_frostball());
}

Blackball& EntityManager::spawn_blackball(Vector2F position, float rotation, Vector2F scale)
{
return this->emplace<Blackball>(position, rotation, scale, &this->sprite_collection.get_blackball());
}

Player& EntityManager::spawn_player(Vector2F position, float rotation, Vector2F scale)
{
return this->emplace<Player>(position, rotation, scale, &this->sprite_collection.get_player_idle());
Expand Down Expand Up @@ -74,33 +98,6 @@ SpriteCollection& EntityManager::get_sprite_collection()
return this->sprite_collection;
}

void EntityManager::handle_screen_wrapping()
{
if(!this->screen_wrapping_enabled())
return;
auto wrap_bounds = this->screen_wrapping_bounds.value();
for(Sprite& sprite : this->get_mutable_sprites())
{
auto& position = sprite.position_screenspace;
if(position.x < 0)
{
position.x = wrap_bounds.x;
}
else if(position.x > wrap_bounds.x)
{
position.x = 0;
}
if(position.y < 0)
{
position.y = wrap_bounds.y;
}
else if(position.y > wrap_bounds.y)
{
position.y = 0;
}
}
}

std::vector<Entity*> EntityManager::get_entities()
{
std::vector<Entity*> entities;
Expand All @@ -119,6 +116,24 @@ std::vector<Entity*> EntityManager::get_entities()
return entities;
}

std::vector<const Entity*> EntityManager::get_entities() const
{
std::vector<const Entity*> entities;
for(auto& sprite_ptr : this->heap_sprites)
{
const Entity* entity_component = dynamic_cast<const Entity*>(sprite_ptr.get());
if(entity_component != nullptr)
entities.push_back(entity_component);
}
for(const Sprite& sprite : this->stack_sprites)
{
const Entity* entity_component = dynamic_cast<const Entity*>(&sprite);
if(entity_component != nullptr)
entities.push_back(entity_component);
}
return entities;
}

std::vector<Player*> EntityManager::get_players()
{
std::vector<Player*> players;
Expand All @@ -131,6 +146,18 @@ std::vector<Player*> EntityManager::get_players()
return players;
}

std::vector<const Player*> EntityManager::get_players() const
{
std::vector<const Player*> players;
for(const Entity* entity : this->get_entities())
{
const Player* player_component = dynamic_cast<const Player*>(entity);
if(player_component != nullptr)
players.push_back(player_component);
}
return players;
}

std::vector<Ghost*> EntityManager::get_ghosts()
{
std::vector<Ghost*> ghosts;
Expand All @@ -141,4 +168,31 @@ std::vector<Ghost*> EntityManager::get_ghosts()
ghosts.push_back(ghost_component);
}
return ghosts;
}

void EntityManager::handle_screen_wrapping()
{
if(!this->screen_wrapping_enabled())
return;
auto wrap_bounds = this->screen_wrapping_bounds.value();
for(Sprite& sprite : this->get_mutable_sprites())
{
auto& position = sprite.position_screenspace;
if(position.x < 0)
{
position.x = wrap_bounds.x;
}
else if(position.x > wrap_bounds.x)
{
position.x = 0;
}
if(position.y < 0)
{
position.y = wrap_bounds.y;
}
else if(position.y > wrap_bounds.y)
{
position.y = 0;
}
}
}
25 changes: 17 additions & 8 deletions src/entity_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@
#include "core/scene.hpp"
#include "sprite_collection.hpp"
#include "player.hpp"
#include "ghost.hpp"
#include "enemies/ghost.hpp"
#include "cursor.hpp"
#include "fireball.hpp"
#include "orbs/fireball.hpp"
#include "orbs/frostball.hpp"
#include "orbs/blackball.hpp"

class EntityManager : public Scene
{
public:
EntityManager(Window& event_window);
const Window& get_window() const;
const Font& get_default_font() const;
bool has_player() const;
bool has_any_alive_player() const;
Cursor& spawn_cursor();
Fireball& spawn_fireball(Vector2F position, float rotation, Vector2F scale);
Frostball& spawn_frostball(Vector2F position, float rotation, Vector2F scale);
Blackball& spawn_blackball(Vector2F position, float rotation, Vector2F scale);
Player& spawn_player(Vector2F position, float rotation, Vector2F scale);
Ghost& spawn_ghost(Vector2F position, float rotation, Vector2F scale);
virtual void update(float delta) override;
Expand All @@ -25,15 +32,17 @@ class EntityManager : public Scene
void enable_screen_wrapping(Vector2I bounds);
void disable_screen_wrapping();
SpriteCollection& get_sprite_collection();

friend class Entity;
friend class Cursor;
friend class Fireball;
protected:
void handle_screen_wrapping();
std::vector<Entity*> get_entities();
std::vector<const Entity*> get_entities() const;
std::vector<Player*> get_players();
std::vector<const Player*> get_players() const;
std::vector<Ghost*> get_ghosts();

friend class Player;
protected:
void handle_screen_wrapping();
Window& window;
Font default_font;
KeyListener key_listener;
MouseListener mouse_listener;
SpriteCollection sprite_collection;
Expand Down
Loading

0 comments on commit 654a702

Please sign in to comment.