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" #include "PyTexture.h"
PyTexture::PyTexture(std::string filename, int sprite_w, int sprite_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(); auto size = texture.getSize();
sheet_width = size.x; sheet_width = size.x;
sheet_height = size.y; sheet_height = size.y;
source = filename;
if (sheet_width % sprite_width != 0 || sheet_height % sprite_height != 0) 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 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; int tx = index % sprite_width, ty = index / sprite_height;
auto ir = sf::IntRect(tx * sprite_width, ty * sprite_height, sprite_width, 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: private:
sf::Texture texture; sf::Texture texture;
std::string source; std::string source;
int sprite_width, sprite_height, sheet_width, sheet_height; int sheet_width, sheet_height;
public: public:
int sprite_width, sprite_height; // just use them read only, OK?
PyTexture(std::string filename, int sprite_w, int sprite_h); 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)); 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) UISprite::UISprite(std::shared_ptr<PyTexture> _ptex, int _sprite_index, sf::Vector2f _pos, float _scale)
: ptex(_ptex), sprite_index(_sprite_index) : 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() //void UISprite::update()
@ -237,7 +237,7 @@ void UISprite::setScale(sf::Vector2f s)
sprite.setScale(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; ptex = _ptex;
if (_sprite_index != -1) // if you are changing textures, there's a good chance you need a new index too 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), : 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) itex(_itex), points(gx * gy)
{ {
// set up blank list of entities // 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 // textures are upside-down inside renderTexture
output.setTexture(renderTexture.getTexture()); 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), : 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->sprite_width), center_y((gy/2) * _ptex->sprite_height),
itex(_itex), points(gx * gy) ptex(_ptex), points(gx * gy)
{ {
// set up blank list of entities // set up blank list of entities
entities = std::make_shared<std::list<std::shared_ptr<UIEntity>>>(); 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 // 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 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( output.setTextureRect(
sf::IntRect(0, 0, sf::IntRect(0, 0,
box.getSize().x, box.getSize().y)); box.getSize().x, box.getSize().y));
@ -354,11 +358,14 @@ void UIGrid::update()
{ {
} }
/*
void UIGrid::setSprite(int ti) void UIGrid::setSprite(int ti)
{ {
int tx = ti % itex->grid_width, ty = ti / itex->grid_width; //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.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) void UIGrid::render(sf::Vector2f)
{ {
@ -369,11 +376,11 @@ void UIGrid::render(sf::Vector2f)
box.getSize().x, box.getSize().y)); box.getSize().x, box.getSize().y));
renderTexture.clear(sf::Color(8, 8, 8, 255)); // TODO - UIGrid needs a "background color" field 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 // 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_x_sq = center_x / ptex->sprite_width;
float center_y_sq = center_y / itex->grid_size; float center_y_sq = center_y / ptex->sprite_height;
float width_sq = box.getSize().x / (itex->grid_size * zoom); float width_sq = box.getSize().x / (ptex->sprite_width * zoom);
float height_sq = box.getSize().y / (itex->grid_size * zoom); float height_sq = box.getSize().y / (ptex->sprite_height * zoom);
float left_edge = center_x_sq - (width_sq / 2.0); float left_edge = center_x_sq - (width_sq / 2.0);
float top_edge = center_y_sq - (height_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)); sprite.setScale(sf::Vector2f(zoom, zoom));
sf::RectangleShape r; // for colors and overlays 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); r.setOutlineThickness(0);
int x_limit = left_edge + width_sq + 2; int x_limit = left_edge + width_sq + 2;
@ -402,8 +409,8 @@ void UIGrid::render(sf::Vector2f)
y+=1) y+=1)
{ {
auto pixel_pos = sf::Vector2f( auto pixel_pos = sf::Vector2f(
(x*itex->grid_size - left_spritepixels) * zoom, (x*ptex->sprite_width - left_spritepixels) * zoom,
(y*itex->grid_size - top_spritepixels) * zoom ); (y*ptex->sprite_height - top_spritepixels) * zoom );
auto gridpoint = at(std::floor(x), std::floor(y)); 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 discovered but not visible, set opacity to 90%
// if not discovered... just don't draw it? // if not discovered... just don't draw it?
if (gridpoint.tilesprite != -1) { if (gridpoint.tilesprite != -1) {
setSprite(gridpoint.tilesprite); sprite = ptex->sprite(gridpoint.tilesprite); //setSprite(gridpoint.tilesprite);
renderTexture.draw(sprite); renderTexture.draw(sprite);
} }
} }
@ -430,10 +437,10 @@ void UIGrid::render(sf::Vector2f)
//auto drawent = e->cGrid->indexsprite.drawable(); //auto drawent = e->cGrid->indexsprite.drawable();
auto& drawent = e->sprite; auto& drawent = e->sprite;
//drawent.setScale(zoom, zoom); //drawent.setScale(zoom, zoom);
drawent.setScale(zoom); drawent.setScale(sf::Vector2f(zoom, zoom));
auto pixel_pos = sf::Vector2f( auto pixel_pos = sf::Vector2f(
(e->position.x*itex->grid_size - left_spritepixels) * zoom, (e->position.x*ptex->sprite_width - left_spritepixels) * zoom,
(e->position.y*itex->grid_size - top_spritepixels) * zoom ); (e->position.y*ptex->sprite_height - top_spritepixels) * zoom );
//drawent.setPosition(pixel_pos); //drawent.setPosition(pixel_pos);
//renderTexture.draw(drawent); //renderTexture.draw(drawent);
drawent.render(pixel_pos, renderTexture); drawent.render(pixel_pos, renderTexture);

View File

@ -173,13 +173,13 @@ private:
std::shared_ptr<PyTexture> ptex; std::shared_ptr<PyTexture> ptex;
public: public:
UIGrid(); UIGrid();
UIGrid(int, int, IndexTexture*, float, float, float, float); //UIGrid(int, int, IndexTexture*, float, float, float, float);
UIGrid(int, int, IndexTexture*, sf::Vector2f, sf::Vector2f); UIGrid(int, int, std::shared_ptr<PyTexture>, sf::Vector2f, sf::Vector2f);
void update(); void update();
void render(sf::Vector2f) override final; void render(sf::Vector2f) override final;
UIGridPoint& at(int, int); UIGridPoint& at(int, int);
PyObjectsEnum derived_type() override final; PyObjectsEnum derived_type() override final;
void setSprite(int); //void setSprite(int);
virtual UIDrawable* click_at(sf::Vector2f point) override final; virtual UIDrawable* click_at(sf::Vector2f point) override final;
int grid_x, grid_y; int grid_x, grid_y;
@ -217,7 +217,7 @@ typedef struct {
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
std::shared_ptr<UISprite> data; std::shared_ptr<UISprite> data;
PyObject* texture; //PyObject* texture;
} PyUISpriteObject; } PyUISpriteObject;
typedef struct { typedef struct {
@ -241,13 +241,13 @@ typedef struct {
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
std::shared_ptr<UIEntity> data; std::shared_ptr<UIEntity> data;
PyObject* texture; //PyObject* texture;
} PyUIEntityObject; } PyUIEntityObject;
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
std::shared_ptr<UIGrid> data; std::shared_ptr<UIGrid> data;
PyObject* texture; //PyObject* texture;
} PyUIGridObject; } PyUIGridObject;
namespace mcrfpydef { 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)){ if (texture != NULL && !PyObject_IsInstance(texture, (PyObject*)&PyTextureType)){
PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance"); PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance");
return -1; return -1;
} else if (texture != NULL) } /*else if (texture != NULL) // to be removed: UIObjects don't manage texture references
{ {
self->texture = texture; self->texture = texture;
Py_INCREF(texture); Py_INCREF(texture);
} else } else
{ {
// default tex? // default tex?
} }*/
auto pytexture = (PyTextureObject*)texture; 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)); self->data->setPosition(sf::Vector2f(x, y));
return 0; return 0;
@ -1289,7 +1289,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c
{ {
PyUISpriteObject* obj = (PyUISpriteObject*)self; PyUISpriteObject* obj = (PyUISpriteObject*)self;
// release reference to font object // release reference to font object
if (obj->texture) Py_DECREF(obj->texture); //if (obj->texture) Py_DECREF(obj->texture);
obj->data.reset(); obj->data.reset();
Py_TYPE(self)->tp_free(self); Py_TYPE(self)->tp_free(self);
}, },
@ -1669,7 +1669,8 @@ static int PyUIGrid_init(PyUIGridObject* self, PyObject* args, PyObject* kwds) {
// Initialize UIGrid // 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 = 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 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)){ if (texture != NULL && !PyObject_IsInstance(texture, (PyObject*)&PyTextureType)){
PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance"); PyErr_SetString(PyExc_TypeError, "texture must be a mcrfpy.Texture instance");
return -1; 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; self->texture = texture;
Py_INCREF(texture); Py_INCREF(texture);
} else } else
{ {
// default tex? // default tex?
} }*/
if (grid != NULL && !PyObject_IsInstance(grid, (PyObject*)&PyUIGridType)) { if (grid != NULL && !PyObject_IsInstance(grid, (PyObject*)&PyUIGridType)) {
PyErr_SetString(PyExc_TypeError, "grid must be a mcrfpy.Grid instance"); 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(&e1);
//ui_elements.push_back(&e2); //ui_elements.push_back(&e2);
t.loadFromFile("./assets/kenney_tinydungeon.png"); //t.loadFromFile("./assets/kenney_tinydungeon.png");
t.setSmooth(false); //t.setSmooth(false);
auto* indextex = new IndexTexture(t, 16, 12, 11); //auto* indextex = new IndexTexture(t, 16, 12, 11);
Resources::game->textures.push_back(*indextex); //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"; //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 // Make UISprite more like IndexSprite: this is bad
//e3->x = 10; e3->y = 10; //e3->x = 10; e3->y = 10;
@ -79,19 +79,19 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
//e3->update(); //e3->update();
// This goes to show how inconvenient the default constructor is. It should be removed // This goes to show how inconvenient the default constructor is. It should be removed
e3->itex = &Resources::game->textures[0]; //e3->itex = &Resources::game->textures[0];
e3->sprite.setTexture(e3->itex->texture); //e3->sprite.setTexture(e3->itex->texture);
e3->sprite_index = 84; //e3->sprite_index = 84;
e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index)); //e3->sprite.setTextureRect(e3->itex->spriteCoordinates(e3->sprite_index));
e3->setPosition(10, 10); //e3->setPosition(10, 10);
e3->setScale(4.0f); //e3->setScale(4.0f);
e1aa->children->push_back(e3); e1aa->children->push_back(e3);
auto e4 = std::make_shared<UISprite>( auto e4 = std::make_shared<UISprite>(
indextex, //&Resources::game->textures[0], ptex, //indextex, //&Resources::game->textures[0],
85, sf::Vector2f(90, 10), 4.0); 85, sf::Vector2f(90, 10), 4.0);
e1aa->children->push_back(e4); e1aa->children->push_back(e4);
//std::cout << "UISprite built: " << e4->sprite.getPosition().x << " " << e4->sprite.getPosition().y << " " << e4->sprite.getScale().x << " " << //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; std::cout << "pointer to ui_elements now shows size=" << ui->size() << std::endl;
*/ */
// UIGrid test: (in grid cells) (in screen pixels) // UIGrid test: (in grid cells) ( in screen pixels )
// constructor args: w h texture x y w h // constructor args: w h texture x y w h
auto e5 = std::make_shared<UIGrid>(4, 4, indextex, 550, 150, 200, 200); auto e5 = std::make_shared<UIGrid>(4, 4, ptex, sf::Vector2f(550, 150), sf::Vector2f(200, 200));
e5->zoom=2.0; e5->zoom=2.0;
e5->points[0].color = sf::Color(255, 0, 0); e5->points[0].color = sf::Color(255, 0, 0);
e5->points[1].tilesprite = 1; e5->points[1].tilesprite = 1;
@ -125,7 +125,7 @@ UITestScene::UITestScene(GameEngine* g) : Scene(g)
e5a->grid = e5; e5a->grid = e5;
//auto e5as = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0); //auto e5as = UISprite(indextex, 85, sf::Vector2f(0, 0), 1.0);
//e5a->sprite = e5as; // will copy constructor even exist for UISprite...? //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); e5a->position = sf::Vector2f(1, 0);
e5->entities->push_back(e5a); e5->entities->push_back(e5a);