• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wartość Keyboard::isKeyPressed() dla dowolnego klawisza SFML

Object Storage Arubacloud
+1 głos
365 wizyt
pytanie zadane 31 października 2020 w C i C++ przez Stefan Marzec Użytkownik (710 p.)
edycja 31 października 2020 przez Stefan Marzec
Mam takie szybkie pytanie. Jest w SFML jakaś "wartość" dla sf::Keyboard::isKeyPressed() dla dowolnego klawisza?  Tzn. chcę aby If z tym warunkiem wykonał się gdy wciśnięty został dowolny klawisz. Chyba nie mogę użyć Eventa, bo muszę zachować stałe wykonywanie głównej pętli. Nie znalazłem za dużo nawet w oficjalnej dokumentacji i na stronie, albo może po prostu nie umiem szukać. Z góry dzięki.

2 odpowiedzi

0 głosów
odpowiedź 31 października 2020 przez VBService Ekspert (253,420 p.)
edycja 31 października 2020 przez VBService

Chodzi tobie, o często używane tzw. "Press any key to ..." wink. Po prostu wykryj samo wywołanie zdarzenia wciśnięcia klawisza.

if (event.type == sf::Event::KeyPressed)
{
   . . .
}

GameDev Academy - How to Handle User Interactions with SFML

[ Edit ] 

Oczywiście miałem na myśli


sf::Event event;
while (window.pollEvent(event)) {
  if (event.type == sf::Event::Closed) {
    window.close();
  } else if (event.type == sf::Event::MouseButtonPressed) {

    std::cout << "Mouse button pressed" << std::endl;

  } else if (event.type == sf::Event::KeyPressed) {

      std::cout << "Some key pressed" << std::endl;

  }
}

w dokumentacji przecież masz The sf::Event type - explained

sf::Event event;

// while there are pending events...
while (window.pollEvent(event))
{
    // check the type of the event...
    switch (event.type)
    {
        // window closed
        case sf::Event::Closed:
            window.close();
            break;

        // key pressed
        case sf::Event::KeyPressed: // <-- TU
            ...
            break;

        // we don't process other types of events
        default:
            break;
    }
}

 

komentarz 31 października 2020 przez VBService Ekspert (253,420 p.)

A próbowałeś?

if (event.type == sf::Event::KeyPressed) {

    //Zmiana klatki
    if (counter >= 1 && counter < 21)

    . . .

    switch (sf::Keyboard::isKeyPressed)
    {
        case sf::Keyboard::Left:
            ...
            break;
        case sf::Keyboard::Right:
            ...
            break;
    }
}

 

komentarz 31 października 2020 przez Stefan Marzec Użytkownik (710 p.)
Specjalnie zamiast Switcha użyłem tylu if'ów aby Mario mógł poruszać się po skosie. Tak, próbowałem. Działało ale nie było to tak płynne. Zastanawiam się czemu nie ma po prostu enumenatora np. sf::Keyboard::Any albo coś takiego.
komentarz 31 października 2020 przez VBService Ekspert (253,420 p.)

Sprawdzasz najpierw czy w ogóle jest "coś wciśnięte" (na klawiaturze wink)

if (event.type == sf::Event::KeyPressed) {
 
             //Zmiana klatki
            if (counter >= 1 && counter < 21)
 
              . . .
 
            //Ruch
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                sprite.move(-2.0f, 0);
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                sprite.move(2.0f, 0);
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                sprite.move(0, -2.0f);
            if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                sprite.move(0, 2.0f);
}

 

komentarz 31 października 2020 przez Stefan Marzec Użytkownik (710 p.)
edycja 1 listopada 2020 przez Stefan Marzec

Nie chodzi o płynność kodu, a animacji. Na stronie napisali, cytując: "sf::Event instances are filled by the pollEvent (or waitEvent) function of the sf::Window class. Only these two functions can produce valid events, any attempt to use an sf::Event which was not returned by successful call to pollEvent (or waitEvent) will result in the same undefined behavior that was mentioned above." Użycie samego porównania typu Eventu bez pollEvent może skutkować problemami. Po prostu postać się zacina, rusza dopiero po chwili, itd. Natomiast przy samym tylko wymienieniu klawiszy osobno coś takiego nie występuje. Niestety nie można tu chyba przesyłać nagrań.

Jeśli chodzi o "niepłynny" kod, to wygląda tak: 

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

int main() {
	sf::RenderWindow window(sf::VideoMode(800, 800), "Window");
	window.setFramerateLimit(240);
	sf::Sprite sprite;
	sf::Texture frame1;
	

	if (!frame1.loadFromFile("mario.png", sf::IntRect(0, 0, 612, 186))) {
		std::cout << "ERROR: Cannot load texture from file." << std::endl;
	}

	sprite.setTexture(frame1);
	sprite.setOrigin(51.0f, 93.0f);
	sprite.setPosition(400.0f, 400.0f);

	int counter = 0;
	

	while (window.isOpen()) {
		sf::Event event;



		while (window.pollEvent(event)) {
			switch (event.type) {
			case sf::Event::Closed:
				window.close();
				break;
			}
		}



		window.clear(sf::Color::White);

		// Jeżeli naciśnięty klawisz:
		if (event.type == sf::Event::KeyPressed) {

			//Zmiana klatki
			if (counter >= 1 && counter < 21)
				sprite.setTextureRect(sf::IntRect(0, 0, 102, 187));
			else if (counter >= 21 && counter < 41)
				sprite.setTextureRect(sf::IntRect(102, 0, 102, 187));
			else if (counter >= 41 && counter < 61)
				sprite.setTextureRect(sf::IntRect(204, 0, 102, 187));
			else if (counter >= 61)
				counter = 1;

			//Ruch
			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
				sprite.move(-2.0f, 0);
			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
				sprite.move(2.0f, 0);
			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
				sprite.move(0, -2.0f);
			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
				sprite.move(0, 2.0f);
		}
		//W przeciwnym wypadku:
		else 
			sprite.setTextureRect(sf::IntRect(510, 0, 102, 187));
		
		

		window.draw(sprite);
		window.display();

		counter++;
		
	}

	return 0;
}

 

komentarz 31 października 2020 przez adrian17 Ekspert (344,860 p.)
Pokażesz, jak wygląda "nie płynny" kod? Bo nie widzę powodu, by miał być znacznie wolniejszy od obecnego.
0 głosów
odpowiedź 31 października 2020 przez adrian17 Ekspert (344,860 p.)

Chyba nie mogę użyć Eventa, bo muszę zachować stałe wykonywanie głównej pętli

Zawsze można tak:

// glowna petla
any_key_pressed = false;

while (window.pollEvent(event))
    // ...
    case sf::Event::KeyPressed:
            any_key_pressed = true;
            break;

// ...
// gdzies pozniej:

if (any_key_pressed) {

}

 

Podobne pytania

0 głosów
2 odpowiedzi 201 wizyt
pytanie zadane 21 października 2015 w C i C++ przez Damian11131 Stary wyjadacz (13,490 p.)
0 głosów
0 odpowiedzi 60 wizyt
pytanie zadane 18 maja 2020 w C i C++ przez Śwież4k Bywalec (2,570 p.)
0 głosów
1 odpowiedź 469 wizyt
pytanie zadane 20 października 2021 w C i C++ przez pawel_000 Początkujący (450 p.)

92,579 zapytań

141,432 odpowiedzi

319,663 komentarzy

61,964 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...