Skocz do zawartości

Cykl dnia i nocy


Rekomendowane odpowiedzi

Cykl dnia i nocy

Poziom: Średni ;P

Cel: Uzyskanie płynnego systemu dnia i nocy, oraz zegara elektronicznego : P

Przykład: POBIERZ

 

1. Rozplanowanie zadań.

Cóż, najpierw trzeba wymyślić, jak to wszystko miałoby działać. W hud'dzie powinniśmy widzieć zegar (np. "7:27", "23:11"...). Jedna minuta w grze niech będzie równa jednej sekundzie naprawdę. Kiedy minuty osiągną 60 godzina powinna się podnieść o jeden, a minuty spaść do zera.

 

Teraz właściwa treść tutoriala, czyli cykl dnia i nocy. Będziemy malować prostokąt o rozmiarach view'a, nad wszystkimi (ew. pod hudem, kursorem itp.) objektami, o odpowiednim image_alpha.

A owa przeźroczystość będzie obliczana na podstawie aktualnej godziny.

 

Więc, zaczynajmy :)

 

2. Zmienne zegara

Zaczniemy oczywiście od zegara. Minuty i godziny będą przecgowywane w zmiennych global.time_minutes oraz global.time_hours. Przedstawię przy okazji moją metodę inicjacji wszystkich potrzebnych zmiennych.

 

Funkcja init()

GML
if(!variable_global_exists("global.inited")) //Jesli nie istnieje zmienne global.inited (czyli jesli inicjacja wykonuje się pierwszy raz)

{

global.time_hours = 15; //Godzina

global.time_minutes = 30; //Minuta

global.inited = true; //Deklaruję zmienną global.inited. To nie ważne, jaką wartosć jej przypisze. Ważne, że już istnieje...

}

Ten prosty bajer daje nam pewność, ze inicjacja wykona się tylko raz. W przypadku, kiedy np. przechodzimy z rooma do rooma, a jakiś objekt miałby kod inicjacji, to zmienne zadeklarowały by się od początku, czyli po części restart gry. Można się przed tym łatwo zabezpieczyć, inicjując grę w pierwszym roomie. Ale zawsze warto się zabezpieczyć, niż potem szukać, co jest problemem... No i wygodniej dodać zmienne do funkcji, niż szukać objektu, w którym to ukryliśmy :)

 

Także "już" zainicjowaliśmy zmienne potrzebne do zegara.

 

3. Malowanie ciemności...

Najpierw stwórzmy kod na malowanie "ciemności"...

 

Stwórz objekt powiedzmy obj_zegar. Ustaw mu depth niższy niż wszystkie objekty w grze (drzewa, krzaki, bohater, ściany itp.), ale najlepiej mniejszy od depthu hud'a. Np. u mnie to jest -10000.

 

obj_zegar - Create:

GML
clouds_alpha = 0; //Przeźroczystość chmur. 0 = niewidoczne chmury; 1 = nic nie widać

timer = 0; //Można to było zrobić na alarmach, ale czasami lepsze są takie rozwiazania. Jak dla mnie kod jest przez to czytelniejszy, a zaraz się przekonacie, o co chodzi...

 

obj_zegar - Draw:

GML
x = view_xview[view_current]; //Ustawiamy x zegara na górny lewy róg ekranu.

y = view_yview[view_current]; //Podobnie y...

draw_set_color(c_black); //Ustawiamy kolor na czarny. Ewentualnie bardziej klikatyczny o niektórych gier może być kolor szary, lub jakiś sprite z lekkim szumem

draw_set_alpha(clouds_alpha * 0.9); //0.9 = maksymalny alpha chmur.

draw_rectangle(x, y, x+640, y+480, 0); //Malujemy prostokąt. 640 i 480 to rozmiary naszego viewa.

draw_set_alpha(1); //Teraz namalujemy godzinę.

draw_set_color(c_white); //Ustawiam kolor na biały...

draw_text(x+5, y+5, string(gen_time())); //I maluje tekst... ale zaraz zaraz. Co to za funckja gen_time()...? Dowiecie się w swoim czasie;)

 

4. Ruch zegara

Co nam po malowaniu, jak jeszcze nawet zegar nie działa :P ?

