EDIT: solved, look at the bottom of this post and thank you
Hi. The challenge I have is to master the map rendering and I need help with solving this
I mean these tiles that are drawn right to the player. These additional tiles are drawn after every tile as you can see in this example where map size is 1x35. I have no clue what can cause it.
Here's the code I use to draw tiles:
/** gfxhandler.cpp */
shared_ptr<sf::Texture> GFXHandler::LoadTexture(std::string filename)
{
map<std::string, shared_ptr<sf::Texture> >::iterator it;
for(auto const &ent1 : textures)
{
if(ent1.first == filename)
{
return textures[filename];
}
}
sf::Texture texture;
if(!texture.loadFromFile(filename))
{
printf("GFXHandler: can't load texture %s\n", filename.c_str());
return shared_ptr<sf::Texture>(0);
}
printf("GFXHandler: loaded %s\n", filename.c_str());
textures[filename] = shared_ptr<sf::Texture>(new sf::Texture(texture));
return textures[filename];
}
void GFXHandler::UnloadTexture(std::string filename)
{
if(this->textures[filename].get())
{
this->textures[filename].reset();
}
}
sf::Sprite GFXHandler::GetSprite(shared_ptr<sf::Texture> texture, unsigned int id)
{
sf::Vector2u tsize = texture->getSize();
sf::Sprite sprite;
sprite.setTexture(*texture.get());
int rectx = 0;
int recty = 0;
unsigned int yrows = (id * 32) / tsize.x;
rectx = (id * 32) % tsize.x;
recty = yrows * 32;
sprite.setTextureRect(sf::IntRect(rectx, recty, rectx + 32, recty + 32));
return sprite;
}
/** gfxhandler.hpp */
class GFXHandler
{
private:
map<std::string, shared_ptr<sf::Texture> > textures;
public:
shared_ptr<sf::Texture> LoadTexture(std::string filename);
void UnloadTexture(std::string filename);
sf::Sprite GetSprite(shared_ptr<sf::Texture> texture, unsigned int id);
};
/** map.cpp */
Map::Map(string filename, shared_ptr<GFXHandler> gfxhandler)
: datafile(filename)
{
this->gfxhandler = gfxhandler;
this->width = datafile.GetNumber();
this->height = datafile.GetNumber();
shared_ptr<sf::Texture> tex = this->gfxhandler->LoadTexture("gfx/map/1.png");
this->layers[0].xrows.resize(this->width);
for(int i = 0; i < this->width; ++i)
{
this->layers[0].xrows[i].yrow.tiles.resize(this->height);
for(int ii = 0; ii < this->height; ++ii)
{
int id = datafile.GetNumber();
this->layers[0].xrows[i].yrow.tiles[ii] = shared_ptr<Tile>(new Tile(id));
shared_ptr<Tile> tile = this->layers[0].xrows[i].yrow.tiles[ii];
if(tile->id != 0)
{
tile->sprite = gfxhandler->GetSprite(tex, tile->id - 1);
tile->sprite.setPosition(sf::Vector2f(i * 32, ii * 32));
}
else
{
puts("Map: empty tile detected\n");
}
}
}
printf("Map created, %ix%i\n", this->width, this->height);
}
void Map::Draw(sf::RenderWindow *window, int x, int y)
{
for(int i = 0; i < this->width; ++i)
{
for(int ii = 0; ii < this->height; ++ii)
{
shared_ptr<Tile> tile = this->layers[0].xrows[i].yrow.tiles[ii];
int tile_x = i * 32 + x;
int tile_y = ii * 32 + y;
tile->sprite.setPosition(sf::Vector2f(tile_x, tile_y));
window->draw(tile->sprite);
}
}
}
/** map.hpp */
class Map
{
public:
struct Tile
{
unsigned int id;
sf::Sprite sprite;
Tile()
: id(0)
{
}
Tile(unsigned int id_)
: id(id_)
{
}
};
struct Layer
{
struct XRow
{
struct YRow
{
vector<shared_ptr<Tile>> tiles;
} yrow;
};
vector<XRow> xrows;
};
private:
DataFile datafile;
int width;
int height;
Layer layers[1];
shared_ptr<GFXHandler> gfxhandler;
public:
Map(string filename, shared_ptr<GFXHandler> gfxhandler);
void Draw(sf::RenderWindow *window, int x, int y);
int Width() { return width; }
int Height() { return height; }
};
Any help really appreciated...
EDIT!!!
I've found the answer, this is not really anything serious...
In GFXHandler::GetSprite() function:
sprite.setTextureRect(sf::IntRect(rectx, recty, 32, 32));
// instead of sprite.setTextureRect(sf::IntRect(rectx, recty, rectx + 32, recty + 32));
Sorry for bothering anyone and it would be nice if someone delete this thread...