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

Sprawdzanie pozycji myszy

Object Storage Arubacloud
+1 głos
1,294 wizyt
pytanie zadane 29 maja 2015 w C i C++ przez majkkel Użytkownik (530 p.)

Witam, napisałem grę, kółko i krzyżyk z wykorzystaniem biblioteki 2d sfml. Wyzcytałem gdzieś na forach i trochę popytałem jak sprawdzać czy gracz kliknął w dane pole i stworzyłem coś takiego:

if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
	sf::Vector2i pozycjaMyszy = sf::Mouse::getPosition(oknoAplikacji);

	if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
	{
	        sf::Vector2f mouse = oknoAplikacji.mapPixelToCoords(sf::Mouse::getPosition(oknoAplikacji));

		sf::FloatRect bounds1 = sprajt1.getGlobalBounds();

		if (bounds1.contains(mouse) && pole1 == 'n' && stan != "win")
		{
			// Jakies instrukcje, mniejsza z tym jakie
		}
    }
}

Dodam, że powyższy kod działa poprawnie i nie chodzi o zmiany kodzie, ale zamiast posiadania działającego kodu chciałbym zrozumieć jak on działa.

Pierwszą linię:

if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
rozumiem w 100%, nie trzeba tłumaczyć.

Tutaj:

sf::Vector2i pozycjaMyszy = sf::Mouse::getPosition(oknoAplikacji);

Vector2 przechowuje jakieś współrzędne, w tym wypadku położenie myszy względem okna. Jeżeli się myle to mnie poprawcie.

Następnie:

if (sf::Mouse::isButtonPressed(sf::Mouse::Left))

nie rozumiem, dlaczego znowu sprawdzam warunek kliknięcia....

i zupełnie nie czaję o co chodzi z tą linijką:

sf::Vector2f mouse = oknoAplikacji.mapPixelToCoords(sf::Mouse::getPosition(oknoAplikacji));

Reszta kodu (ta z klasą FloatRect i obiektem bounds ) jest dla mnie zrozumiała.

Jeżel chcesz pomóc, to prosiłbym o wytłumaczenie tego tak jak komuś kto pierwszy raz się z tym zetknął.

2 odpowiedzi

0 głosów
odpowiedź 29 maja 2015 przez Harsay Pasjonat (23,640 p.)
wybrane 29 maja 2015 przez majkkel
 
Najlepsza

Sprawdzanie drugi raz czy LPM został wciśnięty jest zbędne.

if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
	sf::Vector2i pozycjaMyszy = sf::Mouse::getPosition(oknoAplikacji);
	sf::Vector2f mouse = oknoAplikacji.mapPixelToCoords(pozycjaMyszy);
	sf::FloatRect bounds1 = sprajt1.getGlobalBounds();

	if (bounds1.contains(mouse) && pole1 == 'n' && stan != "win")
	{
		// Jakies instrukcje, mniejsza z tym jakie
	}
}

Kwestia tej linijki.
 

sf::Vector2f mouse = oknoAplikacji.mapPixelToCoords(sf::Mouse::getPosition(oknoAplikacji));

Może być tak, że okno może być większe niż jest zaprogramowane (kiedy umożliwimy użytkownikowi ręczną zmianę rozmiaru okna - jak dobrze pamiętam to SFML skaluje wtedy odpowiednio obraz). W takiej sytuacji należy przekonwertować pozycję myszki na rzeczywistą pozycję wewnątrz okna aplikacji, jeżeli tego nie zrobisz to aplikacja
będzie otrzymywać pozycję nie zgodną z reprezentacją graficzną, lecz zgodną z logiczną.

Sprawdź sobie różnice między wartościami przed i po konwersji.

sf::Vector2f mousePosition = sf::Mouse::getPosition(oknoAplikacji);
sf::Vector2f worldPosition = oknoAplikacji.mapPixelToCoords(mousePosition);

std::cout << "mousePosition | x: " << mousePosition.x << " | y: << mousePosition.y << std::endl;
std::cout << "worldPosition | x: " << worldPosition.x << " | y: << worldPosition.y << std::endl;
komentarz 29 maja 2015 przez majkkel Użytkownik (530 p.)

No dobra, ale nasuwa mi się jeszce jedno pytanie. Mając taki fragment kodu:

if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
    sf::Vector2i pozycjaMyszy = sf::Mouse::getPosition(oknoAplikacji);
    sf::Vector2f mouse = oknoAplikacji.mapPixelToCoords(sf::Mouse::getPosition(oknoAplikacji));
    sf::FloatRect bounds1 = sprajt1.getGlobalBounds();
 
    if (bounds1.contains(mouse) && pole1 == 'n' && stan != "win")
    {
        // Jakies instrukcje, mniejsza z tym jakie
    }
}

Tworzymy zmienną "pozycjaMyszy" typu sf::Vector2i, ale nic z nią nie robimy. Przypisujemy jej pozycję wektora myszy i to by było na tyle ? Bo dalej już nie używamy tej zmiennej i tak jakby zamiast tego:

sf::Vector2i pozycjaMyszy

używamy tego:

sf::Mouse::getPosition(oknoAplikacji)

Czy ta instrukcja nie powinna wyglądać jakoś tak:

sf::Vector2f mouse = oknoAplikacji.mapPixelToCoords( pozycjaMyszy );
komentarz 29 maja 2015 przez Harsay Pasjonat (23,640 p.)
Prawda. Poprawiłem to w kodzie, który podałem niżej ;) Poprawiam kod wyżej.
komentarz 29 maja 2015 przez majkkel Użytkownik (530 p.)
No to wielkie dzięki za poświęcony czas, bo do tej pory nie rozumiałem o co z tym chodzi, a teraz już widzę że linie tego kodu rzeczywiście zazębiają się tworząc jedną całość.
0 głosów
odpowiedź 29 maja 2015 przez niezalogowany

Zajrzałeś w ogóle do dokumentacji? Bo właśnie po to ona jest (Vector2, mapPixelToCoors). Za dużo Ci nie podpowiem, bo nigdy z tej biblioteki nie korzystałem, a mój gameDev ograniczony jest do Unity3D. 

Jeśli jednak dobrze rozumiem, to metoda mapPixelToCoords służy do konwertowania położenia piksela (Vector2i) na położenie obiektu (Vector2f). Ma to w ogóle jakiś sens? Jeśli jestem w błędzie, to proszę mnie poprawić. Tutaj coś jeszcze znalazłem.

Podobne pytania

+3 głosów
2 odpowiedzi 701 wizyt
pytanie zadane 27 czerwca 2015 w C i C++ przez Pan Kulomb Pasjonat (18,630 p.)
–1 głos
2 odpowiedzi 833 wizyt
pytanie zadane 24 sierpnia 2015 w HTML i CSS przez tirex Gaduła (4,430 p.)
0 głosów
1 odpowiedź 357 wizyt
pytanie zadane 22 sierpnia 2015 w JavaScript przez Ivan Maniak (60,650 p.)

92,544 zapytań

141,387 odpowiedzi

319,503 komentarzy

61,930 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!

...