-
Notifications
You must be signed in to change notification settings - Fork 16
At the end of this chapter, your game will look like the image below. We will reach this target in two steps. First, add GUI containers to design a static UI layout. You should be familiar with size flags before continue. Second, whenever we used to call print()
, now we emit a signal. Let GUI containers receive these signals and update their content.
Open MainGUI.tscn
. Remove existing nodes. Add new nodes as shown below. Also remember to change the type of the root node.
MainGUI (MarginContainer)
- MainHBox (HBoxContainer)
-- Modeline (Label)
-- SidebarVBox (VBoxContainer)
--- Turn (Label)
--- Help (Label)
Open MainScene.tscn
. Set MainGUI
node's margin so that it leaves 20 pixel on four sides.
Since there are three label nodes and we intend to apply the same style to them, we'd better create these nodes from a scene. Select MainHBox/Modeline
. Change its font to FiraCode-Regular.ttf
and font color to ABB2BF
. Save the branch as scene: res://sprite/GUIText.tscn
. Replace all label nodes.
The last step in this part is to set containers so as to align text automatically.
Modeline
:
-
Size Flags/Horizontal
:Fill
,Expand
. -
Size Flags/Vertical
:Shrink End
.
SidebarVBox
:
-
Rect/Min Size
:x: 180
.
Turn
:
-
Size Flags/Vertical
:Fill
,Expand
.
There are three labels under MainGUI
node. Help
prints a static text. Turn
prints a number which starts from 0 and updates by 1 whenever PC's turn begins. Modeline
prints one of four texts when: (1) PC tries to leave the dungeon; (2) PC bumps into a wall; (3) PC is close to an NPC; (4) PC kills an NPC.
Let's take care of Help
and Turn
first. Attach SidebarVBox.gd
to SidebarVBox
.
# SidebarVBox.gd
var _turn_counter: int = 0
var _turn_text: String = "Turn: {0}"
onready var _label_help: Label = get_node("Help")
onready var _label_turn: Label = get_node("Turn")
func _ready() -> void:
_label_help.text = "RL Demo"
_update_turn()
func _on_Schedule_turn_started(current_sprite: Sprite) -> void:
if current_sprite.is_in_group(_new_GroupName.PC):
_turn_counter += 1
_update_turn()
func _update_turn() -> void:
_label_turn.text = _turn_text.format([_turn_counter])
Let PCMove.gd
, PCAttack.gd
and EnemyAI.gd
emit three signals instead of print messages in output panel.
# PCMove.gd
signal pc_moved(message)
func _try_move(x: int, y: int) -> void:
if not _ref_DungeonBoard.is_inside_dungeon(x, y):
emit_signal("pc_moved", "You cannot leave the map.")
elif _ref_DungeonBoard.has_sprite(_new_GroupName.WALL, x, y):
emit_signal("pc_moved", "You bump into wall.")
# PCAttack.gd
signal pc_attacked(message)
func attack(group_name: String, x: int, y: int) -> void:
if not _ref_DungeonBoard.has_sprite(group_name, x, y):
return
_ref_RemoveObject.remove(group_name, x, y)
_ref_Schedule.end_turn()
emit_signal("pc_attacked", "You kill Urist McRogueliker! :(")
# EnemyAI.gd
signal enemy_warned(message)
func _on_Schedule_turn_started(current_sprite: Sprite) -> void:
if not current_sprite.is_in_group(_new_GroupName.DWARF):
return
if _pc_is_close(_pc, current_sprite):
emit_signal("enemy_warned", "Urist McRogueliker is scared!")
_ref_Schedule.end_turn()
The last step is attaching Modeline.gd
to Modeline
. The script receives the three signals above. It also receives turn_ended
from Schedule.gd
to clear text every turn.
# Schedule.gd
signal turn_ended(current_sprite)
func end_turn() -> void:
emit_signal("turn_ended", _get_current())
_goto_next()
emit_signal("turn_started", _get_current())
# Modeline.gd
func _ready() -> void:
text = "Press Space to start game."
func _on_Schedule_turn_ended(current_sprite: Sprite) -> void:
if current_sprite.is_in_group(_new_GroupName.PC):
text = ""
func _on_EnemyAI_enemy_warned(message: String) -> void:
text = message
func _on_PCMove_pc_moved(message: String) -> void:
text = message
func _on_PCAttack_pc_attacked(message: String) -> void:
text = message