在SFML中更新文本

时间:2017-09-08 00:51:01

标签: c++ sfml

我每次玩家移动时都会尝试更新文本变量。问题是每次我这样做,新字符串出现在前一个字符串的顶部。当我调整大小或扩展游戏窗口时,字符串会正常显示。

问题状态:

PROBLEM STATE

扩展状态(所需状态):

EXPANDED STATE (DESIRED STATE)

下面我提供问题所在的代码。我知道我的代码可能不是最好的,但我刚开始学习sfml,所以有时候我会硬编码以获得快速的结果。一旦完成这个,我将用更好的编程实践重写整个应用程序。处理所述字符串的地方是void handle_plmove_request(game_packet包,listen_parameters param)和void render_graphics(...)和int main()。我在main()中创建了文本变量,并将它们作为参数传递给执行函数listen_to_server()的线程

#include <list>
#include <sstream>
#include "player.h"


std::string PLAYER_MOVE_REQUEST = "PLAYER_MOVE";
std::string CHIP_CREATION_REQUEST = "CHIP_CREATION";
std::string CHIP_DELETION_REQUEST = "CHIP_DELETION";
std::string MONSTER_ENTITY_MY = "monster";
std::string PLAYER_ENTITY_MY= "player";

    struct game_packet {
        std::string type;
        std::string player_move;
        double chip_position_x; // change it to string
        double chip_position_y;
        double pl1_position_x;
        double pl1_position_y;
        double pl2_position_x;
        double pl2_position_y;
        int score_pl1;
        int score_pl2;
    };

    struct listen_parameters {
        sf::TcpSocket* socket;
        player* player1;
        player* player2;
        sf::RenderWindow* what_window;
        std::list<player>* chipList;
        bool* lock_movement;
        sf::Text* pl1_score;
        sf::Text* pl2_score;
    };

    sf::Packet& operator <<(sf::Packet& packet, const game_packet& pack)
    {
        return packet << pack.type << pack.player_move << pack.chip_position_x << pack.chip_position_y
            << pack.pl1_position_x << pack.pl1_position_y << pack.pl2_position_x << pack.pl2_position_y
            << pack.score_pl1 << pack.score_pl2;
    }

    sf::Packet& operator >>(sf::Packet& packet, game_packet& pack)
    {
        return packet >> pack.type >> pack.player_move >> pack.chip_position_x >> pack.chip_position_y
            >> pack.pl1_position_x >> pack.pl1_position_y >> pack.pl2_position_x >> pack.pl2_position_y
            >> pack.score_pl1 >> pack.score_pl2;
    }

    void handle_plmove_request(game_packet packet, listen_parameters param) {
        std::stringstream int_to_string_pl1;
        std::stringstream int_to_string_pl2;
        double set_xpos = packet.pl1_position_x * 100 + 50;
        double set_ypos = packet.pl1_position_y * 100 + 50;
        param.player1->setCoordinates(set_xpos, set_ypos);
        set_xpos = packet.pl2_position_x * 100 + 50;
        set_ypos = packet.pl2_position_y * 100 + 50;
        param.player2->setCoordinates(set_xpos, set_ypos);
        int_to_string_pl1 << packet.score_pl1;
        param.pl1_score->setString(int_to_string_pl1.str());
        int_to_string_pl2 << packet.score_pl2;
        param.pl2_score->setString(int_to_string_pl2.str());
    }

    void handle_chip_deletion(game_packet packet, listen_parameters param) {
        std::cout << "handling chip_deletion_rquest" << std::endl;
        packet.chip_position_x = packet.chip_position_x * 100 + 50;
        packet.chip_position_y = packet.chip_position_y * 100 + 50;
        player chip_to_delete(packet.chip_position_x, packet.chip_position_y, MONSTER_ENTITY_MY, "0");
        std::cout << "deleting" << packet.chip_position_x << ","
                  << packet.chip_position_y;
        param.chipList->remove(chip_to_delete);
    }

    void handle_chip_creation(game_packet packet, listen_parameters param) {
        param.chipList->clear();
        std::string string_number;
        int new_integer;
        int xpos_newchip;
        int ypos_newchip;
        std::cout << "received integers" << std::endl;
        param.chipList->clear();
        for (auto& it : packet.player_move) {
            if (it != '_')
                string_number += it;
            else {
                std::stringstream string_to_int(string_number);
                string_to_int >> new_integer;
                std::cout << new_integer << ",";
                xpos_newchip = (new_integer % 8) * 100 + 50;
                ypos_newchip = (new_integer / 8) * 100 + 50;
                string_number.clear();
                player new_chip(xpos_newchip, ypos_newchip, MONSTER_ENTITY_MY , "0");
                param.chipList->push_back(new_chip);
            }

        }
        std::cout << std::endl;

    }
    void listen_to_server(listen_parameters param){
        while (true) {
            sf::Packet packet;
            game_packet gamePacket;
            if (param.socket->receive(packet) != sf::Socket::Done)
                std::cout << "data couldn't be received" << std::endl;
            packet >> gamePacket;
            if (gamePacket.type == PLAYER_MOVE_REQUEST)
                handle_plmove_request(gamePacket, param);
            else if (gamePacket.type == CHIP_DELETION_REQUEST) {
                handle_chip_deletion(gamePacket, param);
            }
            else if (gamePacket.type == CHIP_CREATION_REQUEST) {
                handle_chip_creation(gamePacket, param);
            }
        }
    }
    void render_graphics(listen_parameters param) {
        sf::Clock clock;
        sf::Clock bot_clock;
        sf::Font font;
        if (!font.loadFromFile("arial.ttf"))
            std::cout << "can't load" << std::endl;
        sf::Text player1_text;
        sf::Text player2_text;
        player1_text.setFont(font);
        player1_text.setString("PLAYER_1 SCORE");
        player1_text.setFillColor(sf::Color::Red);
        player1_text.setPosition(150, 850);
        player2_text.setFont(font);
        player2_text.setString("PLAYER_2 SCORE");
        player2_text.setFillColor(sf::Color::Blue);
        player2_text.setPosition(500, 850);

        sf::RectangleShape white_square(sf::Vector2f(100, 100));
        white_square.setFillColor(sf::Color(0, 0, 0));
        sf::RectangleShape black_square(sf::Vector2f(100, 100));
        black_square.setFillColor(sf::Color(255, 255, 255));
            while (param.what_window->isOpen()) {
                float two = 2;
                sf::Time elapsed1 = clock.getElapsedTime();
                sf::Time bot_elapsed = bot_clock.getElapsedTime();
                sf::Time two_seconds = sf::seconds(2);
                sf::Time one_millisecond = sf::milliseconds(10);

                if (elapsed1 > one_millisecond) {
                    bool isBlack = true;
                    for (int i = 0; i < 800; i += 100) {
                        for (int j = 0; j < 800; j += 100) {
                            if (isBlack == true) {
                                black_square.setPosition(i + 50, j + 50);
                                param.what_window->draw(black_square);
                                if (j + 100 != 800)
                                    isBlack = false;
                            }
                            else {
                                white_square.setPosition(i + 50, j + 50);
                                param.what_window->draw(white_square);
                                if (j + 100 != 800)
                                    isBlack = true;
                            }
                        }
                    }
                    //std::cout << "displaying child thread" << std::endl;
                    param.player1->setShapePosition();
                    param.what_window->draw(param.player1->getPlayerShape());
                    param.player2->setShapePosition();
                    param.what_window->draw(param.player2->getPlayerShape());
                    param.what_window->draw(player1_text);
                    param.what_window->draw(player2_text);
                    param.what_window->draw(*(param.pl1_score)); // where the score is drawn
                    param.what_window->draw(*(param.pl2_score)); // where the score is drawn

                    for (auto& it : *(param.chipList)) {
                        it.setShapePosition();
                        param.what_window->draw(it.getPlayerShape());
                    }

                    param.what_window->display();
                    clock.restart();
                }
            }

    }

    int main()
    {
        int port_number = 53004;
        sf::TcpSocket socket;
        sf::Socket::Status status = socket.connect("192.168.0.14", port_number);
        if (status != sf::Socket::Done)
            std::cout << "awaiting connection" << std::endl;
        std::cout << "succesfull connection" << std::endl;
        sf::Packet packet;
        int xpos;
        int ypos;
        std::string player_number;
        if (socket.receive(packet) != sf::Socket::Done)
            std::cout << "can't receive packet" << std::endl;
        packet >> xpos >> ypos >> player_number;
        std::cout << "your player number is" << player_number << std::endl;
        sf::RenderWindow window(sf::VideoMode(900, 1000), "SFML works!");
        window.setKeyRepeatEnabled(false);
        window.setActive(false);


        player player1(50,750,PLAYER_ENTITY_MY, "1");
        player player2(750,750, PLAYER_ENTITY_MY, "2");
        sf::RenderWindow* ptr_window = &window;
        std::list<player> chipList;
        bool lock_movement = false;
        sf::Text pl1_score;
        sf::Text pl2_score;
        sf::Font font;
        if (!font.loadFromFile("arial.ttf"))
            std::cout << "can't load" << std::endl;
        pl1_score.setFont(font);
        pl1_score.setFillColor(sf::Color::Red);
        pl1_score.setPosition(250, 950);
        pl2_score.setFont(font);
        pl2_score.setFillColor(sf::Color::Blue);
        pl2_score.setPosition(600, 950);
        pl1_score.setString("0");
        pl2_score.setString("0");

        listen_parameters param{&socket, &player1, &player2, ptr_window,&chipList,&lock_movement,
                                &pl1_score, &pl2_score};
        sf::Thread server_listener_thread{ &listen_to_server, param };
        server_listener_thread.launch();
        sf::Thread graphics(&render_graphics, param);
        graphics.launch();  


        while (window.isOpen()){
            sf::Event event;
            while (window.pollEvent(event))
            {
                std::string ins;
                sf::Packet packet;
                if (lock_movement == false) {
                    switch (event.type)
                    {
                    case sf::Event::Closed:
                        window.close();
                        break;
                    case sf::Event::KeyPressed:
                        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
                            game_packet gamePacket;
                            gamePacket.type = PLAYER_MOVE_REQUEST;
                            ins = "r" + player_number;
                            gamePacket.player_move = ins;
                            packet << gamePacket;
                            if (socket.send(packet) != sf::Socket::Done)
                                std::cout << "couldn't send packet" << std::endl;
                            std::cout << "sending r instruction" << std::endl;
                        }
                        else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
                            game_packet gamePacket;
                            gamePacket.type = PLAYER_MOVE_REQUEST;
                            ins = "l" + player_number;
                            gamePacket.player_move = ins;
                            packet << gamePacket;
                            if (socket.send(packet) != sf::Socket::Done)
                                std::cout << "couldn't send packet" << std::endl;
                            std::cout << "sending l instruction" << std::endl;
                        }
                        else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
                            game_packet gamePacket;
                            gamePacket.type = PLAYER_MOVE_REQUEST;
                            ins = "u" + player_number;
                            gamePacket.player_move = ins;
                            packet << gamePacket;
                            if (socket.send(packet) != sf::Socket::Done)
                                std::cout << "couldn't send packet" << std::endl;
                            std::cout << "sending u instruction" << std::endl;
                        }
                        else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
                            game_packet gamePacket;
                            gamePacket.type = PLAYER_MOVE_REQUEST;
                            ins = "d" + player_number;
                            gamePacket.player_move = ins;
                            packet << gamePacket;
                            if (socket.send(packet) != sf::Socket::Done)
                                std::cout << "couldn't send packet" << std::endl;
                            std::cout << "sending d instruction" << std::endl;
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
        }

        return 0;
    }

摘要:我只是通过更改文本并重新绘制来更新文本。

1 个答案:

答案 0 :(得分:1)

解决方案很简单:只需在每次主循环迭代开始时调用window.clear()。现在你永远不会清除屏幕,只是画过前一个屏幕,只要你填满所有内容,你就不会注意到它。问题是,你永远不会填满比赛场地下面的区域,即显示得分的地方。