good progress, we're building again. Issue with Grid (tile sprite) textures and I think the sprite indexes are being calculated wrong (x and y transposed?)

This commit is contained in:
John McCardle 2024-03-16 21:53:24 -04:00
parent bfd33102d1
commit afd4ff1925
5 changed files with 65 additions and 56 deletions

View File

@ -1,13 +1,13 @@
#include "PyTexture.h"
PyTexture::PyTexture(std::string filename, int sprite_w, int sprite_h)
: sprite_width(sprite_w), sprite_height(sprite_h)
: source(filename), sprite_width(sprite_w), sprite_height(sprite_h)
{
texture = sf::Texture(source);
texture = sf::Texture();
texture.loadFromFile(source);
auto size = texture.getSize();
sheet_width = size.x;
sheet_height = size.y;
source = filename;
if (sheet_width % sprite_width != 0 || sheet_height % sprite_height != 0)
{
std::cout << "Warning: Texture `" << source << "` is not an even number of sprite widths or heights across." << std::endl
@ -15,7 +15,7 @@ PyTexture::PyTexture(std::string filename, int sprite_w, int sprite_h)
}
}
sf::Sprite PyTexture::sprite(int index, sf::Vector2f pos = sf::Vector2f(0, 0), sf::Vector2f s = sf::Vector2f(1.0, 1.0))
sf::Sprite PyTexture::sprite(int index, sf::Vector2f pos, sf::Vector2f s)
{
int tx = index % sprite_width, ty = index / sprite_height;
auto ir = sf::IntRect(tx * sprite_width, ty * sprite_height, sprite_width, sprite_height);

View File

@ -7,8 +7,9 @@ class PyTexture
private:
sf::Texture texture;
std::string source;
int sprite_width, sprite_height, sheet_width, sheet_height;
int sheet_width, sheet_height;
public:
int sprite_width, sprite_height; // just use them read only, OK?
PyTexture(std::string filename, int sprite_w, int sprite_h);
sf::Sprite sprite(int index, sf::Vector2f pos = sf::Vector2f(0, 0), sf::Vector2f s = sf::Vector2f(1.0, 1.0));
};

View File

