improve ui and bug fix

This commit is contained in:
2026-06-02 00:05:37 +02:00
parent 6c4f659fd0
commit 1037d1343d
13 changed files with 262 additions and 19 deletions

View File

@@ -10,6 +10,14 @@ signal on_photo_highlighted(teture: Texture)
signal on_enable_photo_mode_request
@warning_ignore("unused_signal")
signal on_disable_photo_mode_request
@warning_ignore("unused_signal")
signal on_photo_taken_started
@warning_ignore("unused_signal")
signal on_photo_taken_making
@warning_ignore("unused_signal")
signal on_photo_taken_finished
@warning_ignore("unused_signal")
signal on_photo_taken_prepare
const SAVE_PATH: String = "user://savegame.json"

View File

@@ -0,0 +1,19 @@
shader_type canvas_item;
// Dimensione del rettangolo vuoto al centro (in proporzione allo schermo)
// Esempio: vec2(0.6, 0.6) significa che il buco occuperà il 60% dello schermo.
// Puoi modificare questi valori direttamente dall'Inspector di Godot!
uniform vec2 hole_size = vec2(0.6, 0.6);
void fragment() {
// Calcoliamo la distanza dal centro esatto dello schermo (0.5, 0.5)
vec2 center = vec2(0.5, 0.5);
vec2 d = abs(UV - center);
vec2 half_size = hole_size / 2.0;
// Se il pixel si trova all'interno delle dimensioni del buco,
// impostiamo l'Alpha a 0.0 (rendendolo totalmente trasparente).
if (d.x < half_size.x && d.y < half_size.y) {
COLOR.a = 0.0;
}
}

View File

@@ -0,0 +1 @@
uid://dudbt51v33tt7

View File

@@ -0,0 +1,10 @@
shader_type canvas_item;
uniform sampler2D mask_texture;
void fragment() {
vec4 mask_color = texture(mask_texture, UV);
// Sottrae l'alpha della maschera dall'alpha del pannello.
// Dove la maschera è opaca (alpha = 1), il pannello diventerà trasparente (alpha = 0).
COLOR.a = max(COLOR.a - mask_color.a, 0.0);
}

View File

@@ -0,0 +1 @@
uid://44y4fig1hi4y

View File

