Skocz do zawartości

Rekomendowane odpowiedzi

Przedstawiem państwu zrobiony przykład "jak zrobić laser"

[guzik]

Wygląd lasera zmienia się rolką myszy(przewijakiem)

 

W obiektach wszystko jest zrobione z klocków :( oprusz skrptu lasera :)

skrypty lasera są w evencie Draw

Można go używać do woli jako:

-celownik laserowy

-laser jako broń

-bardzo szybkie,niewidoczne strzały.

 

Oddaje wam go ocenie :)

Tylko za mocno nie krytykujcie bo to przykład :)

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności

A czy to nie jest przyklad zrobiony na podstawie jakiegos zagranicznego? Bo nie ma opisow oraz pomieszanie uzycia polskiego i angielskiego slownictwa oraz skrypt z warunkami jest pomieszany z klockami z warunkami? Mów jak na spowiedzi. :)

 

 

I laser sie robi troszke inaczej, dam zaraz przyklad i najwyzej zamieszcze oba zeby bylo do wyboru.

Odnośnik do komentarza
Udostępnij na innych stronach

No.

Będe mówił jak na spowiedzi.

Lasera całkowicie Ja nie zrobiłem tylko to jestest zmieniony skrypt szybkiego strzelania w 3D :(

 

ARGGGHHH!!..

 

Wydało się!! ! :P

 

 

EDIT:

Ale Cały skrypt rozumiem a nie że tylko go skopiowałem i niewiem nawet jak on działa

 

EDIT:

A po drugie tam jest połowa z klocków a połowa skryptu dlatego bo mi się niechciało wszystkiego grupować i pisać.

A tak tylko wsadzałem bloczki i kopiowałem jeden skrypt modyfikując go :P

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności

Tak wygląda funkcja dokładnego wyznaczania odcinka między dwoma punktami gdzie nie ma obiektów:

var x2,y2, ob, dyst;

dyst = maksdyst;
x2 = 0;
y2 = 0;

while ( true )
{
    x2 = x + sin(degtorad( direction + 90 ))*dyst;
    y2 = y + cos(degtorad( direction + 90 ))*dyst;
    ob = collision_line(round(x),round(y),round(x2),round(y2),all,1,1);

    if ( ob )
    {
        dyst = point_distance(x,y,ob.x,ob.y) - ceil(sqrt(sqr(ob.sprite_width)+sqr(ob.sprite_height )));
        while ( true )
        {
            x2 = x + sin(degtorad( direction + 90 ))*dyst;
            y2 = y + cos(degtorad( direction + 90 ))*dyst;
            ob = collision_line(round(x),round(y),round(x2),round(y2),all,1,1);

            if ( ob )
            {
                dyst -= 1;
                break;
            }
            else dyst += 1;
        }
    }
    else break;
}
//mamy juz x2 i y2

Ten algorytm różni się od tego co podał cekol tym, że nie jest sprawdzana kolizja co jeden piksel zaczynając od obiektu, lecz szukamy kolizji z linią o początku x,y i maksymalnym dystansie maksdyst. Jezeli jest jakis obiekt, to dystans jest skracany o wartosc gwarantujaca brak kolizji z tymze obiektem (za taka bezpieczna odleglosc przyjąłem odleglosc miedzy A(x,y) a B(x,y) obiektu kolidujacego pomniejszoną o długość przekatnej jego sprita). Nastepnie jezeli pomiedzy punktami A i B nie ma innych obiektow, to dodajemy do dystansu po jednym pikselku tak, aby uzyskac dokladna odleglosc promienia do styku obiektem. Dzieki temu sposobowi mozna znacznie przyspieszyc dzialanie skryptu lasera w pewnych momentach.

 

 

Przy okazji odkrylem niestety blad GM'a. Otóż jeżeli mam pionową ścianę zbudowaną z kolejnych klocków, to jeżeli skierujemy promień lasera dokładnie w poziom i pomiędzy klockami ściany, to jeśli obiekt "wystrzeliwujący" promień lasera ma np. pozycję y zapisaną jako ułamek, np. 300.5, to laser może przejść przez obiekty. Dlatego też najlepiej w begin step dać x=round(x); i y=round(y);

Odnośnik do komentarza
Udostępnij na innych stronach

"mój" sktypt jest prostrszy :D

    
    laser_example_cel=0

    laser_example_odleglosc=10

for (d=0;d<2048;d+=1;)
{   


    laser_example_x1=   x+cos(degtorad(direction+laser_example_cel))   *laser_example_odleglosc;
    laser_example_y1=   y-sin(degtorad(direction+laser_example_cel))   *laser_example_odleglosc;
    laser_example_bx=   laser_example_x1+cos(degtorad(direction+laser_example_cel))   *(d);    
    laser_example_by=   laser_example_y1-sin(degtorad(direction+laser_example_cel))   *(d);
    
     

      
    
     if instance_position(laser_example_bx,laser_example_by,all) then
    {

    draw_set_color(c_red)
    draw_set_alpha(random(0.3))
    draw_line(laser_example_x1,laser_example_y1,laser_example_bx,laser_example_by)
    draw_set_alpha(1)
    draw_ellipse(laser_example_bx-2,laser_example_by-2,laser_example_bx+2,laser_example_by+2,-1)
    draw_set_alpha(1)   
    exit
    }  
    
    
            
}

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności

No i co z tego, że prostszy. Gracza nie będzie obchodziło jakie skrypty użyłeś, tylko czemu gra mu tak wolno chodzi. :)

 

