Skocz do zawartości

I am Lord

Użytkownicy
  • Postów

    4 891
  • Dołączył

  • Ostatnia wizyta

  • Wygrane w rankingu

    53

Treść opublikowana przez I am Lord

  1. Jak jesteśmy w temacie kolizji, ślizgania itd, to niedawno robiłem małą customową fizykę, zarówno dla platformówki jak i top down. Download GMZ: https://drive.google.com/file/d/0B-1vrtiAAh...Wk2clJKWnM/view sprawdźcie czy plik jest widoczny publicznie Żółta piłka na tym filmiku jest graczem, w platformowym widoku może skakać Całość obliczania kolizji i fizyki odbić czy ślizgów zawiera się w tym kodzie: to jest obiekt par_dynamic:End Step /// physic calc phyPX = phyX; phyPY = phyY; // sub-pixel movement subHS += phyHS; subVS += phyVS; var tempHS = round(subHS); var tempVS = round(subVS); subHS -= tempHS; subVS -= tempVS; var vNormalx = 0; var vNormaly = 0; var vCollision = noone; vR = phyCollisionSize+ceil(phyRSPD); preciseCheck = false; // first collision test is fast, it only check if a collision in a circle between origin and move vector can occur. If not then move else do precision checkings if ( collision_circle(x, y, vR, par_collisionGroup, 0, 1 ) ) preciseCheck = true; else { // simple move x += phyHS; y += phyVS; } // slow precise collision test if ( preciseCheck ) { // horizontal movement var vSignHS = sign(tempHS); repeat ( abs(tempHS) ) { var vMiddle = instance_place(x+vSignHS, y, par_collisionGroup); if ( !vMiddle ) { x += vSignHS; } else { vCollision = vMiddle; vNormalx = -vSignHS; vNormaly = 0; // slopes var vUp = place_meeting(x+vSignHS, y-1, par_collisionGroup); var vDown = place_meeting(x+vSignHS, y+1, par_collisionGroup); if ( !vUp && vDown ) { if ( phyFixSlidingEnabled )/* if ( !place_meeting(x, y-1, par_collisionGroup) )*/ y -= 1; vNormaly = -1; } else if ( vUp && !vDown ) { if ( phyFixSlidingEnabled )/* if ( !place_meeting(x, y+1, par_collisionGroup) )*/ y += 1; vNormaly = 1; } } } // vertical movement var vSignVS = sign(tempVS); repeat ( abs(tempVS) ) { var vMiddle = instance_place(x, y+vSignVS, par_collisionGroup); if ( !vMiddle ) { y += vSignVS; } else { vCollision = vMiddle; vNormaly = -vSignVS; // slopes var vLeft = place_meeting(x-1, y+vSignVS, par_collisionGroup); var vRight = place_meeting(x+1, y+vSignVS, par_collisionGroup); if ( !vLeft && vRight ) { if ( phyFixSlidingEnabled ) /*if ( !place_meeting(x-1, y, par_collisionGroup) )*/ x -= 1; vNormalx = -1; } else if ( vLeft && !vRight ) { if ( phyFixSlidingEnabled ) /*if ( !place_meeting(x+1, y, par_collisionGroup) )*/ x += 1; vNormalx = 1; } } } } // apply dampings // air damping phyHS += -phyFixDrag*phyHS*abs(phyHS); phyVS += -phyFixDrag*phyVS*abs(phyVS); // linear damping phyHS += -phyFixDamping*phyHS; phyVS += -phyFixDamping*phyVS; // apply frictions and bounce if collision if ( vCollision != noone ) { // apply friction var vFric = (1-vCollision.phyFixFriction)*(1-phyFixFriction); phyHS *= vFric; phyVS *= vFric; // apply bounce self var vBounce = 2*phyFixBounce*vCollision.phyFixBounce; var vSpdHS = abs(lerp(vCollision.phyRHS+phyHS, vCollision.phyHS+phyRHS, 0.5)); var vSpdVS = abs(lerp(vCollision.phyRVS+phyRVS, vCollision.phyVS+phyVS, 0.5)); phyHS += vSpdHS*vNormalx*vBounce; phyVS += vSpdVS*vNormaly*vBounce; // apply bounce other if ( vCollision.phyStatic == false ) { var fakeKineticTransfer = vBounce*0.1; // this will unstuck instances in situations where they are in crowd vCollision.phyHS -= vSpdHS*vNormalx+fakeKineticTransfer; vCollision.phyVS -= vSpdVS*vNormaly+fakeKineticTransfer; } } // update read only variables phySPD = sqrt(phyHS*phyHS+phyVS*phyVS); phyRHS = lerp(phyX-phyPX, phyHS, 0.5); phyRVS = lerp(phyY-phyPY, phyVS, 0.5); phyRSPD = sqrt(phyRHS*phyRHS+phyRVS*phyRVS); phyX = x; phyY = y;
  2. Jak oddzielisz ruch po osi X od Y, tak by sprawdzanie kolizji w tych osiach były niezależne od siebie to bardzo łatwo jest zrobić ślizganie. dla przykładu, chyba moim najprostszym rozwiązaniem na jakie wpadłem jest to: GML var posX, posY; posX = 0; posY = 0; if ( keyboard_check(ord('A')) ) posX -= 3; if ( keyboard_check(ord('D')) ) posX += 3; if ( keyboard_check(ord('W')) ) posY -= 3; if ( keyboard_check(ord('S')) ) posY += 3; // jak widać sprawdzanie kolizji w osiach jest od siebie całkowicie niezależne if ( !place_meeting(x+posX, y, p_wall) ) x += posX; if ( !place_meeting(x, y+posY, p_wall) ) y += posY;
  3. to się używa tak samo jak rysowania na surface, więc tak
  4. I am Lord

    SQUOX

    Bo na steamie robi się coraz większy hejt na tego typu produkcje
  5. I am Lord

    Gryf Game Jam

    Yhm, może kiedyś zbiorę na to siły ale ciężko z tym będzie :P
  6. I am Lord

    Gryf Game Jam

    Ja się nie wybieram ale ciekawi mnie jedno, jak to jest na takich imprezach z noclegami? Gdzie się śpi? Śpiwór i na podłodze pod stołem w sali pod swoim laptopem? :D
  7. A zamiast tego jakbyś zrobił: GML H = (ID.y-(ID.sprite_height*0.5))-y; // odległość gracza od cienia na platformie minH = 20; maxH = 65; sh_alpha = 1 - ( clamp(H, minH, maxH)-minH ) * ( 1/(maxH-minH) ); Wtedy skok sprawdzania kolizji nie będzie miał wpływu na alphę o ile się nie pomyliłem gdzieś
  8. W takim razie daj jeszcze więcej niż 3. Twoje platformy są grubości 32 pix więc daj powiedzmy skok o połowę czyli 16
  9. I am Lord

    Suspearia

    Trochę mi się przypomina Bushido Blade na PSX :D Tam się umierało od 1 celnego ciosu.
  10. Potrzebna ci taka precyzja? Myślę że skok o 2 pixele albo 3 byłby w twojej grze ok. Teraz wykonujesz maxymalnie 65 operacji sprawdzania kolizji na step i to tylko w jednym obiekcie a będziesz ich miał więcej. możesz spróbować for ( var i = 0; i < 65; i += 3 ) i zobaczyć jak będzie to wyglądało
  11. Musisz ustalić sobie limit tej pętli. Zakładam też że taki cień ma być nie tylko na postaci gracza ale także na przeciwnikach czy innych obiektach tak więc sprawdzanie takiej kolizji z precyzją co do pixela będzie ultra niewydajne. Kilka przeciwników i spadnie mocno fps. Tak brake kończy pętlę a contiune kończy aktualny krok pętli
  12. Tak zrobisz to za pomocą collision line. Collision line zwraca ID naptkanej instacji. Chciałem byś zrobił wykrywanie odległości między nogami postaci a najbliższej pod nim platformy za pomocą wyszukiwania binarnego ale jeżeli to jest za trudne to ławiejszym sposobem dla ciebie będzie wypuszczenie collision_line w pętli for i zatrzymanie wykonywania tej pętli kiedy linia się z czymś zetknie. Wtedy sobie policzysz ile kroków pętla przeszła i będziesz wiedzieć jaką odległość collision_line pokonał. Na pozycji tej odległości narysujesz cień. Edit: Tzn coś takiego: GML maxymalnaDlugoscLini = 200; dlugoscSkoku = 5; wysokoscCienia = 0; for ( var i = 0; i < maxymalnaDlugoscLini; i += dlugoscSkoku ) { var ID = collision_line(x, y, x, y+i, oSolid, 0, 1); if ( ID != noone ) { wysokoscCienia = i; break; } }
  13. To jest zwykłe działanie matematyczne: współrzędna y dla punktu A minus współrzędna y dla punktu B. Jest jeszcze point_distance() i tego radzę używać zamiast distance_to_object. Różni się to tym że point_distance mierzy faktyczną odległość między punktem A a punktem B a distance_to_object mierzy odległość między krawędziami bounding boxa obiektu z krawędzią drugiego obiektu point_distance() to nic innego jak działanie sqrt( sqr(A.x-B.x)+sqr(A.y-B.y) ) Edit: A co do tematu, to co chcesz osiągnąć zrobisz najoptymalniej dzieki temu: https://gmclan.org/index.php?czytajart=74
  14. O ile wiem te eventy kolizji działają przy tej fizyce i mnie teraz zaskoczyłeś tym bardziej że with(oEgg.id) zadziałało a to jest to samo co other
  15. Zastanawia mnie czemu with (other) nie podziałało, bo powinno
  16. te funkcje z impuls w nazwie ignorują masę ciała przy nadawaniu siły dlatego wybija w kosmos. Użyj apply force ale nie local bo jajko się obraca a ty chcesz nadać siłę globalnie w górę.
  17. Bo tydzień i jest skończona a hajsy lecooo
  18. Tak mi też się fajnie grało. Może to doszlifuj lekko? Lepiej zbalansować, dodać jakiś edytor mapek czy coś.
  19. Czy pojawiające się itemki (gracz nie wie co się pojawi) z powietrza po wejściu postaci w określony obszar się do tego zalicza? Mam mało czasu na robienie gierki ale może coś zdołam wydłubać.
  20. To GML if newX>x { j-=1 } if newX<x { j+=1 } zamień na: GML j += sign(x-newX); działanie takie samo tylko wydajniej.
  21. I tak wygrywasz teraz musisz z tym żyć :D
×
×
  • Dodaj nową pozycję...