mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
improve results screen
This commit is contained in:
@@ -169,7 +169,8 @@ class TextStretchAnimation(BaseAnimation):
|
||||
class TextureResizeAnimation(BaseAnimation):
|
||||
def __init__(self, duration: float, initial_size: float = 1.0,
|
||||
final_size: float = 0.0, delay: float = 0.0,
|
||||
reverse_delay: Optional[float] = None) -> None:
|
||||
reverse_delay: Optional[float] = None,
|
||||
ease_in: Optional[str] = None, ease_out: Optional[str] = None) -> None:
|
||||
super().__init__(duration, delay)
|
||||
self.initial_size = initial_size
|
||||
self.final_size = final_size
|
||||
@@ -177,6 +178,8 @@ class TextureResizeAnimation(BaseAnimation):
|
||||
self.initial_size_saved = initial_size
|
||||
self.final_size_saved = final_size
|
||||
self.reverse_delay_saved = reverse_delay
|
||||
self.ease_in = ease_in
|
||||
self.ease_out = ease_out
|
||||
|
||||
def restart(self) -> None:
|
||||
super().restart()
|
||||
@@ -203,6 +206,7 @@ class TextureResizeAnimation(BaseAnimation):
|
||||
else:
|
||||
animation_time = elapsed_time - self.delay
|
||||
progress = animation_time / self.duration
|
||||
progress = self._apply_easing(progress, self.ease_in, self.ease_out)
|
||||
self.attribute = self.initial_size + ((self.final_size - self.initial_size) * progress)
|
||||
|
||||
|
||||
|
||||
169
libs/utils.py
169
libs/utils.py
@@ -281,62 +281,151 @@ class OutlinedText:
|
||||
def _create_text_vertical(self, text: str, font_size: int, color: ray.Color, bg_color: ray.Color, font: Optional[ray.Font]=None, padding: int=10):
|
||||
rotate_chars = {'-', '‐', '|', '/', '\\', 'ー', '~', '~', '(', ')', '(', ')',
|
||||
'「', '」', '[', ']', '[', ']', '【', '】', '…', '→', '→', ':', ':'}
|
||||
side_punctuation = {'.', ',', '。', '、', "'", '"', '´', '`'}
|
||||
horizontal_punct = {'?', '!', '?', '!', '†'} # Characters that should be drawn horizontally when repeated
|
||||
lowercase_kana = {
|
||||
'ぁ', 'ア','ぃ', 'イ','ぅ', 'ウ','ぇ', 'エ','ぉ', 'オ',
|
||||
'ゃ', 'ャ','ゅ', 'ュ','ょ', 'ョ','っ', 'ッ','ゎ', 'ヮ',
|
||||
'ヶ', 'ヵ','ㇰ','ㇱ','ㇲ','ㇳ','ㇴ','ㇵ','ㇶ','ㇷ','ㇸ',
|
||||
'ㇹ','ㇺ','ㇻ','ㇼ','ㇽ','ㇾ','ㇿ'
|
||||
}
|
||||
|
||||
# Group consecutive horizontal punctuation marks
|
||||
def group_horizontal_sequences(text):
|
||||
groups = []
|
||||
i = 0
|
||||
while i < len(text):
|
||||
if text[i] in horizontal_punct:
|
||||
# Start of a horizontal sequence
|
||||
sequence = text[i]
|
||||
j = i + 1
|
||||
# Continue collecting consecutive horizontal punctuation
|
||||
while j < len(text) and text[j] in horizontal_punct:
|
||||
sequence += text[j]
|
||||
j += 1
|
||||
|
||||
# Only treat as horizontal if there are 2 or more characters
|
||||
if len(sequence) >= 2:
|
||||
groups.append(('horizontal', sequence))
|
||||
else:
|
||||
groups.append(('single', sequence))
|
||||
i = j
|
||||
else:
|
||||
groups.append(('single', text[i]))
|
||||
i += 1
|
||||
return groups
|
||||
|
||||
# Helper function to calculate adjusted character height
|
||||
def get_char_height(char):
|
||||
if char in side_punctuation:
|
||||
return font_size // 4
|
||||
elif char.islower() or char in lowercase_kana:
|
||||
return font_size * 0.88
|
||||
elif char.isspace():
|
||||
return font_size * 0.6
|
||||
else:
|
||||
return font_size
|
||||
|
||||
grouped_text = group_horizontal_sequences(text)
|
||||
|
||||
# Calculate dimensions with proper height adjustments
|
||||
max_char_width = 0
|
||||
total_height = padding * 2
|
||||
|
||||
for char in text:
|
||||
if font:
|
||||
char_size = ray.measure_text_ex(font, char, font_size, 0)
|
||||
for group_type, content in grouped_text:
|
||||
if group_type == 'horizontal':
|
||||
# For horizontal sequences, measure the combined width
|
||||
if font:
|
||||
seq_size = ray.measure_text_ex(font, content, font_size, 0)
|
||||
else:
|
||||
seq_width = ray.measure_text(content, font_size)
|
||||
seq_size = ray.Vector2(seq_width, font_size)
|
||||
max_char_width = max(max_char_width, seq_size.x)
|
||||
total_height += font_size # Horizontal sequences use full font_size
|
||||
else:
|
||||
char_width = ray.measure_text(char, font_size)
|
||||
char_size = ray.Vector2(char_width, font_size)
|
||||
# Single character
|
||||
char = content
|
||||
if font:
|
||||
char_size = ray.measure_text_ex(font, char, font_size, 0)
|
||||
else:
|
||||
char_width = ray.measure_text(char, font_size)
|
||||
char_size = ray.Vector2(char_width, font_size)
|
||||
|
||||
if char in rotate_chars:
|
||||
effective_width = char_size.y
|
||||
else:
|
||||
effective_width = char_size.x
|
||||
if char in rotate_chars:
|
||||
effective_width = char_size.y
|
||||
else:
|
||||
effective_width = char_size.x
|
||||
max_char_width = max(max_char_width, effective_width)
|
||||
|
||||
max_char_width = max(max_char_width, effective_width)
|
||||
# Use the adjusted height instead of fixed font_size
|
||||
total_height += get_char_height(char)
|
||||
|
||||
total_height += len(text) * font_size
|
||||
width = int(max_char_width + (padding * 2))
|
||||
height = total_height
|
||||
height = int(total_height) # Make sure it's an integer
|
||||
image = ray.gen_image_color(width, height, bg_color)
|
||||
|
||||
for i, char in enumerate(text):
|
||||
char_y = i * font_size + padding
|
||||
curr_char_y = padding - font_size
|
||||
|
||||
for group_type, content in grouped_text:
|
||||
if group_type == 'horizontal':
|
||||
# Handle horizontal punctuation sequence
|
||||
char_y = font_size
|
||||
curr_char_y += char_y
|
||||
|
||||
if font:
|
||||
seq_size = ray.measure_text_ex(font, content, font_size, 0)
|
||||
seq_image = ray.image_text_ex(font, content, font_size, 0, color)
|
||||
else:
|
||||
seq_width = ray.measure_text(content, font_size)
|
||||
seq_size = ray.Vector2(seq_width, font_size)
|
||||
seq_image = ray.image_text(content, font_size, color)
|
||||
|
||||
# Center the horizontal sequence
|
||||
char_x = width // 2 - seq_size.x // 2
|
||||
|
||||
ray.image_draw(image, seq_image,
|
||||
ray.Rectangle(0, 0, seq_image.width, seq_image.height),
|
||||
ray.Rectangle(char_x, curr_char_y, seq_image.width, seq_image.height),
|
||||
ray.WHITE)
|
||||
ray.unload_image(seq_image)
|
||||
|
||||
if font:
|
||||
char_size = ray.measure_text_ex(font, char, font_size, 0)
|
||||
char_image = ray.image_text_ex(font, char, font_size, 0, color)
|
||||
else:
|
||||
char_width = ray.measure_text(char, font_size)
|
||||
char_size = ray.Vector2(char_width, font_size)
|
||||
char_image = ray.image_text(char, font_size, color)
|
||||
# Handle single character (existing logic)
|
||||
char = content
|
||||
char_y = get_char_height(char) # Use the helper function
|
||||
curr_char_y += char_y
|
||||
|
||||
if char in rotate_chars:
|
||||
rotated_image = ray.gen_image_color(char_image.height, char_image.width, ray.BLANK)
|
||||
if font:
|
||||
char_size = ray.measure_text_ex(font, char, font_size, 0)
|
||||
char_image = ray.image_text_ex(font, char, font_size, 0, color)
|
||||
else:
|
||||
char_width = ray.measure_text(char, font_size)
|
||||
char_size = ray.Vector2(char_width, font_size)
|
||||
char_image = ray.image_text(char, font_size, color)
|
||||
|
||||
for y in range(char_image.height):
|
||||
for x in range(char_image.width):
|
||||
src_color = ray.get_image_color(char_image, x, y)
|
||||
new_x = char_image.height - 1 - y
|
||||
new_y = x
|
||||
ray.image_draw_pixel(rotated_image, new_x, new_y, src_color)
|
||||
if char in rotate_chars:
|
||||
rotated_image = ray.gen_image_color(char_image.height, char_image.width, ray.BLANK)
|
||||
for y in range(char_image.height):
|
||||
for x in range(char_image.width):
|
||||
src_color = ray.get_image_color(char_image, x, y)
|
||||
new_x = char_image.height - 1 - y
|
||||
new_y = x
|
||||
ray.image_draw_pixel(rotated_image, new_x, new_y, src_color)
|
||||
ray.unload_image(char_image)
|
||||
char_image = rotated_image
|
||||
effective_width = char_size.y
|
||||
else:
|
||||
effective_width = char_size.x
|
||||
|
||||
char_x = width // 2 - effective_width // 2
|
||||
if char in side_punctuation:
|
||||
char_x += font_size//3
|
||||
|
||||
ray.image_draw(image, char_image,
|
||||
ray.Rectangle(0, 0, char_image.width, char_image.height),
|
||||
ray.Rectangle(char_x, curr_char_y, char_image.width, char_image.height),
|
||||
ray.WHITE)
|
||||
ray.unload_image(char_image)
|
||||
char_image = rotated_image
|
||||
effective_width = char_size.y
|
||||
else:
|
||||
effective_width = char_size.x
|
||||
|
||||
char_x = width // 2 - effective_width // 2
|
||||
|
||||
ray.image_draw(image, char_image,
|
||||
ray.Rectangle(0, 0, char_image.width, char_image.height),
|
||||
ray.Rectangle(char_x, char_y, char_image.width, char_image.height),
|
||||
ray.WHITE)
|
||||
ray.unload_image(char_image)
|
||||
|
||||
texture = ray.load_texture_from_image(image)
|
||||
ray.unload_image(image)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import pyray as ray
|
||||
|
||||
from libs.utils import OutlinedText, get_current_ms
|
||||
|
||||
|
||||
class DevScreen:
|
||||
def __init__(self, width: int, height: int):
|
||||
@@ -9,9 +7,6 @@ class DevScreen:
|
||||
self.height = height
|
||||
self.screen_init = False
|
||||
|
||||
self.time_now = get_current_ms()
|
||||
self.test = OutlinedText('Triple Helix', 40, ray.Color(255, 255, 255, 255), ray.Color(101, 0, 82, 255), outline_thickness=4, vertical=True)
|
||||
|
||||
def on_screen_start(self):
|
||||
if not self.screen_init:
|
||||
self.screen_init = True
|
||||
@@ -23,10 +18,7 @@ class DevScreen:
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
|
||||
return self.on_screen_end('TITLE')
|
||||
return self.on_screen_end('RESULT')
|
||||
|
||||
def draw(self):
|
||||
ray.draw_rectangle(0, 0, self.width, self.height, ray.WHITE)
|
||||
src = ray.Rectangle(0, 0, self.test.texture.width, self.test.texture.height)
|
||||
dest = ray.Rectangle(self.width//2 - self.test.texture.width//2, self.height//2 - self.test.texture.height//2, self.test.texture.width, self.test.texture.height)
|
||||
self.test.draw(src, dest, ray.Vector2(0, 0), 0, ray.WHITE)
|
||||
pass
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
import pyray as ray
|
||||
|
||||
from libs.animation import Animation
|
||||
from libs.song_hash import build_song_hashes
|
||||
from libs.utils import global_data
|
||||
from libs.utils import get_current_ms, global_data, load_all_textures_from_zip
|
||||
from scenes.song_select import SongSelectScreen
|
||||
|
||||
|
||||
@@ -18,15 +20,19 @@ class LoadScreen:
|
||||
self.song_select_screen = song_select_screen
|
||||
|
||||
# Progress bar settings
|
||||
self.progress_bar_width = width * 0.6
|
||||
self.progress_bar_height = 20
|
||||
self.progress_bar_width = width * 0.43
|
||||
self.progress_bar_height = 50
|
||||
self.progress_bar_x = (width - self.progress_bar_width) // 2
|
||||
self.progress_bar_y = height * 0.7
|
||||
self.progress_bar_y = height * 0.85
|
||||
|
||||
# Thread references
|
||||
self.loading_thread = None
|
||||
self.navigator_thread = None
|
||||
|
||||
self.textures = load_all_textures_from_zip(Path('Graphics/lumendata/attract/kidou.zip'))
|
||||
|
||||
self.fade_in = None
|
||||
|
||||
def _load_song_hashes(self):
|
||||
"""Background thread function to load song hashes"""
|
||||
try:
|
||||
@@ -71,11 +77,17 @@ class LoadScreen:
|
||||
self.navigator_thread.start()
|
||||
self.navigator_started = True
|
||||
|
||||
if self.loading_complete:
|
||||
return self.on_screen_end('TITLE')
|
||||
if self.loading_complete and self.fade_in is None:
|
||||
self.fade_in = Animation.create_fade(1000, initial_opacity=0.0, final_opacity=1.0, ease_in='cubic')
|
||||
|
||||
if self.fade_in is not None:
|
||||
self.fade_in.update(get_current_ms())
|
||||
if self.fade_in.is_finished:
|
||||
return self.on_screen_end('TITLE')
|
||||
|
||||
def draw(self):
|
||||
ray.draw_rectangle(0, 0, self.width, self.height, ray.BLACK)
|
||||
ray.draw_texture(self.textures['kidou'][1], self.width//2 - self.textures['kidou'][1].width//2, 50, ray.WHITE)
|
||||
|
||||
# Draw progress bar background
|
||||
ray.draw_rectangle(
|
||||
@@ -83,7 +95,7 @@ class LoadScreen:
|
||||
int(self.progress_bar_y),
|
||||
int(self.progress_bar_width),
|
||||
int(self.progress_bar_height),
|
||||
ray.DARKGRAY
|
||||
ray.Color(101, 0, 0, 255)
|
||||
)
|
||||
|
||||
# Draw progress bar fill
|
||||
@@ -98,11 +110,5 @@ class LoadScreen:
|
||||
ray.RED
|
||||
)
|
||||
|
||||
# Draw border
|
||||
ray.draw_rectangle_lines(
|
||||
int(self.progress_bar_x),
|
||||
int(self.progress_bar_y),
|
||||
int(self.progress_bar_width),
|
||||
int(self.progress_bar_height),
|
||||
ray.WHITE
|
||||
)
|
||||
if self.fade_in is not None:
|
||||
ray.draw_rectangle(0, 0, self.width, self.height, ray.fade(ray.WHITE, self.fade_in.attribute))
|
||||
|
||||
197
scenes/result.py
197
scenes/result.py
@@ -1,6 +1,8 @@
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
import pyray as ray
|
||||
from raylib import SHADER_UNIFORM_FLOAT
|
||||
|
||||
from libs import utils
|
||||
from libs.animation import Animation
|
||||
@@ -17,12 +19,17 @@ from libs.utils import (
|
||||
)
|
||||
|
||||
|
||||
class State:
|
||||
FAIL = 0
|
||||
CLEAR = 1
|
||||
RAINBOW = 2
|
||||
|
||||
class ResultScreen:
|
||||
def __init__(self, width: int, height: int):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.screen_init = False
|
||||
self.fade_out = None
|
||||
self.alpha_shader = ray.load_shader('', 'shader/grayscale_alpha.fs')
|
||||
|
||||
def load_textures(self):
|
||||
zip_file = Path('Graphics/lumendata/enso_result.zip')
|
||||
@@ -44,8 +51,12 @@ class ResultScreen:
|
||||
audio.play_sound(self.bgm)
|
||||
self.fade_in = FadeIn()
|
||||
self.fade_out = None
|
||||
self.fade_in_bottom = None
|
||||
self.gauge = None
|
||||
self.score_delay = None
|
||||
self.bottom_characters = BottomCharacters()
|
||||
self.crown = None
|
||||
self.state = None
|
||||
self.score_animator = ScoreAnimator(session_data.result_score)
|
||||
self.score = -1
|
||||
self.good = -1
|
||||
@@ -62,6 +73,10 @@ class ResultScreen:
|
||||
self.update_index = 0
|
||||
self.is_skipped = False
|
||||
self.start_ms = get_current_ms()
|
||||
if session_data.result_bad == 0:
|
||||
self.crown_texture = 125
|
||||
else:
|
||||
self.crown_texture = 124
|
||||
|
||||
def on_screen_end(self):
|
||||
self.screen_init = False
|
||||
@@ -112,12 +127,32 @@ class ResultScreen:
|
||||
self.fade_in.update(get_current_ms())
|
||||
if self.fade_in.is_finished and self.gauge is None:
|
||||
self.gauge = Gauge(get_current_ms(), session_data.result_gauge_length)
|
||||
self.bottom_characters.start()
|
||||
|
||||
self.bottom_characters.update(self.state)
|
||||
|
||||
if self.bottom_characters.is_finished and self.crown is None:
|
||||
if self.gauge is not None and self.gauge.gauge_length > 69:
|
||||
self.crown = Crown()
|
||||
|
||||
if self.gauge is not None:
|
||||
self.gauge.update(get_current_ms())
|
||||
if self.gauge.is_finished and self.score_delay is None:
|
||||
self.score_delay = get_current_ms() + 1883
|
||||
|
||||
if self.score_delay is not None:
|
||||
if get_current_ms() > self.score_delay and self.fade_in_bottom is None:
|
||||
self.fade_in_bottom = Animation.create_fade(333, initial_opacity=0.0, final_opacity=1.0)
|
||||
if self.gauge is not None:
|
||||
self.state = self.gauge.state
|
||||
|
||||
|
||||
if self.fade_in_bottom is not None:
|
||||
self.fade_in_bottom.update(get_current_ms())
|
||||
alpha_loc = ray.get_shader_location(self.alpha_shader, "ext_alpha")
|
||||
alpha_value = ray.ffi.new('float*', self.fade_in_bottom.attribute)
|
||||
ray.set_shader_value(self.alpha_shader, alpha_loc, alpha_value, SHADER_UNIFORM_FLOAT)
|
||||
|
||||
if get_current_ms() >= self.start_ms + 5000:
|
||||
self.handle_input()
|
||||
|
||||
@@ -128,6 +163,9 @@ class ResultScreen:
|
||||
if self.fade_out.is_finished:
|
||||
return self.on_screen_end()
|
||||
|
||||
if self.crown is not None:
|
||||
self.crown.update(get_current_ms())
|
||||
|
||||
def draw_score_info(self):
|
||||
if self.good > -1:
|
||||
for i in range(len(str(self.good))):
|
||||
@@ -146,11 +184,29 @@ class ResultScreen:
|
||||
ray.draw_texture(self.textures['result'][int(str(self.total_drumroll)[::-1][i]) + 136], 1217-(i*24), 186, ray.WHITE)
|
||||
|
||||
def draw_total_score(self):
|
||||
if self.fade_in is None:
|
||||
return
|
||||
|
||||
if not self.fade_in.is_finished:
|
||||
return
|
||||
ray.draw_texture(self.textures['result'][167], 554, 236, ray.WHITE)
|
||||
if self.score > -1:
|
||||
for i in range(len(str(self.score))):
|
||||
ray.draw_texture(self.textures['result'][int(str(self.score)[::-1][i]) + 156], 723-(i*21), 252, ray.WHITE)
|
||||
|
||||
def draw_bottom_textures(self):
|
||||
if self.fade_in_bottom is not None:
|
||||
src = ray.Rectangle(0, 0, self.textures['result'][328].width, self.textures['result'][328].height)
|
||||
if self.state == State.FAIL:
|
||||
dest = ray.Rectangle(0, self.height//2, self.width, self.height//2)
|
||||
ray.draw_texture_pro(self.textures['result'][329], src, dest, ray.Vector2(0, 0), 0, ray.fade(ray.WHITE, min(0.4, self.fade_in_bottom.attribute)))
|
||||
else:
|
||||
dest = ray.Rectangle(0, self.height//2 - 72, self.width, self.height//2)
|
||||
ray.begin_shader_mode(self.alpha_shader)
|
||||
ray.draw_texture_pro(self.textures['result'][328], src, dest, ray.Vector2(0, 0), 0, ray.fade(ray.WHITE, self.fade_in_bottom.attribute))
|
||||
ray.end_shader_mode()
|
||||
self.bottom_characters.draw(self.textures['result'])
|
||||
|
||||
def draw(self):
|
||||
x = 0
|
||||
while x < self.width:
|
||||
@@ -171,6 +227,10 @@ class ResultScreen:
|
||||
|
||||
ray.draw_texture(self.textures['result'][175], 532, 98, ray.fade(ray.WHITE, 0.75))
|
||||
|
||||
ray.draw_texture(self.textures['result'][233 + session_data.selected_difficulty], 289, 129, ray.WHITE)
|
||||
|
||||
self.draw_bottom_textures()
|
||||
|
||||
if self.gauge is not None:
|
||||
self.gauge.draw(self.textures['result'])
|
||||
|
||||
@@ -183,12 +243,141 @@ class ResultScreen:
|
||||
self.draw_score_info()
|
||||
self.draw_total_score()
|
||||
|
||||
if self.crown is not None:
|
||||
self.crown.draw(self.textures['result'], self.crown_texture)
|
||||
|
||||
if self.fade_in is not None:
|
||||
self.fade_in.draw(self.width, self.height, self.textures['result'][326], self.textures['result'][327])
|
||||
|
||||
if self.fade_out is not None:
|
||||
self.fade_out.draw(self.width, self.height)
|
||||
|
||||
class Crown:
|
||||
def __init__(self):
|
||||
duration = 466
|
||||
self.resize = Animation.create_texture_resize(duration, initial_size=3.5, final_size=0.90, ease_in='quadratic')
|
||||
self.resize_fix = Animation.create_texture_resize(216, initial_size=self.resize.final_size, final_size=1.0, delay=self.resize.duration)
|
||||
self.white_fadein = Animation.create_fade(133, initial_opacity=0.0, final_opacity=1.0, delay=self.resize.duration + self.resize_fix.duration, reverse_delay=0)
|
||||
self.gleam = Animation.create_texture_change(400, textures=[(0, 200, 0), (200, 250, 127), (250, 300, 128), (300, 350, 129), (350, 400, 0)], delay=self.resize.duration + self.resize_fix.duration + self.white_fadein.duration)
|
||||
self.fadein = Animation.create_fade(duration, initial_opacity=0.0, final_opacity=1.0, ease_in='quadratic')
|
||||
self.sound = audio.load_sound(Path('Sounds/result/SE_RESULT [1].ogg'))
|
||||
self.sound_played = False
|
||||
|
||||
def update(self, current_ms: float):
|
||||
self.fadein.update(current_ms)
|
||||
self.resize.update(current_ms)
|
||||
self.resize_fix.update(current_ms)
|
||||
self.white_fadein.update(current_ms)
|
||||
self.gleam.update(current_ms)
|
||||
if self.resize_fix.is_finished and not self.sound_played:
|
||||
audio.play_sound(self.sound)
|
||||
self.sound_played = True
|
||||
|
||||
def draw(self, textures: list[ray.Texture], crown_index: int):
|
||||
scale = self.resize.attribute
|
||||
if self.resize.is_finished:
|
||||
scale = self.resize_fix.attribute
|
||||
texture = textures[crown_index]
|
||||
x_x = 335 + (texture.width//2) - ((texture.width * scale)//2)
|
||||
x_y = 150 + (texture.height//2) - ((texture.height * scale)//2)
|
||||
x_source = ray.Rectangle(0, 0, texture.width, texture.height)
|
||||
x_dest = ray.Rectangle(x_x, x_y, texture.width*scale, texture.height*scale)
|
||||
ray.draw_texture_pro(texture, x_source, x_dest, ray.Vector2(0,0), 0, ray.fade(ray.WHITE, self.fadein.attribute))
|
||||
ray.draw_texture(textures[126], int(x_x), int(x_y), ray.fade(ray.WHITE, self.white_fadein.attribute))
|
||||
if self.gleam.attribute != 0:
|
||||
ray.draw_texture(textures[self.gleam.attribute], int(x_x), int(x_y), ray.WHITE)
|
||||
|
||||
class BottomCharacters:
|
||||
def __init__(self):
|
||||
self.move_up = None
|
||||
self.move_down = None
|
||||
self.move_center = None
|
||||
self.bounce_up = None
|
||||
self.bounce_down = None
|
||||
self.flower_up = None
|
||||
self.state = None
|
||||
self.flower_index = 341
|
||||
self.flower_start = None
|
||||
self.char_1_index = 339
|
||||
self.char_2_index = 340
|
||||
self.c_bounce_up = Animation.create_move(266, total_distance=40, ease_in='quadratic')
|
||||
self.c_bounce_down = Animation.create_move(266, total_distance=40, ease_out='quadratic', delay=self.c_bounce_up.duration)
|
||||
self.is_finished = False
|
||||
|
||||
def start(self):
|
||||
self.move_up = Animation.create_move(366, total_distance=380, ease_out='cubic')
|
||||
self.move_down = Animation.create_move(133, total_distance=30, ease_out='cubic', delay=self.move_up.duration-5)
|
||||
|
||||
def update(self, state):
|
||||
self.state = state
|
||||
if self.state == State.CLEAR or self.state == State.RAINBOW:
|
||||
self.char_1_index = 345
|
||||
self.char_2_index = 346
|
||||
if self.bounce_up is None:
|
||||
self.bounce_up = Animation.create_move(266, total_distance=40, ease_in='quadratic')
|
||||
self.bounce_down = Animation.create_move(266, total_distance=40, ease_out='quadratic', delay=self.bounce_up.duration)
|
||||
self.move_center = Animation.create_move(266, total_distance=450, ease_out='quadratic', delay=self.bounce_down.duration+self.bounce_up.duration)
|
||||
if self.flower_up is None:
|
||||
self.flower_up = Animation.create_move(333, total_distance=365, ease_out='quadratic')
|
||||
self.flower_start = get_current_ms()
|
||||
elif self.state == State.FAIL:
|
||||
self.char_1_index = 347
|
||||
self.char_2_index = 348
|
||||
|
||||
if self.move_up is not None:
|
||||
self.move_up.update(get_current_ms())
|
||||
if self.move_down is not None:
|
||||
self.move_down.update(get_current_ms())
|
||||
self.is_finished = self.move_down.is_finished
|
||||
if self.bounce_up is not None:
|
||||
self.bounce_up.update(get_current_ms())
|
||||
if self.bounce_down is not None:
|
||||
self.bounce_down.update(get_current_ms())
|
||||
if self.bounce_down.is_finished and self.bounce_up is not None:
|
||||
self.bounce_up.restart()
|
||||
self.bounce_down.restart()
|
||||
if self.move_center is not None:
|
||||
self.move_center.update(get_current_ms())
|
||||
if self.flower_up is not None:
|
||||
self.flower_up.update(get_current_ms())
|
||||
|
||||
if self.flower_start is not None:
|
||||
if get_current_ms() > self.flower_start + 116*2 + 333:
|
||||
self.flower_index = 343
|
||||
elif get_current_ms() > self.flower_start + 116 + 333:
|
||||
self.flower_index = 342
|
||||
|
||||
self.c_bounce_up.update(get_current_ms())
|
||||
self.c_bounce_down.update(get_current_ms())
|
||||
if self.c_bounce_down.is_finished:
|
||||
self.c_bounce_up.restart()
|
||||
self.c_bounce_down.restart()
|
||||
|
||||
def draw_flowers(self, textures: list[ray.Texture]):
|
||||
if self.flower_up is None:
|
||||
return
|
||||
y = 720+textures[self.flower_index].height - int(self.flower_up.attribute)
|
||||
source_rect = ray.Rectangle(0, 0, textures[self.flower_index].width, textures[self.flower_index].height)
|
||||
dest_rect = ray.Rectangle(1280-textures[self.flower_index].width, y, textures[self.flower_index].width, textures[self.flower_index].height)
|
||||
source_rect.width = -textures[self.flower_index].width
|
||||
ray.draw_texture_pro(textures[self.flower_index], source_rect, dest_rect, ray.Vector2(0, 0), 0, ray.WHITE)
|
||||
ray.draw_texture(textures[self.flower_index], 0, y, ray.WHITE)
|
||||
|
||||
def draw(self, textures: list[ray.Texture]):
|
||||
if self.move_up is None or self.move_down is None:
|
||||
return
|
||||
|
||||
self.draw_flowers(textures)
|
||||
|
||||
y = 720 - int(self.move_up.attribute) + int(self.move_down.attribute)
|
||||
if self.bounce_up is not None and self.bounce_down is not None:
|
||||
y = 720 - int(self.move_up.attribute) + int(self.move_down.attribute) + int(self.bounce_up.attribute) - int(self.bounce_down.attribute)
|
||||
if self.state == State.RAINBOW and self.move_center is not None:
|
||||
center_y = int(self.c_bounce_up.attribute) - int(self.c_bounce_down.attribute)
|
||||
ray.draw_texture(textures[344], 1280//2 - textures[344].width//2, (800 - int(self.move_center.attribute)) + int(center_y), ray.WHITE)
|
||||
|
||||
ray.draw_texture(textures[self.char_1_index], 125, y, ray.WHITE)
|
||||
ray.draw_texture(textures[self.char_2_index], 820, y, ray.WHITE)
|
||||
|
||||
class FadeIn:
|
||||
def __init__(self):
|
||||
@@ -240,6 +429,12 @@ class Gauge:
|
||||
self.rainbow_animation = None
|
||||
self.gauge_fade_in = Animation.create_fade(366, initial_opacity=0.0, final_opacity=1.0)
|
||||
self.is_finished = self.gauge_fade_in.is_finished
|
||||
if self.gauge_length == 87:
|
||||
self.state = State.RAINBOW
|
||||
elif self.gauge_length > 69:
|
||||
self.state = State.CLEAR
|
||||
else:
|
||||
self.state = State.FAIL
|
||||
|
||||
def _create_rainbow_anim(self, current_ms):
|
||||
anim = Animation.create_texture_change((16.67*8) * 3, textures=[((16.67 * 3) * i, (16.67 * 3) * (i + 1), i) for i in range(8)])
|
||||
|
||||
13
shader/grayscale_alpha.fs
Normal file
13
shader/grayscale_alpha.fs
Normal file
@@ -0,0 +1,13 @@
|
||||
// fragment shader
|
||||
#version 330
|
||||
in vec2 fragTexCoord;
|
||||
uniform sampler2D texture0;
|
||||
out vec4 finalColor;
|
||||
uniform float ext_alpha;
|
||||
void main() {
|
||||
vec4 texColor = texture(texture0, fragTexCoord);
|
||||
vec3 last_color = vec3(1.0, 253.0/255.0, (186.0*0.80)/255.0);
|
||||
// Use luminance as alpha (0.0 = transparent, 1.0 = opaque)
|
||||
float alpha = ((texColor.r + texColor.g + texColor.b)/3)*0.70;
|
||||
finalColor = vec4(last_color, alpha * ext_alpha);
|
||||
}
|
||||
Reference in New Issue
Block a user