Proste rysowanie linii w twoim przykładzie pomiędzy ścianą a startową pozycją na moim komputerze daje wynik 140fps, a mój algorytm 900fps. :]

 

 

edit: Obadałem dokładnie błąd GM'a i jednak to nie kwestia ułamkowych wartości x i y lecz niezbyt precyzyjnego działania funkcji collision_line, dlatego lepiej by np. części ściany nachodziły lekko na siebie, np. 1 piksel albo żeby miały większą maskę kolizji.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności

Tymon: Oj rzeczywiście nie pomyślałem o tym aby zaokrąglić także pozycję drugiego końca odcinka, dzięki. :) Ale tak czy siak warto by było to Markowi Overmarsowi zakomunikować.

 

edit: Jednak zaokrąglanie w funkcji collision_line to niezbyt wydajny pomysł. Wywaliłem także ceil - zaokrąglanie w górę przy wyliczaniu przekątnej sprita. W sumie niepotrzebne. Tym razem już zoptymalizowany skrypcik:

var x1,y1,x2,y2,ob,dyst;

dyst = maksdyst;
x1 = round(x);
y1 = round(y);
x2 = 0;
y2 = 0;

while ( true )
{
    x2 = round(x1 + sin(degtorad( direction + 90 ))*dyst);
    y2 = round(y1 + cos(degtorad( direction + 90 ))*dyst);
    ob = collision_line(x1,y1,x2,y2,all,1,1);

    if ( ob )
    {
        dyst = point_distance(x1,y1,ob.x,ob.y) - sqrt(sqr(ob.sprite_width)+sqr(ob.sprite_height));
        while ( true )
        {
            x2 = round(x1 + sin(degtorad( direction + 90 ))*dyst);
            y2 = round(y1 + cos(degtorad( direction + 90 ))*dyst);
            ob = collision_line(x1,y1,x2,y2,all,1,1);
            if ( ob )
            {
                dyst -= 1;
                break;
            }
            else dyst += 1;
        }
    }
    else break;
}

 

 

Cekol: Dopisz w przykładzie skąd zaczerpnąłeś część przykładu, to wrzucę na gmclan. :)

Odnośnik do komentarza
Udostępnij na innych stronach

No dobra

 

Poprawiłem przykład.

Dopisałem w Game info że częsc przykladu zaczerpnąłem ze strony TGG Examples :(

No to jak chcecie to dajcie To do downloadu Gmclanu :)

 

Zrobiłem jeszcze raz link aby się nie męczyć z jazdą na szczyt strony :) : https://gmclan.org/up808_4_laser.html

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności

Postanowiłem jednak nie zamieszczać przykładu, bo by mnie sumienie gryzło. Jeśli chcesz bym to dodał, to musisz uzyskać pozwolenie autora pierwotnego przykładu i dodać do informacji nie tylko "tgg examples", ale info o pierwotnym autorze i link do jego strony. Po prostu nie chcę na gmclan umieszczać przeróbek czy rozbudowanych przykładów z innych stron. Bądźmy profesjonalni.

Odnośnik do komentarza
Udostępnij na innych stronach

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ę
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...