add code step 1
This commit is contained in:
parent
e4fb9933ad
commit
ac51d3031d
1
icon.svg
Normal file
1
icon.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>
|
After Width: | Height: | Size: 994 B |
64
log/logger/logs/v-demo-1.json
Normal file
64
log/logger/logs/v-demo-1.json
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"event_date": "12/22/2024",
|
||||||
|
"item_id": "876528753689",
|
||||||
|
"log_content": "* 完成动画导入功能:\n * 自动检测目录下文件,帧排序后,导入到: res://config/animation/player_sprite_frames.tres \n * 文件名 mapping 到动画 animation 名称\n * 取第一帧作动画\n * 镜像动画\n * 网格化检阅",
|
||||||
|
"tags": [
|
||||||
|
"2@code",
|
||||||
|
"3@art_tool",
|
||||||
|
"2@animation"
|
||||||
|
],
|
||||||
|
"update_date": "12/22/2024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event_date": "12/20/2024",
|
||||||
|
"item_id": "2546254798879",
|
||||||
|
"log_content": "* 游戏时间戳\n * 全局游戏时长记录\n * 当前存档时间状态:章节进度,游戏时长等\n* 场景管理器:发送消息浮窗\n* 事件系统:\n * 数据格式(四要素):\n * 时间(chapter_section,时间戳,周目状态等)\n * 地点(场景id,坐标)\n * 实体(实体id,状态)\n * 实体动作(action_id)\n * 流程:发送事件流程,消费事件流程\n* 存档:\n * 保存全局配置(如游戏总时长,周目数)\n * 分存档保存当前存档状态:时间、场景、实体\n* 组装实体:\n * 规格配置:进行中\n * 素材填充:进行中",
|
||||||
|
"tags": [
|
||||||
|
"2@code",
|
||||||
|
"2@design"
|
||||||
|
],
|
||||||
|
"update_date": "12/22/2024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event_date": "12/19/2024",
|
||||||
|
"item_id": "52643524662456",
|
||||||
|
"log_content": "* 角色移动状态机功能:静止/行走/奔跑/躺卧移动/上下爬行\n * 允许锁定移动/锁定奔跑,躺卧移动与上下爬行互斥\n* 规格化调整:\n * UI 规格化:物品HUD,对话浮窗\n * 场景规格化:层次背景,角色\n* 镜头 Marker :随玩家移动方向轻微偏移,优化视野细节",
|
||||||
|
"tags": [
|
||||||
|
"2@design",
|
||||||
|
"2@code",
|
||||||
|
"2@animation"
|
||||||
|
],
|
||||||
|
"update_date": "12/22/2024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event_date": "12/18/2024",
|
||||||
|
"item_id": "5423765786358",
|
||||||
|
"log_content": "确定资源类型,围绕规格化的资源\n基本工作流设计\n完善 HUD 功能",
|
||||||
|
"tags": [
|
||||||
|
"2@ui",
|
||||||
|
"2@design"
|
||||||
|
],
|
||||||
|
"update_date": "12/22/2024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event_date": "12/17/2024",
|
||||||
|
"item_id": "11242354",
|
||||||
|
"log_content": "加入基础的游戏背景、角色行走功能",
|
||||||
|
"tags": [
|
||||||
|
"2@code"
|
||||||
|
],
|
||||||
|
"update_date": "12/22/2024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"event_date": "12/16/2024",
|
||||||
|
"item_id": "17343458739570",
|
||||||
|
"log_content": "新建项目等",
|
||||||
|
"tags": [
|
||||||
|
"2@design"
|
||||||
|
],
|
||||||
|
"update_date": "12/22/2024"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
140
log/logger/project_log_panel.gd
Normal file
140
log/logger/project_log_panel.gd
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
extends CanvasLayer
|
||||||
|
|
||||||
|
class_name ProjectLogPanel
|
||||||
|
|
||||||
|
enum TAG_TYPE{VERSION=0,FIX=1,FEATURE=2,TOOL=3}
|
||||||
|
|
||||||
|
const TAG_TYPE_COLOR_DICT = {
|
||||||
|
TAG_TYPE.VERSION: Color.SKY_BLUE,
|
||||||
|
TAG_TYPE.FIX: Color.RED,
|
||||||
|
TAG_TYPE.FEATURE: Color.AQUAMARINE,
|
||||||
|
TAG_TYPE.TOOL: Color.ORCHID
|
||||||
|
}
|
||||||
|
|
||||||
|
const TAG_DICT = {
|
||||||
|
TAG_TYPE.VERSION:["demo","0.1","1.0"],
|
||||||
|
TAG_TYPE.FIX:["bugfix","uxfix"],
|
||||||
|
TAG_TYPE.FEATURE:["code","design","ui","audio","art","animation"],
|
||||||
|
TAG_TYPE.TOOL:["art_tool","log_tool","manage_tool"],
|
||||||
|
}
|
||||||
|
|
||||||
|
#const LOG_CONFIG_KEY_prefix = "log_panel_json_"
|
||||||
|
const LOG_DATA_DIR = "res://log/logger/logs/"
|
||||||
|
var log_files = []
|
||||||
|
var current_log_file
|
||||||
|
|
||||||
|
const IMAGE_DIR = ""
|
||||||
|
|
||||||
|
@onready var add_btn := %Add
|
||||||
|
@onready var save_btn := %Save
|
||||||
|
@onready var archives_btn := %Archives as MenuButton
|
||||||
|
@onready var archives_label := %ArchiveLabel as Label
|
||||||
|
@onready var log_items_container = %LogItemsContainer
|
||||||
|
|
||||||
|
const LOG_ITEM_GROUP = "log_item"
|
||||||
|
const LOG_ITEM_GROUP_MENBER = "log_item[{0}]"
|
||||||
|
|
||||||
|
var log_item_scene = preload("res://log/logger/project_log_panel_item.tscn")
|
||||||
|
|
||||||
|
var data = {"items":[]} as Dictionary
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
add_btn.pressed.connect(_on_add)
|
||||||
|
save_btn.pressed.connect(save_logs)
|
||||||
|
archives_btn.get_popup().id_pressed.connect(_on_archive_switch)
|
||||||
|
_load_archives()
|
||||||
|
_on_archive_switch(log_files.find("v-demo-mountwuwang.json"))
|
||||||
|
# var quat = Quaternion.from_euler(Vector3(deg_to_rad(10),0,deg_to_rad(10)))
|
||||||
|
# print(quat)
|
||||||
|
# quat = quat.normalized()
|
||||||
|
# print(quat)
|
||||||
|
# quat = Quaternion(Vector3(1,0,0),deg_to_rad(10)) * Quaternion(Vector3(0,0,1),deg_to_rad(10))
|
||||||
|
# print(quat)
|
||||||
|
# quat = quat.normalized()
|
||||||
|
# print(quat)
|
||||||
|
|
||||||
|
func _load_archives():
|
||||||
|
log_files = DirAccess.get_files_at(LOG_DATA_DIR) as PackedStringArray
|
||||||
|
if log_files.size() == 0:
|
||||||
|
printerr("_load_archives no file exists:",LOG_DATA_DIR)
|
||||||
|
for i in range(0,log_files.size()):
|
||||||
|
archives_btn.get_popup().add_item(log_files[i],i)
|
||||||
|
_on_archive_switch(0)
|
||||||
|
|
||||||
|
func _load_logs():
|
||||||
|
var path = _get_curr_path()
|
||||||
|
if !FileAccess.file_exists(path):
|
||||||
|
printerr("_load_logs no file exists:",path)
|
||||||
|
return
|
||||||
|
var json = ResourceLoader.load(path,"",ResourceLoader.CACHE_MODE_IGNORE)
|
||||||
|
#print("load data=",json.data)
|
||||||
|
print("loaded data")
|
||||||
|
data = json.data
|
||||||
|
if !data.has("items"):
|
||||||
|
data["items"] = []
|
||||||
|
_refresh_items()
|
||||||
|
|
||||||
|
func _get_curr_path():
|
||||||
|
return LOG_DATA_DIR + current_log_file
|
||||||
|
|
||||||
|
func _refresh_items():
|
||||||
|
var items = data["items"] as Array
|
||||||
|
get_tree().call_group(LOG_ITEM_GROUP, "queue_free")
|
||||||
|
for i in range(items.size()):
|
||||||
|
var item_instance = log_item_scene.instantiate() as Control
|
||||||
|
item_instance.add_to_group(LOG_ITEM_GROUP)
|
||||||
|
item_instance.add_to_group(LOG_ITEM_GROUP_MENBER.format([]))
|
||||||
|
item_instance.update.connect(_on_log_item_update.bind(i))
|
||||||
|
#item_instance.save.connect(_on_log_item_save.bind(i))
|
||||||
|
item_instance.remove.connect(_on_log_item_remove.bind(i))
|
||||||
|
log_items_container.add_child(item_instance)
|
||||||
|
if items[i] is Dictionary:
|
||||||
|
item_instance.load_item(items[i])
|
||||||
|
elif items[i] is String:
|
||||||
|
var item_dict = JSON.parse_string(items[i])
|
||||||
|
item_instance.load_item(item_dict)
|
||||||
|
else :
|
||||||
|
push_error("unknow type items[",i,"]=",items[i])
|
||||||
|
|
||||||
|
func save_logs():
|
||||||
|
var path = _get_curr_path()
|
||||||
|
if !FileAccess.file_exists(path):
|
||||||
|
printerr("save_logs no file exists:",path)
|
||||||
|
return
|
||||||
|
#print("save logs data=", data)
|
||||||
|
print("saved logs")
|
||||||
|
var file := FileAccess.open(path, FileAccess.WRITE_READ) as FileAccess
|
||||||
|
file.store_string(JSON.stringify(data, "\t"))
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
func _on_log_item_update(item:LogItem.ItemData, index:int):
|
||||||
|
var json = item.to_json_dict()
|
||||||
|
print("_on_log_item_update item=", json)
|
||||||
|
data["items"][index] = json
|
||||||
|
|
||||||
|
func _on_log_item_save(item:LogItem.ItemData, index:int):
|
||||||
|
var json = item.to_json_dict()
|
||||||
|
print("_on_log_item_save item=", json)
|
||||||
|
data["items"][index] = json
|
||||||
|
save_logs()
|
||||||
|
|
||||||
|
func _on_log_item_remove(index:int):
|
||||||
|
(data["items"] as Array).remove_at(index)
|
||||||
|
save_logs()
|
||||||
|
# reset index for each item
|
||||||
|
_refresh_items()
|
||||||
|
|
||||||
|
func _on_add():
|
||||||
|
(data["items"] as Array).push_front({})
|
||||||
|
save_logs()
|
||||||
|
# reset index for each item
|
||||||
|
_refresh_items()
|
||||||
|
|
||||||
|
func _on_archive_switch(id:int):
|
||||||
|
current_log_file = log_files[id]
|
||||||
|
archives_label.text = log_files[id]
|
||||||
|
_load_logs()
|
||||||
|
|
||||||
|
func _unhandled_input(event):
|
||||||
|
if event.is_action("save"):
|
||||||
|
save_logs()
|
119
log/logger/project_log_panel.tscn
Normal file
119
log/logger/project_log_panel.tscn
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://b3n06jtdpqy5y"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://log/logger/project_log_panel.gd" id="1_2rhk7"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bdy4u3e7rmo7f" path="res://ui/button/sound_button.tscn" id="2_71u5c"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dhvo15vyxpkja" path="res://log/logger/project_log_panel_item.tscn" id="4_1yhgi"]
|
||||||
|
|
||||||
|
[node name="ProjectLogPanel" type="CanvasLayer"]
|
||||||
|
script = ExtResource("1_2rhk7")
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
theme_override_constants/margin_left = 8
|
||||||
|
theme_override_constants/margin_top = 8
|
||||||
|
theme_override_constants/margin_right = 8
|
||||||
|
theme_override_constants/margin_bottom = 8
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/margin_left = 12
|
||||||
|
theme_override_constants/margin_top = 6
|
||||||
|
theme_override_constants/margin_right = 12
|
||||||
|
theme_override_constants/margin_bottom = 6
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 4
|
||||||
|
alignment = 2
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 4
|
||||||
|
theme_override_constants/margin_left = 12
|
||||||
|
theme_override_constants/margin_top = 6
|
||||||
|
theme_override_constants/margin_right = 12
|
||||||
|
theme_override_constants/margin_bottom = 6
|
||||||
|
|
||||||
|
[node name="Title" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
theme_override_colors/font_color = Color(0.670588, 0.952941, 0.972549, 1)
|
||||||
|
theme_override_colors/font_shadow_color = Color(0.180392, 0.180392, 0.180392, 1)
|
||||||
|
theme_override_colors/font_outline_color = Color(0.0156863, 0.258824, 0.341176, 1)
|
||||||
|
theme_override_constants/shadow_offset_x = 2
|
||||||
|
theme_override_constants/shadow_offset_y = 2
|
||||||
|
theme_override_constants/outline_size = 4
|
||||||
|
theme_override_constants/shadow_outline_size = 12
|
||||||
|
theme_override_font_sizes/font_size = 24
|
||||||
|
text = "Project Log"
|
||||||
|
|
||||||
|
[node name="Add" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer" instance=ExtResource("2_71u5c")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Add"
|
||||||
|
script = null
|
||||||
|
|
||||||
|
[node name="Save" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer" instance=ExtResource("2_71u5c")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Save"
|
||||||
|
script = null
|
||||||
|
|
||||||
|
[node name="Archives" type="MenuButton" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Archives"
|
||||||
|
flat = false
|
||||||
|
|
||||||
|
[node name="ArchiveLabel" type="Label" parent="MarginContainer/VBoxContainer/MarginContainer/HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="MarginContainer2" type="MarginContainer" parent="MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
theme_override_constants/margin_left = 8
|
||||||
|
theme_override_constants/margin_top = 8
|
||||||
|
theme_override_constants/margin_right = 8
|
||||||
|
theme_override_constants/margin_bottom = 8
|
||||||
|
|
||||||
|
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/VBoxContainer/MarginContainer2"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer/MarginContainer2/ScrollContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
theme_override_constants/margin_left = 4
|
||||||
|
theme_override_constants/margin_top = 4
|
||||||
|
theme_override_constants/margin_right = 8
|
||||||
|
theme_override_constants/margin_bottom = 4
|
||||||
|
|
||||||
|
[node name="LogItemsContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/MarginContainer2/ScrollContainer/MarginContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 0
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="LogItem" parent="MarginContainer/VBoxContainer/MarginContainer2/ScrollContainer/MarginContainer/LogItemsContainer" instance=ExtResource("4_1yhgi")]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="LogItem2" parent="MarginContainer/VBoxContainer/MarginContainer2/ScrollContainer/MarginContainer/LogItemsContainer" instance=ExtResource("4_1yhgi")]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
198
log/logger/project_log_panel_item.gd
Normal file
198
log/logger/project_log_panel_item.gd
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
extends HBoxContainer
|
||||||
|
|
||||||
|
class_name LogItem
|
||||||
|
|
||||||
|
#signal save(data:ItemData)
|
||||||
|
signal update(data: ItemData)
|
||||||
|
signal remove
|
||||||
|
|
||||||
|
const TAG_BTN_GROUP_PREFIX = "tag_btn"
|
||||||
|
|
||||||
|
@onready var log_content := %LogContent as TextEdit
|
||||||
|
@onready var event_date := %EventDate as Label
|
||||||
|
#@onready var update_date := %LogUpdateDate as Label
|
||||||
|
@onready var tags_container := %TagsContainer as GridContainer
|
||||||
|
@onready var add_tag_btn := %AddTag as MenuButton
|
||||||
|
@onready var reload_btn = %Reload
|
||||||
|
@onready var save_btn = %Save
|
||||||
|
@onready var delete_btn = %Delete
|
||||||
|
|
||||||
|
var original_data := ItemData.new()
|
||||||
|
var data: ItemData = original_data
|
||||||
|
|
||||||
|
|
||||||
|
class ItemData:
|
||||||
|
var item_id := _generate_random_id()
|
||||||
|
var log_content := "":
|
||||||
|
set(new_val):
|
||||||
|
if new_val != log_content:
|
||||||
|
update_date = _get_current_time()
|
||||||
|
log_content = new_val
|
||||||
|
var tags := []:
|
||||||
|
set(new_val):
|
||||||
|
update_date = _get_current_time()
|
||||||
|
tags = new_val
|
||||||
|
var event_date := _get_current_time()
|
||||||
|
var update_date := _get_current_time()
|
||||||
|
|
||||||
|
func _generate_random_id() -> String:
|
||||||
|
# float time
|
||||||
|
var timestamp := Time.get_unix_time_from_system()
|
||||||
|
return str(int(timestamp * 10000 + randi_range(0, 10000)))
|
||||||
|
|
||||||
|
func _get_current_time() -> String:
|
||||||
|
# Returns the current date as a dictionary of keys: year, month, day, and weekday.
|
||||||
|
var dict = Time.get_date_dict_from_system()
|
||||||
|
return str(dict["month"]) + "/" + str(dict["day"]) + "/" + str(dict["year"])
|
||||||
|
|
||||||
|
func duplicate() -> ItemData:
|
||||||
|
var item := ItemData.new()
|
||||||
|
item.item_id = item_id
|
||||||
|
item.log_content = log_content
|
||||||
|
item.tags = tags.duplicate()
|
||||||
|
item.event_date = event_date
|
||||||
|
item.update_date = update_date
|
||||||
|
return item
|
||||||
|
|
||||||
|
func to_json_dict() -> Dictionary:
|
||||||
|
# JSON.stringify(self) doesn't work
|
||||||
|
return {
|
||||||
|
"item_id": item_id,
|
||||||
|
"log_content": log_content,
|
||||||
|
"tags": tags,
|
||||||
|
"event_date": event_date,
|
||||||
|
"update_date": update_date,
|
||||||
|
}
|
||||||
|
|
||||||
|
static func parse(data: Dictionary) -> ItemData:
|
||||||
|
var item := ItemData.new()
|
||||||
|
if data.has("item_id"):
|
||||||
|
item.item_id = data["item_id"]
|
||||||
|
if data.has("tags"):
|
||||||
|
item.tags = data["tags"]
|
||||||
|
if data.has("log_content"):
|
||||||
|
item.log_content = data["log_content"]
|
||||||
|
if data.has("event_date"):
|
||||||
|
item.event_date = data["event_date"]
|
||||||
|
if data.has("update_date"):
|
||||||
|
item.update_date = data["update_date"]
|
||||||
|
return item
|
||||||
|
|
||||||
|
|
||||||
|
# {id:{"btn":btn,"key":key,"name":name,"id":id}}
|
||||||
|
static var tag_btns = {}
|
||||||
|
static var tag_key_to_id_map = {}
|
||||||
|
|
||||||
|
static var tag_shadow_color = Color.html("1b1b1b")
|
||||||
|
static var tag_shadow_outline_size = 1
|
||||||
|
|
||||||
|
|
||||||
|
# id->key
|
||||||
|
var current_tags = {}
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
_load_tag_popup()
|
||||||
|
reload_btn.pressed.connect(_on_reload_pressed)
|
||||||
|
#save_btn.pressed.connect(_save_item)
|
||||||
|
delete_btn.pressed.connect(_remove_signal)
|
||||||
|
log_content.text_changed.connect(_on_log_content_changed)
|
||||||
|
call_deferred("_update_signal")
|
||||||
|
#load_item(original_data)
|
||||||
|
|
||||||
|
|
||||||
|
static func _static_init():
|
||||||
|
var tag_id := 0
|
||||||
|
for tag_type in ProjectLogPanel.TAG_TYPE.values():
|
||||||
|
var tag_color = ProjectLogPanel.TAG_TYPE_COLOR_DICT[tag_type]
|
||||||
|
for tag in ProjectLogPanel.TAG_DICT[tag_type]:
|
||||||
|
var tag_btn = Button.new() as Button
|
||||||
|
tag_btn.add_theme_color_override("font_color", tag_color)
|
||||||
|
tag_btn.add_theme_color_override("font_shadow_color", tag_shadow_color)
|
||||||
|
tag_btn.add_theme_constant_override("shadow_outline_size", tag_shadow_outline_size)
|
||||||
|
tag_btn.text = tag
|
||||||
|
var tag_key = _get_tag_key(tag_type, tag)
|
||||||
|
tag_btns[tag_id] = {"btn": tag_btn, "id": tag_id, "name": tag, "key": tag_key}
|
||||||
|
tag_key_to_id_map[tag_key] = tag_id
|
||||||
|
tag_id += 1
|
||||||
|
|
||||||
|
|
||||||
|
static func _get_tag_key(tag_type: ProjectLogPanel.TAG_TYPE, tag: String):
|
||||||
|
return str(tag_type) + "@" + tag
|
||||||
|
|
||||||
|
|
||||||
|
func _load_tag_popup():
|
||||||
|
var popup = add_tag_btn.get_popup() as PopupMenu
|
||||||
|
for btn_dict in tag_btns.values():
|
||||||
|
popup.add_item(btn_dict["name"], btn_dict["id"])
|
||||||
|
popup.id_pressed.connect(_on_popup_menu_pressed)
|
||||||
|
|
||||||
|
|
||||||
|
func _reload_tag_btns():
|
||||||
|
var btn_group = TAG_BTN_GROUP_PREFIX + data.item_id
|
||||||
|
get_tree().call_group(btn_group, "queue_free")
|
||||||
|
current_tags.clear()
|
||||||
|
for tag_key in data["tags"]:
|
||||||
|
if !tag_key_to_id_map.has(tag_key):
|
||||||
|
push_error("tag_key has been removed!! tag_key=", tag_key)
|
||||||
|
continue
|
||||||
|
var tag_id = tag_key_to_id_map[tag_key]
|
||||||
|
current_tags[tag_id] = tag_key
|
||||||
|
var btn = (tag_btns[tag_id]["btn"] as Button).duplicate()
|
||||||
|
btn.pressed.connect(_on_tag_btn_pressed.bind(btn, tag_id))
|
||||||
|
btn.add_to_group(btn_group)
|
||||||
|
tags_container.add_child(btn)
|
||||||
|
|
||||||
|
|
||||||
|
func load_item(new_data: Dictionary):
|
||||||
|
if new_data.keys().size() != 0:
|
||||||
|
original_data = ItemData.parse(new_data)
|
||||||
|
_reload_original_data()
|
||||||
|
|
||||||
|
|
||||||
|
func _reload_original_data():
|
||||||
|
data = original_data.duplicate()
|
||||||
|
#print("_load_item_data data=", data)
|
||||||
|
log_content.text = data.log_content
|
||||||
|
event_date.text = data.event_date
|
||||||
|
#update_date.text = data["update_date"]
|
||||||
|
_reload_tag_btns()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_popup_menu_pressed(id: int):
|
||||||
|
#{"btn":btn,"key":key,"name":name,"id":id}
|
||||||
|
if !current_tags.has(id):
|
||||||
|
current_tags[id] = tag_btns[id]["key"]
|
||||||
|
data.tags = current_tags.values()
|
||||||
|
_update_signal()
|
||||||
|
#_save_item()
|
||||||
|
_reload_tag_btns()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_log_content_changed():
|
||||||
|
data["log_content"] = log_content.text
|
||||||
|
_update_signal()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_tag_btn_pressed(btn: Control, id: int):
|
||||||
|
current_tags.erase(id)
|
||||||
|
btn.queue_free()
|
||||||
|
data.tags = current_tags.values()
|
||||||
|
_update_signal()
|
||||||
|
#_save_item()
|
||||||
|
|
||||||
|
|
||||||
|
#func _save_item():
|
||||||
|
#save.emit(data)
|
||||||
|
|
||||||
|
|
||||||
|
func _update_signal():
|
||||||
|
update.emit(data)
|
||||||
|
|
||||||
|
|
||||||
|
func _remove_signal():
|
||||||
|
remove.emit()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_reload_pressed():
|
||||||
|
_reload_original_data()
|
||||||
|
_update_signal()
|
86
log/logger/project_log_panel_item.tscn
Normal file
86
log/logger/project_log_panel_item.tscn
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://dhvo15vyxpkja"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://log/logger/project_log_panel_item.gd" id="1_gn7ev"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bdy4u3e7rmo7f" path="res://ui/button/sound_button.tscn" id="2_wb6pu"]
|
||||||
|
|
||||||
|
[node name="LogItem" type="HBoxContainer"]
|
||||||
|
anchors_preset = 14
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_top = -4.0
|
||||||
|
offset_bottom = 4.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_gn7ev")
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="LogContent" type="TextEdit" parent="MarginContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "123"
|
||||||
|
wrap_mode = 1
|
||||||
|
scroll_fit_content_height = true
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="TagsContainer" type="GridContainer" parent="HBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
columns = 2
|
||||||
|
|
||||||
|
[node name="AddTag" type="MenuButton" parent="HBoxContainer/TagsContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Tags"
|
||||||
|
|
||||||
|
[node name="VBoxContainer2" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="EventDate" type="Label" parent="VBoxContainer2"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_colors/font_color = Color(0.929412, 0.929412, 0.929412, 1)
|
||||||
|
theme_override_colors/font_shadow_color = Color(0.105882, 0.105882, 0.105882, 1)
|
||||||
|
theme_override_constants/shadow_offset_x = 1
|
||||||
|
theme_override_constants/shadow_offset_y = 1
|
||||||
|
theme_override_constants/shadow_outline_size = 4
|
||||||
|
text = "01/01/24"
|
||||||
|
|
||||||
|
[node name="LogUpdateDate" type="Label" parent="VBoxContainer2"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
text = "01/01/24"
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Reload" parent="VBoxContainer2/HBoxContainer" instance=ExtResource("2_wb6pu")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Reload"
|
||||||
|
script = null
|
||||||
|
|
||||||
|
[node name="Save" parent="VBoxContainer2/HBoxContainer" instance=ExtResource("2_wb6pu")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Save"
|
||||||
|
script = null
|
||||||
|
|
||||||
|
[node name="Delete" parent="VBoxContainer2/HBoxContainer" instance=ExtResource("2_wb6pu")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
text = "Delete"
|
||||||
|
script = null
|
125
manager/archive_manager/archive_manager.gd
Normal file
125
manager/archive_manager/archive_manager.gd
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
@export var user_archive_root_dir := "user://archive/" # must end with "/"
|
||||||
|
@export var save_dir_prefix := "save"
|
||||||
|
|
||||||
|
var accessible := false
|
||||||
|
var archives: Array[int] # archive id list in ascending order
|
||||||
|
|
||||||
|
var managers = {
|
||||||
|
"TimeManager": TimeManager,
|
||||||
|
"EntityManager": EntityManager,
|
||||||
|
"SceneManager": SceneManager,
|
||||||
|
"InputManager": InputManager,
|
||||||
|
# "ArchiveManager" : ArchiveManager, #self
|
||||||
|
# "AudioManager" : AudioManager,
|
||||||
|
# "EventManager" : EventManager,
|
||||||
|
# "CameraManager" : CameraManager,
|
||||||
|
# "DialogManager" : DialogManager,
|
||||||
|
# "CgManager": CgManager,
|
||||||
|
}
|
||||||
|
|
||||||
|
var autosave_timer := Timer.new()
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
accessible = _check_archive_dirs()
|
||||||
|
if !accessible:
|
||||||
|
return
|
||||||
|
# _open_log_file()
|
||||||
|
add_child(autosave_timer)
|
||||||
|
autosave_timer.wait_time = GlobalConfigManager.config.auto_save_seconds
|
||||||
|
autosave_timer.one_shot = false
|
||||||
|
autosave_timer.timeout.connect(_try_auto_save)
|
||||||
|
autosave_timer.stop()
|
||||||
|
GlobalConfigManager.config.current_selected_save_changed.connect(_check_autosave_options)
|
||||||
|
GlobalConfigManager.config.auto_save_seconds_changed.connect(_check_autosave_options)
|
||||||
|
load_all()
|
||||||
|
SceneManager.pop_notification("预加载完成")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func _check_autosave_options():
|
||||||
|
if (
|
||||||
|
GlobalConfigManager.config.auto_save_seconds > 5
|
||||||
|
and GlobalConfigManager.config.current_selected_save >= 0
|
||||||
|
):
|
||||||
|
autosave_timer.start()
|
||||||
|
else:
|
||||||
|
autosave_timer.stop()
|
||||||
|
|
||||||
|
|
||||||
|
func _try_auto_save():
|
||||||
|
if (
|
||||||
|
GlobalConfigManager.config.auto_save_seconds > 5
|
||||||
|
and GlobalConfigManager.config.current_selected_save >= 0
|
||||||
|
):
|
||||||
|
save_all()
|
||||||
|
SceneManager.pop_notification("自动保存成功")
|
||||||
|
|
||||||
|
|
||||||
|
func _check_archive_dirs() -> bool:
|
||||||
|
# Check if the archive directory is accessible
|
||||||
|
if !DirAccess.dir_exists_absolute(user_archive_root_dir):
|
||||||
|
DirAccess.make_dir_recursive_absolute(user_archive_root_dir)
|
||||||
|
print("Create archive directory:", user_archive_root_dir)
|
||||||
|
var archive_dir_access = DirAccess.open(user_archive_root_dir)
|
||||||
|
if !archive_dir_access:
|
||||||
|
printerr("Archive directory is not accessible")
|
||||||
|
# TODO pop up a dialog to inform the user
|
||||||
|
return false
|
||||||
|
var files = archive_dir_access.get_files()
|
||||||
|
# get archive number
|
||||||
|
for file in files:
|
||||||
|
if file.begins_with(save_dir_prefix):
|
||||||
|
var id_str = file.substr(save_dir_prefix.length())
|
||||||
|
var id = int(id_str)
|
||||||
|
archives.append(id)
|
||||||
|
archives.sort()
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func save_all() -> void:
|
||||||
|
# save config
|
||||||
|
var config = GlobalConfigManager.config
|
||||||
|
var path = user_archive_root_dir + "config" + GlobalConfig.RES_FILE_FORMAT
|
||||||
|
ResourceSaver.save(config, path)
|
||||||
|
if not accessible or GlobalConfigManager.config.current_selected_save == -1:
|
||||||
|
return
|
||||||
|
# Save all managers by the current selected save
|
||||||
|
for manager in managers:
|
||||||
|
# .tres
|
||||||
|
var res = managers[manager].get_data_res()
|
||||||
|
if !res:
|
||||||
|
continue
|
||||||
|
# save to file
|
||||||
|
path = (
|
||||||
|
user_archive_root_dir
|
||||||
|
+ str(config.current_selected_save)
|
||||||
|
+ "/"
|
||||||
|
+ manager
|
||||||
|
+ GlobalConfig.RES_FILE_FORMAT
|
||||||
|
)
|
||||||
|
ResourceSaver.save(res, path)
|
||||||
|
|
||||||
|
|
||||||
|
func load_all() -> void:
|
||||||
|
_check_archive_dirs()
|
||||||
|
# load config
|
||||||
|
var path = user_archive_root_dir + "config" + GlobalConfig.RES_FILE_FORMAT
|
||||||
|
var config
|
||||||
|
if FileAccess.file_exists(path):
|
||||||
|
config = ResourceLoader.load(path)
|
||||||
|
GlobalConfigManager.load_data_res(config)
|
||||||
|
else:
|
||||||
|
config = GlobalConfigManager.config
|
||||||
|
# save config
|
||||||
|
ResourceSaver.save(config, path)
|
||||||
|
if not accessible or config.current_selected_save == -1:
|
||||||
|
return
|
||||||
|
# Load managers by the current selected save
|
||||||
|
path = user_archive_root_dir + save_dir_prefix + str(config.current_selected_save) + "/"
|
||||||
|
for manager in managers:
|
||||||
|
var manager_path = path + manager + GlobalConfig.RES_FILE_FORMAT
|
||||||
|
if FileAccess.file_exists(manager_path):
|
||||||
|
var res = ResourceLoader.load(manager_path)
|
||||||
|
managers[manager].load_data_res(res)
|
1
manager/assemble/asset_metadata.gd
Normal file
1
manager/assemble/asset_metadata.gd
Normal file
@ -0,0 +1 @@
|
|||||||
|
class_name AssetMetadata extends Resource
|
11
manager/assemble/dialog/dialog_manager.gd
Normal file
11
manager/assemble/dialog/dialog_manager.gd
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
11
manager/assemble/entity/entity.gd
Normal file
11
manager/assemble/entity/entity.gd
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
class_name AssetMetadata extends Resource
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
18
manager/assemble/entity/entity_manager.gd
Normal file
18
manager/assemble/entity/entity_manager.gd
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
|
func get_data_res() -> Resource:
|
||||||
|
return null
|
||||||
|
|
||||||
|
|
||||||
|
func load_data_res(data: Resource) -> void:
|
||||||
|
pass
|
15
manager/assemble/scene/scene_manager.gd
Normal file
15
manager/assemble/scene/scene_manager.gd
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
func pop_notification(msg: String, number := 1) -> void:
|
||||||
|
var notification_node = get_node_or_null("/root/Main/UILayer/Notification")
|
||||||
|
if notification_node:
|
||||||
|
notification_node.show_notification(msg, number)
|
||||||
|
else:
|
||||||
|
printerr("Notification node not found")
|
||||||
|
|
||||||
|
func get_data_res() -> Resource:
|
||||||
|
return null
|
||||||
|
|
||||||
|
|
||||||
|
func load_data_res(data: Resource) -> void:
|
||||||
|
pass
|
11
manager/audio_manager/audio_manager.gd
Normal file
11
manager/audio_manager/audio_manager.gd
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
11
manager/camera_manager/camera_manager.gd
Normal file
11
manager/camera_manager/camera_manager.gd
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
11
manager/cg_manager/cg_manager.gd
Normal file
11
manager/cg_manager/cg_manager.gd
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
34
manager/config_manager/global_config.gd
Normal file
34
manager/config_manager/global_config.gd
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
class_name GlobalConfig extends Resource
|
||||||
|
|
||||||
|
# .res would be binary encoded, .tres is text encoded
|
||||||
|
const RES_FILE_FORMAT = ".tres"
|
||||||
|
|
||||||
|
const CONFIG_FILE_NAME = "config"
|
||||||
|
|
||||||
|
const DEBUG = true
|
||||||
|
#const DEBUG = false
|
||||||
|
|
||||||
|
const CANVAS_LAYER_VIGNETTE = 1000
|
||||||
|
const CANVAS_LAYER_PROP_INSPECTOR = 100
|
||||||
|
const CANVAS_LAYER_UI = 99
|
||||||
|
const CANVAS_LAYER_FG = 50
|
||||||
|
const CANVAS_LAYER_BG = -100
|
||||||
|
|
||||||
|
const COLOR_BOARDER = Color.BLACK
|
||||||
|
|
||||||
|
const _ART_RESOURCE_BASE_DIR = "res://asset/art/"
|
||||||
|
|
||||||
|
signal current_selected_save_changed
|
||||||
|
signal auto_save_seconds_changed
|
||||||
|
|
||||||
|
# 注意:编辑与新增属性时,需要同时编辑 GlobalConfigManager.gd 中的 load_data_res 方法
|
||||||
|
@export var game_total_seconds := 0 # 游戏总时长
|
||||||
|
@export var game_rounds := 1 # 当前周目数
|
||||||
|
@export var current_selected_save := -1: # 当前选定存档 id, -1 means no save selected
|
||||||
|
set(val):
|
||||||
|
current_selected_save = val
|
||||||
|
current_selected_save_changed.emit()
|
||||||
|
@export var auto_save_seconds := 60:
|
||||||
|
set(val):
|
||||||
|
auto_save_seconds = val
|
||||||
|
auto_save_seconds_changed.emit()
|
15
manager/config_manager/global_config_manager.gd
Normal file
15
manager/config_manager/global_config_manager.gd
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
var config = GlobalConfig.new()
|
||||||
|
|
||||||
|
|
||||||
|
func get_data_res() -> Resource:
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
func load_data_res(data: Resource) -> void:
|
||||||
|
var new_config = data as GlobalConfig
|
||||||
|
config.game_total_seconds = new_config.game_total_seconds
|
||||||
|
config.game_rounds = new_config.game_rounds
|
||||||
|
config.current_selected_save = new_config.current_selected_save
|
||||||
|
config.auto_save_seconds = new_config.auto_save_seconds
|
31
manager/event_manager/event_manager.gd
Normal file
31
manager/event_manager/event_manager.gd
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
# 事件注册表
|
||||||
|
# { entity: [MatcherConsumer] }
|
||||||
|
var _event_registry: Dictionary = {}
|
||||||
|
|
||||||
|
class MatcherConsumer extends RefCounted:
|
||||||
|
var _matcher: GameEventMatcher
|
||||||
|
var _consumer: Callable
|
||||||
|
|
||||||
|
func _init(matcher: GameEventMatcher, consumer: Callable) -> void:
|
||||||
|
self._matcher = matcher
|
||||||
|
self._consumer = consumer
|
||||||
|
|
||||||
|
# 注册事件
|
||||||
|
func register_event_matcher(event_matcher: GameEventMatcher, consumer: Callable) -> void:
|
||||||
|
if !event_matcher.entity:
|
||||||
|
return
|
||||||
|
var matcher_consumer = MatcherConsumer.new(event_matcher, consumer)
|
||||||
|
if event_matcher.entity not in _event_registry:
|
||||||
|
_event_registry[event_matcher.entity] = []
|
||||||
|
_event_registry[event_matcher.entity].append(matcher_consumer)
|
||||||
|
|
||||||
|
# 触发事件
|
||||||
|
func trigger_event(event: GameEvent) -> void:
|
||||||
|
if event.entity not in _event_registry:
|
||||||
|
return
|
||||||
|
for matcher_consumer in _event_registry[event.entity]:
|
||||||
|
# matcher_consumer = matcher_consumer as MatcherConsumer
|
||||||
|
if matcher_consumer._matcher.match(event):
|
||||||
|
matcher_consumer._consumer.call(event)
|
19
manager/event_manager/game_event.gd
Normal file
19
manager/event_manager/game_event.gd
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
class_name GameEvent extends Resource
|
||||||
|
|
||||||
|
# * 事件&剧情管理器: player / release / debug 事件,触发者:玩家/系统(系统触发意味着进入 CG)
|
||||||
|
# * 事件定义:「通变之谓事」
|
||||||
|
# * 事件发送机制:玩家进行特定操作后,发送事件进度(开始(注意到),尝试&进度,完成:成功or失败)
|
||||||
|
# * 发送内容
|
||||||
|
# * 时间点:玩家现实时间(系统时间),游戏时长(时间戳),章节剧情时间点(事件编号)
|
||||||
|
# * 地点:场景编号,位置坐标
|
||||||
|
# * 实体:道具/NPC/部署点
|
||||||
|
# * 激发器类型:地图区域(手动部署) / 玩家特定操作(自动发送)/ 实体信号(监听玩家特定操作/状态变化)
|
||||||
|
# * 事件订阅机制:订阅开始/进度/成功/失败,触发特定响应
|
||||||
|
# * 消费器能力:执行 CG(锁定/无锁定,剧本/特效) / 执行实体变化脚本(赠送/消耗/状态变化)
|
||||||
|
# * 保存与加载
|
||||||
|
@export var event_id: int
|
||||||
|
@export var packed_time: PackedTime
|
||||||
|
@export var scene: String
|
||||||
|
@export var scene_position: Vector2
|
||||||
|
@export var entity: String
|
||||||
|
@export var entity_action: String
|
43
manager/event_manager/game_event_matcher.gd
Normal file
43
manager/event_manager/game_event_matcher.gd
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
class_name GameEventMatcher extends Resource
|
||||||
|
|
||||||
|
# match event under certain conditions
|
||||||
|
|
||||||
|
# can't be empty
|
||||||
|
@export var entity: String
|
||||||
|
# empty means any action
|
||||||
|
@export var entity_actions: Array[String]
|
||||||
|
# empty means any scene
|
||||||
|
@export var scenes: Array[String]
|
||||||
|
# regex matcher, "[chapter]_[section]", * means any
|
||||||
|
# e.g. 3_* means any section in chapter 3
|
||||||
|
# empty means any chapter_section
|
||||||
|
@export var chapter_section: Array[String]
|
||||||
|
|
||||||
|
# check if the event matches the conditions
|
||||||
|
func match(event: GameEvent) -> bool:
|
||||||
|
if !entity or entity != event.entity:
|
||||||
|
return false
|
||||||
|
if entity_actions.size() > 0 and !entity_actions.has(event.entity_action):
|
||||||
|
return false
|
||||||
|
if scenes.size() > 0 and !scenes.has(event.scene):
|
||||||
|
return false
|
||||||
|
if chapter_section.size() > 0:
|
||||||
|
var chapter := str(event.packed_time.chapter)
|
||||||
|
var section := str(event.packed_time.section)
|
||||||
|
var matched := false
|
||||||
|
for chapter_section_matcher in chapter_section:
|
||||||
|
# regex match
|
||||||
|
var parts = chapter_section_matcher.split("_")
|
||||||
|
if parts.size() != 2:
|
||||||
|
continue
|
||||||
|
var chapter_matcher = parts[0]
|
||||||
|
var section_matcher = parts[1]
|
||||||
|
if chapter_matcher == "*" or chapter_matcher == chapter:
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
if section_matcher == "*" or section_matcher == section:
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
if !matched:
|
||||||
|
return false
|
||||||
|
return true
|
19
manager/input/input_manager.gd
Normal file
19
manager/input/input_manager.gd
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
func get_data_res() -> Resource:
|
||||||
|
return null
|
||||||
|
|
||||||
|
|
||||||
|
func load_data_res(data: Resource) -> void:
|
||||||
|
pass
|
12
manager/time_manager/packed_time.gd
Normal file
12
manager/time_manager/packed_time.gd
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
class_name PackedTime extends Resource
|
||||||
|
|
||||||
|
# 系统时间,游戏时长,章节时间点
|
||||||
|
|
||||||
|
@export var game_archive_id := 0
|
||||||
|
@export var game_rounds := 0
|
||||||
|
@export var timestamp := "2024-12-20 08:00:00" #system
|
||||||
|
@export var game_seconds_all := 0 #game seconds since current archive start
|
||||||
|
@export var game_seconds_current := 0 #game seconds since last chapter
|
||||||
|
@export var chapter := 0 #chapter id
|
||||||
|
@export var section := 0 #section id
|
||||||
|
|
63
manager/time_manager/time_manager.gd
Normal file
63
manager/time_manager/time_manager.gd
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
@export var current_chapter := 0
|
||||||
|
@export var current_section := 0
|
||||||
|
@export var game_seconds_all := 0
|
||||||
|
@export var game_seconds_current := 0
|
||||||
|
|
||||||
|
var timer: Timer
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
timer = Timer.new()
|
||||||
|
timer.wait_time = 1
|
||||||
|
timer.one_shot = false
|
||||||
|
timer.timeout.connect(_on_timer_timeout)
|
||||||
|
add_child(timer)
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_timer_timeout():
|
||||||
|
game_seconds_all += 1
|
||||||
|
game_seconds_current += 1
|
||||||
|
GlobalConfigManager.config.game_total_seconds += 1
|
||||||
|
|
||||||
|
|
||||||
|
func pack_current_time():
|
||||||
|
var packed_time = PackedTime.new()
|
||||||
|
packed_time.time = Time.get_datetime_string_from_system(false, true)
|
||||||
|
packed_time.chapter = current_chapter
|
||||||
|
packed_time.section = current_section
|
||||||
|
packed_time.game_archive_id = ArchiveManager.current_archive_id
|
||||||
|
packed_time.game_seconds_all = game_seconds_all
|
||||||
|
packed_time.game_seconds_current = game_seconds_current
|
||||||
|
|
||||||
|
|
||||||
|
# for log use
|
||||||
|
func get_concise_timemark() -> String:
|
||||||
|
var hour := game_seconds_current / 3600 as int
|
||||||
|
var minute := (game_seconds_current % 3600) / 60 as int
|
||||||
|
var second := game_seconds_current % 60
|
||||||
|
return (
|
||||||
|
"r"
|
||||||
|
+ str(ArchiveManager.current_archive_id)
|
||||||
|
+ "_c"
|
||||||
|
+ str(current_chapter)
|
||||||
|
+ "_s"
|
||||||
|
+ str(current_section)
|
||||||
|
+ " "
|
||||||
|
+ str(hour)
|
||||||
|
+ ":"
|
||||||
|
+ str(minute)
|
||||||
|
+ ":"
|
||||||
|
+ str(second)
|
||||||
|
)
|
||||||
|
|
||||||
|
func get_data_res() -> Resource:
|
||||||
|
return pack_current_time()
|
||||||
|
|
||||||
|
func load_data_res(data: Resource) -> void:
|
||||||
|
var packed_time = data as PackedTime
|
||||||
|
game_seconds_all = packed_time.game_seconds_all
|
||||||
|
game_seconds_current = packed_time.game_seconds_current
|
||||||
|
current_chapter = packed_time.chapter
|
||||||
|
current_section = packed_time.section
|
114
project.godot
Normal file
114
project.godot
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
; Engine configuration file.
|
||||||
|
; It's best edited using the editor UI and not directly,
|
||||||
|
; since the parameters that go here are not all obvious.
|
||||||
|
;
|
||||||
|
; Format:
|
||||||
|
; [section] ; section goes between []
|
||||||
|
; param=value ; assign values to parameters
|
||||||
|
|
||||||
|
config_version=5
|
||||||
|
|
||||||
|
[addons]
|
||||||
|
|
||||||
|
resources_spreadsheet_view/array_color_tint=100.0
|
||||||
|
resources_spreadsheet_view/color_rows=true
|
||||||
|
resources_spreadsheet_view/array_min_width=128.0
|
||||||
|
resources_spreadsheet_view/resource_preview_size=32.0
|
||||||
|
resources_spreadsheet_view/clip_headers=false
|
||||||
|
resources_spreadsheet_view/dupe_arrays=true
|
||||||
|
resources_spreadsheet_view/context_menu_on_leftclick=false
|
||||||
|
|
||||||
|
[application]
|
||||||
|
|
||||||
|
config/name="xiandie"
|
||||||
|
run/main_scene="res://scene/main.tscn"
|
||||||
|
config/features=PackedStringArray("4.3", "Mobile")
|
||||||
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[audio]
|
||||||
|
|
||||||
|
buses/default_bus_layout="res://config/default_bus_layout.tres"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
DebugMenu="*res://addons/debug_menu/debug_menu.tscn"
|
||||||
|
GlobalConfigManager="*res://manager/config_manager/global_config_manager.gd"
|
||||||
|
TimeManager="*res://manager/time_manager/time_manager.gd"
|
||||||
|
EntityManager="*res://manager/assemble/entity/entity_manager.gd"
|
||||||
|
SceneManager="*res://manager/assemble/scene/scene_manager.gd"
|
||||||
|
AudioManager="*res://manager/audio_manager/audio_manager.gd"
|
||||||
|
EventManager="*res://manager/event_manager/event_manager.gd"
|
||||||
|
DialogManager="*res://manager/assemble/dialog/dialog_manager.gd"
|
||||||
|
CameraManager="*res://manager/camera_manager/camera_manager.gd"
|
||||||
|
CgManager="*res://manager/cg_manager/cg_manager.gd"
|
||||||
|
InputManager="*res://manager/input/input_manager.gd"
|
||||||
|
ArchiveManager="*res://manager/archive_manager/archive_manager.gd"
|
||||||
|
|
||||||
|
[display]
|
||||||
|
|
||||||
|
window/size/viewport_width=564
|
||||||
|
window/size/viewport_height=317
|
||||||
|
window/size/window_width_override=1692
|
||||||
|
window/size/window_height_override=951
|
||||||
|
window/stretch/mode="canvas_items"
|
||||||
|
window/stretch/scale_mode="integer"
|
||||||
|
|
||||||
|
[editor_plugins]
|
||||||
|
|
||||||
|
enabled=PackedStringArray("res://addons/debug_menu/plugin.cfg", "res://addons/project-statistics/plugin.cfg")
|
||||||
|
|
||||||
|
[gui]
|
||||||
|
|
||||||
|
theme/custom="res://config/default_theme.tres"
|
||||||
|
theme/custom_font="res://asset/font/zpix-commercial-one-grand.ttf"
|
||||||
|
|
||||||
|
[input]
|
||||||
|
|
||||||
|
save={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"command_or_control_autoremap":true,"alt_pressed":false,"shift_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
up={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
down={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
left={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
right={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
run={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
jump={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
[rendering]
|
||||||
|
|
||||||
|
textures/canvas_textures/default_texture_filter=0
|
||||||
|
renderer/rendering_method="mobile"
|
||||||
|
|
||||||
|
[statistics]
|
||||||
|
|
||||||
|
force_include=PackedStringArray()
|
6
scene/camera/camera_focus_marker.gd
Normal file
6
scene/camera/camera_focus_marker.gd
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
extends Marker2D
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
pass # Replace with function body.
|
||||||
|
|
6
scene/camera/camera_focus_marker.tscn
Normal file
6
scene/camera/camera_focus_marker.tscn
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://cqkeegrcdjyg4"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/camera/camera_focus_marker.gd" id="1_7t4e6"]
|
||||||
|
|
||||||
|
[node name="CameraFocusMarker" type="Marker2D"]
|
||||||
|
script = ExtResource("1_7t4e6")
|
9
scene/camera/main_camera.gd
Normal file
9
scene/camera/main_camera.gd
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
extends Camera2D
|
||||||
|
|
||||||
|
class_name MainCamera
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
enabled = true
|
||||||
|
#position_smoothing_enabled = false
|
||||||
|
position_smoothing_speed = 10
|
||||||
|
position_smoothing_enabled = true
|
6
scene/camera/main_camera.tscn
Normal file
6
scene/camera/main_camera.tscn
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://ogyvstscr0kx"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/camera/main_camera.gd" id="1_pwiuw"]
|
||||||
|
|
||||||
|
[node name="MainCamera" type="Camera2D"]
|
||||||
|
script = ExtResource("1_pwiuw")
|
1
scene/dialog/dialog_container.gd
Normal file
1
scene/dialog/dialog_container.gd
Normal file
@ -0,0 +1 @@
|
|||||||
|
extends Control
|
44
scene/dialog/dialog_container.tscn
Normal file
44
scene/dialog/dialog_container.tscn
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://dmkt1roqc4he7"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/dialog/dialog_container.gd" id="1_s1ka3"]
|
||||||
|
[ext_resource type="Theme" uid="uid://j42sexotwnvk" path="res://config/default_theme.tres" id="2_q6yks"]
|
||||||
|
|
||||||
|
[node name="DialogContainer" type="MarginContainer"]
|
||||||
|
anchors_preset = 12
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = -86.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 0
|
||||||
|
size_flags_vertical = 8
|
||||||
|
theme_override_constants/margin_left = 32
|
||||||
|
theme_override_constants/margin_top = 16
|
||||||
|
theme_override_constants/margin_right = 32
|
||||||
|
theme_override_constants/margin_bottom = 42
|
||||||
|
script = ExtResource("1_s1ka3")
|
||||||
|
|
||||||
|
[node name="DialogPanelContainer" type="PanelContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="DialogMarginContainer" type="MarginContainer" parent="DialogPanelContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme = ExtResource("2_q6yks")
|
||||||
|
theme_type_variation = &"dialog_container"
|
||||||
|
theme_override_constants/margin_left = 12
|
||||||
|
theme_override_constants/margin_top = 8
|
||||||
|
theme_override_constants/margin_right = 12
|
||||||
|
theme_override_constants/margin_bottom = 8
|
||||||
|
|
||||||
|
[node name="RichTextLabel" type="RichTextLabel" parent="DialogPanelContainer/DialogMarginContainer"]
|
||||||
|
custom_minimum_size = Vector2(460, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
mouse_filter = 2
|
||||||
|
text = "Dialog: test
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5"
|
||||||
|
fit_content = true
|
8
scene/ground/boarder_frame.gd
Normal file
8
scene/ground/boarder_frame.gd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
extends Control
|
||||||
|
|
||||||
|
@onready var color_top := %ColorRectTop as ColorRect
|
||||||
|
@onready var color_bottom := %ColorRectBottom as ColorRect
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
color_top.color = GlobalConfig.COLOR_BOARDER
|
||||||
|
color_bottom.color = GlobalConfig.COLOR_BOARDER
|
41
scene/ground/boarder_frame.tscn
Normal file
41
scene/ground/boarder_frame.tscn
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://o4a2eluydtep"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/ground/boarder_frame.gd" id="1_50vde"]
|
||||||
|
|
||||||
|
[node name="BoarderFrame" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_50vde")
|
||||||
|
|
||||||
|
[node name="ColorRectTop" type="ColorRect" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(564, 38.5)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 5
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
offset_left = -282.0
|
||||||
|
offset_right = 282.0
|
||||||
|
offset_bottom = 40.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
color = Color(0.372549, 0.0156863, 0.0156863, 1)
|
||||||
|
|
||||||
|
[node name="ColorRectBottom" type="ColorRect" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(564, 38.5)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 7
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -282.0
|
||||||
|
offset_top = -38.5
|
||||||
|
offset_right = 282.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 0
|
||||||
|
color = Color(0.372549, 0.0156863, 0.0156863, 1)
|
12
scene/ground/parallax_background.gd
Normal file
12
scene/ground/parallax_background.gd
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
extends ParallaxBackground
|
||||||
|
|
||||||
|
#
|
||||||
|
## Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
#func _physics_process(delta: float) -> void:
|
||||||
|
#var x = Input.get_axis("left", "right")
|
||||||
|
#var y = Input.get_axis("up", "down")
|
||||||
|
#camera.position.x += delta * x * 1000
|
||||||
|
#camera.position.y += delta * y * 1000
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
layer = GlobalConfig.CANVAS_LAYER_BG
|
15
scene/ground/parallax_background.tscn
Normal file
15
scene/ground/parallax_background.tscn
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://d0mnndg67dru1"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/ground/parallax_background.gd" id="1_w8735"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dukm6cix2kghn" path="res://asset/art/第一章/场景五(1012外间现实版)/1012外间.png" id="2_6t5qy"]
|
||||||
|
|
||||||
|
[node name="ParallaxBackground" type="ParallaxBackground"]
|
||||||
|
scroll_base_offset = Vector2(-250, -200)
|
||||||
|
script = ExtResource("1_w8735")
|
||||||
|
|
||||||
|
[node name="ParallaxLayer" type="ParallaxLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="Sprite2D" type="Sprite2D" parent="ParallaxLayer"]
|
||||||
|
scale = Vector2(1.33649, 1.32083)
|
||||||
|
texture = ExtResource("2_6t5qy")
|
||||||
|
centered = false
|
5
scene/ground/parallax_foreground.gd
Normal file
5
scene/ground/parallax_foreground.gd
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
extends ParallaxBackground
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
layer = GlobalConfig.CANVAS_LAYER_FG
|
21
scene/ground/parallax_foreground.tscn
Normal file
21
scene/ground/parallax_foreground.tscn
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://02lmmldikfar"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/ground/parallax_foreground.gd" id="1_32n5c"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://c0l7pkwvbrgey" path="res://asset/art/第一章/场景五(1012外间现实版)/前景.png" id="3_4g2yq"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://o4a2eluydtep" path="res://scene/ground/boarder_frame.tscn" id="4_18dtv"]
|
||||||
|
|
||||||
|
[node name="ParallaxForeground" type="ParallaxBackground"]
|
||||||
|
scroll_base_offset = Vector2(-250, -200)
|
||||||
|
script = ExtResource("1_32n5c")
|
||||||
|
|
||||||
|
[node name="ParallaxLayer2" type="ParallaxLayer" parent="."]
|
||||||
|
motion_scale = Vector2(1.1, 1.1)
|
||||||
|
motion_mirroring = Vector2(2000, 1300)
|
||||||
|
|
||||||
|
[node name="Sprite2D" type="Sprite2D" parent="ParallaxLayer2"]
|
||||||
|
position = Vector2(2, 73)
|
||||||
|
scale = Vector2(1.33886, 1.05)
|
||||||
|
texture = ExtResource("3_4g2yq")
|
||||||
|
centered = false
|
||||||
|
|
||||||
|
[node name="ShadedFrame" parent="." instance=ExtResource("4_18dtv")]
|
1
scene/hud/prop_hud.gd
Normal file
1
scene/hud/prop_hud.gd
Normal file
@ -0,0 +1 @@
|
|||||||
|
extends Control
|
85
scene/hud/prop_hud.tscn
Normal file
85
scene/hud/prop_hud.tscn
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
[gd_scene load_steps=12 format=3 uid="uid://dc778gsjfr3ky"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/hud/prop_hud.gd" id="1_bbv0a"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://chyumeohdhwnh" path="res://asset/art/ui/道具快捷栏/normal_left.png" id="2_bjc2b"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cvepj6u80c5wv" path="res://asset/art/ui/道具快捷栏/pressed_left.png" id="3_fca7p"]
|
||||||
|
[ext_resource type="Script" path="res://ui/button/sound_texture_button.gd" id="3_xijdf"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bospbmb0gr2sb" path="res://asset/art/ui/道具快捷栏/Prop.png" id="5_6tt77"]
|
||||||
|
[ext_resource type="Script" path="res://config/audio/audio_stream_collection.gd" id="5_wmvnw"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cor5ec6ogq3fe" path="res://config/audio/casino/card_slide.tres" id="6_32vbt"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://optvgar5g2c" path="res://asset/art/道具/第一章/绳子物品.png" id="8_kpmil"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bgsbwhy1c2jna" path="res://asset/art/ui/道具快捷栏/hand.png" id="9_0crjo"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://boqpr7i2a5uan" path="res://asset/art/ui/道具快捷栏/normal_right.png" id="10_vkaik"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://daj2n408y2vfp" path="res://asset/art/ui/道具快捷栏/pressed_right.png" id="11_a512b"]
|
||||||
|
|
||||||
|
[node name="PropHUD" type="HBoxContainer"]
|
||||||
|
offset_left = 10.0
|
||||||
|
offset_top = 4.0
|
||||||
|
offset_right = 98.0
|
||||||
|
offset_bottom = 36.0
|
||||||
|
scale = Vector2(0.3, 0.3)
|
||||||
|
script = ExtResource("1_bbv0a")
|
||||||
|
|
||||||
|
[node name="LeftMargin" type="MarginContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/margin_left = 8
|
||||||
|
|
||||||
|
[node name="LeftButton" type="TextureButton" parent="LeftMargin"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 4
|
||||||
|
texture_normal = ExtResource("2_bjc2b")
|
||||||
|
texture_pressed = ExtResource("3_fca7p")
|
||||||
|
stretch_mode = 5
|
||||||
|
script = ExtResource("3_xijdf")
|
||||||
|
|
||||||
|
[node name="HudPanel" type="TextureButton" parent="."]
|
||||||
|
custom_minimum_size = Vector2(32, 32)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 4
|
||||||
|
texture_normal = ExtResource("5_6tt77")
|
||||||
|
stretch_mode = 5
|
||||||
|
script = ExtResource("3_xijdf")
|
||||||
|
audio_collections = Array[ExtResource("5_wmvnw")]([ExtResource("6_32vbt")])
|
||||||
|
|
||||||
|
[node name="Prop" type="TextureRect" parent="HudPanel"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -73.0
|
||||||
|
offset_top = -41.0
|
||||||
|
offset_right = 73.0
|
||||||
|
offset_bottom = 41.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
texture = ExtResource("8_kpmil")
|
||||||
|
|
||||||
|
[node name="Mark" type="TextureRect" parent="HudPanel"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -14.0
|
||||||
|
offset_top = -15.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
texture = ExtResource("9_0crjo")
|
||||||
|
|
||||||
|
[node name="RightMargin" type="MarginContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/margin_right = 8
|
||||||
|
|
||||||
|
[node name="RightButton" type="TextureButton" parent="RightMargin"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
texture_normal = ExtResource("10_vkaik")
|
||||||
|
texture_pressed = ExtResource("11_a512b")
|
||||||
|
stretch_mode = 5
|
||||||
|
script = ExtResource("3_xijdf")
|
16
scene/hud/prop_hud_item_2d.tscn
Normal file
16
scene/hud/prop_hud_item_2d.tscn
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://dpgmgc5qf0apc"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_5nh3u"]
|
||||||
|
script/source = "extends StaticBody2D
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
pass"
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_gyjm3"]
|
||||||
|
size = Vector2(38, 38)
|
||||||
|
|
||||||
|
[node name="PropHudItem2D" type="StaticBody2D"]
|
||||||
|
script = SubResource("GDScript_5nh3u")
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
shape = SubResource("RectangleShape2D_gyjm3")
|
4
scene/main.gd
Normal file
4
scene/main.gd
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
$UILayer.layer = GlobalConfig.CANVAS_LAYER_VIGNETTE
|
48
scene/main.tscn
Normal file
48
scene/main.tscn
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
[gd_scene load_steps=12 format=3 uid="uid://dygvcmykn02n8"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://d0mnndg67dru1" path="res://scene/ground/parallax_background.tscn" id="1_f7g4d"]
|
||||||
|
[ext_resource type="Script" path="res://scene/main.gd" id="1_pks84"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://3gk1gxwanw24" path="res://ui/vignette/vignette_shading.tscn" id="2_d1re1"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dmkt1roqc4he7" path="res://scene/dialog/dialog_container.tscn" id="3_prpss"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dc778gsjfr3ky" path="res://scene/hud/prop_hud.tscn" id="4_t7gb2"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://5g07x6q7wwr1" path="res://scene/notification/notification.tscn" id="5_3gg5t"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cekhj65axie0p" path="res://scene/popup/prop_inspector_2d.tscn" id="5_ux0rw"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cjhw5ecygrqty" path="res://scene/player/player_2d.tscn" id="6_6geb0"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cqkeegrcdjyg4" path="res://scene/camera/camera_focus_marker.tscn" id="7_n7qcv"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://ogyvstscr0kx" path="res://scene/camera/main_camera.tscn" id="8_nj084"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://02lmmldikfar" path="res://scene/ground/parallax_foreground.tscn" id="11_anxqu"]
|
||||||
|
|
||||||
|
[node name="Main" type="Node2D"]
|
||||||
|
script = ExtResource("1_pks84")
|
||||||
|
|
||||||
|
[node name="ParallaxBackground" parent="." instance=ExtResource("1_f7g4d")]
|
||||||
|
|
||||||
|
[node name="UILayer" type="CanvasLayer" parent="."]
|
||||||
|
layer = 5
|
||||||
|
|
||||||
|
[node name="HUD2D" parent="UILayer" instance=ExtResource("4_t7gb2")]
|
||||||
|
scale = Vector2(0.24, 0.24)
|
||||||
|
mouse_filter = 0
|
||||||
|
|
||||||
|
[node name="DialogLayer" parent="UILayer" instance=ExtResource("3_prpss")]
|
||||||
|
offset_top = -134.0
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="Notification" parent="UILayer" instance=ExtResource("5_3gg5t")]
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="VignetteShading" parent="." instance=ExtResource("2_d1re1")]
|
||||||
|
|
||||||
|
[node name="PropInspector2D" parent="." instance=ExtResource("5_ux0rw")]
|
||||||
|
|
||||||
|
[node name="Player2D" parent="." instance=ExtResource("6_6geb0")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="CameraFocusMarker" parent="Player2D" instance=ExtResource("7_n7qcv")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="MainCamera" parent="Player2D/CameraFocusMarker" instance=ExtResource("8_nj084")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
position = Vector2(1, 0)
|
||||||
|
|
||||||
|
[node name="ParallaxForeground" parent="." instance=ExtResource("11_anxqu")]
|
6
scene/notification/notification.gd
Normal file
6
scene/notification/notification.gd
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
extends Control
|
||||||
|
|
||||||
|
|
||||||
|
func show_notification(msg, number):
|
||||||
|
#TODO: Implement this method
|
||||||
|
print("show_notification:", msg, number)
|
12
scene/notification/notification.tscn
Normal file
12
scene/notification/notification.tscn
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://5g07x6q7wwr1"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/notification/notification.gd" id="1_j0g80"]
|
||||||
|
|
||||||
|
[node name="Notification" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_j0g80")
|
166
scene/player/player_2d.gd
Normal file
166
scene/player/player_2d.gd
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
extends CharacterBody2D
|
||||||
|
|
||||||
|
class_name MainPlayer
|
||||||
|
|
||||||
|
enum MOVEMENT_STATUS {
|
||||||
|
IDLE,
|
||||||
|
WALKING,
|
||||||
|
RUNNING,
|
||||||
|
LAYING_STAY,
|
||||||
|
LAYING_MOVING,
|
||||||
|
CLIMBING_STAY,
|
||||||
|
CLIMBING,
|
||||||
|
}
|
||||||
|
|
||||||
|
@export var action_locked := false:
|
||||||
|
set(val):
|
||||||
|
action_locked = val
|
||||||
|
_process_action_lock()
|
||||||
|
@export var current_status : MOVEMENT_STATUS
|
||||||
|
@export var facing_direction := Vector2(1.0, -1.0)
|
||||||
|
@export var is_laying := false:
|
||||||
|
set(val):
|
||||||
|
is_laying = val
|
||||||
|
# reset the facing direction wether the player is laying or not.
|
||||||
|
_reset_face_direction()
|
||||||
|
if is_laying:
|
||||||
|
is_climbing = false
|
||||||
|
@export var is_climbing := false:
|
||||||
|
set(val):
|
||||||
|
is_climbing = val
|
||||||
|
# reset the facing direction wether the player is climbing or not.
|
||||||
|
_reset_face_direction()
|
||||||
|
if is_climbing:
|
||||||
|
is_laying = false
|
||||||
|
@export var running_locked := false
|
||||||
|
@export var speed_walking := 300.0
|
||||||
|
@export var speed_runnig := 500.0
|
||||||
|
@export var speed_laying := 150.0
|
||||||
|
@export var speed_climbing := 170.0
|
||||||
|
#const JUMP_VELOCITY = -400.0
|
||||||
|
|
||||||
|
@onready var camera = %MainCamera as Camera2D
|
||||||
|
@onready var sprite = %AnimatedSprite2D as AnimatedSprite2D
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_reset_face_direction()
|
||||||
|
|
||||||
|
func _reset_face_direction() -> void:
|
||||||
|
facing_direction = Vector2(1, -1)
|
||||||
|
|
||||||
|
func _process_action_lock() -> void:
|
||||||
|
# reset status to idle or stay
|
||||||
|
if action_locked:
|
||||||
|
if current_status == MOVEMENT_STATUS.WALKING or current_status == MOVEMENT_STATUS.RUNNING:
|
||||||
|
current_status = MOVEMENT_STATUS.IDLE
|
||||||
|
elif current_status == MOVEMENT_STATUS.LAYING_MOVING:
|
||||||
|
current_status = MOVEMENT_STATUS.LAYING_STAY
|
||||||
|
elif current_status == MOVEMENT_STATUS.CLIMBING:
|
||||||
|
current_status = MOVEMENT_STATUS.CLIMBING_STAY
|
||||||
|
_play_animation()
|
||||||
|
|
||||||
|
# return whether the player status or facing direction has changed.
|
||||||
|
func _check_status(direction) -> bool:
|
||||||
|
var tmp_status = current_status
|
||||||
|
var new_facing_direction := facing_direction
|
||||||
|
if is_laying:
|
||||||
|
if direction.x:
|
||||||
|
new_facing_direction.x = direction.x
|
||||||
|
tmp_status = MOVEMENT_STATUS.LAYING_MOVING
|
||||||
|
else:
|
||||||
|
tmp_status = MOVEMENT_STATUS.LAYING_STAY
|
||||||
|
elif is_climbing:
|
||||||
|
if direction.y:
|
||||||
|
new_facing_direction.y = direction.y
|
||||||
|
tmp_status = MOVEMENT_STATUS.CLIMBING
|
||||||
|
else:
|
||||||
|
tmp_status = MOVEMENT_STATUS.CLIMBING_STAY
|
||||||
|
else:
|
||||||
|
if direction.x:
|
||||||
|
new_facing_direction.x = direction.x
|
||||||
|
tmp_status = MOVEMENT_STATUS.WALKING
|
||||||
|
if !running_locked and Input.is_action_pressed("run"):
|
||||||
|
tmp_status = MOVEMENT_STATUS.RUNNING
|
||||||
|
else:
|
||||||
|
tmp_status = MOVEMENT_STATUS.IDLE
|
||||||
|
if new_facing_direction != facing_direction or tmp_status != current_status:
|
||||||
|
facing_direction = new_facing_direction
|
||||||
|
current_status = tmp_status
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
func _play_animation() -> void:
|
||||||
|
match current_status:
|
||||||
|
MOVEMENT_STATUS.IDLE:
|
||||||
|
if facing_direction.x > 0.0:
|
||||||
|
sprite.play(&"idle_r")
|
||||||
|
else:
|
||||||
|
sprite.play(&"idle_l")
|
||||||
|
MOVEMENT_STATUS.WALKING:
|
||||||
|
if facing_direction.x > 0.0:
|
||||||
|
sprite.play(&"walking_r")
|
||||||
|
else:
|
||||||
|
sprite.play(&"walking_l")
|
||||||
|
MOVEMENT_STATUS.RUNNING:
|
||||||
|
if facing_direction.x > 0.0:
|
||||||
|
sprite.play(&"running_r")
|
||||||
|
else:
|
||||||
|
sprite.play(&"running_l")
|
||||||
|
MOVEMENT_STATUS.LAYING_STAY:
|
||||||
|
if facing_direction.x > 0.0:
|
||||||
|
sprite.play(&"laying_stay_r")
|
||||||
|
else:
|
||||||
|
sprite.play(&"laying_stay_l")
|
||||||
|
MOVEMENT_STATUS.LAYING_MOVING:
|
||||||
|
if facing_direction.x > 0.0:
|
||||||
|
sprite.play(&"laying_moving_r")
|
||||||
|
else:
|
||||||
|
sprite.play(&"laying_moving_l")
|
||||||
|
MOVEMENT_STATUS.CLIMBING_STAY:
|
||||||
|
sprite.play(&"climbing_stay")
|
||||||
|
MOVEMENT_STATUS.CLIMBING:
|
||||||
|
if facing_direction.y > 0.0:
|
||||||
|
sprite.play(&"climbing_down")
|
||||||
|
else:
|
||||||
|
sprite.play(&"climbing_up")
|
||||||
|
|
||||||
|
func _get_speed(direction: Vector2) -> Vector2:
|
||||||
|
match current_status:
|
||||||
|
MOVEMENT_STATUS.WALKING:
|
||||||
|
return Vector2(speed_walking * direction.x, 0.0)
|
||||||
|
MOVEMENT_STATUS.RUNNING:
|
||||||
|
return Vector2(speed_runnig * direction.x, 0.0)
|
||||||
|
MOVEMENT_STATUS.LAYING_MOVING:
|
||||||
|
return Vector2(speed_laying * direction.x, 0.0)
|
||||||
|
MOVEMENT_STATUS.CLIMBING:
|
||||||
|
return Vector2(0, speed_climbing * direction.y)
|
||||||
|
return Vector2(0, 0)
|
||||||
|
|
||||||
|
func _physics_process(_delta: float) -> void:
|
||||||
|
if action_locked:
|
||||||
|
velocity = Vector2.ZERO
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add the gravity.
|
||||||
|
#if not is_on_floor():
|
||||||
|
#velocity += get_gravity() * delta
|
||||||
|
#if Input.is_action_just_pressed("jump") and is_on_floor():
|
||||||
|
#velocity.y = JUMP_VELOCITY
|
||||||
|
var x_direction := Input.get_axis("left", "right")
|
||||||
|
var y_direction := Input.get_axis("up", "down")
|
||||||
|
var direction := Vector2(x_direction, y_direction)
|
||||||
|
if _check_status(direction):
|
||||||
|
_play_animation()
|
||||||
|
var speed := _get_speed(direction) as Vector2
|
||||||
|
velocity.x = move_toward(velocity.x, speed.x, 300.0)
|
||||||
|
velocity.y = move_toward(velocity.y, speed.y, 300.0)
|
||||||
|
move_and_slide()
|
||||||
|
_tweak_camera_marker()
|
||||||
|
|
||||||
|
# drag the camera marker against the player movement
|
||||||
|
# so there will be a better vision in front of the player.
|
||||||
|
func _tweak_camera_marker():
|
||||||
|
var marker = get_node("./CameraFocusMarker") as Node2D
|
||||||
|
if marker:
|
||||||
|
marker.position.x = facing_direction.x * abs(velocity.x) * 0.11
|
||||||
|
marker.position.y = facing_direction.y * abs(velocity.y) * 0.11
|
34
scene/player/player_2d.tscn
Normal file
34
scene/player/player_2d.tscn
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[gd_scene load_steps=5 format=3 uid="uid://cjhw5ecygrqty"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/player/player_2d.gd" id="1_3a78y"]
|
||||||
|
[ext_resource type="SpriteFrames" uid="uid://c43gyexokirl4" path="res://config/animation/player_sprite_frames.tres" id="1_23i43"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://t526pexw4ng4" path="res://asset/art/neutral_point_light.webp" id="3_scilj"]
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fno82"]
|
||||||
|
size = Vector2(105, 238.5)
|
||||||
|
|
||||||
|
[node name="Player2D" type="CharacterBody2D"]
|
||||||
|
script = ExtResource("1_3a78y")
|
||||||
|
current_status = null
|
||||||
|
facing_direction = null
|
||||||
|
running_locked = null
|
||||||
|
speed_walking = null
|
||||||
|
speed_runnig = null
|
||||||
|
speed_laying = null
|
||||||
|
speed_climbing = null
|
||||||
|
|
||||||
|
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
sprite_frames = ExtResource("1_23i43")
|
||||||
|
animation = &"idle_r"
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
position = Vector2(-1, -1)
|
||||||
|
shape = SubResource("RectangleShape2D_fno82")
|
||||||
|
|
||||||
|
[node name="PointLight2D" type="PointLight2D" parent="."]
|
||||||
|
position = Vector2(2, -175)
|
||||||
|
scale = Vector2(0.810547, 0.849609)
|
||||||
|
energy = 0.4
|
||||||
|
texture = ExtResource("3_scilj")
|
||||||
|
height = 50.0
|
12
scene/popup/prop_inspector_2d.gd
Normal file
12
scene/popup/prop_inspector_2d.gd
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
extends CanvasLayer
|
||||||
|
|
||||||
|
@onready var panel := %Panel
|
||||||
|
|
||||||
|
@export var shown := false:
|
||||||
|
set(val):
|
||||||
|
shown = val
|
||||||
|
panel.visible = val
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
layer = GlobalConfig.CANVAS_LAYER_PROP_INSPECTOR
|
15
scene/popup/prop_inspector_2d.tscn
Normal file
15
scene/popup/prop_inspector_2d.tscn
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://cekhj65axie0p"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scene/popup/prop_inspector_2d.gd" id="1_p4yxb"]
|
||||||
|
|
||||||
|
[node name="PropInspector2D" type="CanvasLayer"]
|
||||||
|
script = ExtResource("1_p4yxb")
|
||||||
|
|
||||||
|
[node name="Panel" type="Panel" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
9
scene/settings/settings.tscn
Normal file
9
scene/settings/settings.tscn
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[gd_scene format=3 uid="uid://beok2r6fgburn"]
|
||||||
|
|
||||||
|
[node name="Settings" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
19
ui/button/sound_button.gd
Normal file
19
ui/button/sound_button.gd
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
extends Button
|
||||||
|
|
||||||
|
class_name SoundButton
|
||||||
|
|
||||||
|
@export var audio_collections: Array[AudioStreamCollection]
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
if !audio_collections:
|
||||||
|
audio_collections.append(preload("res://config/audio/ui/ui_click.tres"))
|
||||||
|
#print("sound button loaded default ui_click.tres")
|
||||||
|
|
||||||
|
if audio_collections:
|
||||||
|
#print("sound button load audio_collections into audio_player")
|
||||||
|
var audio_player := RandomAudioStreamPlayer.new()
|
||||||
|
audio_player.audio_collections = audio_collections
|
||||||
|
pressed.connect(audio_player.play_random)
|
||||||
|
add_child(audio_player)
|
||||||
|
else:
|
||||||
|
printerr("sound button has no audio_collections! ignore initialization of audio_player")
|
8
ui/button/sound_button.tscn
Normal file
8
ui/button/sound_button.tscn
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://bdy4u3e7rmo7f"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://ui/button/sound_button.gd" id="1_vn1us"]
|
||||||
|
|
||||||
|
[node name="SoundButton" type="Button"]
|
||||||
|
offset_right = 8.0
|
||||||
|
offset_bottom = 8.0
|
||||||
|
script = ExtResource("1_vn1us")
|
28
ui/button/sound_texture_button.gd
Normal file
28
ui/button/sound_texture_button.gd
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
extends TextureButton
|
||||||
|
|
||||||
|
class_name SoundTextureButton
|
||||||
|
|
||||||
|
@export var audio_collections: Array[AudioStreamCollection]
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
if !audio_collections:
|
||||||
|
audio_collections.append(preload("res://config/audio/ui/ui_click.tres"))
|
||||||
|
#print("sound button loaded default ui_click.tres")
|
||||||
|
|
||||||
|
if audio_collections:
|
||||||
|
#print("sound button load audio_collections into audio_player")
|
||||||
|
var audio_player := RandomAudioStreamPlayer.new()
|
||||||
|
audio_player.audio_collections = audio_collections
|
||||||
|
button_down.connect(audio_player.play_random)
|
||||||
|
add_child(audio_player)
|
||||||
|
else:
|
||||||
|
printerr("sound button has no audio_collections! ignore initialization of audio_player")
|
||||||
|
#button_down.connect(_on_press_down)
|
||||||
|
#button_up.connect(_on_press_up)
|
||||||
|
|
||||||
|
|
||||||
|
#func _on_press_down():
|
||||||
|
#InputUtil.set_cursor_hand_patting()
|
||||||
|
#
|
||||||
|
#func _on_press_up():
|
||||||
|
#InputUtil.set_cursor_hand_rest()
|
8
ui/button/sound_texture_button.tscn
Normal file
8
ui/button/sound_texture_button.tscn
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://cef5mgr1hgpmr"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://ui/button/sound_texture_button.gd" id="1_k7j4d"]
|
||||||
|
|
||||||
|
[node name="SoundButton" type="TextureButton"]
|
||||||
|
size_flags_horizontal = 0
|
||||||
|
size_flags_vertical = 0
|
||||||
|
script = ExtResource("1_k7j4d")
|
100
ui/hud/Inventory.tscn
Executable file
100
ui/hud/Inventory.tscn
Executable file
@ -0,0 +1,100 @@
|
|||||||
|
[gd_scene load_steps=14 format=3 uid="uid://cmyxinb0ickva"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://UI/Inventory.gd" id="1_gbar7"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://2jc6qio7tmuk" path="res://assets/HUD/背包按键/道具快捷栏/zz.png" id="2_c4gqh"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dr1fvkrmtynb6" path="res://assets/HUD/背包按键/道具快捷栏/az.png" id="3_ftsid"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b3pfdsyj0dcdb" path="res://assets/HUD/背包按键/道具快捷栏/wz.png" id="4_rn4wj"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ykv7o43dtjn0" path="res://assets/HUD/背包按键/道具快捷栏/k.png" id="5_o2bgy"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bgjt0y7vs5ix0" path="res://assets/HUD/背包按键/道具快捷栏/s.png" id="6_abx1s"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ukdbwrvd8qdq" path="res://assets/HUD/背包按键/道具快捷栏/zy.png" id="7_n66je"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://sv8u083cpov6" path="res://assets/HUD/背包按键/道具快捷栏/ay.png" id="8_iym7w"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dva4vpj5uo8td" path="res://assets/HUD/背包按键/道具快捷栏/wy.png" id="9_aoirx"]
|
||||||
|
[ext_resource type="FontFile" uid="uid://dehtmf0lanaf3" path="res://assets/HUD/字体/方正楷体简体.TTF" id="10_8p7i8"]
|
||||||
|
|
||||||
|
[sub_resource type="FontFile" id="FontFile_5oap5"]
|
||||||
|
subpixel_positioning = 0
|
||||||
|
msdf_pixel_range = 14
|
||||||
|
msdf_size = 128
|
||||||
|
cache/0/16/0/ascent = 0.0
|
||||||
|
cache/0/16/0/descent = 0.0
|
||||||
|
cache/0/16/0/underline_position = 0.0
|
||||||
|
cache/0/16/0/underline_thickness = 0.0
|
||||||
|
cache/0/16/0/scale = 1.0
|
||||||
|
cache/0/16/0/kerning_overrides/16/0 = Vector2(0, 0)
|
||||||
|
|
||||||
|
[sub_resource type="Theme" id="Theme_bioai"]
|
||||||
|
default_base_scale = 0.98
|
||||||
|
default_font = SubResource("FontFile_5oap5")
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jk1w7"]
|
||||||
|
size = Vector2(83.6779, 34.3683)
|
||||||
|
|
||||||
|
[node name="Inventory" type="VBoxContainer"]
|
||||||
|
offset_left = 10.0
|
||||||
|
offset_top = 7.0
|
||||||
|
offset_right = 277.0
|
||||||
|
offset_bottom = 184.0
|
||||||
|
scale = Vector2(0.18, 0.18)
|
||||||
|
theme_override_constants/separation = 5
|
||||||
|
script = ExtResource("1_gbar7")
|
||||||
|
|
||||||
|
[node name="ItemBar" type="HBoxContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Prev" type="TextureButton" parent="ItemBar"]
|
||||||
|
custom_minimum_size = Vector2(60, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
theme = SubResource("Theme_bioai")
|
||||||
|
texture_normal = ExtResource("2_c4gqh")
|
||||||
|
texture_pressed = ExtResource("3_ftsid")
|
||||||
|
texture_disabled = ExtResource("4_rn4wj")
|
||||||
|
stretch_mode = 3
|
||||||
|
|
||||||
|
[node name="Use" type="TextureButton" parent="ItemBar"]
|
||||||
|
layout_mode = 2
|
||||||
|
texture_normal = ExtResource("5_o2bgy")
|
||||||
|
|
||||||
|
[node name="Prop" type="Sprite2D" parent="ItemBar/Use"]
|
||||||
|
z_index = 1
|
||||||
|
position = Vector2(72, 72)
|
||||||
|
|
||||||
|
[node name="Hand" type="Sprite2D" parent="ItemBar/Use"]
|
||||||
|
z_index = 1
|
||||||
|
position = Vector2(110, 102)
|
||||||
|
texture = ExtResource("6_abx1s")
|
||||||
|
|
||||||
|
[node name="Next" type="TextureButton" parent="ItemBar"]
|
||||||
|
custom_minimum_size = Vector2(60, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
texture_normal = ExtResource("7_n66je")
|
||||||
|
texture_pressed = ExtResource("8_iym7w")
|
||||||
|
texture_disabled = ExtResource("9_aoirx")
|
||||||
|
stretch_mode = 3
|
||||||
|
|
||||||
|
[node name="Area2D" type="Area2D" parent="ItemBar"]
|
||||||
|
visible = false
|
||||||
|
position = Vector2(-200, -99.9999)
|
||||||
|
scale = Vector2(3.60011, 5.23739)
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="ItemBar/Area2D"]
|
||||||
|
position = Vector2(91.4901, 32.4589)
|
||||||
|
scale = Vector2(1, 0.999999)
|
||||||
|
shape = SubResource("RectangleShape2D_jk1w7")
|
||||||
|
one_way_collision_margin = 0.0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_fonts/font = ExtResource("10_8p7i8")
|
||||||
|
theme_override_font_sizes/font_size = 35
|
||||||
|
text = "道具的描述"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
|
[node name="Timer" type="Timer" parent="Label"]
|
||||||
|
wait_time = 1.5
|
||||||
|
one_shot = true
|
||||||
|
|
||||||
|
[connection signal="pressed" from="ItemBar/Prev" to="." method="_on_prev_pressed"]
|
||||||
|
[connection signal="pressed" from="ItemBar/Use" to="." method="_on_use_pressed"]
|
||||||
|
[connection signal="pressed" from="ItemBar/Next" to="." method="_on_next_pressed"]
|
||||||
|
[connection signal="timeout" from="Label/Timer" to="." method="_on_timer_timeout"]
|
11
ui/hud/hud.tscn
Normal file
11
ui/hud/hud.tscn
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://bs63fypttsiop"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cmyxinb0ickva" path="res://ui/hud/Inventory.tscn" id="1_tam4l"]
|
||||||
|
|
||||||
|
[node name="HUD" type="CanvasLayer"]
|
||||||
|
layer = 99
|
||||||
|
|
||||||
|
[node name="Inventory" parent="." instance=ExtResource("1_tam4l")]
|
||||||
|
offset_top = 4.0
|
||||||
|
offset_bottom = 193.0
|
||||||
|
script = null
|
112
ui/hud/inventory.gd
Executable file
112
ui/hud/inventory.gd
Executable file
@ -0,0 +1,112 @@
|
|||||||
|
#背包实现
|
||||||
|
extends VBoxContainer
|
||||||
|
|
||||||
|
var _hand_outro: Tween
|
||||||
|
var _label_outro: Tween
|
||||||
|
#@onready var item_bar = $ItemBar
|
||||||
|
@onready var prev = $ItemBar/Prev
|
||||||
|
@onready var prop = $ItemBar/Use/Prop
|
||||||
|
@onready var hand = $ItemBar/Use/Hand
|
||||||
|
@onready var next = $ItemBar/Next
|
||||||
|
@onready var label = $Label
|
||||||
|
@onready var timer = $Label/Timer
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
#SceneManager.inventory.add_item(preload("res://items/1014_yaoshi.tres"))
|
||||||
|
#SceneManager.inventory.add_item(preload("res://items/3014_yaoshi.tres"))
|
||||||
|
hand.hide()
|
||||||
|
hand.modulate.a = 0.0
|
||||||
|
label.hide()
|
||||||
|
label.modulate.a = 0.0
|
||||||
|
|
||||||
|
SceneManager.inventory.changed.connect(_update_ui)
|
||||||
|
_update_ui(true)
|
||||||
|
|
||||||
|
|
||||||
|
#设置在屏幕中点击任意位置,互动手图案消失
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if event.is_action_pressed("click") and SceneManager.inventory.active_item:
|
||||||
|
SceneManager.inventory.set_deferred("active_item", true)
|
||||||
|
|
||||||
|
_hand_outro = create_tween()
|
||||||
|
_hand_outro.set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE).set_parallel()
|
||||||
|
_hand_outro.tween_property(hand, "scale", Vector2.ONE * 0.5, 0.15) #Vector2.ONE * 0.5 设置手缩放的大小.0.15表示消失的速度
|
||||||
|
_hand_outro.tween_property(hand, "modulate:a", 0.0, 0.15)
|
||||||
|
_hand_outro.chain().tween_callback(hand.hide)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func _update_ui(is_init = false): #is_inte = false 让背包物品在最开始出现时没有动画效果
|
||||||
|
var count = SceneManager.inventory.get_item_count()
|
||||||
|
prev.disabled = count < 2
|
||||||
|
next.disabled = count < 2
|
||||||
|
visible = count > 0
|
||||||
|
|
||||||
|
var item = SceneManager.inventory.get_current_item()
|
||||||
|
if not item:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
label.text = item.description
|
||||||
|
prop.texture = item.prop_texture
|
||||||
|
#item_bar.modulate.a = 1
|
||||||
|
#print("prop")
|
||||||
|
|
||||||
|
#添加背包物品在左右滑动时的弹出动画效果
|
||||||
|
|
||||||
|
if is_init:
|
||||||
|
return
|
||||||
|
|
||||||
|
var tween := create_tween()
|
||||||
|
tween.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
|
||||||
|
tween.tween_property(prop, "scale", Vector2.ONE, 0.15).from(Vector2.ZERO)
|
||||||
|
|
||||||
|
_show_label()
|
||||||
|
|
||||||
|
func _show_label() -> void:
|
||||||
|
if _label_outro and _label_outro.is_valid():
|
||||||
|
_label_outro.kill()
|
||||||
|
_label_outro = null
|
||||||
|
label.show()
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE)
|
||||||
|
tween.tween_property(label,"modulate:a",1.0,0.2)
|
||||||
|
tween.tween_callback(timer.start)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func _on_prev_pressed() -> void:
|
||||||
|
SoundManager.play_sfx("interact")
|
||||||
|
SceneManager.inventory.select_prev()
|
||||||
|
print("prev1")
|
||||||
|
|
||||||
|
func _on_next_pressed() -> void:
|
||||||
|
SoundManager.play_sfx("interact")
|
||||||
|
SceneManager.inventory.select_next()
|
||||||
|
print("next2")
|
||||||
|
|
||||||
|
@onready var use = $ItemBar/Use
|
||||||
|
|
||||||
|
|
||||||
|
func _on_use_pressed() -> void:
|
||||||
|
if use.button_mask == MOUSE_BUTTON_MASK_LEFT:
|
||||||
|
SceneManager.inventory.active_item = SceneManager.inventory.get_current_item()
|
||||||
|
print("use3")
|
||||||
|
|
||||||
|
if _hand_outro and _hand_outro.is_valid():
|
||||||
|
_hand_outro.kill()
|
||||||
|
_hand_outro = null
|
||||||
|
hand.show()
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK).set_parallel()
|
||||||
|
tween.tween_property(hand, "scale", Vector2.ONE, 0.15).from(Vector2.ZERO)
|
||||||
|
tween.tween_property(hand, "modulate:a", 1.0, 0.15)
|
||||||
|
|
||||||
|
_show_label()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_timer_timeout():
|
||||||
|
_label_outro = create_tween()
|
||||||
|
_label_outro.set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE)
|
||||||
|
_label_outro.tween_property(label,"modulate:a",0.0,0.2)
|
||||||
|
_label_outro.chain().tween_callback(label.hide)
|
10
ui/settings.tscn
Normal file
10
ui/settings.tscn
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://c5wtakm14h7cy"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" uid="uid://db8rd4nwl6pve" path="res://asset/art/ui/ui_settings.skt/Layer~2.png" id="1_sl0gr"]
|
||||||
|
|
||||||
|
[sub_resource type="AtlasTexture" id="AtlasTexture_jngmd"]
|
||||||
|
atlas = ExtResource("1_sl0gr")
|
||||||
|
region = Rect2(254, 362, 994, 1314)
|
||||||
|
|
||||||
|
[node name="Settings" type="Sprite2D"]
|
||||||
|
texture = SubResource("AtlasTexture_jngmd")
|
14
ui/vignette/vignette_shading.gd
Normal file
14
ui/vignette/vignette_shading.gd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
extends CanvasLayer
|
||||||
|
|
||||||
|
@export var rgb := Color8(0x3f,0x26,0x31):
|
||||||
|
set(new_val):
|
||||||
|
rgb = new_val
|
||||||
|
%ColorRect.material.set("shader_parameter/vignette_rgb", new_val)
|
||||||
|
|
||||||
|
@export_range(0, 5) var intensity := 0.3:
|
||||||
|
set(new_val):
|
||||||
|
intensity = new_val
|
||||||
|
%ColorRect.material.set("shader_parameter/vignette_intensity", new_val)
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
layer = GlobalConfig.CANVAS_LAYER_VIGNETTE
|
23
ui/vignette/vignette_shading.tscn
Normal file
23
ui/vignette/vignette_shading.tscn
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://3gk1gxwanw24"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://ui/vignette/vignette_shading.gd" id="1_6w7er"]
|
||||||
|
[ext_resource type="Shader" path="res://asset/shader/vignette.gdshader" id="1_akp6k"]
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_pabt5"]
|
||||||
|
shader = ExtResource("1_akp6k")
|
||||||
|
shader_parameter/vignette_intensity = 0.4
|
||||||
|
shader_parameter/vignette_rgb = Color(0.247059, 0.14902, 0.192157, 1)
|
||||||
|
|
||||||
|
[node name="VignetteShading" type="CanvasLayer"]
|
||||||
|
layer = 100
|
||||||
|
script = ExtResource("1_6w7er")
|
||||||
|
|
||||||
|
[node name="ColorRect" type="ColorRect" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
material = SubResource("ShaderMaterial_pabt5")
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
17
util/resource_utils.gd
Normal file
17
util/resource_utils.gd
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
extends Object
|
||||||
|
class_name ResourceUtils
|
||||||
|
|
||||||
|
# # remove editor's cache
|
||||||
|
# func remove_editor_cache(resource: Resource) -> void:
|
||||||
|
# if Engine.is_editor_hint():
|
||||||
|
# (resource)
|
||||||
|
|
||||||
|
|
||||||
|
static func remove_editor_cache(name: String) -> void:
|
||||||
|
pass
|
||||||
|
# var dir = DirAccess.open("res://.godot/editor")
|
||||||
|
# for file in dir.get_files():
|
||||||
|
# if file.get_basename().begins_with(name):
|
||||||
|
# DirAccess.remove_absolute("res://.godot/editor/" + file)
|
||||||
|
# print("Removed editor cache: ", file)
|
||||||
|
# break
|
Loading…
Reference in New Issue
Block a user