160 lines
5.2 KiB
C++
160 lines
5.2 KiB
C++
#include <SFML/Graphics.hpp>
|
|
#include <cmath>
|
|
|
|
#include "Grid.h"
|
|
#include "algorithms/Sidewinder.h"
|
|
#include "algorithms/AldousBroder.h"
|
|
#include "algorithms/Wilsons.h"
|
|
#include "algorithms/HuntAndKill.h"
|
|
#include "algorithms/RecursiveBacktracker.h"
|
|
#include "algorithms/BinaryTree.h"
|
|
|
|
sf::Color interpolateColors(const sf::Color& c1, const sf::Color& c2, float t) {
|
|
auto r = static_cast<sf::Uint8>((1 - t) * c1.r + t * c2.r);
|
|
auto g = static_cast<sf::Uint8>((1 - t) * c1.g + t * c2.g);
|
|
auto b = static_cast<sf::Uint8>((1 - t) * c1.b + t * c2.b);
|
|
return {r, g, b};
|
|
}
|
|
|
|
//From: https://github.com/SFML/SFML/wiki/Source:-Line-segment-with-thickness
|
|
class sfLine : public sf::Drawable
|
|
{
|
|
public:
|
|
sfLine(const sf::Vector2f& point1, const sf::Vector2f& point2, const sf::Color& color = sf::Color::Yellow):
|
|
color(color), thickness(5.f)
|
|
{
|
|
sf::Vector2f direction = point2 - point1;
|
|
sf::Vector2f unitDirection = direction/std::sqrt(direction.x*direction.x+direction.y*direction.y);
|
|
sf::Vector2f unitPerpendicular(-unitDirection.y,unitDirection.x);
|
|
|
|
sf::Vector2f offset = (thickness/2.f)*unitPerpendicular;
|
|
|
|
vertices[0].position = point1 + offset;
|
|
vertices[1].position = point2 + offset;
|
|
vertices[2].position = point2 - offset;
|
|
vertices[3].position = point1 - offset;
|
|
|
|
for (int i=0; i<4; ++i)
|
|
vertices[i].color = color;
|
|
}
|
|
|
|
void draw(sf::RenderTarget &target, sf::RenderStates states) const
|
|
{
|
|
target.draw(vertices,4,sf::Quads);
|
|
}
|
|
|
|
|
|
private:
|
|
sf::Vertex vertices[4];
|
|
float thickness;
|
|
sf::Color color;
|
|
};
|
|
|
|
void lineTo(sf::RenderTexture& render_texture, int x1, int y1, int x2, int y2, const sf::Color& color) {
|
|
sfLine line(sf::Vector2f(x1, y1), sf::Vector2f(x2, y2), color);
|
|
render_texture.draw(line);
|
|
}
|
|
|
|
void drawGridToTexture(sf::RenderTexture& render_texture, const DistanceGrid& grid, int cell_size) {
|
|
auto width = grid.getCols() * cell_size;
|
|
auto height = grid.getRows() * cell_size;
|
|
if (!render_texture.create(width, height)) {
|
|
throw std::runtime_error("Failed to create render texture");
|
|
}
|
|
|
|
auto background = sf::Color::White;
|
|
auto wall = sf::Color::Black;
|
|
auto start = sf::Color::Blue;
|
|
auto goal = sf::Color::Red;
|
|
|
|
render_texture.clear(background);
|
|
for (auto& cell : grid) {
|
|
auto x1 = cell.getCol() * cell_size;
|
|
auto y1 = cell.getRow() * cell_size;
|
|
auto x2 = (cell.getCol() + 1) * cell_size;
|
|
auto y2 = (cell.getRow() + 1) * cell_size;
|
|
|
|
sf::Color color = interpolateColors(start, goal, grid.intensityAt(cell));
|
|
sf::RectangleShape rectangle(sf::Vector2f(cell_size, cell_size));
|
|
rectangle.setPosition(x1, y1);
|
|
rectangle.setFillColor(color);
|
|
render_texture.draw(rectangle);
|
|
|
|
if (!cell.hasNorth()) {
|
|
lineTo(render_texture, x1, y1, x2, y1, wall);
|
|
}
|
|
if (!cell.hasWest()) {
|
|
lineTo(render_texture, x1, y1, x1, y2, wall);
|
|
}
|
|
if (!cell.isLinked(cell.east)) {
|
|
lineTo(render_texture, x2, y1, x2, y2, wall);
|
|
}
|
|
if (!cell.isLinked(cell.south)) {
|
|
lineTo(render_texture, x1, y2, x2, y2, wall);
|
|
}
|
|
}
|
|
render_texture.display();
|
|
}
|
|
|
|
const int CELL_SIZE = 20;
|
|
const int WIDTH = 25;
|
|
const int HEIGHT = 25;
|
|
|
|
int main() {
|
|
|
|
DistanceGrid grid(HEIGHT, WIDTH);
|
|
Sidewinder::on(grid);
|
|
grid.setStart(grid.randomCell());
|
|
|
|
sf::RenderWindow window(sf::VideoMode(WIDTH * CELL_SIZE, HEIGHT * CELL_SIZE), "Hello, SFML!");
|
|
while ( window.isOpen() &&
|
|
!sf::Keyboard::isKeyPressed(sf::Keyboard::Escape) &&
|
|
!sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
|
|
sf::Event event;
|
|
while (window.pollEvent(event)) {
|
|
if (event.type == sf::Event::Closed) {
|
|
window.close();
|
|
}
|
|
}
|
|
|
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
|
|
{
|
|
grid = DistanceGrid(HEIGHT, WIDTH);
|
|
Sidewinder::on(grid);
|
|
grid.setStart(grid.randomCell());
|
|
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
|
grid = DistanceGrid(HEIGHT, WIDTH);
|
|
AldousBroder::on(grid);
|
|
grid.setStart(grid.randomCell());
|
|
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
|
|
grid = DistanceGrid(HEIGHT, WIDTH);
|
|
Wilsons::on(grid);
|
|
grid.setStart(grid.randomCell());
|
|
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::H)) {
|
|
grid = DistanceGrid(HEIGHT, WIDTH);
|
|
HuntAndKill::on(grid);
|
|
grid.setStart(grid.randomCell());
|
|
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::R)) {
|
|
grid = DistanceGrid(HEIGHT, WIDTH);
|
|
RecursiveBacktracker::on(grid);
|
|
grid.setStart(grid.randomCell());
|
|
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::B)) {
|
|
grid = DistanceGrid(HEIGHT, WIDTH);
|
|
BinaryTree::on(grid);
|
|
grid.setStart(grid.randomCell());
|
|
}
|
|
|
|
window.clear(sf::Color::Blue);
|
|
|
|
sf::RenderTexture render_texture;
|
|
drawGridToTexture(render_texture, grid, CELL_SIZE);
|
|
const sf::Texture& texture = render_texture.getTexture();
|
|
sf::Sprite sprite(texture);
|
|
window.draw(sprite);
|
|
window.display();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|