online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
#include <array> #include <bitset> #include <cmath> #include <type_traits> #include <SFML/Graphics.hpp> #include "SimplexNoise.h" enum class Direction : std::size_t { North = 0x0, East = 0x1, South = 0x2, West = 0x3 }; struct Tile { unsigned char height; enum class State : unsigned char { // tile corners -- TopLeft = 0x1, TopRight = 0x2, BottomRight = 0x4, BottomLeft = 0x8, // tile states ------------------ Zero = 0x0, One = TopLeft, Two = TopLeft | TopRight, Three = TopRight, Four = TopRight | BottomRight, Five = BottomRight, Six = BottomRight | BottomLeft, Seven = BottomLeft, Eight = BottomLeft | TopLeft, Nine = TopLeft | TopRight | BottomRight, Ten = TopRight | BottomRight | BottomLeft, Eleven = BottomRight | BottomLeft | TopLeft, Twelve = BottomLeft | TopLeft | TopRight, Thirteen = TopLeft | TopRight | BottomRight | BottomLeft } state; }; constexpr bool operator&(Tile::State lhs, Tile::State rhs) noexcept { return static_cast<bool>( static_cast<std::underlying_type_t<Tile::State>>(lhs) & static_cast<std::underlying_type_t<Tile::State>>(rhs) ); } template<std::size_t MapSize, std::size_t TileSize> class IsometricTilemap final : public sf::Drawable , public sf::Transformable { public: IsometricTilemap() noexcept : tiles_{} , position_{ 0.f, 0.f } , vertices_{ sf::Quads, MapSize * MapSize * 12u } , orientation_{ Direction::North } , simplexNoise_{ 0.2f, 1.f, 2.f, 0.5f } { static_assert( 0u < MapSize && (MapSize & (MapSize - 1u)) == 0u, "MapSize must be greater than 0 and a power of 2" ); static_assert( 0u < TileSize && (TileSize & (TileSize - 1u)) == 0u, "TileSize must be greater than 0 and a power of 2" ); static_assert(static_cast<Tile::State>(15) == Tile::State::Thirteen); update(); auto bounds = vertices_.getBounds(); setOrigin(bounds.width / 2.f + bounds.left, bounds.height / 2.f + bounds.top); } public: void update() noexcept { for(auto y = 0u; y < MapSize; ++y) { for(auto x = 0u; x < MapSize; ++x) { float f = simplexNoise_.fractal( static_cast<size_t>(std::log(MapSize)), static_cast<float>(x) / static_cast<float>(MapSize) + (position_.x / static_cast<float>(MapSize)), static_cast<float>(y) / static_cast<float>(MapSize) + (position_.y / static_cast<float>(MapSize)) ); auto& tile = tiles_[(x + y * MapSize)]; tile.height = static_cast<unsigned>(32.f * std::pow((f + 1.f) / 2.f, 3.f)); tile.state = Tile::State::Zero; } } for(auto y = 0; y < static_cast<int>(MapSize); ++y) { for(auto x = 0; x < static_cast<int>(MapSize); ++x) { auto& tile = tiles_[x + y * MapSize]; unsigned char state = 0x0u; for(auto j = -1; j < 1; ++j) { for(auto i = -1; i < 1; ++i) { if(i == 0 && j == 0) continue; if(auto neighbour = (x + i + (y + j) * static_cast<int>(MapSize)); 0 <= neighbour && neighbour < static_cast<int>(MapSize * MapSize)) { if(tiles_[neighbour].height == tile.height + 1u) { int k = i + j * 3; state |= 1u << static_cast<unsigned>(k < 0 ? k + 4 : k + 3); } } } } tile.state = stateTable_[state]; } } for(auto y = 0u; y < MapSize; ++y) { for(auto x = 0u; x < MapSize; ++x) { renderBlock(x, y); } } } void renderBlock(unsigned x, unsigned y) noexcept { auto& tile = tiles_[x + y * MapSize]; auto *const block = &vertices_[(x + y * MapSize) * 12u]; // orientation_ == Direction::North -------------------------------------------------------------------------------------- block[0u].position = cartesianToIsometric(x, y, tile.state & Tile::State::TopLeft ? tile.height + 1u : tile.height); block[1u].position = cartesianToIsometric(x + 1u, y, tile.state & Tile::State::TopRight ? tile.height + 1u : tile.height); block[2u].position = cartesianToIsometric(x + 1u, y + 1u, tile.state & Tile::State::BottomRight ? tile.height + 1u : tile.height); block[3u].position = cartesianToIsometric(x, y + 1u, tile.state & Tile::State::BottomLeft ? tile.height + 1u : tile.height); block[4u].position = cartesianToIsometric(x, y + 1u, tile.state & Tile::State::BottomLeft ? tile.height + 1u : tile.height); block[5u].position = cartesianToIsometric(x + 1u, y + 1u, tile.state & Tile::State::BottomRight ? tile.height + 1u : tile.height); block[6u].position = cartesianToIsometric(x + 1u, y + 1u, 0u); block[7u].position = cartesianToIsometric(x, y + 1u, 0u); block[8u].position = cartesianToIsometric(x + 1u, y + 1u, tile.state & Tile::State::BottomRight ? tile.height + 1u : tile.height); block[9u].position = cartesianToIsometric(x + 1u, y, tile.state & Tile::State::TopRight ? tile.height + 1u : tile.height); block[10u].position = cartesianToIsometric(x + 1u, y, 0u); block[11u].position = cartesianToIsometric(x + 1u, y + 1u, 0u); sf::Color color; switch(tile.state) { case Tile::State::Zero: color = { 0x73, 0xA3, 0x4D, 0xFF }; break; case Tile::State::One: color = { 0x81, 0xAD, 0x5E, 0xFF }; break; case Tile::State::Two: color = { 0x76, 0xA6, 0x4E, 0xFF }; break; case Tile::State::Three: color = { 0x67, 0x9B, 0x3C, 0xFF }; break; case Tile::State::Four: color = { 0x58, 0x8F, 0x2A, 0xFF }; break; case Tile::State::Five: color = { 0x67, 0x9B, 0x3C, 0xFF }; break; case Tile::State::Six: color = { 0x76, 0xA6, 0x4E, 0xFF }; break; case Tile::State::Seven: color = { 0x81, 0xAD, 0x5E, 0xFF }; break; case Tile::State::Eight: color = { 0x8C, 0xB4, 0x6E, 0xFF }; break; default: color = { 0x81, 0xAD, 0x5E, 0xFF }; break; } for(auto i = 0u; i < 4u; ++i) { block[i].color = color; block[i + 4u].color = { 0x65, 0x43, 0x21, 0xFF }; block[i + 8u].color = { 0x81, 0x61, 0x3C, 0xFF }; } } void scroll(Direction direction) noexcept { switch(direction) { case Direction::North: position_ += { 0.f, -1.f }; break; case Direction::South: position_ += { 0.f, 1.f }; break; case Direction::West: position_ += { -1.f, 0.f }; break; case Direction::East: position_ += { 1.f, 0.f }; break; default: break; } } private: static inline sf::Vector2f cartesianToIsometric(unsigned x, unsigned y, unsigned z) noexcept { return { (static_cast<float>(x) - static_cast<float>(y)) * static_cast<float>(TileSize), (static_cast<float>(x + y) - static_cast<float>(z) * 2.f) * (static_cast<float>(TileSize) / 2.f) }; } void draw(sf::RenderTarget& target, sf::RenderStates states) const override { states.transform *= getTransform(); states.texture = nullptr; target.draw(vertices_, states); } private: std::array<Tile, MapSize * MapSize> tiles_; sf::Vector2f position_; sf::VertexArray vertices_; Direction orientation_; SimplexNoise simplexNoise_; static constexpr std::array<Tile::State, 256u> stateTable_{ static_cast<Tile::State>(0), static_cast<Tile::State>(1), static_cast<Tile::State>(3), static_cast<Tile::State>(3), static_cast<Tile::State>(2), static_cast<Tile::State>(3), static_cast<Tile::State>(3), static_cast<Tile::State>(3), static_cast<Tile::State>(9), static_cast<Tile::State>(9), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(6), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(6), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(8), static_cast<Tile::State>(9), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(10), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(9), static_cast<Tile::State>(9), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(11), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(12), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(13), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(12), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(13), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(4), static_cast<Tile::State>(5), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(6), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(13), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(6), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(6), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(7), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(12), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(13), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(12), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(13), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(12), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(13), static_cast<Tile::State>(13), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(14), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), static_cast<Tile::State>(15), }; }; constexpr auto windowHeight = 720u, windowWidth = 1280u; int main() { sf::RenderWindow window{ { windowWidth, windowHeight }, "SFML Application"}; window.setFramerateLimit(60.f); IsometricTilemap<32u, 16u> tileMap; tileMap.move( std::abs(static_cast<float>(windowWidth / 2u) - tileMap.getPosition().x), std::abs(static_cast<float>(windowHeight / 2u) - tileMap.getPosition().y) ); bool updated = false; while(window.isOpen()) { sf::Event event; while(window.pollEvent(event)) { if(event.type == sf::Event::Closed) window.close(); if(event.type == sf::Event::KeyPressed) { switch(event.key.code) { case sf::Keyboard::W: tileMap.scroll(Direction::North); updated = true; break; case sf::Keyboard::S: tileMap.scroll(Direction::South); updated = true; break; case sf::Keyboard::A: tileMap.scroll(Direction::West); updated = true; break; case sf::Keyboard::D: tileMap.scroll(Direction::East); updated = true; break; case sf::Keyboard::Escape: window.close(); break; default: break; } } } if(updated) { tileMap.update(); updated = false; } window.clear(); window.draw(tileMap); window.display(); } }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue