Staram się owijać wokół tego bardzo Hello-y problem z tworzeniem gier. Stworzyłem grę w kółko i krzyżyk w XNA, więc sądzę, że następnym krokiem będzie klon Breakout .
Należy pamiętać, że nie mam żadnej wiedzy na temat programowania gier lub nawet to, co matematyka powinienem ubiegać się gdzie. Dlatego zadaję to pytanie.
Na pytanie: jak ustalić, gdzie piłka powinna się odbić, gdy uderza w wiosło u dołu ekranu?
Wyobrażam sobie, że byłoby to coś takiego:
- Uchwyć prędkość i kąt z nadchodzącej piłki.
- Wykryj, gdzie dotknął paska (daleko w lewo, daleko w prawo, środek) i zgodnie z tym nadaj mu większą prędkość, jeśli dotknie zewnętrznych obszarów.
- Tu utknąłem. Hehe
Jakieś spostrzeżenia? Zdaję sobie sprawę, że nie jest to proste pytanie typu odpowiedź, ale jestem pewien, że w pewnym momencie wszyscy mają do czynienia.
Czytam książkę Algebra liniowa, która była zalecana na tej stronie, ale nadal nie mam pojęcia, czy powinnam ją tutaj zastosować.
Odpowiedzi:
Oto odpowiednia logika, której użyłem w pongu na mojej stronie głównej : (proszę, zagraj w nią przed przeczytaniem, abyś wiedział, jaki efekt osiągam dzięki poniższemu kodowi)
Zasadniczo, gdy piłka zderza się z łopatką, jej kierunek jest całkowicie ignorowany; otrzymuje nowy kierunek w zależności od tego, jak daleko od środka wiosła się zderzyło. Jeśli piłka uderzy w wiosło w środku, zostanie odesłana dokładnie poziomo; jeśli trafi w krawędź, odlatuje pod ekstremalnym kątem (75 stopni). I zawsze jedzie ze stałą prędkością.
Weź środkową wartość Y wiosła i odejmij przecięcie Y piłki. Jeśli wiosło ma 10 pikseli wysokości, liczba ta będzie wynosić od -5 do 5. Nazywam to „przecięciem względnym”, ponieważ znajduje się teraz w „przestrzeni wiosła”, przecięciu piłki względem środka wiosła.
Weź względne skrzyżowanie i podziel je przez połowę wysokości łopatki. Teraz nasza liczba od -5 do 5 jest liczbą dziesiętną od -1 do 1; jest znormalizowany . Następnie pomnóż go przez maksymalny kąt, o który chcesz odbić piłkę. Ustawiłem na 5 * Pi / 12 radianów (75 stopni).
Na koniec obliczyć nowe prędkości kuli za pomocą prostej trygonometrii.
Może to nie do końca efekt, którego szukasz, lub możesz również określić prędkość, mnożąc znormalizowane przecięcie względne przez prędkość maksymalną; sprawiłoby to, że piłka leciałaby szybciej, jeśli uderzyłaby w pobliżu brzegu wiosła, lub wolniej, gdyby uderzyła w pobliżu środka.
Wektor zawiera zarówno prędkość, jak i kierunek. Przechowuję mój wektor jako „vx” i „vy”; to znaczy prędkość w kierunku x i prędkość w kierunku y. Jeśli nie odbyłeś wstępnego kursu fizyki, może ci się to wydawać obce.
Powodem, dla którego to robię, jest to, że zmniejsza to konieczne obliczenia dla poszczególnych klatek; każda klatka, którą właśnie robisz
x += vx * time;
iy += vy * time;
gdzie czas jest czasem od ostatniej klatki, w milisekundach (dlatego prędkości są w pikselach na milisekundę).Jeśli chodzi o wdrożenie zdolności do zakrzywiania piłki:
Przede wszystkim musisz znać prędkość wiosła w momencie uderzenia piłki; co oznacza, że musisz śledzić historię wiosła, abyś mógł poznać jedną lub więcej wcześniejszych pozycji wiosła, abyś mógł porównać je z bieżącą pozycją, aby sprawdzić, czy się poruszył. (zmiana pozycji / zmiana czasu = prędkość; więc potrzebujesz 2 lub więcej pozycji i czasów tych pozycji)
Teraz musisz także śledzić prędkość kątową piłki, która praktycznie reprezentuje krzywą, po której się porusza, ale jest równoważna obrotowi piłki w świecie rzeczywistym. Podobnie do interpolacji kąta odbicia od względnej pozycji piłki podczas zderzenia z łopatką, należy również interpolować tę prędkość kątową (lub obrót) od prędkości łopatki podczas zderzenia. Zamiast po prostu ustawić obrót, jak w przypadku kąta odbicia, możesz chcieć dodać lub odjąć istniejący obrót piłki, ponieważ zwykle działa to dobrze w grach (gracz może zauważyć, że piłka obraca się i powoduje jej obrót jeszcze bardziej dziko lub przeciwdziałaj spinowi, próbując sprawić, by podróż przebiegła prosto).
Zauważ jednak, że chociaż jest to najbardziej zdrowy rozsądek i prawdopodobnie najłatwiejszy sposób na jego wdrożenie, rzeczywista fizyka odbicia nie zależy wyłącznie od prędkości uderzanego obiektu; obiekt bez prędkości kątowej (bez spinu), który uderzy w powierzchnię pod kątem, będzie miał nadany spin. Może to prowadzić do lepszej mechaniki gry, więc możesz przyjrzeć się temu, ale nie jestem pewien fizyki stojącej za tym, więc nie zamierzam tego wyjaśniać.
źródło
Minęło trochę czasu, odkąd to zrobiłem, ale myślę, że mam rację.
Przy idealnym zderzeniu kąt odbicia jest równy kątowi padania.
Znasz normalną pozycję swojej wiosła (zakładając płaską powierzchnię): N Znasz swoją pierwotną pozycję piłki (na początku pomiaru czasu): P Znasz swoją nową pozycję piłki (na końcu pomiaru czasu): P 'Znasz swój punkt zderzenia: C Zakładając, że obliczyłeś, że segment P -> P' przechodzi przez wiosło, twoja nowa pozycja odbita (P '') byłaby:
P '+ 2 * (N * (P' kropka -N))
Podwyrażenie N * (P 'kropka-N) oblicza głębokość wzdłuż normalnej kolizji, którą przebyła piłka. Znak minus ma poprawić fakt, że sprawdzamy głębokość przeciwną do kierunku normalnego.
P '+ 2 * część podwyrażenia przesuwa piłkę z powrotem ponad płaszczyznę zderzenia o 2-krotność głębokości zderzenia.
Jeśli chcesz mniej niż idealnej kolizji, zmień współczynnik 2 na (1 + (1-k)), gdzie k jest współczynnikiem tarcia. Idealne zderzenie ma wartość ak wynoszącą 0, co powoduje, że kąt odbicia jest dokładnie taki, jak kąt wejściowy. Wartość k równa 1 powoduje zderzenie, w którym kula pozostanie na powierzchni płaszczyzny zderzenia.
Twój nowy wektor prędkości, V '', miałby kierunek P '' - C. Znormalizuj go i pomnóż przez swoją prędkość wejściową, a uzyskana wielkość prędkości będzie taka sama, ale w nowym kierunku. Możesz małpować z tą prędkością, mnożąc ją przez współczynnik l, który albo zwiększy (l> 1), albo zmniejszy (l <1) uzyskaną prędkość.
Podsumowując:
P '' = P '+ (1-k) * (N * (kropka-N)) V' '= l * V * ((P' '- C) / | P' '- C |)
Gdzie k i l to wybrane przez ciebie współczynniki.
źródło
Odbicie można wykonać „dobrze” lub „łatwo”.
„Właściwy” sposób polega na obliczeniu wektorów prostopadłych do ścian. W 2D jest to dość łatwe i prawdopodobnie można je po prostu na stałe zakodować. Następnie krok odbicia zasadniczo pozostawia nienaruszony „równoległy” komponent ruchu i odwraca „prostopadły” komponent. W sieci są prawdopodobnie szczegółowe informacje na ten temat, może nawet w MathWorld.
„Prostym” sposobem jest po prostu zanegowanie ruchu X lub Y po uderzeniu w ścianę. Jeśli uderzysz w boczne ściany, negujesz X. Jeśli uderzysz w górę, negujesz Y. Jeśli chcesz przyspieszyć piłkę, po prostu zwiększ cokolwiek chcesz; możesz przyspieszyć w bieżącym kierunku, mnożąc prędkości X i Y lub możesz przyspieszyć tylko na jednej osi.
źródło
Sam tworzę grę arkanoidalną i myślę, że rozwiązanie, w jaki sposób powinna zachowywać się piłka po uderzeniu w wiosło, jest znacznie prostsze i szybsze niż podejście do grzechu / cos ... działa dobrze dla celów taka gra. Oto co robię:
Oczywiście, ponieważ prędkość piłki rośnie w czasie interpoluję kroki przed / po x, y, aby zachować dokładne wykrywanie kolizji, zapętlając wszystkie „stepX” i „stepY”, które są obliczane dzieląc każdy składnik prędkości przez moduł utworzonego wektora przez obecne i przyszłe pozycje piłki.
Jeśli dojdzie do kolizji z łopatką, dzielę prędkość Y przez 20. To „20” jest najwygodniejszą wartością, jaką znalazłem, aby uzyskać wynikowy maksymalny kąt, gdy piłka uderza w boki łopatki, ale możesz zmienić ją na cokolwiek Twoje potrzeby są, po prostu graj z niektórymi wartościami i wybierz dla siebie coś lepszego. Dzieląc, powiedzmy, prędkość 5, która jest moją początkową prędkością gry przez tę liczbę (20), otrzymuję „współczynnik odbicia” wynoszący 0,25. Obliczenia te utrzymują moje kąty dość proporcjonalne, gdy prędkość rośnie w czasie do mojej maksymalnej wartości prędkości, która na przykład może wynosić 15 (w tym przypadku: 15/20 = 0,75). Biorąc pod uwagę, że moje wiosła x, y struny są w połowie (xiy przedstawiają środek wiosła), następnie mnożę ten wynik przez różnicę między pozycją piłki a pozycją wiosła. Im większa różnica, greatear wynikowy kąt. Poza tym za pomocą padliny ze środkowym uchwytem otrzymujesz prawidłowy znak przyrostu x w zależności od strony uderzenia piłki, bez obawy o obliczenie środka. W pseudokodzie:
Dla n = 0 do modułu ...
jeśli wykryto kolizję, to speedX = - (speedY / 20) * (paddleX - ballX); speedY = -speedY;
wyjście; koniec jeśli
...
x = x + stepX; y = y + krok Y;
koniec dla
Pamiętaj, zawsze staraj się zachować prostotę. Mam nadzieję, że to pomoże!
źródło
Wiosło w Breakout, gdy podąża za opisanym stylem, jest zwykle modelowane jako zakrzywiona powierzchnia. Kąt padania zmienia się w zależności od tego, gdzie uderza wiosło. W martwym punkcie linia styczna do łuku jest całkowicie pozioma, a kula odbija zgodnie z oczekiwaniami. W miarę oddalania się od środka styczna do łuku staje się coraz bardziej nachylona, w wyniku czego kula odbija się inaczej.
Kluczową kwestią jest to, że zmienia się kąt odbicia, a nie prędkość piłki. Prędkość piłki ogólnie po prostu powoli rośnie z czasem.
źródło
angle = 1 - 2 * (ball.x - paddle.left) / paddle.width
da ci liczbę od 1 do -1; to (razy pewna wartość poprawiona dla twojej mechaniki gry) jest nachyleniem linii stycznej w punkcie, w którym uderzyła piłka. Odbij się od tej linii, a nie od linii poziomej.Nolan Bushnell wygłosił przemówienie na SIEGE w miniony weekend i mówił o podobnym problemie z oryginalnym pongiem. Nie musisz wykonywać skomplikowanych obliczeń. Jeśli trafisz w lewą część panelu, wyślij piłkę w lewo. Zrób to samo dla prawej strony.
Na początek możesz ustawić kąt dla lewej i prawej strony 45 stopni. Po zakończeniu gry możesz wrócić i uczynić to bardziej skomplikowanym, ale uczyń to tak prostym, jak to tylko możliwe.
źródło
Breakout to klasyczna praca dla początkujących, która pozwala zanurzyć się w świecie programowania gier opartych na fizyce. Zasadniczo piłka odskakuje, gdy uderza o ścianę. Jak sugerował ktoś powyżej, kąt padania jest równy kątowi odbicia. Ale kiedy weźmiesz pod uwagę piłkę uderzającą w wiosło. Logika podzielona jest na 3 sekcje. 1.) Piłka uderza w środkową część wiosła. 2.) Piłka uderza w lewą część wiosła. 3.) Piłka uderza w prawą pozycję wiosła.
Gdy weźmiesz pod uwagę środkową część: nie musisz różnicować efektu odbicia od tego, który jest stosowany podczas uderzenia piłki. Piłka po prostu odchyla się normalnie, ale gdy uderzy się w którymkolwiek kierunku, sprawa jest inna.
Gdy piłka zostanie uderzona w lewą stronę, tzn. Weź pod uwagę piłkę wychodzącą z lewej strony ekranu i zbliżasz się z łopatką z prawej strony. Następnie, gdy uderzasz piłkę lewą częścią, piłka powinna odbijać się w kierunku, w którym pochodzi z .ie. W lewo, pod tym samym kątem, z którego pochodzi. To samo dotyczy odwrotnie. W części prawej obowiązuje to samo.
Ten ruch piłki podczas uderzenia w lewo lub w prawo czyni ją bardziej wiarygodną.
Mam nadzieję, że masz pomysł, przynajmniej logicznie. Dziękuję
źródło
Wyobraź sobie, że obliczasz odległość między środkiem wiosła a punktem, w którym uderzyła piłka Y i ją wołasz
d
. Załóżmy, żed
ma wartość dodatnią, gdy piłka uderzy powyżej środka wiosła. Możesz teraz zwiększyćd * -0.1
prędkość Y swojej piłki, a zacznie ona zmieniać kierunek. Oto przykład w javascript, który można łatwo przetłumaczyć na c #!źródło
pomoże to http://www-classes.usc.edu/engr/ee-s/477p/s00/pong.html po prostu odwrócić xiy w zależności od tego, gdzie trafi na ekran. jeśli idzie w górę i uderza w górę, odwraca prędkość y, zachowując prędkość x
źródło
Cześć. Ostatnio próbowałem stworzyć grę w piłkę i wymyśliłem rozwiązanie tego problemu. Więc co zrobiłem: wiosło porusza się podczas gry. Mój układ współrzędnych jest taki, jaki jest, lewy górny punkt płótna to 0,0. Łopatka porusza się w tym układzie współrzędnych. Oś x wskazuje od 0 do szerokości obszaru roboczego, a oś y wskazuje od 0 do wysokości obszaru roboczego. Stworzyłem wiosło o stałej szerokości 100 i wysokości 20. A potem narysuję wokół niego wyobrażony okrąg. Kiedy piłka uderza w wiosło, obliczam punkt środkowy wiosła
Następnie odejmuję środek od aktualnej pozycji piłki w ten sposób, że układ współrzędnych znajdzie się na środku łopatki, ballCenter to punkt, w którym piłka uderzyła w łopatkę (- (szerokość wiosła + r) .. 0 .. (szerokość wiosła + r )) to nic innego jak przeskalowanie punktu uderzenia na wiosle
obliczyć punkt przecięcia okręgu za pomocą punktu uderzenia piłki (x0) jest to ponowne obliczenie, prosimy o współrzędną y na okręgu o znanej już współrzędnej x0 i potrzebne było odwrócenie osi y
obliczyć pochodną równania normalnego koła zdefiniowanego wokół łopatki za pomocą łopatki Radis Radius f (x, y) = x ^ 2 + y ^ 2-r ^ 2
znormalizować wektor N, aby uzyskać wektor jednostkowy normalnej powierzchni
teraz mamy znormalizowane (jednostkowe) normalne powierzchni wiosła. Oblicz nowy kierunek za pomocą tych normalnych powierzchni, zostanie to obliczone za pomocą wzoru wektora odbicia: new_direction = old_direction-2 * dot (N, old_direction) * N, ale zamiast tego z normalną powierzchnią skierowaną zawsze w górę, normalna będzie zmieniać się z miejsca na punkt, w którym piłka uderza w wiosło
Opublikowałem swoje rozwiązanie tego problemu. Aby uzyskać więcej informacji i pełną grę, możesz zobaczyć moje repozytorium github:
https://github.com/zoli333/BricksGame
napisane w języku Java z zaćmieniem. Istnieje inne rozwiązanie tego skomentowane w Ball.java, w którym przeskalowanie nie występuje. Nie przesuwam układu współrzędnych do punktu środkowego łopatki, zamiast tego obliczam wszystkie powyższe z górnego układu współrzędnych 0,0 względem punkt środkowy wiosła. Działa to również.
źródło