Skocz do zawartości

Krzywe Beziera - zastosowanie w grach


Rekomendowane odpowiedzi

Krzywe Beziera znajdują zastosowanie w olbrzymiej ilości dziedzin nauki, są podstawową strukturą, na bazie której tworzy się grafikę wektorową, służą do opisu różnorodnych równań. Nie będę o nich pisał, spróbuję natomiast pokazać, w jaki sposób mogą okazać się pomocne w tworzeniu gier komputerowych.

Po podstawową wiedzę nt. krzywych Beziera, odsyłam do Wikipedii: http://pl.wikipedia.org/wiki/Krzywa_Béziera

 

Link: https://gmclan.org/uploader/8433/Krzywe_Beziera.zip

 

W paczce znajdują się trzy pliki projektów i jeden plik ze skryptami. Skrypty, jak i projekty, są opatrzone komentarzami w kodzie.

Opis projektów:

 

-bezier_diagram.gm81: dobrze zacząć od tego pliku, pokazuje budowę krzywej, pozwala zmienić jej kształt, a także ułatwia zrozumienie, dlaczego funkcja przyjmuje argumenty z przedziału od 0 do 1.

 

-bezier_car_acc.gm81: przykład zastosowania krzywej Beziera, aby uzyskać iluzję realistycznego przyspieszania pojazdu. Normalnie przyspieszenie to zależy od wielu czynników, m.in. oporu powietrza, mocy silnika, tarcia. Za pomocą jednej krzywej dostajemy bardzo podobny efekt, mając do dyspozycji jedynie stałą przyspieszenia i wartość maksymalnej prędkości.

screenshot100.png

 

-bezier_random.gm81: przykład zastosowania krzywej Beziera do stworzenia własnego rozkładu prawdopodobieństwa, czyli funkcji prawdopodobieństwa wylosowania wartości z dziedziny (dziedziną tutaj jest przedział <0;1>). Na wielu diagramach widać zależność kształtu krzywej Beziera od otrzymanego rozkładu. Przydaje się np. do zwiększenia szans na strzelenie z broni na krańce rozrzutu zamiast w centrum

screenshot101.png

 

Projekty korzystają z wielomianowych krzywych Beziera trzeciego stopnia, mają pewne limitacje, które można częściowo ominąć stosując więcej punktów kontrolnych (zwiększając stopień wielomianu).

 

Na pewno można znaleźć więcej zastosowań krzywych, choćby symulacje ognia czy korzystanie z krzywych jak z pathów. Polecam eksperymentowanie.

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 miesiąc temu...

vygloda dobrze, ale niemam 8.1 :)

wiec pozvole sobie dodac pare scryptovanych fukcji, ktore uzywam. (przepraszam ,ale nieumiem uzyc spoilera. nic nierobi)

cala krzyva:

GML
//*************************************************** **********************

* Bezier() (funkcja sześciennych krzywej Beziera (n = 3) przez EREG H.)

*

* Opis: dostosowany skrypt Beziera zarządzanie 4 punkty kontrolne.

* Script obliczća pojedyncze punkty krzywych Beziera z określoną dokładnością (argument12)

* Następnie zapisuje indywidualnie początki do ds_grid.

* Ds_grid jest przechowywany w zmiennej globalnej global.DS_GRIDbezier

* W o_bezier DRAW przypadku jest przykładem tego, co kod można użyć danych z ds_grid

* Krzywej Beziera tworzy gładką krzywą. Dla lepszego pomysłu patrz wiki:

* cs.wikipedia.org/wiki/Bézierova_křivka

* lubovo.misto.cz/_MAIL_/curves/bezierr.html

*

* Zastosowanie: ustawienie różnych parametrów ścieżek (spada, rzucanie), wpływ artykułów sił

* (Np. wiatr na spadających liści, strumieniem wody pływające na drewnie)

* Na przykład zmienia swoje motyl menedżerów w oparciu o zmiany w pozycjach 1-4 punktów.

*

* argumenty:

* argument00 = ax x souradnice bodu a

* argument01 = ay y souradnice bodu a

* argument02 = w1 w waga punktu. w = 0 (w linii prostej), w <1 (elipsa), w = 1 (parabola), w> 1 (hiperbola)

* argument03 = bx

* argument04 = by

* argument05 = w2

* argument06 = cx

* argument07 = cy

* argument08 = w3

* argument09 = dx

* argument10 = dy

* argument11 = w4

* argument12 = pocet usecek+1*

*

* priklad:

