Skip to content

Commit

Permalink
add game over state
Browse files Browse the repository at this point in the history
huge refactoring
add Button class
  • Loading branch information
David Arutiunian committed Jan 4, 2018
1 parent 56efbc1 commit 59a75ff
Show file tree
Hide file tree
Showing 19 changed files with 304 additions and 176 deletions.
8 changes: 6 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ if (WIN32 AND CMAKE_BUILD_TYPE MATCHES Release)
src/StateMediator.h
src/Menu.cpp
src/Menu.h
src/opensans.h)
src/opensans.h
src/Button.cpp
src/Button.h)
else ()
add_executable(doodle-jump
resources
Expand Down Expand Up @@ -67,7 +69,9 @@ else ()
src/StateMediator.h
src/Menu.cpp
src/Menu.h
src/opensans.h)
src/opensans.h
src/Button.cpp
src/Button.h)
endif ()

target_compile_features(doodle-jump PUBLIC cxx_std_17)
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ C++ clone of Doodle Jump
- [x] collision adjustment
- [x] first playable version
- [x] endless map
- [ ] game over state
- [x] game over state
- [ ] score
- [ ] bonuses
- [ ] textures

Expand Down
34 changes: 34 additions & 0 deletions src/Button.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "Button.h"

Button::Button(ButtonOptions &buttonOptions)
{
m_shape.setSize(buttonOptions.size);
m_shape.setPosition(buttonOptions.position);
m_shape.setOrigin(buttonOptions.size.x / 2, buttonOptions.size.y / 2);
m_shape.setFillColor(buttonOptions.fillColor);
m_shape.setOutlineColor(buttonOptions.outlineColor);
m_shape.setOutlineThickness(buttonOptions.outlineThickness);

m_p_font = std::make_shared<sf::Font>(sf::Font(buttonOptions.font));
m_text.setFont(*m_p_font);
m_text.setString(buttonOptions.text);
m_text.setCharacterSize(buttonOptions.textSize);
m_text.setFillColor(buttonOptions.textColor);
const sf::FloatRect &bounds = m_text.getLocalBounds();
const sf::Vector2f origin = {bounds.left + bounds.width / 2, bounds.top + bounds.height / 2};
m_text.setOrigin(origin);
m_text.setPosition(buttonOptions.position);
}

void Button::draw(sf::RenderTarget &target, sf::RenderStates states) const
{
target.draw(m_shape, states);
target.draw(m_text, states);
}

const sf::RectangleShape &Button::getShape() const
{
return m_shape;
}

Button::Button() = default;
37 changes: 37 additions & 0 deletions src/Button.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef DOODLE_JUMP_BUTTON_H
#define DOODLE_JUMP_BUTTON_H

#include <SFML/Graphics.hpp>
#include <memory>

struct ButtonOptions
{
sf::Vector2f size;
sf::Vector2f position;
std::string text;
unsigned textSize;
sf::Color fillColor;
sf::Color outlineColor;
unsigned outlineThickness;
sf::Color textColor;
sf::Font font;
};

class Button : public sf::Drawable
{
public:
Button();

explicit Button(ButtonOptions &buttonOptions);

const sf::RectangleShape &getShape() const;

private:
void draw(sf::RenderTarget &target, sf::RenderStates states) const override;

sf::RectangleShape m_shape;
sf::Text m_text;
std::shared_ptr<sf::Font> m_p_font;
};

#endif //DOODLE_JUMP_BUTTON_H
17 changes: 11 additions & 6 deletions src/Doodler.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
#include "Doodler.h"

void Doodler::draw(sf::RenderTarget &target, sf::RenderStates states) const
{
target.draw(m_shape, states);
}

Doodler::Doodler(const StateMediator &stateMediator) : m_stateMediator(stateMediator)
Doodler::Doodler(StateMediator &stateMediator) : m_stateMediator(stateMediator)
{
m_shape.setSize(m_size);
m_shape.setOrigin(m_size.x / 2, m_size.x / 2);
Expand Down Expand Up @@ -34,6 +29,11 @@ void Doodler::updatePosition(const float deltaTime)
setPosition(nextPosition);
checkCollision();
}
if (m_timeAccumulator / TIME_ACCELERATOR > DEAD_TIME)
{
m_stateMediator.setState(State::GameOver);
m_timeAccumulator = 0.f;
}
}

