diff --git a/src/UI.cpp b/src/UI.cpp index 9cca1c2..634ea9b 100644 --- a/src/UI.cpp +++ b/src/UI.cpp @@ -146,6 +146,214 @@ PyObjectsEnum UISprite::derived_type() return PyObjectsEnum::UISPRITE; } +// UIGrid support classes' methods + +UIGridPoint::UIGridPoint() +:color(1.0f, 1.0f, 1.0f), color_overlay(0.0f, 0.0f, 0.0f), walkable(false), transparent(false), + tilesprite(-1), tile_overlay(-1), uisprite(-1) +{ +} + +// UIGrid methods + +UIGrid::UIGrid() +{ +} + +UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, float _x, float _y, float _w, float _h) +: grid_x(gx), grid_y(gy), + zoom(1.0f), center_x((gx/2) * _itex->grid_size), center_y((gy/2) * _itex->grid_size), + itex(_itex), points(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); + sprite.setTexture(_itex->texture); + 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()); +} + +UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, sf::Vector2f _xy, sf::Vector2f _wh) +: grid_x(gx), grid_y(gy), + zoom(1.0f), center_x((gx/2) * _itex->grid_size), center_y((gy/2) * _itex->grid_size), + itex(_itex), points(gx * gy) +{ + box.setSize(_wh); + box.setPosition(_xy); + + box.setFillColor(sf::Color(0,0,0,0)); + renderTexture.create(_wh.x, _wh.y); + sprite.setTexture(_itex->texture); + 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()); + +} + +void UIGrid::update() +{ +} + +void UIGrid::setSprite(int ti) +{ + int tx = ti % itex->grid_width, ty = ti / itex->grid_width; + sprite.setTextureRect(sf::IntRect(tx * itex->grid_size, ty * itex->grid_size, itex->grid_size, itex->grid_size)); +} + +void UIGrid::render(sf::Vector2f) +{ + renderTexture.clear(); + // sprites that are visible according to zoom, center_x, center_y, and box width + float center_x_sq = center_x / itex->grid_size; + float center_y_sq = center_y / itex->grid_size; + + float width_sq = box.getSize().x / (itex->grid_size * zoom); + float height_sq = box.getSize().y / (itex->grid_size * zoom); + float left_edge = center_x_sq - (width_sq / 2.0); + float top_edge = center_y_sq - (height_sq / 2.0); + + int left_spritepixels = center_x - (box.getSize().x / 2.0 / zoom); + int top_spritepixels = center_y - (box.getSize().y / 2.0 / zoom); + + sprite.setScale(sf::Vector2f(zoom, zoom)); + sf::RectangleShape r; // for colors and overlays + r.setSize(sf::Vector2f(itex->grid_size * zoom, itex->grid_size * zoom)); + r.setOutlineThickness(0); + + int x_limit = left_edge + width_sq + 2; + if (x_limit > grid_x) x_limit = grid_x; + + int y_limit = top_edge + height_sq + 2; + if (y_limit > grid_y) y_limit = grid_y; + + // base layer - bottom color, tile sprite ("ground") + for (int x = (left_edge - 1 >= 0 ? left_edge - 1 : 0); + x < x_limit; //x < view_width; + x+=1) + { + //for (float y = (top_edge >= 0 ? top_edge : 0); + for (int y = (top_edge - 1 >= 0 ? top_edge - 1 : 0); + y < y_limit; //y < view_height; + y+=1) + { + auto pixel_pos = sf::Vector2f( + (x*itex->grid_size - left_spritepixels) * zoom, + (y*itex->grid_size - top_spritepixels) * zoom ); + + auto gridpoint = at(std::floor(x), std::floor(y)); + + sprite.setPosition(pixel_pos); + + r.setPosition(pixel_pos); + r.setFillColor(gridpoint.color); + renderTexture.draw(r); + + // tilesprite + // if discovered but not visible, set opacity to 90% + // if not discovered... just don't draw it? + if (gridpoint.tilesprite != -1) { + setSprite(gridpoint.tilesprite); + renderTexture.draw(sprite); + } + } + } + + // middle layer - entities + /* // disabling entity rendering until I can render their UISprite inside the rendertexture (not directly to window) + for (auto e : entities) { + auto drawent = e->cGrid->indexsprite.drawable(); + drawent.setScale(zoom, zoom); + auto pixel_pos = sf::Vector2f( + (drawent.getPosition().x*grid_size - left_spritepixels) * zoom, + (drawent.getPosition().y*grid_size - top_spritepixels) * zoom ); + drawent.setPosition(pixel_pos); + renderTexture.draw(drawent); + } + */ + + // top layer - opacity for discovered / visible status (debug, basically) + /* // Disabled until I attach a "perspective" + for (int x = (left_edge - 1 >= 0 ? left_edge - 1 : 0); + x < x_limit; //x < view_width; + x+=1) + { + //for (float y = (top_edge >= 0 ? top_edge : 0); + for (int y = (top_edge - 1 >= 0 ? top_edge - 1 : 0); + y < y_limit; //y < view_height; + y+=1) + { + + auto pixel_pos = sf::Vector2f( + (x*itex->grid_size - left_spritepixels) * zoom, + (y*itex->grid_size - top_spritepixels) * zoom ); + + auto gridpoint = at(std::floor(x), std::floor(y)); + + sprite.setPosition(pixel_pos); + + r.setPosition(pixel_pos); + + // visible & discovered layers for testing purposes + if (!gridpoint.discovered) { + r.setFillColor(sf::Color(16, 16, 20, 192)); // 255 opacity for actual blackout + renderTexture.draw(r); + } else if (!gridpoint.visible) { + r.setFillColor(sf::Color(32, 32, 40, 128)); + renderTexture.draw(r); + } + + // overlay + + // uisprite + } + } + */ + + // grid lines for testing & validation + /* + sf::Vertex line[] = + { + sf::Vertex(sf::Vector2f(0, 0), sf::Color::Red), + sf::Vertex(box.getSize(), sf::Color::Red), + + }; + + renderTexture.draw(line, 2, sf::Lines); + sf::Vertex lineb[] = + { + sf::Vertex(sf::Vector2f(0, box.getSize().y), sf::Color::Blue), + sf::Vertex(sf::Vector2f(box.getSize().x, 0), sf::Color::Blue), + + }; + + renderTexture.draw(lineb, 2, sf::Lines); + */ + + // render to window + renderTexture.display(); + Resources::game->getWindow().draw(output); + +} + +UIGridPoint& UIGrid::at(int x, int y) +{ + return points[y * grid_x + x]; +} + +PyObjectsEnum UIGrid::derived_type() +{ + return PyObjectsEnum::UIGRID; +} + PyObject* DEFUNCT_py_instance(std::shared_ptr source) { // takes a UI drawable, calls its derived_type virtual function, and builds a Python object based on the return value. diff --git a/src/UI.h b/src/UI.h index 0b71a44..704b404 100644 --- a/src/UI.h +++ b/src/UI.h @@ -3,6 +3,7 @@ #include "Python.h" #include "structmember.h" #include "IndexTexture.h" +#include enum PyObjectsEnum { @@ -15,7 +16,7 @@ enum PyObjectsEnum class UIDrawable { public: - UIDrawable* parent; + //UIDrawable* parent; void render(); virtual void render(sf::Vector2f) = 0; //virtual sf::Rect aabb(); // not sure I care about this yet @@ -97,6 +98,59 @@ public: PyObjectsEnum derived_type() override final; // { return PyObjectsEnum::UISprite; }; }; +// UIGridPoint - revised grid data for each point +class UIGridPoint +{ +public: + sf::Color color, color_overlay; + bool walkable, transparent; + int tilesprite, tile_overlay, uisprite; + UIGridPoint(); +}; + +// UIGridPointState - entity-specific info for each cell +class UIGridPointState +{ +public: + bool visible, discovered; +}; + +class UIGrid; + +class UIEntity: public UIDrawable +{ +public: + //PyObject* self; + std::shared_ptr grid; + std::vector gridstate; + UISprite sprite; + void render(sf::Vector2f) override final; + +}; + +class UIGrid: public UIDrawable +{ +public: + UIGrid(); + UIGrid(int, int, IndexTexture*, float, float, float, float); + UIGrid(int, int, IndexTexture*, sf::Vector2f, sf::Vector2f); + void update(); + void render(sf::Vector2f) override final; + UIGridPoint& at(int, int); + PyObjectsEnum derived_type() override final; + void setSprite(int); + + int grid_x, grid_y; + //int grid_size; // grid sizes are implied by IndexTexture now + sf::RectangleShape box; + float center_x, center_y, zoom; + IndexTexture* itex; + sf::Sprite sprite, output; + sf::RenderTexture renderTexture; + std::vector points; + std::list> entities; +}; + /* template struct CPythonSharedObject { diff --git a/src/UITestScene.cpp b/src/UITestScene.cpp index b5904ab..10d73bb 100644 --- a/src/UITestScene.cpp +++ b/src/UITestScene.cpp @@ -101,6 +101,16 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g) if (ui) std::cout << "pointer to ui_elements now shows size=" << ui->size() << std::endl; */ + + // UIGrid test: (in grid cells) (in screen pixels) + // constructor args: w h texture x y w h + auto e5 = std::make_shared(4, 4, indextex, 550, 150, 200, 200); + e5->points[0].color = sf::Color(255, 0, 0); + e5->points[5].color = sf::Color(0, 255, 0); + e5->points[10].color = sf::Color(0, 0, 255); + e5->points[15].color = sf::Color(255, 255, 255); + + ui_elements->push_back(e5); } void UITestScene::update() @@ -145,5 +155,5 @@ void UITestScene::sRender() game->getWindow().display(); - McRFPy_API::REPL(); + //McRFPy_API::REPL(); }