Przejdźmy od razu do konkretów, wyjaśniać będę w komentarzach. Powiem tylko, że to nie jest tak skomplikowane, jak się wydaje :) (Szkoda, że nie działa tag GML :/)

 

obj_zegar - Step:

GML
if(timer >= 30) //Jeśli zmienna timer (która co klatkę zwiększa się o 1) Osiąga wartość 30 (30 = ilość klatek, po których czas w grze zwiększa się o 1 minutę. Zamiast 30 dajcie ilość klatek z waszej gry. Ewentualnie mniej, jeśli zegar ma lecieć szybciej, lub więcej, jeśli zegar ma lecieć wolniej.)

{

timer = 0; //Zerujemy nasz timer. Teraz będzie potrzebował kolejnych 30 klatek, aby w grze była minuta...

if(global.time_minutes < 59) //Jeśli minuty jeszcze NIE są na tyle duże, aby czas w grze zwiększył się o godzinę...

{

global.time_minutes += 1; //Dodajemy minutę do czasu w grze.

}

else //Ale jeśli minut JEST już na tyle dużo, aby Czas w grze zwięlszył się o godzinę...

{

if(global.time_hours < 23) //Jeśli godzin NIE jest tak dużo, aby minęła cała doba...

{

global.time_hours += 1; //Dodajemy godzinę do czasu w grze...

global.time_minutes = 0; //UStawiamy minuty na 0...

}

else //Ale jeśli godzin JEST tak dużo, aby minął cały dzień...

{

global.time_hours = 0; //Ustawiamy godzinę na 0:00

global.time_minutes = 0;

 

//Tutaj ewentualnie jakiś kod podliczający dni, np. global.time_days += 1;)

}

}

 

}

else //Ale jeśli jeszcze nasza zmienna timer NIE jest aż tak duża, aby minuta w grze podskoczyła...

{

timer += 1; //To dodajemy do niej 1.

}

Po krótszej analizie powinieneś zrozumieć działanie tego kodu. Jak już mówiłem, można to było zrobić na alarmach. No ale ten kod staje się jakd la mei czytelniejszy, bo mam wszystko w jednym evencie, w jednej "kupie" tekstu. A nie kawałki kodów porozwalane po eventach.

 

Swoja drogą zwykły, z pozoru błachy zegarek, a trochę roboty z nim jest...

 

5. A gdyby...?

Zapewne nikt na to nie wpadł, ale ten kod ma wadę. Jeśli w grze będzie powiedzmy siedem po ósmej, to skrypt pokaże to tak: "8:7", a to nam nie pasuje. Powinien pokazać "8:07"

 

Do tego celu stworzymy sobie funkcję gen_time(), któa będzie zwracała nam czas, ale w dobrej formie.

 

gen_time()

GML
// gen_time();

// Funkcja zwracajaca czas w dobrej formie, np. 7:05

//(Ja zawsze tak sobie oznaczam funckje, aby wiedzieć, jak która działa;) )

hours = global.time_hours; //Ustawiam zmienną z godzinami, która posłuży do "obliczeń".

minutes = global.time_minutes; //Podobnei z minutami.

if(string_length(string(minutes)) < 2) //Jeśli minuty składają się z mneij niż 2 znaków (czyli np. 7:0, 7:1, ... 7:8, 7:9)

{

minutes = string_insert("0", string(minutes), 0); //Dorzucam zero na pierwszą pozycję minut. Teraz będzie 7:00, 7:01 itd.

}

 

return string(hours) + ":" + string(minutes); //Funckja musi coś zwracać. także zwracam tekst w cąłkiem poprawnej formie, czyli podzielonej znakiem ":".

I tyle.

 

A teraz najważniejsza część artykułu :D

 

6. Obliczenia chmur

Powiem szczerze, że nie wiem, jak Wam to wyjaśnić. Sam tego typu kody piszę jakoś instynktownie, niemal nigdy się nie mylę :P Także nad tym kodem będziecie musieli sami pomyśleć.

 

Pierwszym etapem jest stworzenie funkcji, która da nam możliwość łatwiejszego porównywania czasu, a mianowicie funkcję, która zwracałaby nam liczbę minut podanej godziny. Czyli np.:

gen_test_time(0, 12) = 12; //"0, 12" należy rozumieć jako "0:12" ;)