void Doodler::checkCollision()
Expand Down Expand Up @@ -140,3 +140,8 @@ const std::function<bool(float, float)> Doodler::areCloseRelative()
return std::abs((lhs - rhs) / rhs) < tolerance;
};
}

void Doodler::draw(sf::RenderTarget &target, sf::RenderStates states) const
{
target.draw(m_shape, states);
}
17 changes: 9 additions & 8 deletions src/Doodler.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class Doodler : public IEntity
{
public:
explicit Doodler(const StateMediator &stateMediator);
explicit Doodler(StateMediator &stateMediator);

void updatePosition(float deltaTime) override;

Expand All @@ -27,35 +27,36 @@ class Doodler : public IEntity
void setFloor(float nextFloor) override;

private:
const StateMediator &m_stateMediator;
StateMediator &m_stateMediator;

const float m_outlineThickness = 2.f;
const float m_initialSpeed = 75.f;

float m_timeAccumulator{0.f};
float m_floor{static_cast<float>(WINDOW_HEIGHT)};
bool m_isFalling{false};

sf::Vector2f m_size{sf::Vector2f(35.f, 50.f)};
sf::Vector2f m_position{sf::Vector2f(WINDOW_WIDTH / 2, m_floor - m_size.x / 2 - m_outlineThickness)};
sf::RectangleShape m_shape{sf::RectangleShape()};

void draw(sf::RenderTarget &target, sf::RenderStates states) const override;

void setVerticalPosition(float nextX, float deltaTime);

const std::function<bool(float, float)> areCloseAbsolute();

const std::function<bool(float, float)> areFuzzyEqual();

const std::function<bool(float, float)> areCloseRelative();

void draw(sf::RenderTarget &target, sf::RenderStates states) const override;

void checkCollision() override;

void setVerticalPosition(float nextX, float deltaTime);

void setNextY();

sf::FloatRect getBounds() const override;

float getNextY() const;

void setNextY();
};

#endif //DOODLE_JUMP_DOODLER_H
8 changes: 7 additions & 1 deletion src/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ void Engine::removePlatforms(Entities &entities)
const std::function<bool(const std::shared_ptr<IEntity> &)> Engine::isDoodler()
{
return [](const std::shared_ptr<IEntity> &p_entity) -> bool {
return p_entity->getType() == EntityType::Doodler;
return p_entity != nullptr && p_entity->getType() == EntityType::Doodler;
};
}

void Engine::reset()
{
m_shouldSetFloor = false;
m_floor = static_cast<float>(WINDOW_HEIGHT);
}
7 changes: 5 additions & 2 deletions src/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ class Engine

void removePlatforms(Entities &entities);

const std::function<bool(const std::shared_ptr<IEntity> &)> isDoodler();

void reset();

private:
std::shared_ptr<IEntity> m_p_doodler;
bool m_shouldSetFloor{false};
float m_floor{static_cast<float>(WINDOW_HEIGHT)};

const std::function<bool(const std::shared_ptr<IEntity> &)> isDoodler();
float m_floor{static_cast<float>(WINDOW_HEIGHT)};

void processCollision(const std::shared_ptr<IEntity> &p_entity);

Expand Down
112 changes: 67 additions & 45 deletions src/EventLoop.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
#include "Doodler.h"
#include "EventLoop.h"
#include "icon.h"
#include "Platform.h"

void EventLoop::createWindow()
void EventLoop::update()
{
sf::ContextSettings settings;
settings.antialiasingLevel = ANTIALIASING_LEVEL;
m_window.create(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), WINDOW_TITLE, sf::Style::Close, settings);
m_window.setFramerateLimit(MAX_FPS);

