【问题标题】:conversion from unsigned int to int, possible loss of data从 unsigned int 转换为 int,可能会丢失数据
【发布时间】:2021-04-08 08:46:54
【问题描述】:

我试图为我的瓦片地图创建一个顶点数组。我按照我在书中找到的这个教程进行操作。应该没有任何错误,但这个东西仍然会弹出:“参数:从无符号整数转换为整数,可能丢失数据”。我不明白这个错误,谁能告诉我问题是什么? 这是代码:

Tilemap.h

    class TileMap : public sf::Drawable, public sf::Transformable
{
public:
    bool Load(const std::string &tileset, sf::Vector2u tileSize, const int* tiles, unsigned int width, unsigned int height) 
    {
        //Loads the tileset texture.
        if (!m_tileset.loadFromFile(tileset))
            return false;

        //Resize the vertex array to fit the level size.
        m_vertices.setPrimitiveType(sf::Quads);
        m_vertices.resize(width * height * 4);

        //Populates the vertex array with one quad per tile.
        for (unsigned int i = 0; i < width; ++i)
            for (unsigned int j = 0; j < height; ++j)
            {
                //Get the current tile number.
                int tileNumber = tiles[i + j * width];

                //Find its position in the tileset texture.
                int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                //Get a pointer to the current tile quad.
                sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                //Define its 4 corners.
                quad[0].position = sf::Vector2f(i * tileSize.x, j * tileSize.y);
                quad[1].position = sf::Vector2f((i + 1) * tileSize.x, j * tileSize.y);
                quad[2].position = sf::Vector2f((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                quad[3].position = sf::Vector2f(i * tileSize.x, (j + 1) * tileSize.y);

                //Define its 4 texture coordinates.
                quad[0].position = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].position = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].position = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].position = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
            }
        return true;
    }
private:

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {   
        //Applies the entity's transform.
        states.transform *= getTransform(); 

        //Applies the texture.
        states.texture = &m_tileset;

        //Draw the vertex array.
        target.draw(m_vertices, states);
    }
    //Constructor
    sf::VertexArray m_vertices;
    sf::Texture m_tileset;
};`

main.ccp

int main()
{
    //Window Stuff
    sf::RenderWindow window(sf::VideoMode(512, 256), "Shattered Soul"); //creates the window.

    window.setFramerateLimit(60); //establishes the frame rate limit.

    //Tile Map
    //Defines the level with an array of tile indices.
    const int level[] =
    {
        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0,
        1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
        0, 1, 0, 0, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
        0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 2, 0, 0,
        0, 0, 1, 0, 3, 0, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1,
        0, 0, 1, 0, 3, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1,
        0, 1, 0, 0, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
    };

    bool playerUp, playerDown, playerLeft, playerRight = false;

    //Initializes Classes
    Player playerObject;
    TileMap tileMap;
    if (!tileMap.Load("graphics/tileset.png", sf::Vector2u(32, 32), level, 16, 8))
        return -1;

    //Loads the player sprite.
    sf::Texture playerTexture;
    playerTexture.loadFromFile("graphics/player.png");
    sf::Sprite playerSprite(playerTexture);
    playerSprite.setPosition(340, 220);
    

    while (window.isOpen()) {
        sf::Event event;
        //Processes events.
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
            //Enables player to exit the game using the Esc button.
            if (event.key.code == sf::Keyboard::Escape) {
                window.close();
            }
        }
        //Enables user to move the player via keyboard.
        playerRight = sf::Keyboard::isKeyPressed(sf::Keyboard::Right);
        playerLeft = sf::Keyboard::isKeyPressed(sf::Keyboard::Left);
        playerUp = sf::Keyboard::isKeyPressed(sf::Keyboard::Up);
        playerDown = sf::Keyboard::isKeyPressed(sf::Keyboard::Down);

        //Updates the player movement
        playerObject.update(playerUp, playerDown, playerLeft, playerRight);
        
        window.clear(); //Clears the window with a white color.

        window.draw(tileMap);
        window.draw(playerSprite); // Draws the player sprite.

        playerSprite.move(sf::Vector2f(playerObject.xvel, playerObject.yvel));
        
        window.display();
        
    }
    return 0;
}

编辑:如果我浪费了你们的时间,我很抱歉。实际上,顶点数组不起作用的原因是由于一个简单的愚蠢错误,我不小心复制了一个不应该存在的代码。

我将这行代码更改为:

 //Define its 4 corners.
                quad[0].position = sf::Vector2f(i * tileSize.x, j * tileSize.y);
                quad[1].position = sf::Vector2f((i + 1) * tileSize.x, j * tileSize.y);
                quad[2].position = sf::Vector2f((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                quad[3].position = sf::Vector2f(i * tileSize.x, (j + 1) * tileSize.y);

                //Define its 4 texture coordinates.
                quad[0].position = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].position = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].position = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].position = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
            }

到这里:

 //Define its 4 texture coordinates.
                quad[0].texCoordinates = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].texCoordinates = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].texCoordinates = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].texCoordinates = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);

基本上我只是将“位置”代码替换为“texCoordinates”,因为它应该表示纹理坐标而不是角。 “位置”变量仅对代码的前一部分有效。

【问题讨论】:

  • 它还会告诉您发生这种情况的确切位置。您可以复制那行并将其放在问题中的单独代码框中吗?

标签: c++ console sfml


【解决方案1】:

一般来说这是因为有符号和无符号类型可以表示不同的数字范围。例如,无符号 8 位整数可以保存数字范围 [0:255],而有符号 8 位整数可以保存范围 [-128:127]。

只要你的数字在公共范围 [0:127] 内就没有问题,但负数不能用无符号类型表示,127 以上的值不能用有符号表示。

如果你的编译器不能证明你试图转换的值在公共范围内,它会给出“可能丢失数据”的警告,然后由你来判断这是否是一个真正的问题(并修复它),或者如果您自己可以保证没有问题。

这就是它对所有数字类型的工作方式(我目前能想到的),唯一的区别是可能的范围是什么。前任对于 32 位整数,有符号范围是 [-2147483648 : 2147483647],无符号​​范围是 [0 : 4294967295]。

【讨论】:

  • "...而有符号的 8 位整数可以保持范围 [-128:127]" - 自 C++20 以来(其中 Two's 补码 有符号整数是强制性的)。在 C++20 之前,[-127,127]` 也是有效范围。
  • @TedLyngmo 等等,在 C++20 之前不需要完整的二进制补码范围?我猜你每天都会学到一些新东西。
  • 是的,花了一些时间 - 有符号整数溢出仍然是未定义的行为。有人建议应该对其进行定义 - 但他们决定放弃。
猜你喜欢
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2014-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多