gen_test_time(0, 55) = 55;

gen_test_time(1, 15) = 75;

gen_test_time(2, 00) = 120;

gen_test_time(3, 30) = 210;

 

Mam nadzieję, że rozumiecie, o co chodzi. Teraz czas na ową funkcję...

 

gen_test_time()

GML
// gen_test_time(hours, minutes)

// Zwraca liczbę minut w podanej godzinie.

return (argument0 * 60) + argument1; //Jak widzicie dość rposta funkcja;)

 

I to już ostatna część artykułu. Teraz już musicie sami pomyśleć ;)

 

obj_zegar - Step:

GML
test_time = gen_test_time(global.time_hours, global.time_minutes);

 

if(test_time < gen_test_time(4, 0)) //od 0:00 do 4:00...

{

clouds_alpha = 1; //...chmury są duże...

}

else if(test_time < gen_test_time(8, 0)) //od 4:00 do 8:00...

{

clouds_alpha = ((gen_test_time(8, 0) - test_time)/(gen_test_time(8, 0) - gen_test_time(4, 0))); //...stopniowo robi się coraz jaśniej....

}

else if(test_time < gen_test_time(22, 0)) //od 8:00 do 22:00...

{

clouds_alpha = 0; //Jest całkiem jasno...

}

else if(test_time < gen_test_time(24, 0)) //od 22:00 do 24:00...

{

clouds_alpha = 1-((gen_test_time(24, 0) - test_time)/(gen_test_time(24, 0) - gen_test_time(22, 0))); //...stopniowo się zciemnia...

}

 

I to wszystko : D

 

7. Próba wyjaśnienia

Nie no, wypadało by chociaż spróbować wyjaśnić ostatnią część kodu :P No więc próbuję...

Mamy takie coś:

 

((gen_test_time(8, 0) - test_time)/(gen_test_time(8, 0) - gen_test_time(4, 0))); //Oryginalna część

(gen_test_time(8, 0) - test_time) / (gen_test_time(8, 0) - gen_test_time(4, 0)); //Usuwam nawiasy, robię spacje, łatwiej będzie zrozumieć ; )

//Jak widzicie to obliczenie skłąda się z dwóch części. COŚ zostaje podzielone przez COŚ2, i wychodzi... odpowiedni alpha chmur :P Objaśniam, co który COŚ oznacza...

(ile minut brakuje do 8:00 (za ile minut wybije 8:00)) / (liczba minut, które miną od 4:00 do 8:00); //Czyli na przykład:

 

(239) / (240); //Godzina 4:01 - jak każdy widzi wynik będzie wysoki - wiec alpha też,a co za tym idzie chmury duże...

(120) / (240); //Godzina 6:00 - Wynik to 0.5.

(60) / (240); //Godzina 7:00 (już prawie jasno) - wynik to 0.25 - więc już prawie wszystko widać ; )

(1) / (240); //Godzina 7:59 (prawie całkiem jasno...) - wynik to... no bardzo mało : D

 

8. Zakończenie

Gratulacje, masz własny system dnia i nocy, który (mam nadzieję ;>) nawet rozumiesz : P

Myślę, że udało mi się wystarczająco dobrze wyjaśnić ostatnią część ; ) Hmmm.... godzinka mi na tym artykuliku zleciała : P Ale co, nudziło mi się ;P A nie wpadłem na lepszy temat na artykuł...

 

PS: Szkoda, że nie ma tagu GML : |

A pisano, że zaraz (bodajże "najpóźniej do południa" dnia wczorajszego) będzie gotowy : P

PS2: Cholera, zwiększcie możliwą do użycia liczbę emotikon :/

 

Edit: Co z tymi [ gml ] się stało...? O_o

Odnośnik do komentarza
Udostępnij na innych stronach

Poczekajcie, zrobię ten przykład :P Bo te tagi [ CODE ] coś rozrypały tabulatory :/

 

Edit: A jak do GM'a wkleiłem to czcionka w GM'owym edytorze się zmieniła,a le tylko kawałkami O_o Już wgrywam na serwer...

Edit2: Jest w pierwszym poście ;) Radzę zwiększyć room_speed, bo troszkę sobie poczekacie :P

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