#include <SFML/Window/Event.hpp>
#include <SFML/System/Time.hpp>
#include <iostream>
#include <stack>
#include <memory>
#include <map>
#include <string>
class State;
class StateMan;
class AssetMan;
struct Context;
class Game;
class MainMenu;
//namespace Engine
//{
enum AssetID
{
MAIN_FONT = 0
};
class State
{
public:
State() {};
virtual ~State() {};
virtual void Init() = 0;
virtual void ProcessInput() = 0;
virtual void Update(sf::Time daltaTime) = 0;
virtual void Draw() = 0;
virtual void Pause() {};
virtual void Start() {};
};
class StateMan
{
private:
std::stack<std::unique_ptr<State>> m_stateStack;
std::unique_ptr<State> m_newState;
bool m_add;
bool m_replace;
bool m_remove;
public:
StateMan() : m_add(false), m_replace(false), m_remove(false)
{
};
~StateMan()
{
};
void Add(std::unique_ptr<State> toAdd, bool replace = false)
{
m_add = true;
m_newState = std::move(toAdd);
m_replace = replace;
};
void PopCurrent()
{
m_remove = true;
};
void ProcessStateChange()
{
if (m_remove && (!m_stateStack.empty()))
{
m_stateStack.pop();
if (!m_stateStack.empty())
{
m_stateStack.top()->Start();
}
m_remove = false;
}
if (m_add)
{
if (m_replace && (!m_stateStack.empty()))
{
m_stateStack.pop();
m_replace = false;
}
if (m_stateStack.empty())
{
m_stateStack.top()->Pause();
}
m_stateStack.push(std::move(m_newState));
m_stateStack.top()->Init();
m_stateStack.top()->Start();
m_add = false;
}
};
std::unique_ptr<State>& GetCurrent()
{
return m_stateStack.top();
};
};
class AssetMan
{
private:
std::map<int, std::unique_ptr<sf::Texture>> m_textures;
std::map<int, std::unique_ptr<sf::Font>> m_fonts;
public:
AssetMan()
{
};
~AssetMan()
{
};
void AddTexture(int id, const std::string& filePath, bool isRepeated = false)
{
auto texture = std::make_unique<sf::Texture>();
if (texture->loadFromFile(filePath))
{
texture->setRepeated(isRepeated);
m_textures[id] = std::move(texture);
}
};
void AddFont(int id, const std::string& filePath)
{
auto font = std::make_unique<sf::Font>();
if (font->loadFromFile(filePath))
{
m_fonts[id] = std::move(font);
}
};
const sf::Texture& GetTexture(int id) const
{
return *(m_textures.at(id).get());
};
const sf::Font& GetFont(int id) const
{
return *(m_fonts.at(id).get());
};
};
struct Context
{
//std::unique_ptr<Engine::AssetMan> m_assets;
//std::unique_ptr<Engine::StateMan> m_states;
//std::unique_ptr<sf::RenderWindow> m_window;
std::unique_ptr<AssetMan> m_assets;
std::unique_ptr<StateMan> m_states;
std::unique_ptr<sf::RenderWindow> m_window;
//std::unique_ptr<MainMenu> m_mainMenu;
Context()
{
//m_assets = std::make_unique<Engine::AssetMan>();
//m_states = std::make_unique<Engine::StateMan>();
//m_window = std::make_unique<sf::RenderWindow>();
//m_mainMenu = std::make_unique<MainMenu>();
m_assets = std::make_unique<AssetMan>();
m_states = std::make_unique<StateMan>();
m_window = std::make_unique<sf::RenderWindow>();
}
};
class Game
{
private:
std::shared_ptr<Context> m_context;
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 60.f);
bool arg;
public:
Game() : m_context(std::make_shared<Context>())
{
m_context->m_window->create(sf::VideoMode(640, 352), "Snake Game", sf::Style::Close);
m_context->m_states->Add(std::make_unique<MainMenu>(m_context));//Ошибка здесь!!!
}
~Game()
{
};
void Run()
{
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Clock clock;
sf::Time timeSinceLastFrame = sf::Time::Zero;
while (m_context->m_window->isOpen())
{
timeSinceLastFrame += clock.restart();
while (timeSinceLastFrame > TIME_PER_FRAME)
{
timeSinceLastFrame -= TIME_PER_FRAME;
m_context->m_states->ProcessStateChange();
m_context->m_states->GetCurrent()->ProcessInput();
m_context->m_states->GetCurrent()->Update(TIME_PER_FRAME);
m_context->m_states->GetCurrent()->Draw();
}
}
};
};
class MainMenu
{
private:
std::shared_ptr<Context> m_context;
sf::Text m_gameTitle;
public:
MainMenu(std::shared_ptr<Context>& context)
: m_context(context)
{
}
~MainMenu()
{
}
void Init()
{
m_context->m_assets->AddFont(MAIN_FONT, "assets/fonts/Pacifico-Regular.ttf");
m_gameTitle.setFont(m_context->m_assets->GetFont(MAIN_FONT));
m_gameTitle.setString("Snake Game");
};
void ProcessInput()
{
sf::Event event;
while (m_context->m_window->pollEvent(event))
{
if (event.type == sf::Event::Closed)
m_context->m_window->close();
}
};
void Update(sf::Time daltaTime)
{
};
void Draw()
{
m_context->m_window->clear();
m_context->m_window->draw(m_gameTitle);
m_context->m_window->display();
};
};
//}
int main()
{
Game game;
game.Run();
return 0;
}```