SFML - Limit ruchu myszki wokół okienka....

0

Witam, przez ostatni czas zgryzam zęby ze względu na problem który mi doskwiera. Muszę zastanowić się nad algorytmem do swojej gry, który będzie odpowiedzialny o blokowanie myszki, gdyby ta chciała wyjść poza ekran (Chcę, by myszką można było poruszać tylko i wyłącznie wokół okienka). Problem niby prosty, więc się zabrałem za to w taki sposób: Jeżeli dana pozycja X lub Y myszki jest poza ekranem (x < 0 || x > 1280, oraz y < 0 || y > 800) to resetuje mi pozycje myszki. Algorytm "jakoś" działa, i wygląda w moim kodzie tak:

    if (sf::Mouse::getPosition(window).x < 0 )
       sf::Mouse::setPosition(sf::Vector2i(0,sf::Mouse::getPosition(window).y),window);
    if (sf::Mouse::getPosition(window).x > 1024)
       sf::Mouse::setPosition(sf::Vector2i(1024,sf::Mouse::getPosition(window).y),window);
    if (sf::Mouse::getPosition(window).y < 0)
       sf::Mouse::setPosition(sf::Vector2i(sf::Mouse::getPosition(window).x,0),window);
    if (sf::Mouse::getPosition(window).y > 800)
       sf::Mouse::setPosition(sf::Vector2i(sf::Mouse::getPosition(window).x,800),window);
 

Dla ułatwienia, w pseudokodzie można było by to zapisać w takiej postaci:

if (MouseX < 0)
MouseSetPosition(0, MouseY);
if (MouseX > 1280) // 1280 to szerokość okienka
MouseSetPosition(1280, MouseY);
if (MouseY < 0)
MouseSetPosition(MouseX,0);
if (MouseY < 800) // 800 to wysokość okienka
MouseSetPosition(MouseX, 800);
 

Niestety, w taki sposób nie mogę doskonale zablokować myszki, bo w rzeczywistości można nią wyjść poza ekran, jeżeli w ciągu jednej klatki szybko machniemy myszką.
W przypadku innych gier, takie coś nie ma miejsca - przykładowo w grze Dota 2, która idealnie blokuje myszkę. (Oczywiście w okienkowym modzie, bo o takim mówimy)

Moje pytanie brzmi, czy jest w SFML 2.0 coś, co umożliwi mi ustanowienie limitu poruszania myszki tylko i wyłącznie w obrębie ekranu. Lub czy istnieje jakaś uniwersalna metoda, o której nie mam zielonego pojęcia.

Pozdrawiam.

0

Jak robiłem arkanoida to rozwiązałem to mniej więcej tak, sprawdzałem czy myszka nie jest krytycznie blisko boków, jeśli tak to cofałem myszkę.
Ten kod sprawdza boki, ale nie rogi okna, tzn musisz dopisać sobie jescze ify na przypadki gdy
X == 1; Y == 1;
X == maxX - 1; Y == 1;
oraz gdy:
X == 1: Y == maxY-1;
x == maxX - 1; Y == maxY-1;

 
#include <SFML/Graphics.hpp>
int main()
{
	const short int s_X = 600;
	const short int s_Y = 600;
    sf::RenderWindow window(sf::VideoMode(s_X, s_Y), "Przyklad");  
    sf::Vector2i pozycja; // Pozycja gryzonia;
    while (window.isOpen())
    {
        sf::Event event;
        sf::Mouse mysza;
        while (window.pollEvent(event))
        {
			/* 
			 * Jeśli user bedzie miał ZAMIAR (a nie już to zrobił) 
			 * wyjść poza ekran to zmień pozycje myszy 
			 * w pętli sprawdzamy pozycje myszy tylko jak została poruszona */
			if(event.MouseMoved)
			{			                     
				pozycja = sf::Mouse::getPosition(window);			
					if(pozycja.x < 1)        sf::Mouse::setPosition(sf::Vector2i(1,pozycja.y),window);
					if(pozycja.x > s_X - 1)  sf::Mouse::setPosition(sf::Vector2i(s_X-3,pozycja.y),window);			
					if(pozycja.y < 1)        sf::Mouse::setPosition(sf::Vector2i(pozycja.x,1),window);
					if(pozycja.y > s_Y - 1)  sf::Mouse::setPosition(sf::Vector2i(pozycja.x,s_Y-3),window);	
			}	
        }
        window.display();
    }
    return 0;
}
0

Odniosę się do Twojego komentarza: robiłem to w pętli głównej.
Hmm. Szczerze mówiąc byłem ciekawy czy to u mnie zadziała. Spróbowałem napisać to w swojej grze z wykorzystaniem eventu, ale to właściwie ma podobny, jak nie identyczny efekt jak w przypadku tego mojego sposobu... Jeżeli nie zrobiłem niczego źle, to oznacza, że za pomocą eventów raczej tego się nie da zrobić. Event jest dopiero po najechaniu myszki, a to oznacza że można wyjechać nią poza ekran.

0

Jeśli interesuje cię rozwiązanie z winapi to możesz użyć tego
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648383%28v=vs.85%29.aspx
Nie wiem tylko czy nie będzie to sprawiać innych problemów.

Może to jeszcze się przyda
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648380%28v=vs.85%29.aspx

0

Jestem tylko ciekawy czy mógłbym połączyć winapi z SFML 2.0 (tak jak np sfml z opengl jeżeli się nie myle). W każdym razie dzięki za referencje, bo właśnie ich potrzebowałem - w mojej obecnej sytuacji bardzo mi pomogliście. Spróbuję poszukać więcej informacji w internecie, i być może właśnie rozwiązanie pokroju winapi. jak uda mi się to zrobić w krótkim czasie to na pewno dam znać! :-)

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