Autor Wątek: Problem kolizji okna?  (Przeczytany 1904 razy)

Offline Bantu

  • Użytkownik

# Czerwiec 09, 2011, 15:38:46
Witam wczoraj zacząłem sobie pisać powoli grę w popularnego snake'a, ale natrafiłem na jeden pewnie mały problem, który się tyczy kolizji postaci z oknem. W kodzie mam sprawdzanie położenia postaci względem krawędzi okna. Wszystko jest okej, gdy wartość X i Y postaci jest mniejsza od 0, czyli górnej i lewej krawędzi, ale jeśli chodzi krawędź prawą i dolną to zdarzenie kolizji zostaje wychwycone dopiero parę pikseli dalej. Mój kod na kolizje ze ścianą wygląda tak:

if (snake.SnakeRect[0].X < 0 || snake.SnakeRect[0].X > 290)
{
restart();
}
if (snake.SnakeRect[0].Y < 0 || snake.SnakeRect[0].Y > 315)
{
restart();
}

Nie ma w tym kodzie jak widać nic szczególnego, po prostu kod sprawdza wartości względem "głowy" węża no i w momencie gdy są większe niż maksymalne wartości okna powinna nastąpić kolizja, a tak się nie dzieje. Nie mam pojęcia w czym może tkwić problem. Jakieś pomysł?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Czerwiec 09, 2011, 15:43:14
A w jaki sposób pobierasz rozmiary okna?

Offline Avaj

  • Użytkownik

# Czerwiec 09, 2011, 15:47:10
uważaj bo do współrzędnych możesz mieć doliczoną ramkę okna albo jakieś takie bzdury

Offline Bantu

  • Użytkownik

# Czerwiec 09, 2011, 15:55:25
Wielkość okna po prostu podaje mu tak jak jest w kodzie odczytane z properties, próbowałem też przez Size.Width i Height, ale wychodziło tak samo jak ręcznie podawałem. W sumie udało mi się rozwiązać problem poprzez danie mniejszych wartości, ale mimo wszystko dla mnie to jest dość dziwne, że mimo podania mu wartości, które są faktyczne nie działa, a gdy mu dam zmniejszone wartości to już działa. Nawet uwzględniając te parę pikseli na ramki i inne duperele było źle. Totalnie mnie to jakoś dezorientuje dlaczego tak może być.

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Czerwiec 09, 2011, 15:57:04
Być może właściwości Width i Height nie są podawane w pikselach, tylko jakichś innych jednostkach.

Offline Kitsune

  • Użytkownik

# Czerwiec 09, 2011, 16:18:16
Cytuj
Być może właściwości Width i Height nie są podawane w pikselach, tylko jakichś innych jednostkach.
W pikselach ale...
w Windowsowym API rozmiar okna liczy się razem z paskiem tytułowym, i ramką. Czyli, musisz dodać 8 pikseli w poziomie (po 4 na boczne krawędzie ramki) i 34 piksele w pionie (30 pikseli na pasek tytułowy i 4 na dolną ramkę) -> szerokość okna + 8, wysokość okna +34.
« Ostatnia zmiana: Czerwiec 09, 2011, 16:20:41 wysłana przez Kitsune »

Offline Vipa

  • Redaktor

# Czerwiec 09, 2011, 16:32:45
A co jeżeli ktoś ustawi większą czcionkę w systemie i pasek tytułowy jest przez to wyższy? Grubość ramki także można regulować z poziomu ustawień systemu.

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Czerwiec 09, 2011, 16:37:55
I dlatego właśnie powinno się korzystać z funkcji WinAPI GetClientRect.

Offline Xirdus

  • Redaktor

# Czerwiec 09, 2011, 17:28:17
Albo używać własnego "wirtualnego" okienka, bez żadnych ramek ani podobnych.

Offline kapec94

  • Użytkownik

# Czerwiec 09, 2011, 17:38:04
Wydaje mi się, że odpowiedź jest dużo prostsza, niż moi przedmówcy myślą.
W swoich obliczeniach do krawędzi ramki porównujesz współrzędne lewego górnego wierzchołka prostokąta swojego snejka, więc kod wykonuje się tylko wtedy, gdy on koliduje ze ścianą.

if (snake.getX() > window.width - snake.width) collision();

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Czerwiec 09, 2011, 17:41:42
Wydaje mi się, że odpowiedź jest dużo prostsza, niż moi przedmówcy myślą.
W swoich obliczeniach do krawędzi ramki porównujesz współrzędne lewego górnego wierzchołka prostokąta swojego snejka, więc kod wykonuje się tylko wtedy, gdy on koliduje ze ścianą.

if (snake.getX() > window.width - snake.width) collision();

Faktycznie, niech żyje spostrzegawczość :-).