Separate scene rendering from Game class
This commit is contained in:
parent
b0cb76d419
commit
0a226fa083
Binary file not shown.
Binary file not shown.
117
src/game.cpp
117
src/game.cpp
|
@ -1,15 +1,5 @@
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
|
||||||
#include <SFML/Graphics/RectangleShape.hpp>
|
|
||||||
#include <SFML/Graphics/ConvexShape.hpp>
|
|
||||||
#include <SFML/Graphics/Text.hpp>
|
|
||||||
|
|
||||||
constexpr int cell_width = 60;
|
|
||||||
constexpr int cell_height = 35;
|
|
||||||
constexpr int cell_deviation = 25;
|
|
||||||
|
|
||||||
constexpr int window_side = cell_width * 4;
|
|
||||||
|
|
||||||
Game::Game()
|
Game::Game()
|
||||||
{
|
{
|
||||||
// Place the player with 10 initial charges onto x: 1, y: 1
|
// Place the player with 10 initial charges onto x: 1, y: 1
|
||||||
|
@ -18,7 +8,10 @@ Game::Game()
|
||||||
// Generate level
|
// Generate level
|
||||||
level = std::make_unique<Level>();
|
level = std::make_unique<Level>();
|
||||||
|
|
||||||
main_window.create(sf::VideoMode(window_side * 3, window_side * 3), "SFML-Test Application", sf::Style::Default);
|
// Prepare level renderer
|
||||||
|
renderer = std::make_unique<Renderer>();
|
||||||
|
|
||||||
|
main_window.create(sf::VideoMode(renderer->windowSize() * 5, renderer->windowSize() * 5), "SFML-Test Application", sf::Style::Default);
|
||||||
main_window.setActive();
|
main_window.setActive();
|
||||||
main_window.setFramerateLimit(60);
|
main_window.setFramerateLimit(60);
|
||||||
|
|
||||||
|
@ -28,7 +21,7 @@ Game::Game()
|
||||||
int Game::run()
|
int Game::run()
|
||||||
{
|
{
|
||||||
// Initial level rendering
|
// Initial level rendering
|
||||||
renderMap();
|
renderer->render(level, hero, main_window);
|
||||||
|
|
||||||
// On the game loop
|
// On the game loop
|
||||||
while (main_window.isOpen())
|
while (main_window.isOpen())
|
||||||
|
@ -46,7 +39,7 @@ int Game::run()
|
||||||
onMoving(event.key.code);
|
onMoving(event.key.code);
|
||||||
|
|
||||||
// Probably something changed! Re-render
|
// Probably something changed! Re-render
|
||||||
renderMap();
|
renderer->render(level, hero, main_window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,101 +103,3 @@ void Game::onMoving(sf::Keyboard::Key &key)
|
||||||
if (!level->mapArray()[attempt_row][attempt_col]->onMovingTo(hero, level))
|
if (!level->mapArray()[attempt_row][attempt_col]->onMovingTo(hero, level))
|
||||||
hero->setPosition(initial_row, initial_col);
|
hero->setPosition(initial_row, initial_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::renderMap()
|
|
||||||
{
|
|
||||||
const Map &map = level->mapArray();
|
|
||||||
|
|
||||||
float painter_x = 60, painter_y = 60;
|
|
||||||
float horizontal_shift = 0, vertical_shift = 0;
|
|
||||||
|
|
||||||
sf::RectangleShape background_brush({static_cast<float>(main_window.getSize().x), static_cast<float>(main_window.getSize().y)});
|
|
||||||
background_brush.setFillColor(palette::Black);
|
|
||||||
background_brush.setPosition(0.f, 0.f);
|
|
||||||
main_window.draw(background_brush);
|
|
||||||
|
|
||||||
// Brush for cell sprites
|
|
||||||
sf::ConvexShape convex_brush;
|
|
||||||
convex_brush.setPointCount(4);
|
|
||||||
convex_brush.setPoint(0, sf::Vector2f(cell_deviation, 0.f));
|
|
||||||
convex_brush.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
|
|
||||||
convex_brush.setPoint(2, sf::Vector2f(cell_width, cell_height));
|
|
||||||
convex_brush.setPoint(3, sf::Vector2f(0.f, cell_height));
|
|
||||||
convex_brush.setFillColor(palette::Blue);
|
|
||||||
convex_brush.setOutlineThickness(0);
|
|
||||||
convex_brush.setPosition(painter_x, painter_y);
|
|
||||||
|
|
||||||
// Counter for available charges
|
|
||||||
sf::Text text;
|
|
||||||
sf::Font font;
|
|
||||||
font.loadFromFile("font/VeraMono.ttf");
|
|
||||||
text.setFont(font);
|
|
||||||
text.setFillColor(palette::White);
|
|
||||||
text.setCharacterSize(25);
|
|
||||||
text.setPosition(50, 350);
|
|
||||||
text.setString("Available bridge cells: " + std::to_string(hero->charges()));
|
|
||||||
|
|
||||||
// Where is hero
|
|
||||||
coordinate hero_row, hero_col;
|
|
||||||
hero->position(hero_row, hero_col);
|
|
||||||
|
|
||||||
// Draw map from 2D array
|
|
||||||
for (coordinate x = 0; x < level->width(); ++x)
|
|
||||||
{
|
|
||||||
horizontal_shift = static_cast<float>(level->width()) * cell_deviation;
|
|
||||||
|
|
||||||
for (coordinate y = 0; y < level->height(); ++y)
|
|
||||||
{
|
|
||||||
vertical_shift = static_cast<float>(map[y][x]->heightShift());
|
|
||||||
|
|
||||||
// If cell has any height value, we should draw walls for it
|
|
||||||
if (vertical_shift > 0)
|
|
||||||
{
|
|
||||||
// Brush for vertical walls
|
|
||||||
sf::ConvexShape convex_wall_brush;
|
|
||||||
convex_wall_brush.setPointCount(6);
|
|
||||||
convex_wall_brush.setPoint(0, sf::Vector2f(cell_deviation + cell_width, -vertical_shift));
|
|
||||||
convex_wall_brush.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
|
|
||||||
convex_wall_brush.setPoint(2, sf::Vector2f(cell_width, cell_height));
|
|
||||||
convex_wall_brush.setPoint(3, sf::Vector2f(0.f, cell_height));
|
|
||||||
convex_wall_brush.setPoint(4, sf::Vector2f(0.f, cell_height - vertical_shift));
|
|
||||||
convex_wall_brush.setPoint(5, sf::Vector2f(cell_width, cell_height));
|
|
||||||
convex_wall_brush.setOutlineThickness(0);
|
|
||||||
|
|
||||||
sf::Color wall_color(sf::Uint8(map[y][x]->color().r - 40), sf::Uint8(map[y][x]->color().g - 40), sf::Uint8(map[y][x]->color().b - 40));
|
|
||||||
convex_wall_brush.setFillColor(wall_color);
|
|
||||||
|
|
||||||
convex_wall_brush.setPosition(painter_x + horizontal_shift, painter_y);
|
|
||||||
|
|
||||||
main_window.draw(convex_wall_brush);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the top surface of the cell itself
|
|
||||||
|
|
||||||
float final_x = painter_x + horizontal_shift;
|
|
||||||
float final_y = painter_y - vertical_shift;
|
|
||||||
|
|
||||||
convex_brush.setPosition(final_x, final_y);
|
|
||||||
convex_brush.setFillColor(map[y][x]->color());
|
|
||||||
|
|
||||||
main_window.draw(convex_brush);
|
|
||||||
|
|
||||||
if (hero_row == y && hero_col == x)
|
|
||||||
{
|
|
||||||
// Draw the hero sprite
|
|
||||||
convex_brush.setFillColor(palette::White);
|
|
||||||
main_window.draw(convex_brush);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move painter to next cell of current column
|
|
||||||
painter_y += cell_height;
|
|
||||||
horizontal_shift -= cell_deviation;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move painter to next column
|
|
||||||
painter_y = 60;
|
|
||||||
painter_x += cell_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
main_window.draw(text);
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <SFML/Graphics/RenderWindow.hpp>
|
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
#include <SFML/Window.hpp>
|
|
||||||
|
|
||||||
#include "hero.h"
|
#include "hero.h"
|
||||||
#include "level.h"
|
#include "level.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
/// The main class where all the process happens
|
/// The main class where all the process happens
|
||||||
class Game
|
class Game
|
||||||
|
@ -17,6 +16,7 @@ private:
|
||||||
// Game entities
|
// Game entities
|
||||||
HeroPtr hero;
|
HeroPtr hero;
|
||||||
LevelPtr level;
|
LevelPtr level;
|
||||||
|
std::unique_ptr<Renderer> renderer;
|
||||||
|
|
||||||
int current_level;
|
int current_level;
|
||||||
|
|
||||||
|
@ -29,9 +29,6 @@ private:
|
||||||
/// Move player by pressed key
|
/// Move player by pressed key
|
||||||
void onMoving(sf::Keyboard::Key &key);
|
void onMoving(sf::Keyboard::Key &key);
|
||||||
|
|
||||||
/// Render game state
|
|
||||||
void renderMap();
|
|
||||||
|
|
||||||
/// Prepare map and hero for a game level
|
/// Prepare map and hero for a game level
|
||||||
//void loadLevel(int level_index = 1);
|
//void loadLevel(int level_index = 1);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
|
#include "level.h"
|
||||||
|
#include "hero.h"
|
||||||
|
|
||||||
|
constexpr unsigned int DEFAULT_CELL_WIDTH = 60;
|
||||||
|
constexpr unsigned int DEFAULT_CELL_HEIGHT = 35;
|
||||||
|
constexpr unsigned int DEFAULT_CELL_DEVIATION = 25;
|
||||||
|
|
||||||
|
constexpr unsigned int DEFAULT_WINDOW_SIDE = DEFAULT_CELL_WIDTH * 4;
|
||||||
|
|
||||||
|
Renderer::Renderer() :
|
||||||
|
cell_width(DEFAULT_CELL_WIDTH),
|
||||||
|
cell_height(DEFAULT_CELL_HEIGHT),
|
||||||
|
cell_deviation(DEFAULT_CELL_DEVIATION),
|
||||||
|
window_size(DEFAULT_WINDOW_SIDE),
|
||||||
|
init_painter_x(60),
|
||||||
|
init_painter_y(60),
|
||||||
|
vertical_shift(0),
|
||||||
|
horizontal_shift(0)
|
||||||
|
{
|
||||||
|
font.loadFromFile("font/VeraMono.ttf");
|
||||||
|
text_charges.setFont(font);
|
||||||
|
text_charges.setFillColor(palette::White);
|
||||||
|
text_charges.setCharacterSize(25);
|
||||||
|
|
||||||
|
brush_background.setFillColor(palette::Black);
|
||||||
|
brush_background.setPosition(0.f, 0.f);
|
||||||
|
|
||||||
|
brush_cell.setPointCount(4);
|
||||||
|
brush_cell.setPoint(0, sf::Vector2f(cell_deviation, 0.f));
|
||||||
|
brush_cell.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
|
||||||
|
brush_cell.setPoint(2, sf::Vector2f(cell_width, cell_height));
|
||||||
|
brush_cell.setPoint(3, sf::Vector2f(0.f, cell_height));
|
||||||
|
brush_cell.setFillColor(palette::Blue);
|
||||||
|
brush_cell.setOutlineThickness(0);
|
||||||
|
|
||||||
|
brush_wall.setPointCount(6); // Points 0 and 4 should be calculated each iteration of rendering
|
||||||
|
brush_wall.setPoint(1, sf::Vector2f(cell_deviation + cell_width, 0.f));
|
||||||
|
brush_wall.setPoint(2, sf::Vector2f(cell_width, cell_height));
|
||||||
|
brush_wall.setPoint(3, sf::Vector2f(0.f, cell_height));
|
||||||
|
brush_wall.setPoint(5, sf::Vector2f(cell_width, cell_height));
|
||||||
|
brush_wall.setOutlineThickness(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Renderer::drawCell(const CellPtr &cell, sf::RenderWindow &main_window)
|
||||||
|
{
|
||||||
|
vertical_shift = static_cast<float>(cell->heightShift());
|
||||||
|
|
||||||
|
// If cell has any height value, we should draw walls for it
|
||||||
|
if (vertical_shift > 0)
|
||||||
|
{
|
||||||
|
brush_wall.setPoint(0, sf::Vector2f(cell_deviation + cell_width, -vertical_shift));
|
||||||
|
brush_wall.setPoint(4, sf::Vector2f(0.f, cell_height - vertical_shift));
|
||||||
|
|
||||||
|
sf::Color wall_color(sf::Uint8(cell->color().r - 40), sf::Uint8(cell->color().g - 40), sf::Uint8(cell->color().b - 40));
|
||||||
|
brush_wall.setFillColor(wall_color);
|
||||||
|
brush_wall.setPosition(painter_x + horizontal_shift, painter_y);
|
||||||
|
|
||||||
|
main_window.draw(brush_wall);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the top surface of the cell itself
|
||||||
|
float final_x = painter_x + horizontal_shift;
|
||||||
|
float final_y = painter_y - vertical_shift;
|
||||||
|
|
||||||
|
brush_cell.setPosition(final_x, final_y);
|
||||||
|
brush_cell.setFillColor(cell->color());
|
||||||
|
|
||||||
|
main_window.draw(brush_cell);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Renderer::render(const LevelPtr &level, const HeroPtr &hero, sf::RenderWindow &main_window)
|
||||||
|
{
|
||||||
|
if (!hero || !level)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const Map &map = level->mapArray();
|
||||||
|
|
||||||
|
painter_x = init_painter_x;
|
||||||
|
painter_y = init_painter_y;
|
||||||
|
horizontal_shift = 0;
|
||||||
|
vertical_shift = 0;
|
||||||
|
|
||||||
|
brush_background.setSize({static_cast<float>(main_window.getSize().x), static_cast<float>(main_window.getSize().y)});
|
||||||
|
main_window.draw(brush_background);
|
||||||
|
|
||||||
|
brush_cell.setPosition(painter_x, painter_y);
|
||||||
|
|
||||||
|
// Where is hero
|
||||||
|
coordinate hero_row, hero_col;
|
||||||
|
hero->position(hero_row, hero_col);
|
||||||
|
|
||||||
|
// Draw map from 2D array
|
||||||
|
for (coordinate x = 0; x < level->width(); ++x)
|
||||||
|
{
|
||||||
|
horizontal_shift = static_cast<float>(level->width()) * cell_deviation;
|
||||||
|
|
||||||
|
for (coordinate y = 0; y < level->height(); ++y)
|
||||||
|
{
|
||||||
|
drawCell(map[y][x], main_window);
|
||||||
|
|
||||||
|
if (hero_row == y && hero_col == x)
|
||||||
|
{
|
||||||
|
// Draw the hero sprite
|
||||||
|
brush_cell.setFillColor(palette::White);
|
||||||
|
main_window.draw(brush_cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move painter to next cell of current column
|
||||||
|
painter_y += cell_height;
|
||||||
|
horizontal_shift -= cell_deviation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move painter to next column
|
||||||
|
painter_y = init_painter_y;
|
||||||
|
painter_x += cell_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
text_charges.setPosition(50, 350);
|
||||||
|
text_charges.setString("Available charges left: " + std::to_string(hero->charges()));
|
||||||
|
main_window.draw(text_charges);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Renderer::windowSize() const
|
||||||
|
{
|
||||||
|
return window_size;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef RENDERER_H
|
||||||
|
#define RENDERER_H
|
||||||
|
|
||||||
|
#include <SFML/Graphics/RectangleShape.hpp>
|
||||||
|
#include <SFML/Graphics/ConvexShape.hpp>
|
||||||
|
#include <SFML/Graphics/Text.hpp>
|
||||||
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
|
#include <SFML/Window.hpp>
|
||||||
|
|
||||||
|
class Level;
|
||||||
|
class Cell;
|
||||||
|
class Hero;
|
||||||
|
|
||||||
|
/// Represents functionality to draw game level onto window
|
||||||
|
class Renderer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float cell_width, cell_height, cell_deviation;
|
||||||
|
unsigned int window_size;
|
||||||
|
|
||||||
|
float init_painter_x, init_painter_y;
|
||||||
|
float painter_x, painter_y;
|
||||||
|
|
||||||
|
float vertical_shift, horizontal_shift;
|
||||||
|
|
||||||
|
sf::Text text_charges;
|
||||||
|
sf::Font font;
|
||||||
|
|
||||||
|
sf::RectangleShape brush_background;
|
||||||
|
sf::ConvexShape brush_cell;
|
||||||
|
sf::ConvexShape brush_wall;
|
||||||
|
|
||||||
|
bool drawCell(const std::unique_ptr<Cell> &cell, sf::RenderWindow &main_window);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Renderer();
|
||||||
|
|
||||||
|
bool render(const std::unique_ptr<Level> &level, const std::unique_ptr<Hero> &hero, sf::RenderWindow &main_window);
|
||||||
|
|
||||||
|
unsigned int windowSize() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RENDERER_H
|
|
@ -11,14 +11,16 @@ SOURCES += \
|
||||||
game.cpp \
|
game.cpp \
|
||||||
hero.cpp \
|
hero.cpp \
|
||||||
level.cpp \
|
level.cpp \
|
||||||
main.cpp
|
main.cpp \
|
||||||
|
renderer.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
cell.h \
|
cell.h \
|
||||||
entity.h \
|
entity.h \
|
||||||
game.h \
|
game.h \
|
||||||
hero.h \
|
hero.h \
|
||||||
level.h
|
level.h \
|
||||||
|
renderer.h
|
||||||
|
|
||||||
# Only to highlight syntax when I am on Windows
|
# Only to highlight syntax when I am on Windows
|
||||||
win32:INCLUDEPATH += d:\SFML-2.5.1\include
|
win32:INCLUDEPATH += d:\SFML-2.5.1\include
|
||||||
|
|
Loading…
Reference in New Issue