@@ -9,11 +9,21 @@ enum Weather {RAIN, SNOW}
@onready var collectible_icon_button: Button = $%CollectibleIconButton
@onready var resume_button: Button = $GameMenuPanel/GameMenu/Pages/Page3/OptionMenu/VBoxContainer/ResumeButton
@onready var weather_row: HBoxContainer = $%WeatherRow
@onready var time_of_day_row: HBoxContainer = $%TimeOfDayRow
@onready var photo_mode_texture_panel: Panel = $%PhotoModeTexturePanel
@onready var photo_mode_texture_mask: TextureRect = $%PhotoModeTextureMask
@onready var photo_mode_black_screen: ColorRect = $%PhotoModeBlackScreen
@onready var collection_options: VBoxContainer = $%CollectionOptions
@onready var audio_player: Control = $%AudioPlayer
var cycle = false
func _ready() -> void:
GameState.on_enable_photo_mode_request.connect(_on_enable_photo_mode)
GameState.on_disable_photo_mode_request.connect(_on_disable_photo_mode)
GameState.on_photo_taken_started.connect(_on_photo_taken_started)
GameState.on_photo_taken_finished.connect(_on_photo_taken_finished)
GameState.on_photo_taken_prepare.connect(_on_photo_capture_prepare)
menu_icon_button.pressed.connect(_on_menu_icon_button_pressed)
photo_icon_button.pressed.connect(_on_photo_icon_button_pressed)
collectible_icon_button.pressed.connect(_on_collectible_icon_button_pressed)
@@ -36,8 +46,8 @@ func _on_collectible_icon_button_pressed() -> void:
TweenFX.fold_in(game_menu)
func _on_resume_button_pressed() -> void:
TweenFX.fold_out(game_menu)
await TweenFX.fold_out(game_menu).finished
var tween = TweenFX.fold_out(game_menu)
await tween.finished
game_menu_panel.hide()
GameState.resume_game()
@@ -47,10 +57,11 @@ func _on_time_of_day_row_on_option_changed(data: String) -> void:
UIEvents.time_option_item_changed.emit(0)
"Day":
UIEvents.time_option_item_changed.emit(1)
"Sunset":
UIEvents.time_option_item_changed.emit(2)
"Night":
UIEvents.time_option_item_changed.emit(3)
"Cycle":
cycle = !cycle
UIEvents.toggle_pause_daytime.emit(cycle)
_:
pass
@@ -80,11 +91,71 @@ func pick_random_weather() -> void:
weather_row.on_icon_pressed_changed(random_button)
func _on_enable_photo_mode() -> void:
hide_ui_for_photo_mode()
photo_mode_texture_mask.scale = Vector2(1,1)
photo_mode_texture_mask.show()
photo_mode_texture_mask.modulate.a = 0.0
photo_mode_texture_panel.show()
var mat = photo_mode_texture_panel.material as ShaderMaterial
if mat:
mat.set_shader_parameter("hole_size", Vector2(0.72, 0.0))
var tween = create_tween()
tween.tween_property(mat, "shader_parameter/hole_size", Vector2(0.72, 0.806), 0.3).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
var alpha_tween = create_tween()
alpha_tween.tween_property(photo_mode_texture_mask, "modulate:a", 1.0, 0.3).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
TweenFX.fold_in(photo_mode_texture_mask)
func _on_disable_photo_mode() -> void:
TweenFX.fold_out(photo_mode_texture_mask)
await TweenFX.fold_out(photo_mode_texture_mask).finished
show_ui_for_photo_mode()
var mat = photo_mode_texture_panel.material as ShaderMaterial
if mat:
var mat_tween = create_tween()
mat_tween.tween_property(mat, "shader_parameter/hole_size", Vector2(0.72, 0.0), 0.3).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_IN)
var alpha_tween = create_tween()
alpha_tween.tween_property(photo_mode_texture_mask, "modulate:a", 0.0, 0.3).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
var tween = TweenFX.fold_out(photo_mode_texture_mask)
await tween.finished
photo_mode_texture_panel.hide()
func _on_photo_capture_prepare() -> void:
photo_mode_texture_panel.hide()
photo_mode_texture_mask.hide()
func _on_photo_taken_started() -> void:
photo_mode_texture_panel.show()
photo_mode_texture_mask.show()
photo_mode_black_screen.scale = Vector2(1,1)
photo_mode_black_screen.show()
var tween = TweenFX.fade_in(photo_mode_black_screen, 0.06)
await tween.finished
await RenderingServer.frame_post_draw
GameState.on_photo_taken_making.emit()
func _on_photo_taken_finished() -> void:
var tween = TweenFX.fade_out(photo_mode_black_screen, 0.06)
await tween.finished
photo_mode_black_screen.hide()
func hide_ui_for_photo_mode() -> void:
TweenFX.fade_out(weather_row, 0.25)
TweenFX.fade_out(time_of_day_row, 0.25)
TweenFX.fade_out(menu_icon_button, 0.25)
TweenFX.fade_out(collection_options, 0.25)
TweenFX.fade_out(audio_player, 0.25)
func show_ui_for_photo_mode() -> void:
weather_row.show()
time_of_day_row.show()
menu_icon_button.show()
collection_options.show()
audio_player.show()
TweenFX.fade_in(weather_row, 0.25)
TweenFX.fade_in(time_of_day_row, 0.25)
TweenFX.fade_in(menu_icon_button, 0.25)
TweenFX.fade_in(collection_options, 0.25)
TweenFX.fade_in(audio_player, 0.25)

View File

