问题
All my sprites are reversed when I try to draw my isometric map.
Here is the tileset.png mentionned in the following code :
Object.h/Object.cpp
I can use them to draw tiles, UI element, etc. ...
#pragma once
class Object {
public:
    //FUNCTIONS
    Object();
    void addComponent(float value);
    int getComponent(float index);
    void editComponent(float index, float value);
    void deleteComponent(float index);
private:
    vector<int> components;
};
#include "Object.cpp"
-
#pragma once
//FUNCTIONS
Object::Object() {
    //...
}
void Object::addComponent(float value) {
    components.push_back(value);
}
int Object::getComponent(float index) {
    return components[index];
}
void Object::editComponent(float index, float value) {
    components[index] = value;
}
void Object::deleteComponent(float index) {
    components.erase(components.begin() + index);
}
Note: I may have weird includes, I'm struggling with visual studio ha ha.
Scene.h/Scene.cpp
Handle data & graphics
#pragma once
class Scene {
public:
    Scene(float w, float h, int mapx, int mapy, int tilesize, int mapwidth, int mapheight);
    void run();
    void addLayer();
    void loadTileset(sf::String url);
    void loadUiTileset(sf::String url);
    //functions
    //...
    //getters
    //...
    //setters
    //...
private:
    sf::RenderWindow window;
    float width;
    float height;
    int nb_layers;
    int map_x;
    int map_y;
    int map_width;
    int map_height;
    int tile_size;
    int selected_tile_index;
    sf::RenderTexture texture;
    sf::Sprite tile;
    sf::Sprite map;
    sf::Texture tileset;
    vector<Object> tiles;
    sf::Texture uiTileset;
    //private functions
    void updateMap();
    //...
    void processEvent();
    void update(sf::Time deltaTime);
    void render();
    //...
};
#include "Scene.cpp"
-
#pragma once
//functions
Scene::Scene(float w, float h, int mapx, int mapy, int tilesize, int mapwidth, int mapheight) : window(sf::VideoMode(w, h), "Editor") {
    width = w;
    height = h;
    map_x = mapx;
    map_y = mapy;
    map_width = mapwidth;
    map_height = mapheight;
    tile_size = tilesize;
    selected_tile_index = 0;//default
    nb_layers = 0;
}
void Scene::run() {
    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;
    sf::Time TimePerFrame = sf::seconds(1.f / 60.f);
    while (window.isOpen()) {
        processEvent();
        timeSinceLastUpdate += clock.restart();
        while (timeSinceLastUpdate > TimePerFrame) {
            timeSinceLastUpdate -= TimePerFrame;
            processEvent();
            update(TimePerFrame);
        }
        render();
    }
}
void Scene::addLayer() {
    nb_layers += 1;
    int tile_x = map_x,
        tile_y = map_y,
        num_layer = nb_layers - 1,
        layer_pos = (num_layer * tile_size) / 2,
        tile_zOrder = -1;
    tile_y -= layer_pos;
    int x = map_x,
        y = map_y;
    for (int h = 0; h < map_height; h++) {
        for (int w = 0; w < map_width; w++) {
            tile_zOrder = (w * (h + 1)) + (num_layer * 10);
            x = carthesianToIsometric(tile_x, tile_y)[0];
            y = carthesianToIsometric(tile_x, tile_y)[1] - layer_pos;
            cout << x << ", " << y << endl;
            Object tile;
            tile.addComponent(selected_tile_index);
            tile.addComponent(x);
            tile.addComponent(y);
            tile.addComponent(tile_zOrder);
            tile.addComponent(num_layer);
            tiles.push_back(tile);
            tile_x += tile_size;
        }
        tile_x = 0;
        tile_y += tile_size;
    }
    updateMap();
}
void Scene::loadTileset(sf::String url) {
    if (!tileset.loadFromFile(url))
    {
        cout << std::string(url) << "couldn't be loaded..." << endl;
    }
}
void Scene::loadUiTileset(sf::String url) {
    if (!uiTileset.loadFromFile(url))
    {
        cout << std::string(url) << "couldn't be loaded..." << endl;
    }
}
//getters
//...
//setters
//...
//private functions
void Scene::updateMap() {
    int tile_position_x = 0,
        tile_position_y = 0;
    int tile_x = 0,
        tile_y = 0;
    if (!texture.create(map_width * tile_size, (map_height * tile_size) / 2))
        cout << "Texture couldn't be loaded... " << endl;
    texture.clear(sf::Color(133, 118, 104, 255));
    sf::Sprite image;
    image.setTexture(tileset);
    int tileset_width = image.getGlobalBounds().width,
        tileset_height = image.getGlobalBounds().height;
    tile.setTexture(tileset);
    for (int tile_index = 0; tile_index < tiles.size(); tile_index++) {
        tile_position_x = getTilePosition(tileset_width, tileset_height, tiles[tile_index].getComponent(0), tile_size)[0];
        tile_position_y = getTilePosition(tileset_width, tileset_height, tiles[tile_index].getComponent(0), tile_size)[1];
        tile.setTextureRect(sf::IntRect(tile_position_x, tile_position_y, tile_size, tile_size));
        tile_x = tiles[tile_index].getComponent(1);
        tile_y = tiles[tile_index].getComponent(2);
        tile.setPosition(sf::Vector2f(tile_x, tile_y));
        texture.draw(tile);
    }
    map.setTexture(texture.getTexture());
}
void Scene::processEvent() {
    sf::Event event;
    while (window.pollEvent(event)) {
        switch (event.type) {
        case sf::Event::Closed:
            window.close();
            break;
        case sf::Event::KeyPressed:
            if (event.key.code == sf::Keyboard::Escape)
                window.close();
            break;
        }
    }
}
void Scene::update(sf::Time deltaTime) {
    //REMEMBER: distance = speed * time
    //MOVEMENT, ANIMATIONS ETC. ..
}
void Scene::render() {
    window.clear();
    window.draw(map);
    window.display();
}
main.cpp
#pragma once
//global functions + main headers + class headers =>
#include "globalfunctions.h"
int main() {
    int map_width = 15,
        map_height = 15,
        tile_size = 64;
    float scene_width = map_width * tile_size,
        scene_height = (map_height * tile_size) / 2;
    Scene engine(scene_width, scene_height, 0, 0, tile_size, map_width, map_height);
    engine.loadTileset("tileset.png");
    //engine.loadUiTileset("menu.png");
    engine.addLayer();
    //...
    engine.run();
    return EXIT_SUCCESS;
}
globalfunctions.h
Some utility functions. getTilePosition(...) allow me to get x, y on a texture with a given tile index. Example : if I want to draw the tile n°0 of the tileset texture.
#pragma once
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <math.h>
#include <vector>
using namespace std;
vector<float> getTilePosition(float tileset_width, float tileset_height, float tile_index, float tile_size) {//In a tileset
    float tileX = 0,
        tileY = 0,
        tilePerLine = 0;
    tilePerLine = tileset_width / tile_size;
    tileY = floor(tile_index / tilePerLine);
    tileX = ((tile_index + 1) - (tileY * tilePerLine)) - 1;
    tileX *= tile_size;
    tileY *= tile_size;
    vector<float> coords;
        coords.push_back(tileX);
        coords.push_back(tileY);
    return coords;
}
vector<int> carthesianToIsometric(int x, int y) {
    vector<int> coords;
    float isoX = (x - y) / 2,
        isoY = (x + y) / 4;
    coords.push_back(isoX);
    coords.push_back(isoY);
    return coords;
}
#include "Object.h"
#include "Scene.h"
//...
And here, the WTF result I get :
Thanks for reading all that weird code !
Edit :
When I change
tile.setPosition(sf::Vector2f(tile_x, tile_y));
to
tile.setPosition(sf::Vector2f(0, 0));
in updateMap() from scene.cpp :
Unfortunatly, I cannot explain why. Maybe it will help you to understand the problem.
回答1:
In case someone encounter the same problem : As @Spectre suggested it was a problem of the sfml function draw().
http://en.sfml-dev.org/forums/index.php?topic=6903.0
You need to use display on the sf::renderTexture after your cleared it.
来源:https://stackoverflow.com/questions/38121699/2d-isometricdiamond-shape-game-engine-reversed-sprites