The graphics looks strange when I try to flip an image using setScale().
My tileset:
(http://i60.tinypic.com/30krul5.png)
This is what it looks like when I run it:
(http://i58.tinypic.com/25hkai0.png)
This is what it should look like:
(http://i62.tinypic.com/211phcy.png)
My code:
#include <SFML/Graphics.hpp>
const int tilemap_tilewidth = 4;
const int tilemap_tileheight = 2;
const int tilesize_x = 32;
const int tilesize_y = 32;
const int mapwidth = 128;
const int mapheight = 128;
const int mapwidth_in_tiles = mapwidth / 32;
const int mapheight_in_tiles = mapheight / 32;
struct tile
{
bool flip_x;
bool flip_y;
int index;
};
struct tile tilemapdata [mapheight_in_tiles][mapwidth_in_tiles] =
{
{{0, 0, 0}, {0, 0, 0}, {0, 0, 1}, {0, 0, 2}},
{{0, 0, 3}, {0, 0, 7}, {1, 0, 3}, {0, 1, 7}},
{{0, 0, 1}, {0, 0, 2}, {1, 0, 1}, {0, 0, 0}},
{{0, 0, 1}, {0, 0, 2}, {1, 0, 4}, {1, 0, 3}}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(128, 128), "SFML Game");
sf::Texture tilemap;
if (!tilemap.loadFromFile("Resources/tileset.png"))
{
return -1;
}
sf::Sprite currenttile;
currenttile.setTexture(tilemap);
currenttile.setOrigin(sf::Vector2f(tilesize_x / 2, tilesize_y / 2));
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
for(int y = 0; y < mapheight / tilesize_y; y++)
{
for(int x = 0; x < mapwidth / tilesize_x; x++)
{
int tilepos_x = ((tilemapdata[y][x].index % tilemap_tilewidth) * tilesize_x);
int tilepos_y = (tilemapdata[y][x].index / tilemap_tilewidth) * tilesize_y;
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilepos_x + tilesize_x, tilepos_y + tilesize_y));
currenttile.setPosition(sf::Vector2f(x * tilesize_x + (tilesize_x / 2), y * tilesize_y + (tilesize_y / 2)));
currenttile.setScale(tilemapdata[y][x].flip_x ? -1 : 1, tilemapdata[y][x].flip_y ? -1 : 1); //this line seems to mess things up
window.draw(currenttile);
}
}
window.display();
}
return 0;
}
IntRect is made of Left, Top, Width and Height. It was Right and Bottom for the last two in SFML 1.x.
This line is wrong in SFML 2.0:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilepos_x + tilesize_x, tilepos_y + tilesize_y));
it should go:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilesize_x, tilesize_y));
Because of the order you drew it in when scale was 1, 1 it was looking ok, the 'additional' parts of each tile got overdrawn by later tiles and last row and column drew the 'additional' part outside the window.
That's also why result is so weird with different scale, the tiles rotated around (since texture rect is larger the origin isn't actually in the middle of sprite) and trampled over each other this time...
Very ironic how old SFML Rect class usage, window size, tile drawing order and scale worked together for this 'bug'.
IntRect is made of Left, Top, Width and Height. It was Right and Bottom for the last two in SFML 1.x.
This line is wrong in SFML 2.0:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilepos_x + tilesize_x, tilepos_y + tilesize_y));
it should go:
currenttile.setTextureRect(sf::IntRect(tilepos_x, tilepos_y, tilesize_x, tilesize_y));
Because of the order you drew it in when scale was 1, 1 it was looking ok, the 'additional' parts of each tile got overdrawn by later tiles and last row and column drew the 'additional' part outside the window.
That's also why result is so weird with different scale, the tiles rotated around (since texture rect is larger the origin isn't actually in the middle of sprite) and trampled over each other this time...
Very ironic how old SFML Rect class usage, window size, tile drawing order and scale worked together for this 'bug'.
Thanks, it's working now.