@@ -7,7 +7,13 @@
[ext_resource type="PackedScene" uid="uid://cpeyt1dgrtglc" path="res://core/radio/radio.tscn" id="5_nevjt"]
[ext_resource type="AudioStream" uid="uid://70cc8she43re" path="res://docs/gyms/radio/lofi_01.ogg" id="6_kd244"]
[ext_resource type="PackedScene" uid="uid://dg4f3v0ukpmay" path="res://core/main_scene_ui/audio_player.tscn" id="7_lapqe"]
[ext_resource type="PackedScene" uid="uid://cifadwamy04ko" path="res://core/main_scene_ui/photo_taken.tscn" id="8_t1xop"]
[ext_resource type="Texture2D" uid="uid://dcsy5yawnlxhq" path="res://core/photo_mode/assets/reticolo.png" id="9_4cc8f"]
[ext_resource type="Shader" uid="uid://dudbt51v33tt7" path="res://core/main_scene_ui/center_hole.gdshader" id="10_shader"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_hole"]
shader = ExtResource("10_shader")
shader_parameter/hole_size = Vector2(0.72, 0.806)
[node name="MainSceneUi" type="Control" unique_id=1359391222]
process_mode = 3
@@ -30,6 +36,7 @@ offset_right = 160.0
grow_vertical = 0
[node name="TimeOfDayRow" parent="VBoxContainer" unique_id=1734127019 instance=ExtResource("2_4cc8f")]
unique_name_in_owner = true
layout_mode = 2
[node name="IconButton2" parent="VBoxContainer/TimeOfDayRow" index="1" unique_id=638856991]
@@ -39,10 +46,10 @@ data = "Sunrise"
data = "Day"
[node name="IconButton4" parent="VBoxContainer/TimeOfDayRow" index="3" unique_id=1375190490]
data = "Sunset"
data = "Night"
[node name="IconButton5" parent="VBoxContainer/TimeOfDayRow" index="4" unique_id=315412403]
data = "Night"
data = "Cycle"
[node name="ShowContainerTween" parent="VBoxContainer/TimeOfDayRow" index="5" unique_id=160227524]
tween_types = Array[String](["impact_land", "fade_in"])
@@ -93,6 +100,7 @@ offset_left = -160.0
grow_horizontal = 0
[node name="CollectionOptions" type="VBoxContainer" parent="." unique_id=542153805]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 6
anchor_left = 1.0
@@ -114,6 +122,7 @@ unique_name_in_owner = true
layout_mode = 2
[node name="AudioPlayer" parent="." unique_id=425192018 node_paths=PackedStringArray("radio") instance=ExtResource("7_lapqe")]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
@@ -142,9 +151,19 @@ grow_vertical = 2
unique_name_in_owner = true
layout_mode = 1
[node name="PhotoModeTextureMask" type="TextureRect" parent="." unique_id=1377788813]
[node name="PhotoModeTexturePanel" type="Panel" parent="." unique_id=901556197]
unique_name_in_owner = true
visible = false
material = SubResource("ShaderMaterial_hole")
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="PhotoModeTextureMask" type="TextureRect" parent="PhotoModeTexturePanel" unique_id=1377788813]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -153,6 +172,31 @@ grow_horizontal = 2
grow_vertical = 2
pivot_offset_ratio = Vector2(0.5, 0.5)
texture = ExtResource("9_4cc8f")
stretch_mode = 3
metadata/_edit_use_anchors_ = true
[node name="PhotoModeBlackScreen" type="ColorRect" parent="." unique_id=1928591477]
unique_name_in_owner = true
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 1)
[node name="PhotoTaken" parent="." unique_id=683693112 instance=ExtResource("8_t1xop")]
visible = false
layout_mode = 1
anchor_left = 0.465625
anchor_top = 0.4287037
anchor_right = 0.534375
anchor_bottom = 0.5712963
offset_right = 0.0
offset_bottom = 0.0
grow_horizontal = 2
grow_vertical = 2
[node name="Radio" parent="." unique_id=1234112225 instance=ExtResource("5_nevjt")]
playlist = Array[AudioStream]([ExtResource("6_kd244")])

View File

@@ -0,0 +1,26 @@
extends Control
@onready var photo_texture: TextureRect = $%PhotoTexture
func _ready() -> void:
GameState.on_photo_taken_prepare.connect(_hide_photo_taken)
GameState.on_photo_taken_finished.connect(_show_photo_taken)
CollectionManager.on_photo_saved.connect(_set_photo_taken)
func _hide_photo_taken() -> void:
hide()
func _set_photo_taken(file_path) -> void:
var image = Image.load_from_file(file_path)
if image:
var texture = ImageTexture.create_from_image(image)
photo_texture.texture = texture
func _show_photo_taken() -> void:
scale = Vector2(1,1)
modulate.a = 1.0
rotation_degrees = 0.0
show()
var tween = TweenFX.explode(self, 5, 3)
await tween.finished
hide()

