Ju1ian Temat założony przez niniejszego użytkownika |
[Allegro] Kolizje w platformówce ;) » 2008-04-16 14:31:51 Witam! Mam problem ze wskakiwaniem na platformę w platformówce (fajnie się pisze :)). Próbowałem z tym co zrobił Easykoder: bool kolizja( float x1, float y1, float s1, float w1, int x2, int y2, int s2, int w2 ) { if( x2 <= x1 + s1 && x2 > x1 && y2 >= y1 && y2 <= y1 + w1 ) return true; else if( x2 <= x1 + s1 && x2 > x1 && y2 + w2 >= y1 && y2 + w2 <= y1 + w1 ) return true; else if( x2 + s2 <= x1 + s1 && x2 + s2 > x1 && y2 >= y1 && y2 <= y1 + w1 ) return true; else if( x2 + s2 <= x1 + s1 && x2 + s2 > x1 && y2 + w2 >= y1 && y2 + w2 <= y1 + w1 ) return true; else return false; };
if( kolizja( ludek_x, ludek_y, ludek->h, ludek->w, platfa_x, platfa_y, platfa->h, platfa->w ) == true ) { ludek_y == platfa_y - 20; }
To w ogóle nie działa. Wiem, że dodatkowo "ludek_y==platfa_y-20" jest niepoprawne . Przez to (gdyby kolizja działała) ludzik mógłby chodzić po niebie. Już od dłuższego czasu szukam rozwiązania. Mam nadzieję, że przyjdziecie mi z pomocą ;D Za odpowiedź bardzo dziękuję ;) |
|
DejaVu |
» 2008-04-16 15:02:06 Porównanie: ludek_y == platfa_y - 20; Przypisanie: ludek_y = platfa_y - 20; |
|
Ju1ian Temat założony przez niniejszego użytkownika |
» 2008-04-16 15:05:14 Ja nie mogę, taki błąd xD. Tylko, że ten system kolizji coś nie za bardzo działa. Odpalam program, a mój ludek lewituje i nie chce skakać ;/ (;)) Dam mój kod do skoku: if( key[ KEY_UP ] || key[ KEY_SPACE ] ) if( ludek_y == klocki_y ) ludek_ruch_y =- 10;
ludek_x += ludek_ruch_x; ludek_y += ludek_ruch_y;
if( ludek_ruch_x > 0.1 ) ludek_ruch_x -= 0.5; else if( ludek_ruch_x <- 0.1 ) ludek_ruch_x += 0.5; else ludek_ruch_x = 0; if( ludek_y < 270 ) { ludek_ruch_y += 0.3; } if( ludek_y > klocki_y ) { ludek_y = klocki_y; }
|
|
DejaVu |
Grawitacja w grze - opis ogólny » 2008-04-17 00:45:35 Generalnie ruch w osi Y powinieneś opisać za pomocą ruchu jednostajnie przyśpieszonego. Powinno to działać tak: przyśpieszenie: g=9.81 - zakładając że oś Y masz skierowaną w dół (wartości na ekranie rosną w dół). y = pos_start + V_start * t +( g *( t * t ) ) / 2.0; W momencie kliknięcia skoku zmienne powinny uzyskać następujące wartości: Zaznaczam, że jest to bardzo ogólne rozwiązanie, które powinno zostać dostosowane umiejętnie do projektu. Jeśli ja miałbym implementować 'grawitację' bo tak naprawdę o to się rozchodzi problem skoku i spadania posiadając wyżej wymieniony wzór, zrobiłbym to następująco: 1. Utworzyć strukturę dla obiektu, który ma podlegać grawitacji, np: struct SPunkt { double x; double y; }; enum ERuch { 0 = RuchStop, RuchLewo, RuchPrawo, RuchSkok } stcuct SFizyka { SPunkt pozycja; SPunkt predkosc; SPunkt przyspieszenie; double czas; ERuch przed; ERuch teraz; };
struct SObiekt { SFizyka start; SFizyka aktualna; }; 2. W kolejnym kroku skupiłbym się na inicjacji obiektu: SObiekt ludek; ludek.start.pozycja.x = 100; ludek.start.pozycja.y = 200; ludek.start.predkosc.x = 0; ludek.start.predkosc.y = 0; ludek.start.przyspieszenie.x = 0; ludek.start.przyspieszenie.y = 9.81; ludek.start.czas = 0; ludek.aktualna = ludek.start; ludek.teraz = RuchStop; ludek.przed = ludek.teraz;
3. Następnie robimy pętlę, w której będziemy tworzyli ruch. while( true ) { if( klawisz[ PRAWO ] && !klawisz[ LEWO ] ) { ludek.aktualna.predkosc.x = 5; ludek.teraz = RuchPrawo; } else if( !klawisz[ PRAWO ] && klawisz[ LEWO ] ) { ludek.aktualna.predkosc.x = - 5; ludek.teraz = RuchLewo; } else { ludek.aktualna.predkosc.x = 0; ludek.teraz = RuchStop; } Sleep( 20 ); if( ludek.teraz != ludek.przed ) { ludek.przed = ludek.teraz; ludek.start = ludek.aktualna; } ludek.aktualna.czas += 0.02; double deltaT = ludek.aktualna.czas - ludek.start.czas; }
4. Kolejnym krokiem będzie podczepienie ludzika pod animację, czyli wyświetlanie ludzika na współrzędnych ludek.aktualna.x i ludek.aktualna.y. 5. W następnym kroku wyznaczyć wzory (wcześniej o jednym wspomniałem) dla pozycja, predkosc i przyspieszenie i do ludek.aktualna, zapisywać nowo wyliczone współrzędne. Do wylicznia współrzędnych wykorzystać deltaT i pola ze struktury ludek.start (bez pola czasu). 6. W przedostatnim kroku dodałbym warunek sprawdzania, czy coś się znajduje pod obiektem i jeśli tak, to albo nie wykonywał grawitacji, albo ustawiał przyśpieszenie = 0 (dla osi y), gdy pod obiektem istnieje obiekt (czyli jest kolizja). Jeśli pod ludzikiem nie ma niczego, to ustawiać grawitację. 7. Ostatni krok to dodanie skoku. Jedyne co trzeba zrobić to: if(...) { ludek.teraz = RuchSkok; ludek.aktualna.V = - 50; }
Jeśli dobrze oprogramujesz krok 5 i 6 gra będzie działała z satysfakcjonującym rezultatem :) Dodatkowo szkielet, który przedstawiłem umożliwi Ci łatwe zablokowanie sterowania lewo/prawo podczas lotu jeśli będziesz chciał, aby sterowanie strzałkami w locie nie było możliwe. |
|
Ju1ian Temat założony przez niniejszego użytkownika |
» 2008-04-17 10:30:06 Naprawdę bardzo dziękuję Ci za wszystko, ale jestem na razie na tyle słaby, że nie mogę tego oprogramować. ;( Na tym forum starasz się pomagać jak najlepiej, nigdzie indziej tak nie robią ;) Chodziło mi tylko o kolizje, ale to na pewno się bardzo przyda. Z kolizjami mam 3 problemy. 1. Gdy narysuję sobie większą platformę to kolizja nie obejmuje jej całej. 2. Gdy już stoję na platformie, to gdy już za długo na niej jestem i chcę zejść to spadam z ogromną prędkością ;) 3. Gdy jestem pod platformą i chcę na nią wskoczyć, to naciskam SPACJĘ, od razu znajduję się na platformie (teleport ;)) i na niej robię skok. Na prawdę za wszystko dziękuję. |
|
DejaVu |
» 2008-04-17 14:20:32 Siadając do skoku/spadania nie możesz myśleć jak o problemie programistycznym, ale jak o problemie matematycznym lub fizycznym.
Utwórz sobie układ współrzędnych: oś pozioma: t (czas) oś pionowa: y (pozycja w osi y) Zakładasz że ludek jest na pozycji ludek_y=10. Wiesz, że czas biegnie w stałym tempie, więc obojętnie czy ludzikiem będziesz chodził lewo/prawo czy też będziesz się nie ruszał, to wykresem będzie linia prosta. Jeśli klikasz spację to znaczy, że chcesz aby ludzik zmnienił swoją pozycję. Jeśli dodasz do obecnej pozycji wartość np. 30, to na wykresie zaobeserwujesz, że wykres nie jest ciągły, czyli otrzymasz efekt 'teleportacji' w osi y. Twoim zadaniem jest dojść do nowej wartości ludek_y+30 rozłożonym w czasie delta_t. Czyli np. zrobić tak, aby załóżmy od kliknięcia skoku, 100 razy pozycja ludzika y zmieniała się o wartość ludek_y+=(30.0/100.0). Pamiętaj, że ludek_y, musi być typu double, bo int Ci będzie zjadał ułamki i nic się nie będzie działo. |
|
Ju1ian Temat założony przez niniejszego użytkownika |
» 2008-04-17 17:07:07 Ale ja skoki mam już dopracowane i wszystko działa ;) Chodzi mi tylko o te 3 problemy, które napisałem u góry. Gdy ludzik u mnie skacze, to jest efekt grawitacji, czyli skacze na początku szybko, a potem ledwo co. Spada na początku wolniutko, a im dłużej spada tym szybciej. Pozdrowienia ;) |
|
DejaVu |
» 2008-04-17 17:23:05 1. Gdy narysuję sobie większą platformę to kolizja nie obejmuje jej całej. 2. Gdy już stoję na platformie, to gdy już za długo na niej jestem i chcę zejść to spadam z ogromną prędkością 3. Gdy jestem pod platformą i chcę na nią wskoczyć, to naciskam SPACJĘ, od razu znajduję się na platformie (teleport ) i na niej robię skok. Na prawdę za wszystko dziękuję.
|
Ad 1. A jak masz zrobione wykrywanie kolizji między ciałem a obiektem? Jako dwa okręgi czy okrąg-odcinek czy prostokąt-prostokąt? Ad 2. Musisz pokazać kod, który realizuje grawitację Ad 3. Napisałeś, że ten problem masz rozwiązany... zgadza się? |
|
« 1 » 2 3 4 |