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 <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()
|
||||
{
|
||||
// Place the player with 10 initial charges onto x: 1, y: 1
|
||||
|
@ -18,7 +8,10 @@ Game::Game()
|
|||
// Generate 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.setFramerateLimit(60);
|
||||
|
||||
|
@ -28,7 +21,7 @@ Game::Game()
|
|||
int Game::run()
|
||||
{
|
||||
// Initial level rendering
|
||||
renderMap();
|
||||
renderer->render(level, hero, main_window);
|
||||
|
||||
// On the game loop
|
||||
while (main_window.isOpen())
|
||||
|
@ -46,7 +39,7 @@ int Game::run()
|
|||
onMoving(event.key.code);
|
||||
|
||||
// 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))
|
||||
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 <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <SFML/System/Time.hpp>
|
||||
#include <SFML/Window.hpp>
|
||||
|
||||
#include "hero.h"
|
||||
#include "level.h"
|
||||
#include "renderer.h"
|
||||
|
||||
/// The main class where all the process happens
|
||||
class Game
|
||||
|
@ -17,6 +16,7 @@ private:
|
|||
// Game entities
|
||||
HeroPtr hero;
|
||||
LevelPtr level;
|
||||
std::unique_ptr<Renderer> renderer;
|
||||
|
||||
int current_level;
|
||||
|
||||
|
@ -29,9 +29,6 @@ private:
|
|||
/// Move player by pressed key
|
||||
void onMoving(sf::Keyboard::Key &key);
|
||||
|
||||
/// Render game state
|
||||
void renderMap();
|
||||
|
||||
/// Prepare map and hero for a game level
|
||||
//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 \
|
||||
hero.cpp \
|
||||
level.cpp \
|
||||
main.cpp
|
||||
main.cpp \
|
||||
renderer.cpp
|
||||
|
||||
HEADERS += \
|
||||
cell.h \
|
||||
entity.h \
|
||||
game.h \
|
||||
hero.h \
|
||||
level.h
|
||||
level.h \
|
||||
renderer.h
|
||||
|
||||
# Only to highlight syntax when I am on Windows
|
||||
win32:INCLUDEPATH += d:\SFML-2.5.1\include
|
||||
|
|
Loading…
Reference in New Issue