sf::Image icon;
if (icon.loadFromMemory(ICON_IMAGE.data, std::size(ICON_IMAGE.data)))
const State state = m_stateMediator.getGameState();
switch (state)
{
m_window.setIcon(ICON_IMAGE.width, ICON_IMAGE.height, icon.getPixelsPtr());
case State::Game:
{
m_view.followTo(m_p_doodler);
for (auto &&m_entity : m_entities)
{
m_entity->updatePosition(m_deltaTime);
}
m_engine.checkCollision(m_entities);
m_engine.addPlatforms(m_entities);
m_engine.removePlatforms(m_entities);
break;
}
default:
break;
}
}

Expand All @@ -22,9 +31,9 @@ void EventLoop::pollEvents()
sf::Event event{};
while (m_window.pollEvent(event))
{
const sf::Vector2i &mousePosition = sf::Mouse::getPosition(m_window);
const sf::Vector2f &mousePosition = sf::Vector2f(sf::Mouse::getPosition(m_window));
m_stateMediator.triggerEventHandler(event);
m_menu.eventHandler(event, {static_cast<float>(mousePosition.x), static_cast<float>(mousePosition.y)});
m_menu.eventHandler(event, mousePosition, std::bind(&EventLoop::restart, this));
}
}

Expand All @@ -36,28 +45,48 @@ void EventLoop::redrawFrame()
case State::Game:
drawGameScreen();
break;
case State::GameOver:
case State::MainMenu:
drawMenuScreen();
break;
default:
break;
}
}

void EventLoop::drawGameScreen()
{
m_window.clear(sf::Color::White);
m_window.setView(m_view.getView());
for (auto &&m_entity : m_entities)
{
m_window.draw(*m_entity);
}
m_window.display();
}

void EventLoop::update()
void EventLoop::drawMenuScreen()
{
const State state = m_stateMediator.getGameState();
switch (state)
sf::View &view = m_view.getView();
view.setCenter(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
m_window.setView(view);
m_window.clear(sf::Color::White);
m_window.draw(m_menu);
m_window.display();
}

void EventLoop::createWindow()
{
sf::ContextSettings settings;
settings.antialiasingLevel = ANTIALIASING_LEVEL;
m_window.create(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), WINDOW_TITLE, sf::Style::Close, settings);
m_window.setFramerateLimit(MAX_FPS);
m_window.requestFocus();

sf::Image icon;
if (icon.loadFromMemory(ICON_IMAGE.data, std::size(ICON_IMAGE.data)))
{
case State::Game:
for (auto &&m_entity : m_entities)
{
m_entity->updatePosition(m_deltaTime);
}
break;
default:
break;
m_window.setIcon(ICON_IMAGE.width, ICON_IMAGE.height, icon.getPixelsPtr());
}
}

Expand All @@ -66,34 +95,27 @@ const sf::RenderWindow &EventLoop::getWindow() const
return m_window;
}

EventLoop::EventLoop(const View &view,
sf::RenderWindow &window,
StateMediator &stateMediator,
Menu &menu,
Entities &entities)
: m_view(view),
m_window(window),
m_stateMediator(stateMediator),
m_menu(menu),
m_entities(entities)
void EventLoop::init()
{
createWindow();
}
if (!m_window.isOpen())
{
createWindow();
}

void EventLoop::drawGameScreen()
{
m_window.clear(sf::Color::White);
m_window.setView(m_view.getView());
for (auto &&m_entity : m_entities)
for (size_t i = 0; i < PLATFORM_COUNT; ++i)
{
m_window.draw(*m_entity);
std::shared_ptr<Platform> p_platform = std::make_shared<Platform>(Platform());
m_entities.push_back(p_platform);
}
m_window.display();

m_p_doodler = std::make_shared<Doodler>(Doodler(m_stateMediator));
m_entities.push_back(m_p_doodler);
}

void EventLoop::drawMenuScreen()
void EventLoop::restart()
{
m_window.clear(sf::Color::White);
m_window.draw(m_menu);
m_window.display();
Platform::reset();
m_engine.reset();
m_entities.clear();
init();
}
Loading

0 comments on commit 59a75ff

Please sign in to comment.