@ -192,7 +192,7 @@ UISprite::UISprite(IndexTexture* _itex, int _sprite_index, sf::Vector2f pos, flo
UISprite::UISprite(std::shared_ptr<PyTexture> _ptex, int _sprite_index, sf::Vector2f _pos, float _scale)
: ptex(_ptex), sprite_index(_sprite_index)
{
sprite = ptex(sprite_index, _pos, sf::Vector2f(_scale, _scale));
sprite = ptex->sprite(sprite_index, _pos, sf::Vector2f(_scale, _scale));
}
//void UISprite::update()
@ -237,7 +237,7 @@ void UISprite::setScale(sf::Vector2f s)
sprite.setScale(s);
}
void UISprite::setTexture(std::shared_ptr<PyTexture> _ptex, int _sprite_index=-1)
void UISprite::setTexture(std::shared_ptr<PyTexture> _ptex, int _sprite_index)
{
ptex = _ptex;
if (_sprite_index != -1) // if you are changing textures, there's a good chance you need a new index too
@ -302,9 +302,10 @@ UIGrid::UIGrid()
{
}
UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, float _x, float _y, float _w, float _h)
/*
UIGrid::UIGrid(int gx, int gy, std::shared_ptr<PyTexture> _ptex, 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),
zoom(1.0f), center_x((gx/2) * _ptex->sheet_width), center_y((gy/2) * _ptex->sheet_height),
itex(_itex), points(gx * gy)
{
// set up blank list of entities
@ -323,11 +324,12 @@ UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, float _x, float _y, float _w
// textures are upside-down inside renderTexture
output.setTexture(renderTexture.getTexture());
}
*/
UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, sf::Vector2f _xy, sf::Vector2f _wh)
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) * _itex->grid_size), center_y((gy/2) * _itex->grid_size),
itex(_itex), points(gx * gy)
zoom(1.0f), center_x((gx/2) * _ptex->sprite_width), center_y((gy/2) * _ptex->sprite_height),
ptex(_ptex), points(gx * gy)
{
// set up blank list of entities
entities = std::make_shared<std::list<std::shared_ptr<UIEntity>>>();
@ -340,7 +342,9 @@ UIGrid::UIGrid(int gx, int gy, IndexTexture* _itex, sf::Vector2f _xy, sf::Vector
// 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.setTexture(_itex->texture);
//sprite.setTexture(_itex->texture);
sprite = ptex->sprite(0);
output.setTextureRect(
sf::IntRect(0, 0,
box.getSize().x, box.getSize().y));
@ -354,11 +358,14 @@ 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));
//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));
sprite = ptex->sprite(ti);
}
*/
void UIGrid::render(sf::Vector2f)
{
@ -369,11 +376,11 @@ void UIGrid::render(sf::Vector2f)
box.getSize().x, box.getSize().y));
renderTexture.clear(sf::Color(8, 8, 8, 255)); // TODO - UIGrid needs a "background color" field
// 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 center_x_sq = center_x / ptex->sprite_width;
float center_y_sq = center_y / ptex->sprite_height;
float width_sq = box.getSize().x / (itex->grid_size * zoom);
float height_sq = box.getSize().y / (itex->grid_size * zoom);
float width_sq = box.getSize().x / (ptex->sprite_width * zoom);
float height_sq = box.getSize().y / (ptex->sprite_height * zoom);
float left_edge = center_x_sq - (width_sq / 2.0);
float top_edge = center_y_sq - (height_sq / 2.0);
@ -382,7 +389,7 @@ void UIGrid::render(sf::Vector2f)
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.setSize(sf::Vector2f(ptex->sprite_width * zoom, ptex->sprite_height * zoom));
r.setOutlineThickness(0);
int x_limit = left_edge + width_sq + 2;
@ -402,8 +409,8 @@ void UIGrid::render(sf::Vector2f)
y+=1)
{
auto pixel_pos = sf::Vector2f(
(x*itex->grid_size - left_spritepixels) * zoom,
(y*itex->grid_size - top_spritepixels) * zoom );
(x*ptex->sprite_width - left_spritepixels) * zoom,
(y*ptex->sprite_height - top_spritepixels) * zoom );
auto gridpoint = at(std::floor(x), std::floor(y));
@ -417,7 +424,7 @@ void UIGrid::render(sf::Vector2f)
// if discovered but not visible, set opacity to 90%
// if not discovered... just don't draw it?
if (gridpoint.tilesprite != -1) {
setSprite(gridpoint.tilesprite);
sprite = ptex->sprite(gridpoint.tilesprite); //setSprite(gridpoint.tilesprite);
renderTexture.draw(sprite);
}
}
@ -430,10 +437,10 @@ void UIGrid::render(sf::Vector2f)
//auto drawent = e->cGrid->indexsprite.drawable();
auto& drawent = e->sprite;
//drawent.setScale(zoom, zoom);
drawent.setScale(zoom);
drawent.setScale(sf::Vector2f(zoom, zoom));
auto pixel_pos = sf::Vector2f(
(e->position.x*itex->grid_size - left_spritepixels) * zoom,
(e->position.y*itex->grid_size - top_spritepixels) * zoom );
(e->position.x*ptex->sprite_width - left_spritepixels) * zoom,
(e->position.y*ptex->sprite_height - top_spritepixels) * zoom );
//drawent.setPosition(pixel_pos);
//renderTexture.draw(drawent);
drawent.render(pixel_pos, renderTexture);

View File

