本文内容已上传开源仓库:扫雷:一个简单的扫雷游戏,基于Godot4.6 - AtomGit | GitCode
一、在Tile节点上挂载脚本
打开tile.tscn,在选中Tile节点的状态下,点击右侧挂在脚本按钮:

点击文件夹图标选择保存路径为"代码"文件夹,其余内容保持默认,选择好后点击创建:

二、信号与连接
在Godot中,信号是一个重要概念,是节点内部、节点与节点之间互相通信的桥梁。
现在来想象这样一个场景:你在房间里写代码,外卖员在楼下按门铃。
- 「按门铃」是一个事件(有人来了);
- 「门铃响」是一个信号(通知你 "有外卖");
- 你听到门铃后去开门,是响应信号的动作。
在Godot中,信号的逻辑完全一样:
- 事件:比如 "鼠标点击了 Tile 格子""键盘按下了空格";
- 信号:节点发出的「通知」(比如Tile的gui_input信号,就是在说 "我被鼠标 / 键盘操作了!");
- 响应函数:你写的代码(就是 "听到通知后要做的事")。
接下来,我们来尝试使用Godot自带的信号连接:
在左侧的栏目中,点击"信号"切换至信号栏,找到"gui_input(event:InputEvent):

双击打开连接页面,保持默认,点击连接:

可以看到,脚本里已经自动创建了一个名为"_on_gui_input"的响应函数:

在这里,gui_input(event:InputEvent)括号里的内容,是信号的捎带信息:
- event是一个变量,存了 "具体是什么操作";
- 比如你左键点击Tile,event里就会存 "这是鼠标左键按下事件";你右键点击,event就存 "这是鼠标右键按下事件"。
- 后面你写代码时,就能通过event判断用户是左键还是右键,从而做不同的事(左键翻开、右键插旗)。
三、完善tile脚本
python
extends Control
# 自定义信号:当格子被点击时发送,传递自身引用
signal clicked(tile: Node)
# 节点绑定
@onready var bg: ColorRect = $ColorRect
# 状态变量
var is_revealed: bool = false # 标记格子是否已翻开
# 处理鼠标输入事件
func _on_gui_input(event: InputEvent):
# 检查是否是鼠标按钮按下事件
if event is InputEventMouseButton and event.pressed:
# 检查是否是左键点击
if event.button_index == MOUSE_BUTTON_LEFT:
# 发送点击信号
clicked.emit(self)
# 翻开格子函数
func reveal():
# 如果已经翻开,直接返回
if is_revealed:
return
# 标记为已翻开
is_revealed = true
# 改变背景颜色为浅灰色,表示已翻开
bg.color = Color(0.9, 0.9, 0.9)
需要注意的是,在此处,我们必须将ColorRect的Mouse-Filter属性设为Ignore,否则会出现"吞输入"的问题,当鼠标点击地块时,被判定为点击在了ColorRect上而非Tile上,这样就无法正常翻开地块了:

四、完善主逻辑
python
extends Control
const GRID_SIZE = 10
const TILE_SCENE = preload("res://场景/tile.tscn")
var tiles: Array = []
@onready var grid: GridContainer = $grid
func _ready():
_init_grid()
_connect_signals() # 新增:连接信号
func _init_grid():
for i in range(GRID_SIZE * GRID_SIZE):
var tile = TILE_SCENE.instantiate()
tile.custom_minimum_size = Vector2(50, 50)
grid.add_child(tile)
tiles.append(tile)
# 新增:连接所有格子的点击信号
func _connect_signals():
for tile in tiles:
tile.clicked.connect(_on_tile_clicked)
# 新增:处理格子点击事件
func _on_tile_clicked(tile: Control):
tile.reveal()
五、运行测试
点击运行按钮,可以看到鼠标左键可以正常让色块变色:

