Skocz do zawartości


Zdjęcie

Pomocy, problemik matematyczny


  • Zaloguj się, aby dodać odpowiedź
9 odpowiedzi w tym temacie

#1 tyro

tyro

    Generał

  • Head Admin
  • PipPipPipPipPipPipPipPipPipPip
  • 5 593 postów

Napisano 25 stycznia 2013 - 10:03

Nigdy nie byłem dobry z matmy, jakoś sobie w życiu radzę starając się zawsze rozkładać problemy na najprostsze możliwe elementy. tym razem napotkałem problem, który nie wiem jak ugryźć.

Problem z algorytmem, którego potrzebuję w pluginie minecrafta. Spokojnie, nie chodzi mi o grę, ale o rozwiązanie matematyczne.

Sytuacja praktyczna:

Jest mapa (w każdej grze jest jakaś mapa), są na niej gracze, którzy się poruszają tu i tam. Jest wyznaczony środek mapy, gdzie jest spawn. Mapa jest nieskończona, czyli teoretycznie można iść w nieskończoność. Ale ja tego nie chcę, bo się porozchodzą i nie trafią na siebie. Dlatego chcę zbudować barierę. Jeżeli gracz odejdzie na większą odległość od spawn niż to jest ustawione, to go teleportuje do punktu położonego przed granicą. Rozumiecie?

Mam taki plugin, ale do tej pory działał tak, że spawn był zawsze ustawiony w punkcie x=0, z=0 (zero, zero).

Jesli granica była 1000 jednostek, to gra sprawdzała wartość bezwzględną pozycji gracza i jeśli x lub z było większe niż 1000, to teleportowało gracza do punktu o współrzędnych 0.98 * x, 0.98 * z. W ten sposób gracz odbijał się od bariery. Było to proste po spawn był w 0,0.

Ale teraz potrzebuję, żeby punkt spawn w dowolnym innym punkcie, niekoniecznie zero. I tu pojawia się

Problem matematyczny:

Jest układ współrzędnych x, z (y w grze to wysokość). Układ typowy od minus do plus nieskończoności. (w praktyce od -10000 do +10000).

Dane:

- punkt "zero" spawn (x, z) ustalony dowolnie na układzie współrzędnych.

- granica: g - dozwolona stała odległość od spawn. Z tym, że odległość 'po kwadracie' a nie po okręgu. Czyli granica jest osiągnięta wtedy, gdy którakolwiek współrzędna x lub z jest większa niż granica.

- pozycja gracza (x1,z1) punktu, w którym znajduje się gracz.

Szukane:

- sprawdzanie czy punkt (gracz) jest w granicy. - ten problem rozwiązuję tak, że biorę wartość bezwzględną z różnicy między współrzędnymi pozycji gracza i punktu spawn
czyli gracz jest poza granicą jeśli: Abs(x1 - x) > g lub Abs (z1 - z) > g i to chyba jest dobrze.

- wyznaczanie nowej, dozwolonej pozycji gracza - tu jest problem do rozwiązania. Trzeba znaleźć nowy punkt o współrzędnych mieszczących się w obszarze granicy i zbliżony do aktualnej pozycji gracza.

Czyli trzeba znaleźć (x2,z2) które znajdują się np. w odległości 98% od spawn, w pobliżu pozycji gracza.

Żeby było prościej zakodować, szukamy nowego x2, jeśli x1 jest poza granicą, lub nowe z2 jesli z1 jest poza granicą.

Algorytm musi uwzględniać sytuacje, gdzie spawn znajduje się w każdej 'ćwiartce' układu współrzędnych, granica mieści się lub nie w tej ćwiartce i tak samo gracz.

I co wy na to?


  • 0

#2 dumbass

dumbass

    Porucznik

  • Oldie
  • PipPipPipPipPipPip
  • 850 postów

Napisano 25 stycznia 2013 - 11:10

moim zdaniem najlatwiej

rzutujesz układ wspołrzędnych gracza na układ świata lub odwrotnie,

