diff --git a/bg/dynamic_bg/dynamic_bg_pattern/dynamic_bg_pattern.gd b/bg/dynamic_bg/dynamic_bg_pattern/dynamic_bg_pattern.gd index 6c892a7..a9ac014 100644 --- a/bg/dynamic_bg/dynamic_bg_pattern/dynamic_bg_pattern.gd +++ b/bg/dynamic_bg/dynamic_bg_pattern/dynamic_bg_pattern.gd @@ -11,8 +11,8 @@ func _ready(): else: $Word1.set_word("qd<"[randi_range(0, 2)]) $Word2.set_word("=*"[randi_range(0, 1)]) - $Word1.set_color(ImageLib.get_palette_color_by_name("mid")) - $Word2.set_color(ImageLib.get_palette_color_by_name("mid")) + $Word1.set_color(ImageLib.get_palette_color_by_info("blue", "mid")) + $Word2.set_color(ImageLib.get_palette_color_by_info("blue", "mid")) func _process(delta): position += velocity * delta @@ -21,9 +21,9 @@ func _process(delta): func _on_victory_change(v: bool): if v: - $Word1.set_color(ImageLib.get_palette_color_by_name("light")) - $Word2.set_color(ImageLib.get_palette_color_by_name("light")) + $Word1.set_color(ImageLib.get_palette_color_by_info("blue", "light")) + $Word2.set_color(ImageLib.get_palette_color_by_info("blue", "light")) else: - $Word1.set_color(ImageLib.get_palette_color_by_name("mid")) - $Word2.set_color(ImageLib.get_palette_color_by_name("mid")) + $Word1.set_color(ImageLib.get_palette_color_by_info("blue", "mid")) + $Word2.set_color(ImageLib.get_palette_color_by_info("blue", "mid")) diff --git a/levels/chapter_menu/level_menu/level_menu.gd b/levels/chapter_menu/level_menu/level_menu.gd index 35203a9..b24c371 100644 --- a/levels/chapter_menu/level_menu/level_menu.gd +++ b/levels/chapter_menu/level_menu/level_menu.gd @@ -2,7 +2,6 @@ extends Node2D class_name LevelMenu -# const I_NUMBER = ["I","II","III","VI","V"] const LevelButtonScn := preload("res://levels/chapter_menu/level_menu/level_button/level_button.tscn") const BaseLevelScn := preload("res://levels/base_level/base_level.tscn") @@ -44,12 +43,14 @@ func _on_button_enter_level(chap_id: int, lvl_id: int) -> void: func _on_previous_chapter_button_pressed(): self.chapter_id -= 1 $UI/Title.text = LevelData.CHAP_NAMES[chapter_id]["name-en"] + ImageLib.change_theme(ImageLib.COLOR_THEMES[ImageLib.COLOR_THEMES.find(ImageLib.theme_to) - 1], LevelMenuCamera.MOVE_TIME) $UI/PreviousChapterButton.set_disabled(true) $UI/NextChapterButton.set_disabled(true) func _on_next_chapter_button_pressed(): self.chapter_id += 1 + ImageLib.change_theme(ImageLib.COLOR_THEMES[ImageLib.COLOR_THEMES.find(ImageLib.theme_to) + 1], LevelMenuCamera.MOVE_TIME) $UI/Title.text = LevelData.CHAP_NAMES[chapter_id]["name-en"] $UI/PreviousChapterButton.set_disabled(true) $UI/NextChapterButton.set_disabled(true) diff --git a/main.gd b/main.gd index 33b77d4..21b3f15 100644 --- a/main.gd +++ b/main.gd @@ -1,6 +1,9 @@ class_name Main extends Node +func _ready(): + ImageLib.init() + func _on_main_menu_enter_level(): $BGMPlayer.play() @@ -9,4 +12,4 @@ func _on_main_menu_enter_level(): func _on_bgm_player_finished(): $BGMPlayer.play() func set_victory(v: bool): - $DynamicBg.set_victory(v) + $UI/DynamicBg.set_victory(v) diff --git a/main.tscn b/main.tscn index f524bda..99276c8 100644 --- a/main.tscn +++ b/main.tscn @@ -1,27 +1,41 @@ -[gd_scene load_steps=6 format=3 uid="uid://c17fbsiogbgo1"] +[gd_scene load_steps=8 format=3 uid="uid://c17fbsiogbgo1"] [ext_resource type="PackedScene" uid="uid://c07co5p46apu7" path="res://objects/main_menu/main_menu.tscn" id="1_fk6j6"] [ext_resource type="Script" path="res://main.gd" id="1_nb6uf"] [ext_resource type="PackedScene" uid="uid://d3geq38s5fjc6" path="res://bg/dynamic_bg/dynamic_bg.tscn" id="2_8k4il"] +[ext_resource type="PackedScene" uid="uid://budvuitfjtjcd" path="res://scripts/image_lib/image_lib.tscn" id="2_771gm"] [ext_resource type="AudioStream" uid="uid://cr3nkhf0fejm5" path="res://levels/base_level/bgm.wav" id="3_n81it"] [ext_resource type="PackedScene" uid="uid://prht3u5pnjls" path="res://scripts/cursor_manager/cursor_manager.tscn" id="5_pqych"] +[ext_resource type="Material" uid="uid://rywrg5id25dr" path="res://shaders/main_shader.tres" id="6_tvi4r"] [node name="Main" type="Node"] script = ExtResource("1_nb6uf") -[node name="DynamicBg" parent="." instance=ExtResource("2_8k4il")] -offset_right = 0.0 -offset_bottom = 0.0 +[node name="ImageLib" parent="." instance=ExtResource("2_771gm")] [node name="MainMenu" parent="." instance=ExtResource("1_fk6j6")] -[node name="BGMPlayer" type="AudioStreamPlayer2D" parent="."] -position = Vector2(234, 150) +[node name="BGMPlayer" type="AudioStreamPlayer" parent="."] stream = ExtResource("3_n81it") volume_db = -4.685 -attenuation = 0.0001 [node name="CursorManager" parent="." instance=ExtResource("5_pqych")] -[connection signal="enter_level" from="MainMenu" to="." method="_on_main_menu_enter_level"] -[connection signal="finished" from="BGMPlayer" to="." method="_on_bgm_player_finished"] +[node name="UI" type="CanvasLayer" parent="."] +layer = -1 + +[node name="DynamicBg" parent="UI" instance=ExtResource("2_8k4il")] +offset_right = 0.0 +offset_bottom = 0.0 + +[node name="ScreenShader" type="CanvasLayer" parent="."] +layer = 100 + +[node name="ShaderRect" type="ColorRect" parent="ScreenShader"] +material = ExtResource("6_tvi4r") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 diff --git a/objects/card/card.gd b/objects/card/card.gd index c404e52..34ab833 100644 --- a/objects/card/card.gd +++ b/objects/card/card.gd @@ -111,7 +111,7 @@ func set_word(value: String) -> void: ImageLib.update_animation( $CardBackSprite, 1, 3, 1, "res://objects/card/card%d.png", ImageLib.get_palette_color_by_info("blue", "light"), - ImageLib.get_palette_color_by_name(new_color_name) + ImageLib.get_palette_color_by_info("blue", new_color_name) ) diff --git a/objects/card_base/card_base.gd b/objects/card_base/card_base.gd index 80806e6..72690f8 100644 --- a/objects/card_base/card_base.gd +++ b/objects/card_base/card_base.gd @@ -71,11 +71,9 @@ func set_word(e: String) -> void: ImageLib.update_animation( $CardBaseSprite, 1, 3, 1, "res://objects/card_base/card_base.png", ImageLib.get_palette_color_by_info("blue", "light"), - ImageLib.get_palette_color_by_name(new_color_name) + ImageLib.get_palette_color_by_info("blue", new_color_name) ) - $DisabledSprite.texture = ImageLib.replace_palette_colors_in_image($DisabledSprite.texture) - ## 获取字符。 func get_word() -> String: diff --git a/objects/styled_button/styled_button.gd b/objects/styled_button/styled_button.gd index e24f1ef..53dab9e 100644 --- a/objects/styled_button/styled_button.gd +++ b/objects/styled_button/styled_button.gd @@ -5,11 +5,3 @@ class_name StyledButton func _on_pressed(): $SFXButtonDown.play() - - -func _ready(): - for box_theme in ["normal", "hover", "presssed", "disabled", "focus"]: - var stylebox := get_theme_stylebox(box_theme) - if stylebox is StyleBoxTexture: - stylebox.texture = ImageLib.replace_palette_colors_in_image(stylebox.texture) - add_theme_stylebox_override(box_theme, stylebox) diff --git a/objects/table_cloth/table_cloth.gd b/objects/table_cloth/table_cloth.gd deleted file mode 100644 index 190ba02..0000000 --- a/objects/table_cloth/table_cloth.gd +++ /dev/null @@ -1,7 +0,0 @@ -extends Panel - - -func _ready(): - var stylebox := get_theme_stylebox("panel") - stylebox.texture = ImageLib.replace_palette_colors_in_image(stylebox.texture) - add_theme_stylebox_override("panel", stylebox) diff --git a/objects/table_cloth/table_cloth.tscn b/objects/table_cloth/table_cloth.tscn index fa269a1..7c0f2ee 100644 --- a/objects/table_cloth/table_cloth.tscn +++ b/objects/table_cloth/table_cloth.tscn @@ -1,8 +1,7 @@ -[gd_scene load_steps=6 format=3 uid="uid://7kd53bu4qorc"] +[gd_scene load_steps=5 format=3 uid="uid://7kd53bu4qorc"] [ext_resource type="Texture2D" uid="uid://1gcwvbyjejey" path="res://objects/table_cloth/table_cloth.png" id="1_8qui1"] [ext_resource type="Texture2D" uid="uid://cb5gytqlvjj2v" path="res://objects/table_cloth/golden_cloth.png" id="2_3edv5"] -[ext_resource type="Script" path="res://objects/table_cloth/table_cloth.gd" id="2_wo6il"] [sub_resource type="StyleBoxTexture" id="StyleBoxTexture_js8qc"] texture = ExtResource("1_8qui1") @@ -24,7 +23,6 @@ offset_right = 109.0 offset_bottom = 40.0 mouse_filter = 2 theme_override_styles/panel = SubResource("StyleBoxTexture_js8qc") -script = ExtResource("2_wo6il") [node name="GoldenCloth" type="Panel" parent="."] visible = false diff --git a/objects/word/word.gd b/objects/word/word.gd index 621e4e0..b4b9b8c 100644 --- a/objects/word/word.gd +++ b/objects/word/word.gd @@ -41,7 +41,7 @@ func set_text_id(value: int) -> void: ## 根据当前的 [member text_id] 更新动画。 func update_animation() -> void: - ImageLib.update_animation(self, text_id + 1, 3, STEP, "res://objects/word/sprites/sprite%d.png", Color.BLACK, self.color) + ImageLib.update_animation(self, text_id + 1, 3, STEP, "res://objects/word/sprites/sprite%d.png") @@ -63,8 +63,8 @@ func get_word() -> String: ## 设置字符颜色为 [param value] 并更新动画。 func set_color(value: Color) -> void: - color = value - update_animation() + self.color = value + self.material.set_shader_parameter("color", value) ## 设置是否为关卡通过状态。 @@ -83,3 +83,4 @@ func set_victory(v: bool) -> void: func _ready(): update_animation() + set_color(self.color) \ No newline at end of file diff --git a/objects/word/word.gdshader b/objects/word/word.gdshader new file mode 100644 index 0000000..088d704 --- /dev/null +++ b/objects/word/word.gdshader @@ -0,0 +1,8 @@ +shader_type canvas_item; + +uniform vec4 color : source_color; + +void fragment() { + COLOR = texture(TEXTURE, UV); + COLOR.rgb = color.rgb; +} \ No newline at end of file diff --git a/objects/word/word.tscn b/objects/word/word.tscn index 3678ecc..1b1f98a 100644 --- a/objects/word/word.tscn +++ b/objects/word/word.tscn @@ -1,7 +1,13 @@ -[gd_scene load_steps=4 format=3 uid="uid://cvx7wowcbfo0r"] +[gd_scene load_steps=6 format=3 uid="uid://cvx7wowcbfo0r"] [ext_resource type="Texture2D" uid="uid://cyyu6tsje4x72" path="res://objects/word/sprites/sprite3.png" id="1_ariam"] [ext_resource type="Script" path="res://objects/word/word.gd" id="1_lkxlh"] +[ext_resource type="Shader" path="res://objects/word/word.gdshader" id="1_n15m3"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_bx5kk"] +resource_local_to_scene = true +shader = ExtResource("1_n15m3") +shader_parameter/color = null [sub_resource type="SpriteFrames" id="SpriteFrames_3n85j"] animations = [{ @@ -15,5 +21,6 @@ animations = [{ }] [node name="Word" type="AnimatedSprite2D"] +material = SubResource("ShaderMaterial_bx5kk") sprite_frames = SubResource("SpriteFrames_3n85j") script = ExtResource("1_lkxlh") diff --git a/scripts/image_lib.gd b/scripts/image_lib/image_lib.gd similarity index 50% rename from scripts/image_lib.gd rename to scripts/image_lib/image_lib.gd index e4032c4..eb80ee0 100644 --- a/scripts/image_lib.gd +++ b/scripts/image_lib/image_lib.gd @@ -1,4 +1,4 @@ -class_name ImageLib +class_name ImageLib extends Node ## 不同主题下的配色模板。 @@ -26,18 +26,61 @@ const PALETTE = { "golden": Color("#f5df4d"), "black": Color.BLACK, "red": Color("#dd4132"), - } -} + }, + "yellow": { + "lightest": Color("#ffb938"), + "light": Color("#e69b22"), + "mid": Color("#ad6a45"), + "darkest": Color("#7a5e37"), + "golden": Color("#f5df4d"), + "black": Color.BLACK, + "red": Color("#dd4132"), + }, + "purple": { + "lightest": Color("#e29bfa"), + "light": Color("#ca7ef2"), + "mid": Color("#773bbf"), + "darkest": Color("#4e278c"), + + "golden": Color("#f5df4d"), + "black": Color.BLACK, + "red": Color("#dd4132"), + }, +} -const COLOR_THEMES := ["blue", "green"] ## 可选的配色主题 [code]theme[/code] 取值。 +const COLOR_THEMES := ["blue", "green", "yellow", "purple"] ## 可选的配色主题 [code]theme[/code] 取值。 const COLOR_NAMES := ["lightest", "light", "mid", "darkest", "golden", "black", "red"] ## 可选的颜色代号 [code]name[/code] 取值。 -static var theme := "blue" ## 当前主题。 +const MainShader := preload("res://shaders/main_shader.tres") + + + +static var theme_from := "blue" +static var theme_to := "blue" +static var wait_time := 0.0 +static var timer := 0.0 + + +static func init(): + MainShader.set_shader_parameter("blue_lightest", PALETTE["blue"]["lightest"]) + MainShader.set_shader_parameter("blue_light", PALETTE["blue"]["light"]) + MainShader.set_shader_parameter("blue_mid", PALETTE["blue"]["mid"]) + MainShader.set_shader_parameter("blue_darkest", PALETTE["blue"]["darkest"]) + MainShader.set_shader_parameter("theme_lightest", PALETTE["blue"]["lightest"]) + MainShader.set_shader_parameter("theme_light", PALETTE["blue"]["light"]) + MainShader.set_shader_parameter("theme_mid", PALETTE["blue"]["mid"]) + MainShader.set_shader_parameter("theme_darkest", PALETTE["blue"]["darkest"]) + +static func change_theme(new_theme: String, duration: float) -> void: + theme_from = theme_to + theme_to = new_theme + timer = 0.0 + wait_time = duration ## 获取 [param color] 的主题色 [code]theme[/code] 和代号 [code]name[/code]。 @@ -47,9 +90,9 @@ static var theme := "blue" ## 当前主题。 ## 否则返回 [code][theme, name][/code]。 static func get_color_info(color: Color) -> Variant: for col_theme in PALETTE.keys(): - for name in PALETTE[col_theme].keys(): - if color == PALETTE[col_theme][name]: - return [col_theme, name] + for col_name in PALETTE[col_theme].keys(): + if color == PALETTE[col_theme][col_name]: + return [col_theme, col_name] return null @@ -65,14 +108,14 @@ static func replace_color(image: Texture2D, old_color: Color, new_color: Color) ## 将 [param image] 中,在 [member PALETTE] 出现过的 [Color] 替换为当前配色主题下相同代号的 [Color]。 -static func replace_palette_colors_in_image(image: Texture2D) -> Texture2D: - var new_texture = image.get_image() - for x in range(new_texture.get_width()): - for y in range(new_texture.get_height()): - var info = get_color_info(new_texture.get_pixel(x, y)) - if info != null: - new_texture.set_pixel(x, y, PALETTE[theme][info[1]]) - return ImageTexture.create_from_image(new_texture) +# static func replace_palette_colors_in_image(image: Texture2D) -> Texture2D: +# var new_texture = image.get_image() +# for x in range(new_texture.get_width()): +# for y in range(new_texture.get_height()): +# var info = get_color_info(new_texture.get_pixel(x, y)) +# if info != null: +# new_texture.set_pixel(x, y, PALETTE[theme][info[1]]) +# return ImageTexture.create_from_image(new_texture) ## 为 [AnimatedSprite2D] [param sprite] 生成动画并播放。 @@ -98,7 +141,7 @@ static func update_animation( old_color: Color = Color.BLACK, new_color: Color = Color.BLACK ) -> void: - var animation_id = "%d_%d_%d_%s_%s_%s" % [start, n, step, path_pattern, theme, new_color.to_html()] + var animation_id = "%d_%d_%d_%s_%s" % [start, n, step, path_pattern, new_color.to_html()] if not sprite.sprite_frames.has_animation(animation_id): sprite.sprite_frames.add_animation(animation_id) for i in range(n): @@ -109,21 +152,37 @@ static func update_animation( image = load(path_pattern) if old_color != new_color: image = ImageLib.replace_color(image, old_color, new_color) - image = ImageLib.replace_palette_colors_in_image(image) sprite.sprite_frames.add_frame(animation_id, image) sprite.play(animation_id) -## 获取当前主题下,代号为 [param name] 的颜色值。 +## 获取当前主题下,代号为 [param col_name] 的颜色值。 ## [br][br] -## [param name] 的取值参见 [member COLOR_NAMES]。 -static func get_palette_color_by_name(name: String) -> Color: - return PALETTE[theme][name] +## [param col_name] 的取值参见 [member COLOR_NAMES]。 +static func get_palette_color_by_name(col_name: String) -> Color: + if timer >= wait_time: + return PALETTE[theme_to][col_name] + else: + return PALETTE[theme_from][col_name].lerp(PALETTE[theme_to][col_name], timer / wait_time) -## 获取主题 [param col_theme] 下,代号为 [param name] 的颜色值。 +## 获取主题 [param col_theme] 下,代号为 [param col_name] 的颜色值。 ## [br][br] -## [param col_theme] 和 [param name] 的取值参见 [member COLOR_THEMES] 和 [member COLOR_NAMES]。 -static func get_palette_color_by_info(col_theme: String, name: String) -> Color: - return PALETTE[col_theme][name] +## [param col_theme] 和 [param col_name] 的取值参见 [member COLOR_THEMES] 和 [member COLOR_NAMES]。 +static func get_palette_color_by_info(col_theme: String, col_name: String) -> Color: + return PALETTE[col_theme][col_name] + + +func _process(delta: float): + prints(timer, wait_time) + if timer < wait_time: + timer += delta + MainShader.set_shader_parameter("theme_lightest", ImageLib.get_palette_color_by_name("lightest")) + MainShader.set_shader_parameter("theme_light", ImageLib.get_palette_color_by_name("light")) + MainShader.set_shader_parameter("theme_mid", ImageLib.get_palette_color_by_name("mid")) + MainShader.set_shader_parameter("theme_darkest", ImageLib.get_palette_color_by_name("darkest")) + if timer >= wait_time: + timer = 0.0 + wait_time = -1.0 + ImageLib.theme_from = ImageLib.theme_to \ No newline at end of file diff --git a/scripts/image_lib/image_lib.tscn b/scripts/image_lib/image_lib.tscn new file mode 100644 index 0000000..ce8ce8b --- /dev/null +++ b/scripts/image_lib/image_lib.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://budvuitfjtjcd"] + +[ext_resource type="Script" path="res://scripts/image_lib/image_lib.gd" id="1_ye06g"] + +[node name="ImageLib" type="Node"] +script = ExtResource("1_ye06g") diff --git a/shaders/main_shader.gdshader b/shaders/main_shader.gdshader new file mode 100644 index 0000000..15cb664 --- /dev/null +++ b/shaders/main_shader.gdshader @@ -0,0 +1,26 @@ +shader_type canvas_item; + +uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; + +uniform vec4 blue_lightest = vec4(-1); +uniform vec4 blue_light = vec4(-1); +uniform vec4 blue_mid = vec4(-1); +uniform vec4 blue_darkest = vec4(-1); +uniform vec4 theme_lightest = vec4(-1); +uniform vec4 theme_light = vec4(-1); +uniform vec4 theme_mid = vec4(-1); +uniform vec4 theme_darkest = vec4(-1); + +void fragment() { + vec4 col = texture(SCREEN_TEXTURE, SCREEN_UV); + if (col == blue_lightest) + COLOR = theme_lightest; + else if (col == blue_light) + COLOR = theme_light; + else if (col == blue_mid) + COLOR = theme_mid; + else if (col == blue_darkest) + COLOR = theme_darkest; + else + COLOR = col; +} \ No newline at end of file diff --git a/shaders/main_shader.tres b/shaders/main_shader.tres new file mode 100644 index 0000000..759f993 --- /dev/null +++ b/shaders/main_shader.tres @@ -0,0 +1,14 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://rywrg5id25dr"] + +[ext_resource type="Shader" path="res://shaders/main_shader.gdshader" id="1_y6u4q"] + +[resource] +shader = ExtResource("1_y6u4q") +shader_parameter/blue_lightest = Vector4(-1, -1, -1, -1) +shader_parameter/blue_light = Vector4(-1, -1, -1, -1) +shader_parameter/blue_mid = Vector4(-1, -1, -1, -1) +shader_parameter/blue_darkest = Vector4(-1, -1, -1, -1) +shader_parameter/theme_lightest = Vector4(-1, -1, -1, -1) +shader_parameter/theme_light = Vector4(-1, -1, -1, -1) +shader_parameter/theme_mid = Vector4(-1, -1, -1, -1) +shader_parameter/theme_darkest = Vector4(-1, -1, -1, -1)