Sinais próprios
Um nó declara um sinal e nunca fica sabendo quem escuta. Cinco painéis se conectam a ele e acendem quando chega a vez de cada um.
O editor acima está rodando este projeto. Mude uma linha e ele recarrega.
Classes do Godot usadas
signalSignal.emitSignal.connectPanelContainer
O código
scripts/main.gd
extends Node
signal ping(slot: int)
signal broadcast(message: String)
const NAMES: Array = ['audio', 'score', 'quest', 'hud', 'save']
const TICK: float = 0.09
var status: Label
var elapsed: float = 0.0
var emitted: int = 0
func _ready() -> void:
var column: VBoxContainer = _root()
var title: Label = Label.new()
title.text = 'Five listeners, one signal'
title.add_theme_font_size_override('font_size', 28)
column.add_child(title)
var hint: Label = Label.new()
hint.text = 'main.gd declares signal ping(slot) and knows nothing about who listens. Each panel connects itself.'
hint.add_theme_color_override('font_color', Color('#8a90a0'))
column.add_child(hint)
var row: HBoxContainer = HBoxContainer.new()
row.add_theme_constant_override('separation', 16)
column.add_child(row)
var listener_script: GDScript = Get.script('listener')
for i in NAMES.size():
var listener: PanelContainer = PanelContainer.new()
listener.set_script(listener_script)
row.add_child(listener)
listener.setup(i, NAMES[i])
ping.connect(listener.on_ping)
broadcast.connect(listener.on_broadcast)
var button: Button = Button.new()
button.text = 'emit broadcast to everyone'
button.pressed.connect(func(): broadcast.emit('broadcast'))
column.add_child(button)
status = Label.new()
status.add_theme_color_override('font_color', Color('#8eef97'))
status.text = 'nothing emitted yet'
column.add_child(status)
print('a ping walks the slots on its own, the button hits every listener at once')
func _process(delta: float) -> void:
elapsed += delta
if elapsed < TICK:
return
elapsed = 0.0
var slot: int = emitted % NAMES.size()
emitted += 1
if emitted % 13 == 0:
broadcast.emit('broadcast')
status.text = 'broadcast reached all %d listeners' % NAMES.size()
return
ping.emit(slot)
status.text = 'ping(%d) emitted, %d emits so far' % [slot, emitted]
func _root() -> VBoxContainer:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
var center: CenterContainer = CenterContainer.new()
add_child(center)
center.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
var column: VBoxContainer = VBoxContainer.new()
column.custom_minimum_size = Vector2(1030, 0)
column.add_theme_constant_override('separation', 18)
center.add_child(column)
return columnscripts/listener.gd
extends PanelContainer
const IDLE: Color = Color('#2a2f3d')
const LIT: Color = Color('#8da5f3')
var slot: int = 0
var hits: int = 0
var glow: float = 0.0
var style: StyleBoxFlat
var counter: Label
var last: Label
func setup(index: int, listener_name: String) -> void:
slot = index
style = StyleBoxFlat.new()
style.bg_color = IDLE
style.set_corner_radius_all(14)
style.set_content_margin_all(18)
add_theme_stylebox_override('panel', style)
custom_minimum_size = Vector2(190, 150)
var box: VBoxContainer = VBoxContainer.new()
box.add_theme_constant_override('separation', 6)
add_child(box)
var title: Label = Label.new()
title.text = listener_name
title.add_theme_font_size_override('font_size', 20)
box.add_child(title)
last = Label.new()
last.text = 'slot %d' % slot
last.add_theme_color_override('font_color', Color('#8a90a0'))
box.add_child(last)
counter = Label.new()
counter.text = '0'
counter.add_theme_font_size_override('font_size', 44)
box.add_child(counter)
func on_ping(index: int) -> void:
if index != slot:
return
hits += 1
glow = 1.0
counter.text = str(hits)
last.text = 'ping(%d)' % index
func on_broadcast(message: String) -> void:
hits += 1
glow = 1.0
counter.text = str(hits)
last.text = message
func _process(delta: float) -> void:
if glow <= 0.0:
return
glow = maxf(glow - delta * 3.0, 0.0)
style.bg_color = IDLE.lerp(LIT, glow)