Init
This commit is contained in:
commit
ac521c3129
|
@ -0,0 +1,3 @@
|
||||||
|
*.ogg
|
||||||
|
*.png
|
||||||
|
*user*
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include "application.h"
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
constexpr int SCREEN_WIDTH = 640;
|
||||||
|
constexpr int SCREEN_HEIGHT = 480;
|
||||||
|
const sf::Time TIME_PER_SECOND = sf::seconds(1.f / 60.f);
|
||||||
|
|
||||||
|
Application::Application() :
|
||||||
|
render_window({SCREEN_WIDTH, SCREEN_HEIGHT}, "Test")
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Application::registerStates()
|
||||||
|
{
|
||||||
|
map_states[State::Tag::Game] = std::make_unique<Game>(render_window, this);
|
||||||
|
|
||||||
|
active_state_tag = State::Tag::Game;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::run()
|
||||||
|
{
|
||||||
|
sf::Clock clock;
|
||||||
|
sf::Time since_last_update = sf::Time::Zero;
|
||||||
|
|
||||||
|
while (render_window.isOpen())
|
||||||
|
{
|
||||||
|
map_states[active_state_tag]->processInput();
|
||||||
|
sf::Time delta = clock.restart();
|
||||||
|
|
||||||
|
since_last_update -= TIME_PER_SECOND;
|
||||||
|
map_states[active_state_tag]->processInput();
|
||||||
|
|
||||||
|
//if (!b_pause)
|
||||||
|
map_states[active_state_tag]->update(delta);
|
||||||
|
|
||||||
|
map_states[active_state_tag]->draw();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef APPLICATION_H
|
||||||
|
#define APPLICATION_H
|
||||||
|
|
||||||
|
#include "state.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class Application
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Application();
|
||||||
|
|
||||||
|
void registerStates();
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
sf::RenderWindow render_window;
|
||||||
|
|
||||||
|
std::map<State::Tag, StateUPtr> map_states;
|
||||||
|
State::Tag active_state_tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // APPLICATION_H
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef COMMAND_H
|
||||||
|
#define COMMAND_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace Category
|
||||||
|
{
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Scene = 1 << 0,
|
||||||
|
Player = 1 << 1,
|
||||||
|
Enemy = 1 << 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class SceneNode;
|
||||||
|
namespace sf { class Time; }
|
||||||
|
|
||||||
|
struct Command
|
||||||
|
{
|
||||||
|
std::function<void(SceneNode&, sf::Time)> action;
|
||||||
|
Category::Type category;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename GameObject, typename Functon>
|
||||||
|
std::function<void(SceneNode&, const sf::Time&)> derivedAction(Functon func)
|
||||||
|
{
|
||||||
|
return [=] (SceneNode& node, const sf::Time& time)
|
||||||
|
{
|
||||||
|
//assert(dynamic_cast<GameObject*>(&node));
|
||||||
|
func(static_cast<GameObject&>(node), time);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // COMMAND_H
|
|
@ -0,0 +1,31 @@
|
||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += c++17
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
CONFIG -= qt
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
application.cpp \
|
||||||
|
entity.cpp \
|
||||||
|
enemy.cpp \
|
||||||
|
game.cpp \
|
||||||
|
main.cpp \
|
||||||
|
player.cpp \
|
||||||
|
scenenode.cpp \
|
||||||
|
spritenode.cpp \
|
||||||
|
state.cpp \
|
||||||
|
world.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
application.h \
|
||||||
|
command.h \
|
||||||
|
entity.h \
|
||||||
|
enemy.h \
|
||||||
|
game.h \
|
||||||
|
player.h \
|
||||||
|
resourceholder.h \
|
||||||
|
scenenode.h \
|
||||||
|
spritenode.h \
|
||||||
|
state.h \
|
||||||
|
world.h
|
||||||
|
|
||||||
|
unix:LIBS += -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "enemy.h"
|
||||||
|
|
||||||
|
// /////////////////////////////////////////////////////////// //
|
||||||
|
|
||||||
|
static Textures::Id toTextureID(const Enemy::Type& type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Enemy::Type::Shotguner:
|
||||||
|
return Textures::Id::Shotguner;
|
||||||
|
|
||||||
|
case Enemy::Type::Weakling:
|
||||||
|
return Textures::Id::Weakling;
|
||||||
|
|
||||||
|
case Enemy::Type::Player:
|
||||||
|
return Textures::Id::Player;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Textures::Id::Weakling;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /////////////////////////////////////////////////////////// //
|
||||||
|
|
||||||
|
Enemy::Enemy(Type type, const TextureHolder& texture_holder) :
|
||||||
|
enemy_type(type),
|
||||||
|
enemy_sprite(texture_holder.get(toTextureID(type)))
|
||||||
|
{
|
||||||
|
const sf::FloatRect bounds = enemy_sprite.getLocalBounds();
|
||||||
|
enemy_sprite.setOrigin(bounds.width / 2.f, bounds.height / 2.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Enemy::~Enemy()
|
||||||
|
{}
|
||||||
|
|
||||||
|
Enemy::Type Enemy::type() const
|
||||||
|
{
|
||||||
|
return enemy_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Category::Type Enemy::category() const
|
||||||
|
{
|
||||||
|
return Category::Type::Enemy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Enemy::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
|
||||||
|
{
|
||||||
|
target.draw(enemy_sprite, states);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef FAIRY_H
|
||||||
|
#define FAIRY_H
|
||||||
|
|
||||||
|
#include "entity.h"
|
||||||
|
#include "resourceholder.h"
|
||||||
|
|
||||||
|
#include <SFML/Graphics/Sprite.hpp>
|
||||||
|
|
||||||
|
class Enemy : public Entity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Player,
|
||||||
|
Weakling,
|
||||||
|
Shotguner
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit Enemy(Type type, const TextureHolder& texture_holder);
|
||||||
|
virtual ~Enemy() override;
|
||||||
|
|
||||||
|
Type type() const;
|
||||||
|
Category::Type category() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type enemy_type;
|
||||||
|
sf::Sprite enemy_sprite;
|
||||||
|
|
||||||
|
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
using EnemySPtr = std::shared_ptr<Enemy>;
|
||||||
|
using EnemyUPtr = std::unique_ptr<Enemy>;
|
||||||
|
|
||||||
|
#endif // FAIRY_H
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "entity.h"
|
||||||
|
|
||||||
|
Entity::Entity() :
|
||||||
|
vector_velocity(0.f, 0.f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Entity::~Entity()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Entity::setVelocity(sf::Vector2f vel)
|
||||||
|
{
|
||||||
|
vector_velocity = vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::setVelocity(float vx, float vy)
|
||||||
|
{
|
||||||
|
vector_velocity.x = vx;
|
||||||
|
vector_velocity.y = vy;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sf::Vector2f& Entity::velocity() const
|
||||||
|
{
|
||||||
|
return vector_velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::accelerate(sf::Vector2f vel)
|
||||||
|
{
|
||||||
|
vector_velocity += vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::updateCurrent(const sf::Time& dt)
|
||||||
|
{
|
||||||
|
move(vector_velocity * dt.asSeconds());
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef ENTITY_H
|
||||||
|
#define ENTITY_H
|
||||||
|
|
||||||
|
#include "scenenode.h"
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
|
||||||
|
class Entity : public SceneNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Entity();
|
||||||
|
virtual ~Entity() = 0;
|
||||||
|
|
||||||
|
void setVelocity(sf::Vector2f vel);
|
||||||
|
void setVelocity(float vx, float vy);
|
||||||
|
const sf::Vector2f& velocity() const;
|
||||||
|
void accelerate(sf::Vector2f vel);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
sf::Vector2f vector_velocity;
|
||||||
|
|
||||||
|
virtual void updateCurrent(const sf::Time& dt) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ENTITY_H
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
Game::Game(sf::RenderWindow &window, Application *application) :
|
||||||
|
State(window, application),
|
||||||
|
world(render_window)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Game::~Game()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool Game::processInput()
|
||||||
|
{
|
||||||
|
std::queue<Command>& queue = world.getCommandQueue();
|
||||||
|
|
||||||
|
sf::Event event;
|
||||||
|
while (render_window.pollEvent(event))
|
||||||
|
{
|
||||||
|
player.handleEvent(event, queue);
|
||||||
|
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case sf::Event::GainedFocus:
|
||||||
|
b_pause = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Event::LostFocus:
|
||||||
|
b_pause = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Event::Closed:
|
||||||
|
render_window.close();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.handleRealtimeInput(queue);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::update(const sf::Time &dt)
|
||||||
|
{
|
||||||
|
world.update(dt);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::draw()
|
||||||
|
{
|
||||||
|
render_window.clear();
|
||||||
|
world.draw();
|
||||||
|
render_window.setView(render_window.getDefaultView());
|
||||||
|
render_window.display();
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
|
||||||
|
#include "world.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
|
#include <SFML/Window/Keyboard.hpp>
|
||||||
|
|
||||||
|
class Game final : public State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Game(sf::RenderWindow& window, Application *application);
|
||||||
|
virtual ~Game() override;
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
World world;
|
||||||
|
Player player;
|
||||||
|
|
||||||
|
bool b_pause;
|
||||||
|
bool b_to_right, b_to_left, b_to_up, b_to_down;
|
||||||
|
|
||||||
|
bool processInput() override;
|
||||||
|
bool update(const sf::Time& dt) override;
|
||||||
|
void draw() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GAME_H
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Application app;
|
||||||
|
app.registerStates();
|
||||||
|
app.run();
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "player.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "enemy.h"
|
||||||
|
|
||||||
|
Player::Player() :
|
||||||
|
player_speed(45.f)
|
||||||
|
{
|
||||||
|
map_key_bindings[sf::Keyboard::Left] = Action::MoveLeft;
|
||||||
|
map_key_bindings[sf::Keyboard::Right] = Action::MoveRight;
|
||||||
|
map_key_bindings[sf::Keyboard::Up] = Action::MoveUp;
|
||||||
|
map_key_bindings[sf::Keyboard::Down] = Action::MoveDown;
|
||||||
|
|
||||||
|
map_action_bindings[Action::MoveLeft].action =
|
||||||
|
[&] (SceneNode& node, const sf::Time& time)
|
||||||
|
{
|
||||||
|
node.move(-player_speed * time.asSeconds(), 0.f);
|
||||||
|
};
|
||||||
|
|
||||||
|
map_action_bindings[Action::MoveRight].action =
|
||||||
|
[&] (SceneNode& node, const sf::Time& time)
|
||||||
|
{
|
||||||
|
node.move(player_speed * time.asSeconds(), 0.f);
|
||||||
|
};
|
||||||
|
|
||||||
|
map_action_bindings[Action::MoveUp].action =
|
||||||
|
[&] (SceneNode& node, const sf::Time& time)
|
||||||
|
{
|
||||||
|
node.move(0.f, -player_speed * time.asSeconds());
|
||||||
|
};
|
||||||
|
|
||||||
|
map_action_bindings[Action::MoveDown].action =
|
||||||
|
[&] (SceneNode& node, const sf::Time& time)
|
||||||
|
{
|
||||||
|
node.move(0.f, player_speed * time.asSeconds());
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& pair : map_action_bindings)
|
||||||
|
pair.second.category = Category::Enemy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::handleRealtimeInput(std::queue<Command>& queue)
|
||||||
|
{
|
||||||
|
for (const auto& pair : map_key_bindings)
|
||||||
|
if (sf::Keyboard::isKeyPressed(pair.first) && isRealtime(pair.second))
|
||||||
|
queue.push(map_action_bindings[pair.second]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::handleEvent(const sf::Event &event, std::queue<Command> &queue)
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case sf::Event::KeyPressed:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef PLAYER_H
|
||||||
|
#define PLAYER_H
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <map>
|
||||||
|
#include <SFML/Window/Event.hpp>
|
||||||
|
|
||||||
|
class Command;
|
||||||
|
|
||||||
|
class Player
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Player();
|
||||||
|
|
||||||
|
enum class Action
|
||||||
|
{
|
||||||
|
MoveLeft,
|
||||||
|
MoveRight,
|
||||||
|
MoveUp,
|
||||||
|
MoveDown
|
||||||
|
};
|
||||||
|
|
||||||
|
void assignKey(Action action, sf::Keyboard::Key key);
|
||||||
|
sf::Keyboard::Key getAssignedKey(Action action) const;
|
||||||
|
|
||||||
|
void handleEvent(const sf::Event& event, std::queue<Command>& queue);
|
||||||
|
void handleRealtimeInput(std::queue<Command>& queue);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float player_speed;
|
||||||
|
std::map<sf::Keyboard::Key, Action> map_key_bindings;
|
||||||
|
std::map<Action, Command> map_action_bindings;
|
||||||
|
|
||||||
|
static bool isRealtime(Action action) {return true;}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLAYER_H
|
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef RESOURCEHOLDER_H
|
||||||
|
#define RESOURCEHOLDER_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace sf { class Texture; class Font; }
|
||||||
|
|
||||||
|
template <typename Resource, typename Id>
|
||||||
|
class ResourceHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool load(Id id, const std::string& filename)
|
||||||
|
{
|
||||||
|
std::unique_ptr<Resource> resource(new Resource());
|
||||||
|
if (!resource->loadFromFile(filename))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
map_resources[id] = std::move(resource);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource& get(Id id) const
|
||||||
|
{
|
||||||
|
const auto found = map_resources.find(id);
|
||||||
|
assert(found != map_resources.end());
|
||||||
|
|
||||||
|
return *found->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<Id, std::unique_ptr<Resource>> map_resources;
|
||||||
|
};
|
||||||
|
|
||||||
|
// /////////////////////////////////////////////////////////// //
|
||||||
|
|
||||||
|
namespace Textures
|
||||||
|
{
|
||||||
|
enum class Id
|
||||||
|
{
|
||||||
|
Player,
|
||||||
|
Weakling,
|
||||||
|
Shotguner,
|
||||||
|
|
||||||
|
Background
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
using TextureHolder = ResourceHolder<sf::Texture, Textures::Id>;
|
||||||
|
using FontHolder = ResourceHolder<sf::Font, Textures::Id>;
|
||||||
|
|
||||||
|
#endif // RESOURCEHOLDER_H
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "scenenode.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
SceneNode::SceneNode()
|
||||||
|
{}
|
||||||
|
|
||||||
|
SceneNode::~SceneNode()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool SceneNode::attachChild(const SceneNodeSPtr &child)
|
||||||
|
{
|
||||||
|
child->parent = shared_from_this();
|
||||||
|
vec_children.emplace_back(std::move(child));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneNodeSPtr SceneNode::detachChild(const SceneNode &node)
|
||||||
|
{
|
||||||
|
const auto found = std::find_if(vec_children.begin(), vec_children.end(),
|
||||||
|
[&] (SceneNodeSPtr& p) -> bool
|
||||||
|
{
|
||||||
|
return p.get() == &node;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (found == vec_children.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
SceneNodeSPtr result = *found;
|
||||||
|
result->parent = nullptr;
|
||||||
|
vec_children.erase(found);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Transform SceneNode::getWorldTransform() const
|
||||||
|
{
|
||||||
|
sf::Transform transform = sf::Transform::Identity;
|
||||||
|
|
||||||
|
for (SceneNodeConstSPtr node = shared_from_this(); node != nullptr; node = node->parent)
|
||||||
|
{
|
||||||
|
transform *= node->getTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Vector2f SceneNode::getWorldPosition() const
|
||||||
|
{
|
||||||
|
return getWorldTransform() * sf::Vector2f();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneNode::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||||
|
{
|
||||||
|
states.transform *= getTransform();
|
||||||
|
drawCurrent(target, states);
|
||||||
|
|
||||||
|
for (const auto& ch : vec_children)
|
||||||
|
ch->draw(target, states);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneNode::update(const sf::Time& dt)
|
||||||
|
{
|
||||||
|
updateCurrent(dt);
|
||||||
|
updateChildren(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneNode::onCommand(const Command& command, const sf::Time& dt)
|
||||||
|
{
|
||||||
|
if (command.category & category())
|
||||||
|
command.action(*shared_from_this(), dt);
|
||||||
|
|
||||||
|
for (auto& ch : vec_children)
|
||||||
|
ch->onCommand(command, dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Category::Type SceneNode::category() const
|
||||||
|
{
|
||||||
|
return Category::Type::Scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
|
||||||
|
{}
|
||||||
|
|
||||||
|
void SceneNode::updateCurrent(const sf::Time& dt)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void SceneNode::updateChildren(const sf::Time &dt)
|
||||||
|
{
|
||||||
|
for (SceneNodeSPtr& child : vec_children)
|
||||||
|
child->update(dt);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef SCENENODE_H
|
||||||
|
#define SCENENODE_H
|
||||||
|
|
||||||
|
#include "command.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
class SceneNode;
|
||||||
|
using SceneNodeUPtr = std::unique_ptr<SceneNode>;
|
||||||
|
using SceneNodeSPtr = std::shared_ptr<SceneNode>;
|
||||||
|
using SceneNodeConstSPtr = std::shared_ptr<const SceneNode>;
|
||||||
|
|
||||||
|
class SceneNode : public std::enable_shared_from_this<SceneNode>,
|
||||||
|
public sf::Transformable,
|
||||||
|
public sf::Drawable,
|
||||||
|
private sf::NonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SceneNode();
|
||||||
|
virtual ~SceneNode();
|
||||||
|
|
||||||
|
bool attachChild(const SceneNodeSPtr &child);
|
||||||
|
SceneNodeSPtr detachChild(const SceneNode& node);
|
||||||
|
|
||||||
|
sf::Transform getWorldTransform() const;
|
||||||
|
sf::Vector2f getWorldPosition() const;
|
||||||
|
|
||||||
|
void update(const sf::Time& dt);
|
||||||
|
void onCommand(const Command& command, const sf::Time& dt);
|
||||||
|
|
||||||
|
virtual Category::Type category() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<SceneNodeSPtr> vec_children;
|
||||||
|
SceneNodeSPtr parent;
|
||||||
|
|
||||||
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override final;
|
||||||
|
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
virtual void updateCurrent(const sf::Time& dt);
|
||||||
|
|
||||||
|
void updateChildren(const sf::Time& dt);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCENENODE_H
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "spritenode.h"
|
||||||
|
|
||||||
|
SpriteNode::SpriteNode(const sf::Texture& texture)
|
||||||
|
{
|
||||||
|
sprite.setTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteNode::~SpriteNode()
|
||||||
|
{}
|
||||||
|
|
||||||
|
SpriteNode::SpriteNode(const sf::Texture& texture, const sf::IntRect& rect)
|
||||||
|
{
|
||||||
|
sprite.setTexture(texture);
|
||||||
|
sprite.setTextureRect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const
|
||||||
|
{
|
||||||
|
target.draw(sprite, states);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef SPRITENODE_H
|
||||||
|
#define SPRITENODE_H
|
||||||
|
|
||||||
|
#include "scenenode.h"
|
||||||
|
|
||||||
|
class SpriteNode : public SceneNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SpriteNode(const sf::Texture& texture);
|
||||||
|
explicit SpriteNode(const sf::Texture& texture,
|
||||||
|
const sf::IntRect& rect);
|
||||||
|
virtual ~SpriteNode();
|
||||||
|
|
||||||
|
private:
|
||||||
|
sf::Sprite sprite;
|
||||||
|
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
using SpriteNodeUPtr = std::unique_ptr<SpriteNode>;
|
||||||
|
using SpriteNodeSPtr = std::shared_ptr<SpriteNode>;
|
||||||
|
|
||||||
|
#endif // SPRITENODE_H
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
|
State::State(sf::RenderWindow &window, Application *application) :
|
||||||
|
render_window(window),
|
||||||
|
app(application)
|
||||||
|
{}
|
||||||
|
|
||||||
|
State::~State()
|
||||||
|
{}
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef STATE_H
|
||||||
|
#define STATE_H
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
|
#include <SFML/Window/Event.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Application;
|
||||||
|
|
||||||
|
class State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit State(sf::RenderWindow& window, Application *application);
|
||||||
|
virtual ~State() = 0;
|
||||||
|
|
||||||
|
virtual void draw() = 0;
|
||||||
|
virtual bool update(const sf::Time& dt) = 0;
|
||||||
|
virtual bool processInput() = 0;
|
||||||
|
|
||||||
|
enum class Tag
|
||||||
|
{
|
||||||
|
Menu,
|
||||||
|
Game
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
sf::RenderWindow& render_window;
|
||||||
|
Application *app;
|
||||||
|
};
|
||||||
|
|
||||||
|
using StateUPtr = std::unique_ptr<State>;
|
||||||
|
using StateSPtr = std::shared_ptr<State>;
|
||||||
|
|
||||||
|
#endif // STATE_H
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include "world.h"
|
||||||
|
#include "spritenode.h"
|
||||||
|
#include "enemy.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
World::World(sf::RenderWindow& window) :
|
||||||
|
world_window(window),
|
||||||
|
world_view(window.getDefaultView()),
|
||||||
|
scene_graph(new SceneNode()),
|
||||||
|
world_bounds(0.f, 0.f, world_view.getSize().x, 2000.f),
|
||||||
|
world_spawn_pos(world_view.getSize().x / 2.f, world_bounds.height - world_view.getSize().y),
|
||||||
|
player(nullptr)
|
||||||
|
{
|
||||||
|
loadTextures();
|
||||||
|
buildScene();
|
||||||
|
|
||||||
|
world_view.setCenter(world_spawn_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::update(const sf::Time &dt)
|
||||||
|
{
|
||||||
|
world_view.move(0.f, world_speed * dt.asSeconds());
|
||||||
|
player->setVelocity(0.f, 0.f);
|
||||||
|
|
||||||
|
while (!queue_commands.empty())
|
||||||
|
{
|
||||||
|
scene_graph->onCommand(queue_commands.front(), dt);
|
||||||
|
queue_commands.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
//sf::Vector2f position = player->getPosition();
|
||||||
|
sf::Vector2f velocity = player->velocity();
|
||||||
|
|
||||||
|
if (velocity.x != 0.f && velocity.y != 0.f)
|
||||||
|
player->setVelocity(velocity / std::sqrt(2.f));
|
||||||
|
|
||||||
|
player->accelerate({0.f, world_speed});
|
||||||
|
|
||||||
|
scene_graph->update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::draw()
|
||||||
|
{
|
||||||
|
world_window.setView(world_view);
|
||||||
|
world_window.draw(*scene_graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::queue<Command>& World::getCommandQueue()
|
||||||
|
{
|
||||||
|
return queue_commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool World::loadTextures()
|
||||||
|
{
|
||||||
|
return /*texture_holder.load(Textures::Id::Weakling, "sprite_weakling.png")
|
||||||
|
&& texture_holder.load(Textures::Id::Shotguner, "sprite_shotguner.png")
|
||||||
|
&& */texture_holder.load(Textures::Id::Background, "sprite_back.png")
|
||||||
|
&& texture_holder.load(Textures::Id::Player, "sprite.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::buildScene()
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < LayerCount; ++i)
|
||||||
|
{
|
||||||
|
SceneNodeSPtr layer(new SceneNode());
|
||||||
|
arr_layers[i] = layer;
|
||||||
|
|
||||||
|
scene_graph->attachChild(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::Texture texture = texture_holder.get(Textures::Id::Background);
|
||||||
|
sf::IntRect texture_rect(world_bounds);
|
||||||
|
texture.setRepeated(true);
|
||||||
|
|
||||||
|
SpriteNodeSPtr background_sprite(new SpriteNode(texture, texture_rect));
|
||||||
|
background_sprite->setPosition(world_bounds.left, world_bounds.top);
|
||||||
|
|
||||||
|
arr_layers[Background]->attachChild(background_sprite);
|
||||||
|
|
||||||
|
player = std::make_shared<Enemy>(Enemy::Type::Player, texture_holder);
|
||||||
|
player->setPosition(world_spawn_pos);
|
||||||
|
player->setVelocity(40.f, world_speed);
|
||||||
|
arr_layers[Air]->attachChild(player);
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef WORLD_H
|
||||||
|
#define WORLD_H
|
||||||
|
|
||||||
|
#include "enemy.h"
|
||||||
|
#include "resourceholder.h"
|
||||||
|
#include "scenenode.h"
|
||||||
|
#include <queue>
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
|
|
||||||
|
class World : private sf::NonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit World(sf::RenderWindow& window);
|
||||||
|
|
||||||
|
void update(const sf::Time& dt);
|
||||||
|
void draw();
|
||||||
|
|
||||||
|
std::queue<Command>& getCommandQueue();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool loadTextures();
|
||||||
|
void buildScene();
|
||||||
|
|
||||||
|
enum Layer
|
||||||
|
{
|
||||||
|
Background,
|
||||||
|
Air,
|
||||||
|
LayerCount
|
||||||
|
};
|
||||||
|
|
||||||
|
std::queue<Command> queue_commands;
|
||||||
|
|
||||||
|
sf::RenderWindow& world_window;
|
||||||
|
sf::View world_view;
|
||||||
|
TextureHolder texture_holder;
|
||||||
|
SceneNodeSPtr scene_graph;
|
||||||
|
std::array<SceneNodeSPtr, LayerCount> arr_layers;
|
||||||
|
|
||||||
|
sf::FloatRect world_bounds;
|
||||||
|
sf::Vector2f world_spawn_pos;
|
||||||
|
float world_speed;
|
||||||
|
EnemySPtr player;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WORLD_H
|
Loading…
Reference in New Issue