* bezier(ax, ay, w1, bx, by, w2, cx, cy, w3, dx, dy, w4, krok, nr);

*

* return: ID cislo ds_grid-u ve kterem je ulozena bezier() krivka.

*

* zdroj: [url="http://gmc.yoyogames.com/index.php?showtopic=329984&page=2"]http://gmc.yoyogames.com/index.php?showtop...9984&page=2[/url]

*

*************************************************************************/

var cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, cp4x, cp4y, cp5x, cp5y;

var drawx, drawy, prevx, prevy, dsId, dsIdName, krok, nr;

var t, t13, t3, w1, w2, w3, w4, wt;

ax = argument0;

ay = argument1;

w1 = argument2;

bx = argument3;

by = argument4;

w2 = argument5;

cx = argument6;

cy = argument7;

w3 = argument8;

dx = argument9;

dy = argument10;

w4 = argument11;

krok = argument12;

nr = argument13

 

// nastavi cislo gridu bezierovy krivky

dsIdName = "DS_GRIDbezier"+string(nr);

 

variable_global_set(dsIdName, ds_grid_create(4,krok+1) );

dsId = variable_global_get(dsIdName );

//ds_grid_clear(dsIdName,0);

// ulozi 1. souradnici 1. usecky

prevx = ax;

prevy = ay;

 

// kontrola kvuli deleni 0

if (krok<=0) {krok=0.000001; };

 

// vypocet bezierovy krivky a ulozeni souradnic do ds_GRID

for(iti=0; iti<=krok; iti+=1){

t = iti/krok

t1 = 1 - t;

t13 = t1 * t1 * t1;

t3 = t * t * t;

wt = t13*w1 + t*t1*t1*3*w2 + t*t*t1*3*w3 + t3*w4;

 

if (wt=0){wt=0.000001; }; // kontrola kvuli deleni 0

// vypocet souradnic bodu na krivce

drawx = (ax*t13*w1 + bx*t*t1*t1*3*w2 + cx*t*t*t1*3*w3 + dx*t3*w4)/wt;

drawy = (ay*t13*w1 + by*t*t1*t1*3*w2 + cy*t*t*t1*3*w3 + dy*t3*w4)/wt;

 

ds_grid_add(dsId, 0, iti, prevx);

ds_grid_add(dsId, 1, iti, prevy);

ds_grid_add(dsId, 2, iti, drawx);

ds_grid_add(dsId, 3, iti, drawy);

prevx = drawx;

prevy = drawy;

}

// ulozi posledni usecku do GRID

ds_grid_add(dsId, 0, iti, prevx);

ds_grid_add(dsId, 1, iti, prevy);

ds_grid_add(dsId, 2, iti, dx);

ds_grid_add(dsId, 3, iti, dy);

 

return dsIdName;

jedyny punkt ustavienie:

GML
//************************************************* **********************

* Beziera () (funkcja sześciennych krzywej Beziera (n = 3) przez EREG H.)

*

* Opis: dostosowany skrypt Beziera zarządzanie 4 punkty kontrolne.

* Skrypt oblicza punktów Beziera krzywa z określoną dokładnością (argument12)

* Następnie zwraca x, y na krzywej.

* Krzywej Beziera tworzy gładką krzywą. Dla lepszego pomysłu patrz wiki:

* Cs.wikipedia.org/wiki/Bézierova_křivka

* lubovo.misto.cz/_MAIL_/krzywe/bezierr.html

*

* Zastosowanie: ustawienie różnych parametrów ścieżek (spada, rzucanie), wpływy z artykułów sił

* (Np. wiatr na spadających liści, strumieniem wody pływające na drewnie)

* Na przykład, piłka zmienia swoje menedżerów w oparciu o zmiany w pozycjach 1-4 punktów.

*

* Argumenty:

* Argument00 = ax x współrzędnych punktu i

* Argument01 = y i y współrzędne punktu

* Argument02 w = masa Punkt w1. w = 0 (w linii prostej), w <1 (elipsa), w = 1 (parabola), w> 1 (hiperbola)

* Argument03 = bx

* Argument04 = by

* Argument05 = w2

* Argument06 = cx

* Argument07 = cy

* Argument08 = w3

* Argument09 = dx

* Argument10 = dy

* Argument11 = w4

* Argument12 = Punkt między 0 a 1 = 0% do 100% krzywej orbity

*

* Zwraca: globalnej tablicy, która przechowuje x,y punktu na krzywej.

* Wybór pól odbywa się poprzez BezierGetP(stringName)

