pre-7DRL 2024 commit: got UIGrid to render. Needs entities, sprite tests, and python API

This commit is contained in:
John McCardle 2024-03-02 00:42:21 -05:00
parent 198ed337e3
commit 197211fa76
3 changed files with 274 additions and 2 deletions

View File

@ -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<UIDrawable> source)
{
// takes a UI drawable, calls its derived_type virtual function, and builds a Python object based on the return value.

View File

@ -3,6 +3,7 @@
#include "Python.h"
#include "structmember.h"
#include "IndexTexture.h"
#include <list>
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<int> 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<UIGrid> grid;
std::vector<UIGridPointState> 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<UIGridPoint> points;
std::list<std::shared_ptr<UIEntity>> entities;
};
/*
template<typename T>
struct CPythonSharedObject {

View File

@ -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<UIGrid>(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();
}