Ruskiekomando Opublikowano 20 Lipca 2021 Udostępnij Opublikowano 20 Lipca 2021 Czołem, dzień dobry! Zwracam się z prośbą o pomoc w 'ugryzieniu' tematu. Sytuacja wygląda następująco: W głównym Roomie' mam wyrysowany path po którym poruszają się 2 typy wrogów (oEnemy, oEnemySecondary). Dla uproszczenia możemy pominąć kwestię rozpoznawania który jest który. Ponadto, na ścieżce mam do wyboru ( ilość postawionych uzależniona od ilości monet) dwa rodzaje wież (oTower,oTower2) które 'strzelają' dwoma różnymi typami pocisków (oBullet, oBulletSecondary). Każda z instancji Enemies po utraceniu swoich 'punktów życia', 'znika' ( instance_destroy() ). Mechanizm wykrywania i strzelania do przeciwników rozwiązałem tak: Cytat oTower1 create: maxRange = 130; minRange = 60; fire_rate = room_speed / 2; shooting = false; objectToShoot = noone alarm[0]:if(instance_exists(objectToShoot)){ var bullet = instance_create_depth(x,y, -9, oBullet); bullet.speed = 2; bullet.direction = point_direction(x,y, objectToShoot.x, objectToShoot.y); alarm[0] = fire_rate; } else { shooting = false; } Draw: draw_self(); if(mouseOver(x,y,sprite_width, sprite_height)) { draw_circle(x,y, minRange, true); draw_circle(x,y, maxRange, true); }; var oEnemyEn = instance_nearest(x + minRange,y + minRange,oEnemy); var oEnemySecEn = instance_nearest(x + minRange,y + minRange,oEnemySecondary); if (oEnemyEn) { var distanceToOEnemy = point_distance(x, y, oEnemyEn.x, oEnemyEn.y); } if(oEnemySecEn){ var distanceToOEnemySecondary = point_distance(x, y, oEnemySecEn.x, oEnemySecEn.y); } if (oEnemyEn && !oEnemySecEn) { var en = instance_nearest(x + minRange,y + minRange,oEnemy); } else if (oEnemyEn && oEnemySecEn) { if (distanceToOEnemy > distanceToOEnemySecondary) { var en = instance_nearest(x + minRange,y + minRange,oEnemySecondary); } else if ( distanceToOEnemy <= distanceToOEnemySecondary) { var en = instance_nearest(x + minRange,y + minRange,oEnemy); } } else if (!oEnemyEn && oEnemySecEn) { var en = instance_nearest(x + minRange,y + minRange,oEnemySecondary); } else if (!oEnemyEn && !oEnemySecEn) { var en = instance_nearest(x + minRange,y + minRange,oEnemy); } if(en != noone) { if((point_distance(x, y, en.x, en.y) <= maxRange + 4) && (point_distance(x, y, en.x, en.y) >= minRange + 4)) { if(shooting == false) { alarm[0] = 1; shooting = true } objectToShoot = en; if(mouseOver(x,y,sprite_width, sprite_height)) { draw_circle(x,y, minRange, true); draw_circle(x,y, maxRange, true); }; }else { shooting = false; objectToShoot = noone; } } Jak wyraźnie widać na załączonym wyżej przykładzie, kwestia namierzania i strzelania opiera się głównie na metodzie instance_nearest() oraz point_distance(). Same zaś enemies poruszają się po path: Cytat path_start(Path1, oGlobalVariables.spd ,0,1); hp = oGlobalVariables.hp; I tu pojawia się moje pytanie. Czy jest jakiś sposób aby 'kula' (oBullet) po wystrzale zamiast lecieć 'prosto do celu', leciała do góry po parabolli. Tak jak jest np. prowadzony 'ogień' z haubicy. Pozdrawiam. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
SimianVirus7 Opublikowano 20 Lipca 2021 Udostępnij Opublikowano 20 Lipca 2021 No witam! Jeśli chodzi Ci mniej więcej o taki efekt: To miałem to samo pytanie w 2018r. Zrobiłem to za pomocą Konrada-GM i mój kod wyglądał mniej więcej tak: CREATE pocisku: ///Caly kod inicjializacji strzelania // wirtualna pozycja do wyliczenia "wygiecia" ghost_x = x //to jest tak naprawde xstart ghost_y = y //to jest tak naprawde ystart ale później będzie manipulacja tych dwóch zmiennych // strona lotu czaru // 1 - prawa strona // -1 - lewa strona var _pd = point_direction(x, y, oPlayer.x, oPlayer.y); if(_pd > 90 and _pd < 270) wing = -1 else wing = 1 //prawo lub lewo // poczatkowy dystans do celu start_distance = point_distance(xstart, ystart, oPlayer.x, oPlayer.y); //wybierz czy pocisk ma leciec gora czy dolem way = choose(true, false); STEP pocisku: // liczymy aktualna odleglosc var distance = point_distance(ghost_x, ghost_y, oPlayer.x, oPlayer.y); var angle = point_direction(ghost_x, ghost_y, oPlayer.x, oPlayer.y); var angle90 = angle + 90 * wing; //90 - sila zagiecia // glowna funkcja przesuniecia var factor = sin((distance / start_distance) * pi); var maxlen = sqr(log2(start_distance)); var offx = lengthdir_x(maxlen * factor, angle90); var offy = lengthdir_y(maxlen * factor, angle90); // poruszamy obiektem w kierunku celu var spd = irandom(7)+2; ghost_x += lengthdir_x(spd, angle); ghost_y += lengthdir_y(spd, angle); // Zaginamy if(way) //w=true leci gora { x = ghost_x + offx; y = ghost_y + offy; } else //w=false leci dolem { x = ghost_x - offx; y = ghost_y - offy; } Jeżeli chcesz obszernego wytłumaczenia, to poczytaj odpowiedź od @Konrad-GM, bo nieźle mi to wtedy wytłumaczył. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Ruskiekomando Opublikowano 20 Lipca 2021 Autor Udostępnij Opublikowano 20 Lipca 2021 Hej @SimianVirus7. Po pierwsze dziękuję, za szybką odpowiedź. Naturalnie, post z 2018 widziałem, zamierzam cały wątek prześledzić dokładniej i wyciągnąć wnioski. Zasadniczo to w sumie o efekt lotu parabolicznego mi chodziło, z tym jednak zastrzeżeniem, że oEnemy porusza się ze stałą prędkością po path'ie. Boję się więc, że 'kula' będzie śledziła non stop wrogi obiekt i w konsekwencji tor lotu pocisku przypominać będzie odwróconą literę 'U', ale z jedną dużo dłuższą połową Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
SimianVirus7 Opublikowano 20 Lipca 2021 Udostępnij Opublikowano 20 Lipca 2021 Cóż, chyba już wiem o co Ci chodzi. Ja zrobiłem to samo w swojej grze, czyli, że pocisk ma lecieć w miejsce w którym gracz był, kiedy był wystrzelony czar. Dla osiągnięcia takiego efektu, stworzyłem osobny obiekt "oTarget". Pojawiał się on podczas strzału w miejscu gracza i do niego odwoływał się pocisk przy obliczaniu x,y (w górnym przykładzie, wylicza on dystans odwołując się do oPlayer.x/oPlayer.y); Mniej więcej tak wyglądałby pseudokod: if(strzal == true) { var _target = instance_create(oPlayer.x, oPlayer.y, oTarget) //wpisuje go do zmiennej, żeby nim manipulować var _pocisk = instance_create(x, y, oPocisk); _pocisk.target_x = _target.x; //przypisz dla pocisku współrzędną x celu _pocisk.target_y = _target.y; //przypisz dla pocisku współrzędną y celu } i wtedy każde wyliczenia odwołują się do target_x/target_y a nie do oPlayer.x/oPlayer.y U siebie dodałem jeszcze, że jak pocisk ma kolizje z oTarget (tym przypisanym), to traci prędkość i znika po czasie. Efekt wyszedł taki: (Obiekt oTarget nie ma sprite, dlatego go nie widać) Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Threef Opublikowano 21 Lipca 2021 Udostępnij Opublikowano 21 Lipca 2021 Rozwiązanie jakie ja używam u siebie w jednym projekcie to stworzenie zaokrąglanego nie zamkniętego path dla pocisku. Punkt początkowy i końcowy mamy. Wystarczy dodać pomiędzy nimi jeszcze jeden punkt w x = mean( x1, x2 ) i y = mean( y1, y2 )-50 Pocisk będzie podążał po path całkiem ładnym łukiem Uzjel 1 Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się