* Albo pomoc variable_global_get(nazwa);

*

* Przykłady:

* Beziera (ax, ay, w1, bx, by, w2, cx, cy, w3, dx, dy, w4, krok, punkt);

*

* Źródło: [url="http://gmc.yoyogames.com/index.php?showtopic=329984&page=2"]http://gmc.yoyogames.com/index.php?showtop...9984&page=2[/url]

*

************************************************** ***********************/

 

var cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, cp4x, cp4y, cp5x, cp5y;

var drawx, drawy, prevx, prevy, dsId, dsIdName, krok, nr;

var t, t13, t3, w1, w2, w3, w4, wt;

ax = argument0;

ay = argument1;

w1 = argument2;

bx = argument3;

by = argument4;

w2 = argument5;

cx = argument6;

cy = argument7;

w3 = argument8;

dx = argument9;

dy = argument10;

w4 = argument11;

bod = argument12;

nr = argument13;

 

// nastavi cislo gridu bezierovy krivky

dsIdName = "ARRAYbezier"+string(nr);

 

// kontrola kvuli deleni 0

if (bod<=0) {bod=0.000001; };

 

// vypocet bezierovy krivky a ulozeni souradnic do ds_GRID

t = bod

t1 = 1 - t;

t13 = t1 * t1 * t1;

t3 = t * t * t;

wt = t13*w1 + t*t1*t1*3*w2 + t*t*t1*3*w3 + t3*w4;

 

// kontrola kvuli deleni 0

if (wt=0){wt=0.000001; };

 

// vypocet souradnic bodu na krivce

variable_global_set(dsIdName+"[0]", (ax*t13*w1 + bx*t*t1*t1*3*w2 + cx*t*t*t1*3*w3 + dx*t3*w4)/wt );

variable_global_set(dsIdName+"[1]", (ay*t13*w1 + by*t*t1*t1*3*w2 + cy*t*t*t1*3*w3 + dy*t3*w4)/wt );

 

return dsIdName;

jedyny punkt latve uzyskanie x albo y:
GML
/************************************************* ****************************

* BezierGetP (Punkt Beziera przez Ereg H.)

*

* Opis: wybiera współrzędne punktu P na krzywej Beziera z pola danego argumentu

*

* argumenty: argument0 = jmeno_ds_grid

* argument1 = cislo nebo retezec "x" nebo "y" bodu

* ("x" muze byt nahrazeno 0/false a "y" muze byt nahrazeno 1/true)

*

* Zwraca: wielkość współrzędnych x lub y

*

* Przykłady: object.x = BezierGetP(global.ARRAYbezier1,x)

* object.x = BezierGetP(variable_string,x)

* instance_create( BezierGetP(pok,0), BezierGetP(pok,"y"), o_pokus1 );

* instance_create( BezierGetP(pok,false), BezierGetP(pok,true), o_pokus1 );

*

*****************************************************************************/

dsIdName = argument0;

osa = argument1;

 

if (!variable_global_exists(dsIdName+"[0]") ) {return "BezierGetP: array error"; };

 

if (string(osa)=="x" || string(osa)=="0") {osa=0; }

else if (string(osa)=="y" || string(osa)=="1") {osa=1; }

else {return "BezierGetP: axis error"; };

 

return variable_global_get(dsIdName+"["+string(osa)+"]" );

Odnośnik do komentarza
Udostępnij na innych stronach

Na naszym forum nie ma funkcji "spoiler", możesz najwyżej umieścić tekst w tagach (color="#EFEFEF")(/color) {zamień nawiasy okrągłe na kwadratowe} : )

Te funkcje robią właściwie to samo, co moje, tylko moje są rozbite na kilka mniejszych i chyba dają lepszy przelicznik kontroli nad krzywą do stopnia skomplikowania kodu, jako że są osobne funkcje dla każdej współrzędnej.

 

E: właśnie zauważyłem, że twoje funkcje wykorzystują wagi punktów. Uznałem, że nie są zbytnio potrzebne do typowych zastosowań w grach i zwiększyłyby skomplikowanie kodu, dlatego nie umieściłem ich w moich funkcjach.

Odnośnik do komentarza
Udostępnij na innych stronach

spoiler chcialem tylko spowodu dlugosci scryptow

 

mas racje nic nowego pod sloncem. :)

brakovalo mi dostepu do GM8.1(innym moze tez), dlatego umiescilem je do twego tematu.

 

obliczenia so z neta, ja tylko zrobilem z nich script latvy do vbudovania i uzycia v dovolnym programu :)

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