w 1 przypadku sprowadza się to do sprawdzenia odległości punktu od prostej. wiesz w jakim kierunku gracz sie porusza wiesz gdzie znajduja sie proste. dalej mozesz dodadkowo sie zabezpieczyc zeby sprawdzanie odleglosci nastepowalo tylko w jakims bezposrednim sasiedztwie tych prostych. dalej obliczywszy kierunek ruchu gracza cofasz go wedlug wektora o tym samym kierunku lecz przeciwnym zwrocie.


  • 0
S&D stanowcze NIE precz z CS'em w COD'zie!!!!!!!!a na HC grają sami KAMPERZY i CZAIDUPY

#3 tyro

tyro

    Generał

  • Head Admin
  • PipPipPipPipPipPipPipPipPipPip
  • 5 593 postów

Napisano 25 stycznia 2013 - 12:02

o rany dumbass, dzięki, wiesz jak załamać kolegę. wektorów nie tykam. cuda się dzieją jak zaczynam ruszać wektory.

ja to rozpisałem, ale mi się pogmatwało i się zaplątałem w morze warunków i z prostego (intuicja mi mówiła, że to proste) problemu zrobił mi się koszmarek.

mam rozwiązanie, proste, aż genialne i wydaje się działać.

Eurobercik:

Jeżeli:
X1-x > g
X1 > x
To wyteleportuj gracza na:
X + 0,98g ,y1, z1

Jeżeli:
X1-x>g
X1 < x
Tu wyteleportuj gracza na:
X - 0,98g, y1, z1

Potem trzeba zrobić to samo z Z. Chyba zadziała.



  • 0

#4 dumbass

dumbass

    Porucznik

  • Oldie
  • PipPipPipPipPipPip
  • 850 postów

Napisano 25 stycznia 2013 - 12:23

z tym jest pewien problem a wlasciwie 2 :D kiedys robilem kolizje ta metoda i przy pewnych wartosciach obiekt i tak przejdzie za granice, do dzis nie mam pojecia dlaczego tak sie dzieje (napisz sobie zwykla aplikacje gdzie jakas pileczka odbija sie od podlogi w koncu przestanie sie odbijac i przejdzie na 2 strone) z 2 pomoze rysunek

t50iz8.png

Załączone pliki

  • Załączony plik  1.png   31,48 KB   0 Ilość pobrań

  • 0
S&D stanowcze NIE precz z CS'em w COD'zie!!!!!!!!a na HC grają sami KAMPERZY i CZAIDUPY

#5 tyro

tyro

    Generał

  • Head Admin
  • PipPipPipPipPipPipPipPipPipPip
  • 5 593 postów

Napisano 25 stycznia 2013 - 01:20

mhm... teraz dopiero zajarzyłem. sorry starość, zwiotczenie synaps itd.
Generalnie mi tu przedstawiasz rozwiązanie problemu bariery w bardziej profesjonalny sposób.
Coś o czym myślałem podchodząc do sprawy budowy samej bariery i sposobu 'powstrzymania' gracza przed pójściem dalej.
Wówczas po kilku próbach twardego powstrzymywania gracza, które się nie powiodły, bo wektory robiły z graczem co chciały, postanowiłem pójść na skróty i nie powstrzymywać graczy 'twardo', tylko zwyczajnie ich cofać przed barierę.
Przede wszystkim dlatego, że nie umiałem tego zrobić, ale również dlatego, że aby ich powstrzymywać wektorem ruchu, musiałbym korzystać ze zdarzeń wysokiej częstotliwości, takich jak np. player move event. Staram się tego unikać, ze względu na obciążenie serwera. Dlatego działam w oparciu o timer, który co kilka sekund sprawdza pozycję graczy i podejmuje działanie - jeśli są poza barierą, zwyczajnie teleportuje kawałek przed.
W praktyce wygląda to tak, że idziesz, dochodzisz do bariery i nic się nie dzieje, ale po chwili będąc już za barierą serwer cofa cię.
W zależności od prędkości ruchu i timingu, możesz przejść nawet kilkadziesiąt jednostek poza barierę.
W przypadku minecrafta, nie robi to różnicy - mapa jest nieskończona i czy ustawię granicę na 3000 jednostek czy na 3100 nie ma to znaczenia. Zawsze zresztą zakładam, że graczowi uda się pokonać nawet 100 jednostek, jeśli serwer złapie laga.
Koniec końców zależy mi na tym, żeby nie szli na 5000 tys albo dalej.
No i funkcja jest prosta kilkanaście linijek.

