Wątek przeniesiony 2023-03-05 22:34 z C/C++ przez cerrato.

Ogromny spad klatek gdy użytkownik wciśnie 2 klawisze SFML

0

Piszę grę która używa biblioteki SFML 2.5.1, gdy gracz wciśnie klawisz W a następnie D występuje ogromny spadek klatek.
Czy istnieje jakaś funkcja albo inna rzecz która może to naprawić?

kod:

#include <SFML/Graphics.hpp>
#include <string>
#include <ctime>
#include <iostream>
#include <array>
using namespace std;
using namespace sf;


int main()
{   
    ContextSettings settings;
    settings.antialiasingLevel = 8.0;
    RenderWindow w(VideoMode(640*2,480*2), "Game");
    w.setVerticalSyncEnabled(true);

    double Speed = 4;
    CircleShape Player(80, 8);

    while (w.isOpen())
    {
        Event event;
        while (w.pollEvent(event))
        {
            if (event.type == Event::Closed)
                w.close();
	    if (Keyboard::isKeyPressed(Keyboard::D))
	    {
		Player.move(Speed, 0.f);
	    }
	    if (Keyboard::isKeyPressed(Keyboard::A))
	    {
		Player.move(-Speed, 0.f);
	    }
	    if (Keyboard::isKeyPressed(Keyboard::S))
	    {
		Player.move(0.f, Speed);
	    }
	    if (Keyboard::isKeyPressed(Keyboard::W))
	    {
		Player.move(0.f, -Speed);
	    }
        }
        w.clear();
	w.draw(Player);
	w.display();
    }

    return 0;
}
2

Twoja aplikacja cały czas "działa wolno".
Zmień w.setFramerateLimit(2) na wyższą wartość, np. 60.

1

Jeżeli zamierzasz zrobić płynny ruch, wyjmij sprawdzanie wciśnięcia klawiszy z pętli while(w.pollevent(event)). Gdy są one w pętli, ruch nie jest płynny i mogą wystąpić problemy z ruchem na skos.

2

Pytanie jeszcze - na jakim jesteś systemie? Bo patrząc na źródła SFML, to wygląda na to, że na Linuxie każde wywołanie isKeyPressed powoduje nawiązanie nowego połączenia z display serverem oraz zamknięcie go. Taka operacja może zajmować trochę czasu.

https://github.com/SFML/SFML/blob/69ea0cd863aed1d4092b970b676924a716ff718b/src/SFML/Window/Unix/KeyboardImpl.cpp

bool isKeyPressedImpl(KeyCode keycode)
{
    if (keycode != nullKeyCode)
    {
        const auto display = sf::priv::openDisplay();

        // Get the whole keyboard state
        char keys[32];
        XQueryKeymap(display.get(), keys);

        // Check our keycode
        return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
    }

    return false;
}

Poza tym, @karol1165 dobrze radzi - na obecną chwilę, twoje sprawdzanie, czy klawisze są wciśnięte, odbywa się wewnątrz pętli while(w.pollevent(event)). Gracz porusza się więc za każdym razem, gdy przychodzi jakieś wydarzenie - nawet, jeśli wydarzeniem był ruch myszą, ale klawisz jest wciśnięty, odpalasz poruszanie się gracza.

1 użytkowników online, w tym zalogowanych: 0, gości: 1