SFML Backspace不会触发多次

时间:2018-03-24 16:56:03

标签: c++ if-statement sfml backspace keyboard-input

所以我在这里使用SFML,我基本上想用输入的字母组成一个字符串。 SFML有一个内置的东西来检查是否在窗口内按下了键,它还有一个用来检测它是否像反退区一样特定,所以我想把它们结合起来,这样你就可以键入和退格一个字符串(因为没有退格检测,如果你按下它就不会做任何事情。)

这是我的代码:

#include <iostream>
#include "SFML/Window.hpp"
#include <vector>

using namespace std;
using namespace sf;

int main() {
    // Initializes the class and creates the window
    Window window;
    window.create(VideoMode(800, 600), "Test window", Style::Close | Style::Titlebar | Style::Resize);
    // Run while the window is open
    vector <char> sentence;
    while (window.isOpen()) {
        Event event;
        // Check if an event is triggered
        while (window.pollEvent(event)) {
            // If the event is to close it, close it
            if (event.type == Event::Closed) {
                window.close();
            }
            // If the backspace key is pressed
            else if (event.type == Event::KeyPressed) {
                if (event.key.code == Keyboard::BackSpace) {
                    sentence.pop_back();
                }
            }
            // If text is entered in the window
            else if (event.type == Event::TextEntered) {
                sentence.push_back(static_cast <char> (event.text.unicode));
                cout << "Sentence = ";
                for (int i = 0; i < sentence.size(); i++) {
                    cout << sentence[i];
                }
                cout << endl;
            }
        }
    }
    return 0;
}

基本上,它会创建一个窗口,然后检查它是否已关闭,然后检查是否按下了退格区,然后检查是否没有按下退格键,但是有一个不同的键。

所以这一切在我的IDE(Visual Studio 2017社区)上运行得很好,但是,当我多次按退格键(它第一次运行)时,它不会删除该字符。

我的假设是,这是由于事件没有清除,但这没有意义,因为你仍然可以做一些事情,比如在按退格键后关闭窗口等等。为什么即使您多次按下退格键,它也只触发退格if function一次?

1 个答案:

答案 0 :(得分:0)

退格也是一个角色,即使它是不可见的。因此,当您按退格键时,它将从缓冲区中删除最后一个字符,并向缓冲区添加一个不可见的字符。

因此,您必须忽略TextEntered事件上的退格字符。 此外,您需要检查弹出窗口,因此在没有元素时不要尝试弹出。

这是我的代码的更新版本。

#include <iostream>
#include <SFML/Graphics.hpp>

void print_scentence(const std::vector<char>& sentence) {
    std::cout << "Sentence = ";
    for (auto c : sentence)
    {
        std::cout << c;
    }
    std::cout << "\n";
}

int main() {
    // Initializes the class and creates the window
    sf::Window window;
    window.create(sf::VideoMode(800, 600), "Test window", sf::Style::Close | sf::Style::Titlebar | sf::Style::Resize);
    // Run while the window is open
    std::vector<char> sentence;
    while (window.isOpen()) {
        sf::Event event;
        // Check if an event is triggered
        while (window.pollEvent(event)) {
            // If the event is to close it, close it
            if (event.type == sf::Event::Closed) {
                window.close();
            }
            // If the backspace key is pressed
            else if (event.type == sf::Event::KeyPressed) {
                if (event.key.code == sf::Keyboard::BackSpace && !sentence.empty()) {
                    sentence.pop_back();
                    print_scentence(sentence);
                }
            }
            // If text is entered in the window
            else if (event.type == sf::Event::TextEntered) {
                if (event.text.unicode == 8) {
                    continue;
                }

                sentence.push_back(static_cast<char>(event.text.unicode));
                print_scentence(sentence);
            }
        }
    }
}

从代码中可以看出,我建议不要使用using namespace,使用range-base for循环迭代向量并使用\n而不是std::endl,就像你一样想要换行而不是强制冲洗。

此外,除非您要直接使用OpenGL或以其他方式使用窗口句柄,否则您可能希望使用sf::RenderWindow