# Godot低耦合RPG对话框 **Repository Path**: xun99/rpg-dlg ## Basic Information - **Project Name**: Godot低耦合RPG对话框 - **Description**: 一款Godot3.3中设计的简单的RPG对话框元件场景,对话框与数据分离,后期会持续改进 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-08-08 - **Last Updated**: 2023-02-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Godot RPG-Dialog元件 这是基于Godot组件化编程思想,设计的第一个低耦合可复用元件,实现的基础效果如下: ![1628487379920](readme.assets/1628487379920.png) ## 元件场景结构 ![1628487629753](readme.assets/1628487629753.png) ![1628487616882](readme.assets/1628487616882.png) ### dialog.gd ```python extends Control signal click signal last_clicked signal next_clicked signal skip_clicked # 低耦合RPG对话框,通过赋值text来显示文本 var text setget set_text # 要显示的文本 var role_name setget set_role_name export(float) var speed = 0.02 # 单个文字显示时间 onready var tw = $"NinePatchRect/RichTextLabel/Tween" onready var rht = $"NinePatchRect/RichTextLabel" onready var nameLab = $"NinePatchRect/name/Label" # ============ 节点虚函数 ============= func _ready(): rht.bbcode_enabled = true # 开启富文本标签的BBCode模式 pass # ============ 自定义函数、方法 ============= # 显示对话框 func show(): visible = true pass # 隐藏对话框 func hide(): visible = false # 按打字机效果显示富文本框text属性中的文本 func show_text(): var time = rht.text.length() * speed rht.percent_visible = 0 tw.interpolate_property(rht,"percent_visible",0,1,time) tw.start() # ============ 属性setget处理函数 ============= # 为元件赋值text属性 - 对话的文字内容 func set_text(value): yield(get_tree().create_timer(0.5), "timeout") rht.bbcode_text = value show_text() pass # 为元件赋值role_name属性 - 对话的角色名称 func set_role_name(value): nameLab.text = value pass # ============ 事件处理函数 ============= func _on_RichTextLabel_click(): emit_signal("click") pass # Replace with function body. func _on_lastBtn_pressed(): emit_signal("last_clicked") pass # Replace with function body. func _on_nextBtn_pressed(): emit_signal("next_clicked") pass # Replace with function body. func _on_skipBtn_pressed(): emit_signal("skip_clicked") pass # Replace with function body. ``` 可以看到上述设计中通过将场景中子节点的信号以自定义信号形式传递到元件外部,使用者就可以在实际使用场景中通过处理这些自定义信号来完成具体的功能,这就是所谓的“事件映射法”。 ### RichTextLabel.gd ```python extends RichTextLabel signal click func _gui_input(event): # 左键单击 if event is InputEventMouseButton and event.pressed: if event.button_index == BUTTON_LEFT: emit_signal("click") # 触发自定义事件click pass ``` #### _gui_input _gui_input更适合场景上的GUI的事件处理和自定义信号。 ## 主场景 ![1628488124869](readme.assets/1628488124869.png) ![1628488149611](readme.assets/1628488149611.png) ### main.gd ```python extends Control var dlg_msg=[] var now_index = 0 func _ready(): $RPGDialog.role_name = "凌波丽" dlg_msg=[ "大家好,我是[color=red]凌波丽[/color]", "这是我的RPG对话框项目", "在这里我将演示如何使用此元件" ] $RPGDialog.show() $RPGDialog.text = dlg_msg[0] func show_dlg_text(): if now_index 0: now_index -= 1 $RPGDialog.text = dlg_msg[now_index] func _on_RPGDialog_click(): show_dlg_text() pass # Replace with function body. func _on_RPGDialog_last_clicked(): show_dlg_text_last() pass # Replace with function body. func _on_RPGDialog_next_clicked(): show_dlg_text() pass # Replace with function body. func _on_RPGDialog_skip_clicked(): $RPGDialog.hide() now_index = 0 pass # Replace with function body. ``` ## 低耦合元件设计的好处 可以看出,上面的对话框除了核心的文字显示功能外,不涉及任何实际的数据和按钮信号处理,相反把这些都抛给实际使用元件的主场景。 这样的设计好处是,元件功能保持了简单和单一化,但却也拥有了宝贵的复用性。只要你想,不同项目的不同游戏场景都可以使用同样的元件,处理相似或不相似的数据或逻辑。