Nie mogłem sobie poradzić tylko z tymi plusami i minusami osi współrzędnych. Za dużo było tych warunków, a nie mogłem zajarzyć prostego wzoru, synapsy już nie te....

btw. przykładu:Załączony plik  t50iz8.png   42,47 KB   17 Ilość pobrań
  • 0

#6 dumbass

dumbass

    Porucznik

  • Oldie
  • PipPipPipPipPipPip
  • 850 postów

Napisano 25 stycznia 2013 - 01:44

tak jest prawidlowy ale nie chcesz zeby sie odbijal w taki sposob tylko wracal:X zla terminologia z mojej strony. dlatego najpierw sobie sprawdz warunek czy gracz znalazl sie w bliskosci granicy nie wiem powiedzmy te 100 jednostek od niej a pozniej juz dokladnie kolizje z nia


  • 0
S&D stanowcze NIE precz z CS'em w COD'zie!!!!!!!!a na HC grają sami KAMPERZY i CZAIDUPY

#7 JSokol

JSokol

    Plutonowy

  • Member
  • PipPipPip
  • 166 postów

Napisano 26 stycznia 2013 - 12:37

Punkty:

U(x,y) to współrzędne gracza

S(i,j) to współrzędne obranego spawna

r = dozwolona ogległość od i oraz j w której jeszcze może znajdować się gracz.

if(x<i-r)

x = i-r;

else if(x>i+r)

x = i+r;

if(y<j-r)

y = j-r;

else if(y>j+r)

y = j+r;

To w sytuacji ogólnej przeniesie gracza na skraj dopuszczalnej granicy (nie sprawdzam czy nie wychodzi się poza "niekończony" obszar).

Jeśli chcesz to przerobić na 98% od dopuszczalnej odległości, to wystarczy:

if(x<i-r)

x = i-(int)(r*0,98);

else if(x>i+r)

x = i+(int)(r*0,98);

if(y<j-r)

y = j-(int)(r*0,98);

else if(y>j+r)

y = j+(int)(r*0,98);

O to chodziło?


Użytkownik JSokol edytował ten post 26 stycznia 2013 - 12:40

  • 0

#8 tyro

tyro

    Generał

  • Head Admin
  • PipPipPipPipPipPipPipPipPipPip
  • 5 593 postów

Napisano 26 stycznia 2013 - 08:20

tak, dzięki wielkie :)
wprowadziłem w życie i działa, i już pojawiły się skargi, że pół zamku jest niedostępne, bo był na granicy jak była liczona od punktu 0.0 , a że spawn jest przesunięty, więc obszar dozwolony się przesunął. Musiałem poszerzyć obszar :)
  • 0

#9 dumbass

dumbass

    Porucznik

  • Oldie
  • PipPipPipPipPipPip
  • 850 postów

Napisano 26 stycznia 2013 - 08:46

pewnie bo moje to zle:(


  • 0
S&D stanowcze NIE precz z CS'em w COD'zie!!!!!!!!a na HC grają sami KAMPERZY i CZAIDUPY

#10 tyro

tyro

    Generał

  • Head Admin
  • PipPipPipPipPipPipPipPipPipPip
  • 5 593 postów

Napisano 26 stycznia 2013 - 09:57

dobre dumbass i również dzięki za pomoc, ale trochę trudne w realizacji.
minecraft serwer API oferuje co prawda metody operowania wektorami, ale nie udało mi się tego dobrze ogarnąć. Metody wektorowe dziwnie działają, dają nieprzewidziane efekty, najczęściej nie takie jakbym chciał, dlatego zastosowałem prostszą metodę, nie tak profesjonalną jak wektory, ale ją rozumiem i umiem zastosować :)
  • 0




Użytkownicy przeglądający ten temat: 1