View File

@@ -0,0 +1 @@
uid://dyye4efo503ih

View File

@@ -0,0 +1,48 @@
[gd_scene format=3 uid="uid://cifadwamy04ko"]
[ext_resource type="Script" uid="uid://dyye4efo503ih" path="res://core/main_scene_ui/photo_taken.gd" id="1_1n86s"]
[node name="PhotoTaken" type="Control" unique_id=683693112]
custom_minimum_size = Vector2(132, 154)
layout_mode = 3
anchor_right = 0.06875
anchor_bottom = 0.1425926
offset_right = -132.0
offset_bottom = -154.0
pivot_offset_ratio = Vector2(0.5, 0.5)
script = ExtResource("1_1n86s")
metadata/_edit_use_anchors_ = true
[node name="ColorRect" type="ColorRect" parent="." unique_id=1876357733]
custom_minimum_size = Vector2(132, 154)
layout_mode = 1
anchors_preset = -1
anchor_left = 0.465625
anchor_top = 0.4287037
anchor_right = 0.534375
anchor_bottom = 0.5712963
grow_horizontal = 2
grow_vertical = 2
pivot_offset_ratio = Vector2(0.5, 0.5)
mouse_filter = 2
metadata/_edit_use_anchors_ = true
[node name="MarginContainer" type="MarginContainer" parent="ColorRect" unique_id=405077013]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 14
theme_override_constants/margin_top = 15
theme_override_constants/margin_right = 14
theme_override_constants/margin_bottom = 50
[node name="PhotoTexture" type="TextureRect" parent="ColorRect/MarginContainer" unique_id=1754898569]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
mouse_filter = 2
expand_mode = 1
stretch_mode = 6

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -31,9 +31,10 @@ func get_all_collectibles() -> Array[CollectibleResource]:
func get_unlocked_collectible_ids() -> Array[StringName]:
return unlocked_collectibles_ids
func save_photo_to_disk_async() -> void:
await RenderingServer.frame_post_draw
var image = get_viewport().get_texture().get_image()
func save_photo_to_disk_async(image: Image) -> void:
if not image:
return
if not DirAccess.dir_exists_absolute("user://photos"):
DirAccess.make_dir_absolute("user://photos")

View File

@@ -21,9 +21,13 @@ var previous_camera: Camera3D
var initial_local_pos: Vector3
var initial_local_basis: Basis
var is_making_photo = false
var captured_image: Image
func _ready() -> void:
GameState.on_enable_photo_mode_request.connect(enable_photo_mode)
GameState.on_disable_photo_mode_request.connect(disable_photo_mode)
GameState.on_photo_taken_making.connect(take_photo_async)
initial_local_pos = position
initial_local_basis = basis
@@ -50,13 +54,23 @@ func _input(event: InputEvent) -> void:
if not is_active:
GameState.on_enable_photo_mode_request.emit()
else:
if not is_making_photo:
GameState.on_disable_photo_mode_request.emit()
if event is InputEventMouseMotion and is_active:
total_yaw -= event.relative.x * rotation_speed
if event.is_action_pressed("take_photo"):
take_photo_async()
if !is_active or is_making_photo:
return
is_making_photo = true
GameState.on_photo_taken_prepare.emit()
await RenderingServer.frame_post_draw
captured_image = get_viewport().get_texture().get_image()
GameState.on_photo_taken_started.emit()
func _process(delta: float) -> void:
if not is_active:
@@ -81,13 +95,10 @@ func _process(delta: float) -> void:
basis = rotated_basis.orthonormalized()
func take_photo_async() -> void:
if !is_active:
return
var targets = get_tree().get_nodes_in_group("collectible")
var space_state = get_world_3d().direct_space_state
await CollectionManager.save_photo_to_disk_async()
await CollectionManager.save_photo_to_disk_async(captured_image)
for target in targets:
if not target.collectible_data:
@@ -104,3 +115,5 @@ func take_photo_async() -> void:
CollectionManager.unlock_collectible(target.collectible_data.id)
GameState.save_game()
GameState.on_photo_taken_finished.emit()
is_making_photo = false