From 2c1946c29b357af1575ce9de2c4a6efa220c8f8c Mon Sep 17 00:00:00 2001 From: John McCardle Date: Mon, 27 Feb 2023 07:02:34 -0500 Subject: [PATCH] Grid - widget for holding multi-layer map data --- src/Grid.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++ src/Grid.h | 37 +++++++++++++++ src/UITestScene.cpp | 75 ++++++++++++++++++++++++----- src/UITestScene.h | 2 + 4 files changed, 216 insertions(+), 11 deletions(-) create mode 100644 src/Grid.cpp create mode 100644 src/Grid.h diff --git a/src/Grid.cpp b/src/Grid.cpp new file mode 100644 index 0000000..87dd12b --- /dev/null +++ b/src/Grid.cpp @@ -0,0 +1,113 @@ +#include "Grid.h" +#include + +GridPoint::GridPoint(): + color(0, 0, 0, 0), walkable(true), tilesprite(-1), transparent(true), visible(false), discovered(false), color_overlay(0,0,0,255), tile_overlay(-1), uisprite(-1) +{}; + +void Grid::setSprite(int ti) +{ + int tx = ti % texture_width, ty = ti / texture_width; + sprite.setTextureRect(sf::IntRect(tx * grid_size, ty * grid_size, grid_size, grid_size)); +} + +Grid::Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h): + grid_size(gs), + grid_x(gx), grid_y(gy), + zoom(1.0f), center_x(gx), center_y(gy), + texture_width(12), texture_height(11) +{ + //grid_size = gs; + //zoom = 1.0f; + //grid_x = gx; + //grid_y = gy; + points.resize(gx*gy); + box.setSize(sf::Vector2f(_w, _h)); + box.setPosition(sf::Vector2f(_x, _y)); + box.setFillColor(sf::Color(0,0,0,0)); + + renderTexture.create(_w, _h); + + texture.loadFromFile("./assets/kenney_tinydungeon.png"); + texture.setSmooth(false); + sprite.setTexture(texture); + + //output.setSize(box.getSize()); + output.setTextureRect( + sf::IntRect(0, 0, + box.getSize().x, box.getSize().y)); + output.setPosition(box.getPosition()); + // textures are upside-down inside renderTexture + output.setTexture(renderTexture.getTexture()); + + // Show one texture at a time + sprite.setTexture(texture); +} + +void Grid::render(sf::RenderWindow & window) +{ + renderTexture.clear(); + //renderTexture.draw(box); + + // sprites that are visible according to zoom, center_x, center_y, and box width + auto box_size = box.getSize(); + float view_width = box_size.x / (grid_size * zoom); + float view_height = box_size.y / (grid_size * zoom); + + float top_offset = (center_y * grid_size) - box_size.y/2.0f; + float left_offset = (center_x * grid_size) - box_size.x/2.0f; + + sprite.setScale(sf::Vector2f(zoom, zoom)); + + auto box_pos = box.getPosition(); + + int x_start = std::floor(center_x - view_width/2.0f); + int x_end = std::ceil(center_x + view_width/2.0f); + int y_start = std::floor(center_y - view_height/2.0f); + int y_end = std::ceil(center_y + view_height/2.0f); + + for (int x = 0; + x < grid_x; //x < view_width; + x++) + { + for (int y = 0; + y < grid_y; //y < view_height; + y++) + { + // convert grid's coordinate to pixel coords to draw + //float window_x = (x_start + x) * grid_size * zoom; + //float window_y = (y_start + y) * grid_size * zoom; + float natural_x = x * grid_size * zoom; + float natural_y = y * grid_size * zoom; + sprite.setPosition( + sf::Vector2f(natural_x - left_offset, + natural_y - top_offset)); + + auto gridPoint = at(x, y); + // color? + + // tilesprite + // if discovered but not visible, set opacity to 90% + // if not discovered... just don't draw it? + setSprite(at(x, y).tilesprite); + renderTexture.draw(sprite); + + // overlay + + // uisprite + + } + } + + // grid lines for testing & validation + + + // render to window + renderTexture.display(); + window.draw(output); +} + +GridPoint& Grid::at(int x, int y) +{ + return points[y * grid_x + x]; +} diff --git a/src/Grid.h b/src/Grid.h new file mode 100644 index 0000000..41e00ed --- /dev/null +++ b/src/Grid.h @@ -0,0 +1,37 @@ +#include "Common.h" + +class GridPoint +{ +public: + // Layers: color, walkable, tilesprite, transparent, visible, discovered, overlay, uisprite + sf::Color color; + bool walkable; + int tilesprite; + bool transparent, visible, discovered; + sf::Color color_overlay; + int tile_overlay, uisprite; + GridPoint(); +}; + +class Grid +{ +private: + Grid(); + sf::RectangleShape box; // view on window + sf::Texture texture; + sf::Sprite sprite, output; + sf::RenderTexture renderTexture; + void setSprite(int); + const int texture_width, texture_height; + +public: + Grid(int gx, int gy, int gs, int _x, int _y, int _w, int _h); + int grid_x, grid_y; // rectangle map size (integer - sprites) + int grid_size; // pixel size of 1 sprite + float zoom, center_x, center_y; // center in fractional sprites + + std::vector points; // grid visible contents + void render(sf::RenderWindow&); // draw to screen + GridPoint& at(int, int); + +}; diff --git a/src/UITestScene.cpp b/src/UITestScene.cpp index be5c721..243b4a5 100644 --- a/src/UITestScene.cpp +++ b/src/UITestScene.cpp @@ -1,6 +1,7 @@ #include "UITestScene.h" #include "ActionCode.h" #include +#include sf::Texture texture; @@ -19,7 +20,7 @@ void setSpriteTexture(int ti) } UITestScene::UITestScene(GameEngine* g) -: Scene(g) +: Scene(g), grid(30, 10, 16, 20, 20, 400, 320) { // demo sprites from texture file texture.loadFromFile("./assets/kenney_tinydungeon.png"); @@ -27,10 +28,39 @@ UITestScene::UITestScene(GameEngine* g) // Show one texture at a time test_sprite.setTexture(texture); - test_sprite.setPosition(sf::Vector2f(50.0f, 50.0f)); + test_sprite.setPosition(sf::Vector2f(20.0f, 20.0f)); test_sprite.setScale(sf::Vector2f(4.0f, 4.0f)); setSpriteTexture(0); + // random for this test + //std::default_random_engine generator(42); + //std::normal_distribution distribution(0, 131); + std::random_device rd; // Will be used to obtain a seed for the random number engine + std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() + std::uniform_int_distribution<> distrib(0, 131); + // Use distrib to transform the random unsigned int + // generated by gen into an int in [1, 6] + //for (int n = 0; n != 10; ++n) + // std::cout << distrib(gen) << ' '; + // std::cout << '\n'; + + + // Test grid with random sprite noise + + for (int _x = 0; _x < 30; _x++) + for (int _y = 0; _y < 10; _y++) + //grid.at(_x, _y).tilesprite = _y*11 + _x; + //if (!_x % 2 || _y == 0) grid.at(_x, _y).tilesprite = 121; + //else + grid.at(_x, _y).tilesprite = distrib(gen); + + for (int _x = 0; _x < 30; _x++) + { + grid.at(_x, 0).tilesprite = 121; + grid.at(_x, 5).tilesprite = 123; + grid.at(_x, 9).tilesprite = 10; + } + // Load sound buffer.loadFromFile("./assets/boom.wav"); sound.setBuffer(buffer); @@ -187,13 +217,33 @@ void UITestScene::doAction(std::string name, std::string type) if (ACTION("sound_test", "start")) { sound.play(); } - if (ACTION("left", "start")) { viewport.move(-10, 0); } - if (ACTION("right", "start")) { viewport.move(10, 0); } - if (ACTION("up", "start")) { viewport.move(0, -10); } - if (ACTION("down", "start")) { viewport.move(0, 10); } - if (ACTION("down", "start")) { viewport.move(0, 10); } - if (ACTION("zoom_down", "start")) { if (zoom > 0.2f) zoom -= 0.1f; viewport.zoom(zoom); } - if (ACTION("zoom_up", "start")) { if (zoom < 10.0f) zoom += 0.1f; viewport.zoom(zoom); } + if (ACTION("left", "start")) { + //viewport.move(-10, 0); + grid.center_x -= 0.5; + } + if (ACTION("right", "start")) { + //viewport.move(10, 0); + grid.center_x += 0.5; + } + if (ACTION("up", "start")) { + //viewport.move(0, -10); + grid.center_y -= 0.5; + } + if (ACTION("down", "start")) { + //viewport.move(0, 10); + grid.center_y += 0.5; + } + //if (ACTION("down", "start")) { + // viewport.move(0, 10); + //} + if (ACTION("zoom_down", "start")) { + //if (zoom > 0.2f) zoom -= 0.1f; viewport.zoom(zoom); + if (grid.zoom > 0.75f) grid.zoom -= 0.25f; + } + if (ACTION("zoom_up", "start")) { + //if (zoom < 10.0f) zoom += 0.1f; viewport.zoom(zoom); + if (grid.zoom < 5.0f) grid.zoom += 0.25f; + } //std::cout << "viewport: " << viewport.getCenter().x << ", " << viewport.getCenter().y << std::endl; if (type.compare("resize")) // get center coordinate from game coordinate viewport, apply to new window viewport, restore zoom level @@ -273,6 +323,8 @@ void UITestScene::sRender() game->getWindow().draw(text); + //draw grid + grid.render(game->getWindow()); //test_button.render(game->getWindow()); //if (test_menu.visible) test_menu.render(game->getWindow()); @@ -286,12 +338,13 @@ void UITestScene::sRender() } // test Python sprite code - McRFPy_API::executePyString("mcrfpy.drawSprite(123, 10, 10)"); - McRFPy_API::executePyString("mcrfpy.drawSprite(121, 15, 15)"); + McRFPy_API::executePyString("mcrfpy.drawSprite(123, 36, 10)"); + //McRFPy_API::executePyString("mcrfpy.drawSprite(121, 15, 15)"); //game->api->executePyString("mcrfpy.drawSprite(123, 10, 10)") //game->api->executePyString("mcrfpy.drawSprite(121, 15, 15)") + // draw test sprite on top of everything game->getWindow().draw(test_sprite); diff --git a/src/UITestScene.h b/src/UITestScene.h index a42587f..539d934 100644 --- a/src/UITestScene.h +++ b/src/UITestScene.h @@ -6,6 +6,7 @@ #include "Button.h" #include "UIMenu.h" #include "VectorShape.h" +#include "Grid.h" class UITestScene: public Scene { @@ -21,6 +22,7 @@ class UITestScene: public Scene float zoom = 1; sf::Vector2f resolution; int grid_spacing = 500; + Grid grid; public: UITestScene(GameEngine*);