From 452b213ac72f003854140e66b0fb22303b9a5276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maksymilian=20Wilczy=C5=84ski?= Date: Tue, 25 Nov 2025 10:19:18 +0100 Subject: [PATCH] a transition, i guess --- assets/mask.png | Bin 0 -> 8012 bytes assets/mask2.png | Bin 0 -> 9341 bytes mask.py | 45 +++++++++++++++++++++++++++++ src/main.cpp | 73 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 98 insertions(+), 20 deletions(-) create mode 100644 assets/mask.png create mode 100644 assets/mask2.png create mode 100644 mask.py diff --git a/assets/mask.png b/assets/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..e500e1c5a90d517c585f8b875ec95789368a7599 GIT binary patch literal 8012 zcmeAS@N?(olHy`uVBq!ia0y~yUFcojifV-4IpZ~drX@2_IfIJr_IMD@a6_4a2}n82VBi386PXl1R10SV zh!Rj6l^hL((UdTn9e`U9oFOKu{9%;< zdF~Ki&wUmKrz?)l_>$Qfe+Q6B3fQeZV-5*Dy2%zZ@qnC@DAoX?;6w1j2_P=IPv$Uy zhVva}pr)Q@ELg)v{Q$@afiy;xF1#fpXab?ZfZG8i3(J^iI1NDDmPphY06)|if(AZX z*r53UW*^i;Xk1ty0?mI=*T5ofC~=`h8+r&rqlo$eiX#M}MJh=t1gfWo8Jum<^A`5> z1Dz^*Cfxu^FzBg^C|Q^f=7WtuPt7n{=nPdI6KKK;BY)tVzq(QU8#GtO&|r&}sqkq+ zn-POgm?fiTpCL6|9u*2`xWjcPllD zTk3fXhtr`Eh`lO;>A4TB#EGh?=Klv(j0`^K`BlE%l`LJfZUTtw>FVdQ&MBb@0EE~v AdH?_b literal 0 HcmV?d00001 diff --git a/assets/mask2.png b/assets/mask2.png new file mode 100644 index 0000000000000000000000000000000000000000..00e8b11bbfad3f6bcd2d91dd91e7534c1d8b93b8 GIT binary patch literal 9341 zcmeHMOKclO7~Z6ANt#pyA_0X%maRlvQF|YW?RZtwq;^Ow)gej^O>dp-j-6G!kL+%0 zCskVuDi9~QAVnwwP8?AoQW4KS#4&;^QbcoWFGQ6nDndNOj6J)`ZZ~d{Rtlhv6wS{3 z|NM_{{{P#D-yRzs-naMJy%a_5%Z+5mDQY*mjP$qdLBnfb&b)z!c4OqUMNu8y_`ijE zfAJZl^|Vr$uqW~-L`hd;K-MQ=tg0GFo1%^$s~SL>hBiG3ONy3e?tFEXp%ppJoQmhU zype%Z%E-J4PtK1Pr1@znB{RofqK{TZWI%;BpsQ+Gv&3qesoNFNHC|>Jx~^hRrfNg(tlj?e-p@GRHQ@{#BFk1Pl~|=Wrkf>}Po+{UC$NGLMH*3SPP0KZs#ymd3t4DMrefHNuF=>c znAB(OG=oBIUX93X7-dDll^EUN0duBAo040zgR?`}&g6 zgxuF31x1jI_7)|n2tlGR4&%=LtS-&s5^(m*TipMOsh}PN-RaWSFxrji*ZIEUpeEv{o$g;9+1R7>5QxF+#QWp(1OE20LV8X!?LhFHb$D-g_ z+^~&2SbvIj*}CR-)DdIgOP8zA#AQ3EA&N5*mz9^^TBfL;&Rlk|P+eU6>3aKjTvz1! zr!#*aULATql7BUFA-VL+(%OE^mhb+mp3^Tz@TKu4)rLpVO5@?u`MZ1S7xHPU70m}0 zh+Er}v*h;lvMz3)l16b-Rw{v)U$#Jlo_DqBQ z9U+dq?yc5NycaxG!-MNSc=`fKsQV07Zd;;o{%&y1r%s;DL-%Fkn?6Khn+v_gb2Q`} zU6_O2lXLU|>G&giZhE02V4NVU#OU1<075x75;eck6l=~W;Hz^ zFOHXgyZ0F0MBSe7vVqsdt%EdHa{JFKb)x&QhLr{uNLzTrTSx{rI0A`Dw)t`Znzul!ECqFQc?rW5qyMzlD6D{$b6hn z=wXqLkQ2_W=&-%E#cpKtmM84A%W zP6$E>0)9CQDZexSDfAquEc6pLzWs3QUu* literal 0 HcmV?d00001 diff --git a/mask.py b/mask.py new file mode 100644 index 0000000..644fc50 --- /dev/null +++ b/mask.py @@ -0,0 +1,45 @@ +from PIL import Image + +# Wymiary (bez zmian) +SZEROKOSC = 1280 +WYSOKOSC_PLYNNA = 1080 +WYSOKOSC_CZARNA = 720 +WYSOKOSC_GRADIENTU = WYSOKOSC_PLYNNA - WYSOKOSC_CZARNA # 360 + +# Stopień nieliniowości (im wyższy, tym wolniejszy spadek na początku) +# 1.0 = Liniowy, 2.0 = Quadratic (Wolniejszy start, szybszy koniec), 3.0 = Cubic +WSPOLCZYNNIK_EASING = 2.5 + +# 1. Utwórz przezroczysty obraz +img = Image.new('RGBA', (SZEROKOSC, WYSOKOSC_PLYNNA), (0, 0, 0, 0)) +pixels = img.load() + +# 2. Ustaw w pełni czarny obszar (bez zmian) +for x in range(SZEROKOSC): + for y in range(WYSOKOSC_CZARNA): + pixels[x, y] = (0, 0, 0, 255) + +# 3. Zmodyfikowany gradient nieliniowy (Ease-In, czyli spowolnienie na początku) +for y in range(WYSOKOSC_CZARNA, WYSOKOSC_PLYNNA): + + # 1. Oblicz współrzędną w zakresie 0.0 do 1.0 (liniowo) + y_gradient = y - WYSOKOSC_CZARNA + wspolczynnik_liniowy = y_gradient / WYSOKOSC_GRADIENTU # 0.0 na 720px, 1.0 na 1080px + + # 2. Zastosuj funkcję nieliniową (np. Power/Expo Ease-In) + # Ta funkcja powoduje, że 'współczynnik_nieliniowy' rośnie wolniej na początku. + wspolczynnik_nieliniowy = wspolczynnik_liniowy ** WSPOLCZYNNIK_EASING + + # 3. Konwersja na krycie (alpha) + # Ponieważ chcemy, by krycie MALAŁO od 255 do 0: + # Używamy 1.0 - wspolczynnik_nieliniowy (czyli od 1.0 do 0.0) + krycie_skalarne = 1.0 - wspolczynnik_nieliniowy + alpha = int(255 * krycie_skalarne) + + # Zastosuj krycie + for x in range(SZEROKOSC): + # Użyj maks. 0, aby uniknąć ujemnych wartości na wszelki wypadek + pixels[x, y] = (0, 0, 0, max(0, alpha)) + +# Zapisz obraz +img.save('mask.png') \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index aa33416..80764f8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,14 +63,25 @@ int main() { uint32_t dialogue_id = compositor_insert(compositor, text_getfb(dialogue_text), WIDTH - 140, 160, 60, HEIGHT - 130, 4); - uint32_t* black = (uint32_t*)malloc(WIDTH * HEIGHT * sizeof(uint32_t)); - for (int i = 0; i < WIDTH * HEIGHT; i++) { - black[i] = 0xFF000000; - } - uint32_t black_id = compositor_insert(compositor, black, - WIDTH, HEIGHT, 0, 0, 5); - compositor_set_alpha(compositor, black_id, 0.0f); + uint32_t* mask = image_load_resized("assets/mask.png", 1280, 1080); + // okay so this requires some math + // inserting at 0,0 (top-left anchor) means it will cover the whole screen + // we need to insert it above the screen, so -1080 + uint32_t mask_id = compositor_insert(compositor, mask, 1280, 1080, 0, -1080, 5); + compositor_set_visible(compositor, mask_id, false); + + uint32_t* mask2 = image_load_resized("assets/mask2.png", 1280, 1080); + // here, we put it in the center, as this is the slide out + uint32_t mask2_id = compositor_insert(compositor, mask2, 1280, 1080, 0, 0, 5); + compositor_set_visible(compositor, mask2_id, false); + + uint32_t* black = (uint32_t*)malloc(WIDTH * HEIGHT * sizeof(uint32_t)); + for (int i = 0; i < WIDTH * HEIGHT; i++) { + black[i] = 0xFF000000; + } + uint32_t black_id = compositor_insert(compositor, black, WIDTH, HEIGHT, 0, 0, 6); compositor_set_visible(compositor, black_id, false); + compositor_set_alpha(compositor, black_id, 0.0f); compositor_animate_move(compositor, maksw_happy_id, 60, POS_Y, 1.0f, EASE_OUT_CUBIC); compositor_animate_scale(compositor, maksw_happy_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC, true); @@ -133,12 +144,14 @@ int main() { static unsigned int lines = 0; static bool dialog_finished = false; + static bool transitioning = false; // HACK if (mouse_clicked || key_pressed) { if (text_is_animating(dialogue_text)) { text_show_all_current(dialogue_text); } else { + // do i like this approach? mixed feelings if (lines == 0) { // line 2 compositor_animation_complete_all(compositor); @@ -153,22 +166,20 @@ int main() { else if (lines == 1) { // line 3 compositor_animation_complete_all(compositor); - compositor_animate_scale(compositor, wikor_id, 1.0f, 0.2f, EASE_IN_OUT_CUBIC); - compositor_set_visible(compositor, maksw_happy_id, false); - compositor_set_visible(compositor, maksw_neutral_id, true); - compositor_animate_scale(compositor, maksw_neutral_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC); - text_clear(dialogue_text); - text_clear(name_text); - text_push(name_text, "maksw", 0.0f, true); - text_push(dialogue_text, "why so.. serious?", 30.0f, true); + + compositor_set_visible(compositor, mask_id, true); + compositor_animate_move(compositor, mask_id, 0, 0, 0.5f, EASE_OUT_CUBIC, false); + + transitioning = true; lines++; } else if (lines == 2) { - // fade out - compositor_animation_complete_all(compositor); - compositor_animate_scale(compositor, maksw_neutral_id, 1.0f, 0.2f, EASE_IN_OUT_CUBIC); - compositor_set_visible(compositor, black_id, true); - compositor_animate_fade(compositor, black_id, 1.0f, 1.5f, EASE_IN_OUT_CUBIC); + // (line 4), fade out + compositor_animation_complete_all(compositor); + + compositor_set_visible(compositor, black_id, true); + compositor_animate_fade(compositor, black_id, 1.0f, 1.0f, EASE_IN_OUT_CUBIC, false); + dialog_finished = true; lines++; } @@ -180,12 +191,31 @@ int main() { compositor_tick(compositor, delta_time_sec); + if (transitioning) { + if (compositor_is_element_animating(compositor, mask_id) == false) { + compositor_set_visible(compositor, maksw_happy_id, false); + compositor_set_visible(compositor, maksw_neutral_id, true); + compositor_animate_scale(compositor, maksw_neutral_id, 1.05f, 0.5f, EASE_IN_OUT_CUBIC); + text_clear(dialogue_text); + text_clear(name_text); + text_push(name_text, "maksw", 0.0f, true); + text_push(dialogue_text, "why so.. serious?", 30.0f, true); + + compositor_set_visible(compositor, mask_id, false); + compositor_set_visible(compositor, mask2_id, true); + compositor_animate_move(compositor, mask2_id, 0, HEIGHT, 0.5f, EASE_IN_CUBIC, false); + + transitioning = false; + } + } + if (dialog_finished) { compositor_mark_content_dirty(compositor, black_id); if (compositor_is_element_animating(compositor, black_id) == false) { running = false; } } + if (text_nextframe(name_text, delta_time_sec)) compositor_mark_content_dirty(compositor, name_id); if (text_nextframe(dialogue_text, delta_time_sec)) @@ -200,6 +230,9 @@ int main() { if (wikor) image_free(wikor); if (black) free(black); + if (mask) image_free(mask); + if (mask2) image_free(mask2); + if (bg) image_free(bg); if (textbox) image_free(textbox);