1

所以我在这里使用 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即使多次按下它也只会触发一次退格?

4

1 回答 1

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

于 2018-03-27T08:19:41.867 回答