求助:在Godot中实现宝可梦式长按按键持续网格移动
实现Godot网格移动的长按连续移动功能
要实现宝可梦风格的长按方向键持续网格移动,需要跟踪按键状态、添加移动完成后的自动续移逻辑,同时处理长按的初始延迟(避免轻触触发连续移动)。以下是修改后的完整代码及关键改动说明:
extends Area2D onready var ray = $RayCast2D onready var tween = $Tween export var speed = 30 export var hold_delay = 0.3 # 长按触发连续移动的延迟时间(秒) var tile_size = 16 var inputs = {"move_right": Vector2.RIGHT, "move_left": Vector2.LEFT, "move_up": Vector2.UP, "move_down": Vector2.DOWN} var current_dir = null var is_holding = false var hold_timer = 0.0 func _ready(): position = position.snapped(Vector2.ONE * tile_size) position += Vector2.ONE * tile_size/2 # 绑定动画完成信号,用于触发下一次移动 tween.connect("tween_completed", self, "_on_tween_completed") func _process(delta): if tween.is_active(): # 移动过程中更新长按计时器 if is_holding and current_dir: hold_timer -= delta if hold_timer <= 0: hold_timer = 1.0 / speed # 连续移动间隔与单次移动时间同步 move(current_dir) return # 检测当前按住的方向键 var new_dir = null for dir in inputs.keys(): if Input.is_action_pressed(dir): new_dir = dir break if new_dir: if current_dir != new_dir: # 切换方向或首次按下,立即移动并初始化长按状态 current_dir = new_dir is_holding = true hold_timer = hold_delay move(current_dir) else: is_holding = true else: # 松开按键,重置所有状态 current_dir = null is_holding = false hold_timer = 0.0 func move(dir): ray.cast_to = inputs[dir] * tile_size ray.force_raycast_update() if !ray.is_colliding(): move_tween(dir) func move_tween(dir): tween.interpolate_property(self, "position", position, position + inputs[dir] * tile_size, 1.0/speed, Tween.TRANS_SINE, Tween.EASE_IN_OUT) tween.start() func _on_tween_completed(object, key): # 移动完成后,若仍处于长按状态且计时器已归零,自动触发下一次移动 if is_holding and current_dir and hold_timer <= 0: hold_timer = 1.0 / speed move(current_dir)
关键改动说明
- 状态变量新增:
current_dir:记录当前按住的方向,确保只处理有效方向is_holding:标记用户是否处于长按状态hold_delay:可自定义的长按触发延迟,避免误触hold_timer:控制连续移动的触发时机
- 输入逻辑重构:
- 改用
_process持续检测输入状态,替代原单次事件触发逻辑,支持捕捉长按状态 - 首次按下方向键立即移动,之后等待延迟进入连续移动循环
- 松开按键时自动重置状态,停止连续移动
- 改用
- 动画完成回调:
- 绑定
tween_completed信号,确保一次移动动画结束后,若满足长按条件自动启动下一格移动 - 连续移动间隔与单次移动时间保持一致,保证移动流畅性
- 绑定
- 碰撞检测保留:
- 每次移动前仍通过RayCast检测前方障碍物,确保网格移动的合法性
内容的提问来源于stack exchange,提问作者Θάνος Δριβάκος
相关产品推荐
相关产品推荐

