Kết nối với tín hiệu
Thuộc phần Lập trình hướng đối tượng trong hành trình GDScript của Coddy. Bài học 37 trên 65.
connect() nhận hàm cần chạy dưới dạng Callable. Ghi tên phương thức không có dấu ngoặc đơn hoặc viết lambda:
chest.opened.connect(_on_chest_opened) # một phương thức (method) của script này
chest.opened.connect(quest_log.add_entry) # một phương thức của đối tượng khác
chest.opened.connect(func(): print("Creak!")) # một hàm lambdaGodot đặt tên cho phương thức lắng nghe theo thứ tự _on_, tên đối tượng phát tín hiệu, rồi đến tên tín hiệu: _on_chest_opened. Một tín hiệu có thể kết nối với nhiều hàm, và chúng chạy theo thứ tự được kết nối.
Một đối tượng lắng nghe thường tự kết nối trong một phương thức nhận đối tượng phát sự kiện:
# quest_log.gd
class_name QuestLog
extends RefCounted
var chests_opened := 0
func track(chest: Chest) -> void:
if not chest.opened.is_connected(_on_chest_opened):
chest.opened.connect(_on_chest_opened)
func untrack(chest: Chest) -> void:
if chest.opened.is_connected(_on_chest_opened):
chest.opened.disconnect(_on_chest_opened)
func _on_chest_opened() -> void:
chests_opened += 1Kết nối cùng một hàm với cùng một tín hiệu hai lần sẽ gây ra lỗi, và ngắt kết nối một hàm chưa được kết nối cũng vậy. is_connected() kiểm tra trước. disconnect() ngừng lắng nghe, và lần phát tín hiệu tiếp theo sẽ không chạy hàm đó nữa.
Truyền CONNECT_ONE_SHOT làm đối số (argument) thứ hai, kết nối sẽ tự xóa sau lần gọi đầu tiên: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).
Lambda giữ giá trị mà biến cục bộ có tại thời điểm tạo lambda. count += 1 bên trong một lambda đã kết nối sẽ thay đổi bản sao đó, còn count trong _ready() vẫn là 0. Hãy giữ bộ đếm trong biến thành viên của một đối tượng lắng nghe, như QuestLog.
Thử thách
DễTrường bắn có các mục tiêu phát tín hiệu hit khi bị bắn. Hãy viết ScoreBoard để lắng nghe các tín hiệu đó:
watch(target)kết nối tín hiệuhitcủa mục tiêu với_on_target_hit. Theo dõi một mục tiêu đã được theo dõi không làm thay đổi gì.ignore(target)ngắt kết nối tín hiệu. Bỏ theo dõi một mục tiêu chưa được theo dõi không làm thay đổi gì._on_target_hit()cộng10vàopointsvà in raHit! Score: N.
Theo dõi hai lần hoặc bỏ theo dõi một mục tiêu chưa được theo dõi không được gây lỗi, vì bất kỳ lỗi nào cũng khiến bài kiểm tra thất bại. target.gd đã hoàn chỉnh.
Code được cung cấp đọc số lượng mục tiêu, sau đó đọc các lệnh như watch 0, ignore 0 và shoot 0, rồi in ra điểm số cuối cùng. Với hai mục tiêu và các lệnh watch 0, shoot 0, shoot 1, watch 1, watch 1, shoot 1, ignore 0, shoot 0, chương trình in ra:
Shot target 0
Hit! Score: 10
Shot target 1
Shot target 1
Hit! Score: 20
Shot target 0
Final score: 20Code của bạn nằm trong score_board.gd và target.gd. main.gd chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.
Tự làm thử
extends Node
func _ready():
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
var board := ScoreBoard.new()
var targets: Array[Target] = []
for i in int(OS.read_string_from_stdin()):
targets.append(Target.new())
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
var target := targets[int(parts[1])]
if parts[0] == "watch":
board.watch(target)
elif parts[0] == "ignore":
board.ignore(target)
else:
print("Shot target ", parts[1])
target.shoot()
print("Final score: ", board.points)
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng về OOP
Tệp bên ngoàiGiới thiệu về OOPLớp và đối tượngTừ khóa selfPhương thứcThuộc tínhHàm khởi tạo (_init)Ôn tập: máy tính đơn giản4Tính đa hình
Xem lại cách ghi đè phương thứcĐịnh kiểu vịtLớp và phương thức trừu tượngThiết kế interfaceÔn tập: máy tính hình học7Tín hiệu
Tín hiệu là gì?Khai báo và phát tín hiệuKết nối với tín hiệuTín hiệu có đối sốÔn tập: hệ thống sức khỏe10Các mẫu thiết kế phần 2
Mẫu lệnhMẫu bộ chuyển đổiMẫu trang tríMẫu phương thức khuôn mẫuMẫu trạng tháiMẫu tổng hợp2Thuộc tính của lớp
Biến instance và biến staticHàm staticPhương thức thiết lập thuộc tínhPhương thức lấy thuộc tínhQuy ước về tính riêng tưÔn tập: trình quản lý tài khoản ngân hàng5Tính đóng gói
Thành viên công khai và riêng tưXác thực bằng phương thức setterẨn thông tinThuộc tính chỉ đọcÔn tập: hệ thống hồ sơ học sinh8Khái niệm OOP nâng cao
Kết hợp và kế thừaLớp bên trongNode dưới dạng thành phầnRefCounted và NodeEnum trong lớpTự luyện tập: Trình biên dịch GDScript online