Fix Grid to support None/null texture and fix error message bug
- Allow Grid to be created with None as texture parameter - Use default cell dimensions (16x16) when no texture provided - Skip sprite rendering when texture is null, but still render colors - Fix issue #77: Corrected copy/paste error in Grid.at() error messages - Grid now functional for color-only rendering and entity positioning Test created to verify Grid works without texture, showing colored cells. Closes #77
This commit is contained in:
parent
18cfe93a44
commit
1c71d8d4f7
4 changed files with 186 additions and 26 deletions
|
|
@ -6,9 +6,15 @@ UIGrid::UIGrid() {}
|
|||
|
||||
UIGrid::UIGrid(int gx, int gy, std::shared_ptr<PyTexture> _ptex, sf::Vector2f _xy, sf::Vector2f _wh)
|
||||
: grid_x(gx), grid_y(gy),
|
||||
zoom(1.0f), center_x((gx/2) * _ptex->sprite_width), center_y((gy/2) * _ptex->sprite_height),
|
||||
zoom(1.0f),
|
||||
ptex(_ptex), points(gx * gy)
|
||||
{
|
||||
// Use texture dimensions if available, otherwise use defaults
|
||||
int cell_width = _ptex ? _ptex->sprite_width : DEFAULT_CELL_WIDTH;
|
||||
int cell_height = _ptex ? _ptex->sprite_height : DEFAULT_CELL_HEIGHT;
|
||||
|
||||
center_x = (gx/2) * cell_width;
|
||||
center_y = (gy/2) * cell_height;
|
||||
entities = std::make_shared<std::list<std::shared_ptr<UIEntity>>>();
|
||||
|
||||
box.setSize(_wh);
|
||||
|
|
@ -18,7 +24,10 @@ UIGrid::UIGrid(int gx, int gy, std::shared_ptr<PyTexture> _ptex, sf::Vector2f _x
|
|||
// create renderTexture with maximum theoretical size; sprite can resize to show whatever amount needs to be rendered
|
||||
renderTexture.create(1920, 1080); // TODO - renderTexture should be window size; above 1080p this will cause rendering errors
|
||||
|
||||
sprite = ptex->sprite(0);
|
||||
// Only initialize sprite if texture is available
|
||||
if (ptex) {
|
||||
sprite = ptex->sprite(0);
|
||||
}
|
||||
|
||||
output.setTextureRect(
|
||||
sf::IntRect(0, 0,
|
||||
|
|
@ -40,12 +49,17 @@ void UIGrid::render(sf::Vector2f offset, sf::RenderTarget& target)
|
|||
sf::IntRect(0, 0,
|
||||
box.getSize().x, box.getSize().y));
|
||||
renderTexture.clear(sf::Color(8, 8, 8, 255)); // TODO - UIGrid needs a "background color" field
|
||||
|
||||
// Get cell dimensions - use texture if available, otherwise defaults
|
||||
int cell_width = ptex ? ptex->sprite_width : DEFAULT_CELL_WIDTH;
|
||||
int cell_height = ptex ? ptex->sprite_height : DEFAULT_CELL_HEIGHT;
|
||||
|
||||
// sprites that are visible according to zoom, center_x, center_y, and box width
|
||||
float center_x_sq = center_x / ptex->sprite_width;
|
||||
float center_y_sq = center_y / ptex->sprite_height;
|
||||
float center_x_sq = center_x / cell_width;
|
||||
float center_y_sq = center_y / cell_height;
|
||||
|
||||
float width_sq = box.getSize().x / (ptex->sprite_width * zoom);
|
||||
float height_sq = box.getSize().y / (ptex->sprite_height * zoom);
|
||||
float width_sq = box.getSize().x / (cell_width * zoom);
|
||||
float height_sq = box.getSize().y / (cell_height * zoom);
|
||||
float left_edge = center_x_sq - (width_sq / 2.0);
|
||||
float top_edge = center_y_sq - (height_sq / 2.0);
|
||||
|
||||
|
|
@ -54,7 +68,7 @@ void UIGrid::render(sf::Vector2f offset, sf::RenderTarget& target)
|
|||
|
||||
//sprite.setScale(sf::Vector2f(zoom, zoom));
|
||||
sf::RectangleShape r; // for colors and overlays
|
||||
r.setSize(sf::Vector2f(ptex->sprite_width * zoom, ptex->sprite_height * zoom));
|
||||
r.setSize(sf::Vector2f(cell_width * zoom, cell_height * zoom));
|
||||
r.setOutlineThickness(0);
|
||||
|
||||
int x_limit = left_edge + width_sq + 2;
|
||||
|
|
@ -74,8 +88,8 @@ void UIGrid::render(sf::Vector2f offset, sf::RenderTarget& target)
|
|||
y+=1)
|
||||
{
|
||||
auto pixel_pos = sf::Vector2f(
|
||||
(x*ptex->sprite_width - left_spritepixels) * zoom,
|
||||
(y*ptex->sprite_height - top_spritepixels) * zoom );
|
||||
(x*cell_width - left_spritepixels) * zoom,
|
||||
(y*cell_height - top_spritepixels) * zoom );
|
||||
|
||||
auto gridpoint = at(std::floor(x), std::floor(y));
|
||||
|
||||
|
|
@ -85,10 +99,10 @@ void UIGrid::render(sf::Vector2f offset, sf::RenderTarget& target)
|
|||
r.setFillColor(gridpoint.color);
|
||||
renderTexture.draw(r);
|
||||
|
||||
// tilesprite
|
||||
// tilesprite - only draw if texture is available
|
||||
// if discovered but not visible, set opacity to 90%
|
||||
// if not discovered... just don't draw it?
|
||||
if (gridpoint.tilesprite != -1) {
|
||||
if (ptex && gridpoint.tilesprite != -1) {
|
||||
sprite = ptex->sprite(gridpoint.tilesprite, pixel_pos, sf::Vector2f(zoom, zoom)); //setSprite(gridpoint.tilesprite);;
|
||||
renderTexture.draw(sprite);
|
||||
}
|
||||
|
|
@ -104,8 +118,8 @@ void UIGrid::render(sf::Vector2f offset, sf::RenderTarget& target)
|
|||
//drawent.setScale(zoom, zoom);
|
||||
drawent.setScale(sf::Vector2f(zoom, zoom));
|
||||
auto pixel_pos = sf::Vector2f(
|
||||
(e->position.x*ptex->sprite_width - left_spritepixels) * zoom,
|
||||
(e->position.y*ptex->sprite_height - top_spritepixels) * zoom );
|
||||
(e->position.x*cell_width - left_spritepixels) * zoom,
|
||||
(e->position.y*cell_height - top_spritepixels) * zoom );
|
||||
//drawent.setPosition(pixel_pos);
|
||||
//renderTexture.draw(drawent);
|
||||
drawent.render(pixel_pos, renderTexture);
|
||||
|
|
@ -229,21 +243,25 @@ int UIGrid::init(PyUIGridObject* self, PyObject* args, PyObject* kwds) {
|
|||
|
||||
// Convert PyObject texture to IndexTexture*
|
||||
// This requires the texture object to have been initialized similar to UISprite's texture handling
|
||||
|
||||
//if (!PyObject_IsInstance(textureObj, (PyObject*)&PyTextureType)) {
|
||||
if (!PyObject_IsInstance(textureObj, PyObject_GetAttrString(McRFPy_API::mcrf_module, "Texture"))) {
|
||||
PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance");
|
||||
return -1;
|
||||
}
|
||||
PyTextureObject* pyTexture = reinterpret_cast<PyTextureObject*>(textureObj);
|
||||
// TODO (7DRL day 2, item 4.) use shared_ptr / PyTextureObject on UIGrid
|
||||
//IndexTexture* texture = pyTexture->data.get();
|
||||
|
||||
// Initialize UIGrid
|
||||
std::shared_ptr<PyTexture> texture_ptr = nullptr;
|
||||
|
||||
// Allow None for texture
|
||||
if (textureObj != Py_None) {
|
||||
//if (!PyObject_IsInstance(textureObj, (PyObject*)&PyTextureType)) {
|
||||
if (!PyObject_IsInstance(textureObj, PyObject_GetAttrString(McRFPy_API::mcrf_module, "Texture"))) {
|
||||
PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance or None");
|
||||
return -1;
|
||||
}
|
||||
PyTextureObject* pyTexture = reinterpret_cast<PyTextureObject*>(textureObj);
|
||||
texture_ptr = pyTexture->data;
|
||||
}
|
||||
|
||||
// Initialize UIGrid - texture_ptr will be nullptr if texture was None
|
||||
//self->data = new UIGrid(grid_x, grid_y, texture, sf::Vector2f(box_x, box_y), sf::Vector2f(box_w, box_h));
|
||||
//self->data = std::make_shared<UIGrid>(grid_x, grid_y, pyTexture->data,
|
||||
// sf::Vector2f(box_x, box_y), sf::Vector2f(box_w, box_h));
|
||||
self->data = std::make_shared<UIGrid>(grid_x, grid_y, pyTexture->data, pos_result->data, size_result->data);
|
||||
self->data = std::make_shared<UIGrid>(grid_x, grid_y, texture_ptr, pos_result->data, size_result->data);
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
|
|
@ -365,9 +383,16 @@ PyObject* UIGrid::get_texture(PyUIGridObject* self, void* closure) {
|
|||
//return self->data->getTexture()->pyObject();
|
||||
// PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPointState")
|
||||
//PyTextureObject* obj = (PyTextureObject*)((&PyTextureType)->tp_alloc(&PyTextureType, 0));
|
||||
|
||||
// Return None if no texture
|
||||
auto texture = self->data->getTexture();
|
||||
if (!texture) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
auto type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Texture");
|
||||
auto obj = (PyTextureObject*)type->tp_alloc(type, 0);
|
||||
obj->data = self->data->getTexture();
|
||||
obj->data = texture;
|
||||
return (PyObject*)obj;
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +404,7 @@ PyObject* UIGrid::py_at(PyUIGridObject* self, PyObject* o)
|
|||
return NULL;
|
||||
}
|
||||
if (x < 0 || x >= self->data->grid_x) {
|
||||
PyErr_SetString(PyExc_ValueError, "x value out of range (0, Grid.grid_y)");
|
||||
PyErr_SetString(PyExc_ValueError, "x value out of range (0, Grid.grid_x)");
|
||||
return NULL;
|
||||
}
|
||||
if (y < 0 || y >= self->data->grid_y) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ class UIGrid: public UIDrawable
|
|||
{
|
||||
private:
|
||||
std::shared_ptr<PyTexture> ptex;
|
||||
// Default cell dimensions when no texture is provided
|
||||
static constexpr int DEFAULT_CELL_WIDTH = 16;
|
||||
static constexpr int DEFAULT_CELL_HEIGHT = 16;
|
||||
public:
|
||||
UIGrid();
|
||||
//UIGrid(int, int, IndexTexture*, float, float, float, float);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue