Skocz do zawartości

Załamanie światła


Rekomendowane odpowiedzi

Miejmy nadzieję, że tym razem sprawa okaże się mniej problematyczna.

 

Znów mowa o tym silniku, tym razem chodzi o promień latarki, który w podstawowej wersji, potrafi się powiększać i kurczyć, względem położenia kursora.

 

Mój konkretny problem dotyczy tego, iż ów promień przechodzi na wylot przez ściany, a jak wiadomo, wygląda to "tak średnio bym powiedział, tak średnio"

Przejdźmy do meritum:

W jaki sposób można wyskalować sprite światła, aby zmniejszał się, jeśli postać zbliża się do ściany i żeby całkowicie zaniknął, kiedy stoję centralnie pod nią? W prostych słowach, jak sprawić aby ten promień nie przebijał "solidnych" obiektów ?

Odnośnik do komentarza
Udostępnij na innych stronach

Dobra, może z innej strony, bez przykładu. Po prostu podpowiedzcie mi jakim kodem można zmienić skalę sprita, jeśli powiedzmy ociera się o ścianę i analogicznie przy zmniejszeniu dystansu zmniejsza się promień.

@Ujzel - domyślam się że jest to przestarzałe, ale ja zajmuję się grami raczej hobbystycznie, co więcej kilka ładnych lat nie otwierałem GMa, więc nie jestem na bieżąco.

Odnośnik do komentarza
Udostępnij na innych stronach

1/szerokość sprite'a to wielkość image_xscale dla 1px szerokości. Znając ilość pikseli do celu mnoższysz odległość przez tę wartość (1/szerokość) i masz. Innymi słowy image_xscale = Odleglosc/szerokosc.

Odnośnik do komentarza
Udostępnij na innych stronach

Co Ci potrzeba, mogę podać wszelkie kody.

Kod kontrolera światła:

 

CREATE:

GML
global.sfShadow = surface_create(view_wview[1], view_hview[1]);

 

STEP:

GML
surface_set_target(global.sfShadow);

{

draw_clear_alpha($dddddd, 1);

draw_set_blend_mode(bm_subtract);

{

with(swiatlo_parent)

{

draw_sprite_ext(spr, 0, x-view_xview[1], y-view_yview[1], sclX, sclY, dir, make_color_rgb(alpha*255, alpha*255, alpha*255), 1);

}

}

draw_set_blend_mode(bm_normal);

 

draw_set_blend_mode(bm_add);

{

with(swiatlo_parent)

{

if(cAlpha > 0)

{

draw_sprite_ext(spr, 0, x-view_xview[1], y-view_yview[1], sclX, sclY, dir, $ffffff-color, cAlpha);

}

}

}

draw_set_blend_mode(bm_normal);

}

surface_reset_target();

 

ROOM END:

 

GML
surface_free(global.sfShadow);

 

DRAW:

 

GML
draw_set_blend_mode(bm_subtract);

{

draw_surface(global.sfShadow, view_xview[1], view_yview[1]);

}

draw_set_blend_mode(bm_normal);

 

Obiekt "Światło Latarki"

 

CREATE

 

GML
//Inicjuje odpowiednie zmiene (jesli jeszcze nie istnieja

if(!variable_local_exists("spr")) //Sprite swiatla - domyslnie sLight

{ spr = s_latarka; }

if(!variable_local_exists("sclX")) //Shala poziomo - domyslnie 3

{ sclX = 6; }

if(!variable_local_exists("sclY")) //Pionowo - d. 3

{ sclY = 3; }

if(!variable_local_exists("dir")) //Kat spritu swiatla - d. 0

{ dir = 0; }

if(!variable_local_exists("alpha")) //Moc, sila swiatla (od 0 do 1) - domyslnie 1

{ alpha = 1; }

if(!variable_local_exists("color")) //Dodatkowo: kolor swiatla

{ color = c_white; }

if(!variable_local_exists("cAlpha")) //i intensywosc tego koloru

{ cAlpha = 0; }

 

 

I wreszcie sama LATARKA:

GML
[/gml]

CREATE[/b]

 

[gml]//Przyklad latarki na takim czyms.

ins = instance_create(x, y, o_swiatlo_latara); //Tworzymy obiekt swiatla, jego id pobieramy do zmiennej ins, aby moc go kontrolowac

ins.spr = s_latarka; //Ustawiamy jego sprite na sLaareczka

ins.color = c_white; //Kolor na lekkoniebieski

ins.cAlpha = 1; //Intensywnosc koloru na 1 (max)

ins.dir = o_gracz.direction //Aktualizujemy kat

STEP:

 

GML
ins.dir = o_gracz.direction //Aktualizujemy kat
Odnośnik do komentarza
Udostępnij na innych stronach

Z tym, że to co widzisz czarne na tym screenie nie musi być czarne, może być półprzeźroczyste, granatowe, różowe, wystarczy tylko ustawić kolor i przeźroczystość.

 

Edit: Obczailem ten Twoj przyklad i jest bardzo ograniczony wiec nie moge duzo zrobic, ale to powinno pomoc:

 

W step oLatareczka:

GML
ins.dir = point_direction(x, y, mouse_x, mouse_y); //Aktualizujemy kat

var col;

col = collision_line(x,y,mouse_x,mouse_y,oSciana,false,true);

if (col==noone) then ins.sclX = point_distance(x, y, mouse_x, mouse_y)/50; //I skale pozioma (dlugosc latarki)

else ins.sclX = point_distance(x,y,col.x,col.y)/50;

 

To zakłada że nazwiesz ścianę oSciana.

Odnośnik do komentarza
Udostępnij na innych stronach

Okej, tylko temat jest taki, że ja w stepie latareczki mam stałą skalę, bez wydłużania/ skracania poprzez mychę, mam w stepie po prostu:

 

GML
ins.dir = o_gracz.direction //Aktualizujemy kat</span>

 

Teraz pod to można zrobić to łamanie, bo z Twoim kodem nic się zbytnio nie zmienia.

@Edit - kody wszystkie których ja używam są wyżej :)

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ę...