@ -173,13 +173,13 @@ private:
std::shared_ptr<PyTexture> ptex;
public:
UIGrid();
UIGrid(int, int, IndexTexture*, float, float, float, float);
UIGrid(int, int, IndexTexture*, sf::Vector2f, sf::Vector2f);
//UIGrid(int, int, IndexTexture*, float, float, float, float);
UIGrid(int, int, std::shared_ptr<PyTexture>, sf::Vector2f, sf::Vector2f);
void update();
void render(sf::Vector2f) override final;
UIGridPoint& at(int, int);
PyObjectsEnum derived_type() override final;
void setSprite(int);
//void setSprite(int);
virtual UIDrawable* click_at(sf::Vector2f point) override final;
int grid_x, grid_y;
@ -217,7 +217,7 @@ typedef struct {
typedef struct {
PyObject_HEAD
std::shared_ptr<UISprite> data;
PyObject* texture;
//PyObject* texture;
} PyUISpriteObject;
typedef struct {
@ -241,13 +241,13 @@ typedef struct {
typedef struct {
PyObject_HEAD
std::shared_ptr<UIEntity> data;
PyObject* texture;
//PyObject* texture;
} PyUIEntityObject;
typedef struct {
PyObject_HEAD
std::shared_ptr<UIGrid> data;
PyObject* texture;
//PyObject* texture;
} PyUIGridObject;
namespace mcrfpydef {
@ -1265,16 +1265,16 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c
if (texture != NULL && !PyObject_IsInstance(texture, (PyObject*)&PyTextureType)){
PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance");
return -1;
} else if (texture != NULL)
} /*else if (texture != NULL) // to be removed: UIObjects don't manage texture references
{
self->texture = texture;
Py_INCREF(texture);
} else
{
// default tex?
}
}*/
auto pytexture = (PyTextureObject*)texture;
self->data = std::make_shared<UISprite>(pytexture->data.get(), sprite_index, sf::Vector2f(x, y), scale);
self->data = std::make_shared<UISprite>(pytexture->data, sprite_index, sf::Vector2f(x, y), scale);
self->data->setPosition(sf::Vector2f(x, y));
return 0;
@ -1289,7 +1289,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c
{
PyUISpriteObject* obj = (PyUISpriteObject*)self;
// release reference to font object
if (obj->texture) Py_DECREF(obj->texture);
//if (obj->texture) Py_DECREF(obj->texture);
obj->data.reset();
Py_TYPE(self)->tp_free(self);
},
@ -1669,7 +1669,8 @@ static int PyUIGrid_init(PyUIGridObject* self, PyObject* args, PyObject* kwds) {
// Initialize UIGrid
//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, box_x, box_y, 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));
return 0; // Success
}
@ -1909,14 +1910,14 @@ static int PyUIEntity_init(PyUIEntityObject* self, PyObject* args, PyObject* kwd
if (texture != NULL && !PyObject_IsInstance(texture, (PyObject*)&PyTextureType)){
PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance");
return -1;
} else if (texture != NULL)
} /*else if (texture != NULL) // this section needs to go; texture isn't optional and isn't managed by the UI objects anymore
{
self->texture = texture;
Py_INCREF(texture);
} else
{
// default tex?
}
}*/
if (grid != NULL && !PyObject_IsInstance(grid, (PyObject*)&PyUIGridType)) {
PyErr_SetString(PyExc_TypeError, "grid must be a mcrfpy.Grid instance");

View File

@ -61,15 +61,15 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
//ui_elements.push_back(&e1);
//ui_elements.push_back(&e2);
t.loadFromFile("./assets/kenney_tinydungeon.png");
t.setSmooth(false);
auto* indextex = new IndexTexture(t, 16, 12, 11);
Resources::game->textures.push_back(*indextex);
//t.loadFromFile("./assets/kenney_tinydungeon.png");
//t.setSmooth(false);
//auto* indextex = new IndexTexture(t, 16, 12, 11);
//Resources::game->textures.push_back(*indextex);
auto ptex = std::make_shared<PyTexture>("./assets/kenney_tinydungeon.png", 16, 16);
//std::cout << Resources::game->textures.size() << " textures loaded.\n";
auto e3 = std::make_shared<UISprite>();
auto e3 = std::make_shared<UISprite>(ptex, 84, sf::Vector2f(10, 10), 4.0);
// Make UISprite more like IndexSprite: this is bad
//e3->x = 10; e3->y = 10;
@ -79,19 +79,19 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
//e3->update();
// This goes to show how inconvenient the default constructor is. It should be removed
e3->itex = &Resources::game->textures[0];
e3->sprite.setTexture(e3->itex->texture);
e3->sprite_index = 84;
e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index));
e3->setPosition(10, 10);
e3->setScale(4.0f);
//e3->itex = &Resources::game->textures[0];
//e3->sprite.setTexture(e3->itex->texture);
//e3->sprite_index = 84;
//e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index));
//e3->setPosition(10, 10);
//e3->setScale(4.0f);
e1aa->children->push_back(e3);
auto e4 = std::make_shared<UISprite>(
indextex, //&Resources::game->textures[0],
ptex, //indextex, //&Resources::game->textures[0],
85, sf::Vector2f(90, 10), 4.0);
e1aa->children->push_back(e4);
//std::cout << "UISprite built: " << e4->sprite.getPosition().x << " " << e4->sprite.getPosition().y << " " << e4->sprite.getScale().x << " " <<
@ -104,9 +104,9 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
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);
// 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, ptex, sf::Vector2f(550, 150), sf::Vector2f(200, 200));
e5->zoom=2.0;
e5->points[0].color = sf::Color(255, 0, 0);
e5->points[1].tilesprite = 1;
@ -125,7 +125,7 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
e5a->grid = e5;
//auto e5as = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0);
//e5a->sprite = e5as; // will copy constructor even exist for UISprite...?
e5a->sprite = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0);
e5a->sprite = UISprite(ptex, 85, sf::Vector2f(0, 0), 1.0);
e5a->position = sf::Vector2f(1, 0);
e5->entities->push_back(e5a);