在sf :: RectangleShape上设置纹理的完全随机行为

时间:2018-01-09 19:58:49

标签: c++ sfml

在我的游戏中,我有一个班级view::Player代表玩家代币移动和玩家标签显示他的统计数据。令牌很好,但是一旦我实现了标签(sf::RectangleShape),就会发生奇怪的事情。

enter image description here

这4个矩形是玩家标签,你可以看到,其中只有2个设置了纹理。现在有趣的是,基于我之前选择的std::string玩家名称,第二个矩形有时也没有纹理。如果我将玩家数量更改为1,2或3,则只有最后一个玩家将具有纹理。我不知道发生了什么,为什么,所以我需要从我的应用程序开始。

因此,对于入口点,创建std::vector<std::string>玩家名称的类,其在控制台中编写,游戏的其余部分具有由SFML处理的GUI。

void NewGame::start() {
    std::cout << "***Welcome to Eurobusiness Board Game***\n" <<
        "How many players are going to play? [2, 3 or 4] \n";
    do {
        std::cin >> m_numberOfPlayers;
    } while (m_numberOfPlayers < 2 || m_numberOfPlayers > 4);

    for (size_t i = 0; i < m_numberOfPlayers; ++i) {
        bool isNameUnique;
        std::string name;
        std::cout << "Enter name of player nr " << i + 1 << "\n";       

        do {
            std::cin >> name;
            isNameUnique = true;
            if (m_playerNames.size() > 0) {
                for (size_t i = 0; i < m_playerNames.size(); ++i) {
                    if (name == m_playerNames[i]) {
                        std::cout << "Choose unique name for every player. \n";
                        isNameUnique = false;
                    }
                    else {
                        isNameUnique = true;
                    }
                }
            }           
        } while (!isNameUnique);    
        m_playerNames.push_back(name);
    }

    view::GameView newGameView(m_numberOfPlayers, m_playerNames);
}

由此,我们转到view::GameView,这是处理绘图和与用户交互的主类。它的构造函数看起来像

view::GameView::GameView(int numberOfPlayers, std::vector<std::string>& playerNames)
    : m_game(numberOfPlayers, playerNames), m_numberOfPlayers(numberOfPlayers)
{
    m_data = std::make_unique<Data>();
    m_data->window.create(sf::VideoMode(APPLICATION_SCREEN_WIDTH, APPLICATION_SCREEN_HEIGHT), APPLICATION_TITLE, sf::Style::Close | sf::Style::Titlebar);
    gameLoop();
}

标题的最重要部分

namespace view {
    class GameView {
        logic::Game m_game;
        std::vector<view::Player> m_players;
    };
}

播放器的名称被传递给logic::Game,这是处理所有逻辑的主类,这里是这个类的构造函数

logic::Game::Game(size_t numberOfPlayers, std::vector<std::string>& playerNames)
    : m_numberOfPlayers(numberOfPlayers) {
    for (size_t i = 0; i < numberOfPlayers; ++i) {
        m_players.emplace_back(Player(playerNames[i]));
    }
}

然后`logic :: Game&#39;的重要部分头

namespace logic {
    class Game {
        std::vector<logic::Player> m_players;
        logic::Player& getPlayer(int i) { return m_players[i]; }
    };
}

所以直到现在,我通过std::vector<logic::Player>中的构造函数和logic::Gamestd::vector<view::Player>传递的名称获得了view::GameView已创建的玩家,其中没有任何元素。在我开始在此向量中放置项目之前,这是我的view::Player类。

namespace view {
    class Player {
        logic::Player* m_player;
        sf::CircleShape m_token;
        sf::RectangleShape m_label;
        sf::Texture m_texture;
    public:
        Player(logic::Player&);
        void create(sf::Color, int, int);
        sf::CircleShape& getToken() {
            return m_token;
        }
        sf::RectangleShape& getLabel() {
            return m_label;
        }
    };
}

view::Player::Player(logic::Player& player) {
    m_player = &player;

    if (!m_texture.loadFromFile(PLAYER_LABEL)) {
        std::cout << "Can't load texture.\n";
    }   
}

void view::Player::create(sf::Color color, 
    int labelPositionX, int labelPositionY) {

    m_token.setFillColor(color);
    m_token.setRadius(10);
    m_token.setPosition(STARTING_POSITION_X, STARTING_POSITION_Y);
    m_token.setOutlineColor(sf::Color::Black);
    m_token.setOutlineThickness(2);
    m_token.setOrigin({ 20, 20 });

    m_label.setSize(sf::Vector2f(PLAYER_LABEL_WIDTH, PLAYER_LABEL_HEIGHT));
    m_label.setTexture(&m_texture);
    m_label.setPosition(labelPositionX, labelPositionY);
    m_label.setTextureRect(sf::IntRect(0, 0, 140, 70));
}

有了这个,我回到view::GameViewcreatePlayers()initialise()函数中调用gameLoop()void view::GameView::createPlayers() { sf::Color color; int labelPositionX = PLAYER_LABEL_POSITION_X; int labelPositionY; for (int i = 0; i < m_numberOfPlayers; ++i) { if (i == 0) { color = sf::Color::Red; labelPositionY = PLAYER_ONE_LABEL_POSITION_Y; } if (i == 1) { color = sf::Color::Blue; labelPositionY = PLAYER_TWO_LABEL_POSITION_Y; } if (i == 2) { color = sf::Color::Green; labelPositionY = PLAYER_THREE_LABEL_POSITION_Y; } if (i == 3) { color = sf::Color::Yellow; labelPositionY = PLAYER_FOUR_LABEL_POSITION_Y; } m_players.push_back(view::Player(m_game.getPlayer(i))); m_players[i].create(color, labelPositionX, labelPositionY); } } 启动后的第一件事

draw()

并在for (int i = 0; i < m_numberOfPlayers; ++i) { this->m_data->window.draw(m_players[i].getToken()); this->m_data->window.draw(m_players[i].getLabel()); }

中完成
m_token

我知道它的代码相当多,但老实说我不知道​​要删除什么然后粘贴到这里,因为随机的事情使它更糟糕,例如,我从{{1}删除了view::Player::create()初始化突然,第一个纹理也加载了,但它的sf::IntRect被设置在其他地方。我不知道在设计的某个地方是否存在重大缺陷,或者我只是做了一些我无法找到的小错误。

0 个答案:

没有答案