HOME / 第 3 部分 · 2D 游戏开发实战 / 第 24 课
MODULE 3 · 2D 游戏开发实战
第 24 课 · 敌人 AI 基础:巡逻与追击
🎯 本课学习目标
- 实现敌人自动巡逻
- 让敌人检测玩家并追击
- 控制敌人速度与转向
本课实现最基础的敌人 AI:来回巡逻 + 发现玩家后追击。
📖 详细教学步骤
创建敌人场景搭建
新建场景,根节点 CharacterBody2D,命名 Enemy,保存 enemy.tscn;子节点:Sprite2D + CollisionShape2D;挂脚本 enemy.gd。
巡逻:来回移动代码
敌人以固定速度来回移动,撞墙掉头:
GDSCRIPTextends CharacterBody2D
@export var speed: float = 100.0
var direction: int = 1 # 1=右, -1=左
func _physics_process(delta):
velocity.x = direction * speed
move_and_slide()
# 撞墙掉头
if is_on_wall():
direction *= -1
巡逻 + 边缘检测(防掉落)进阶
走到平台边缘要掉头,用 RayCast2D 往下探测:
GDSCRIPT# 子节点: RayCast2D (位置在敌人脚下方, 朝下, 长度30)
@onready var floor_ray: RayCast2D = $FloorRay
func _physics_process(delta):
velocity.x = direction * speed
move_and_slide()
if is_on_wall() or not floor_ray.is_colliding():
direction *= -1 # 撞墙或前方没地面就掉头
追击:朝玩家移动代码
用 Area2D 感应玩家,进入范围就追击:
GDSCRIPTextends CharacterBody2D
@export var speed: float = 100.0
@export var chase_speed: float = 180.0
var chasing: bool = false
@onready var player = get_tree().get_first_node_in_group("player")
func _physics_process(delta):
if chasing and player:
# 朝玩家方向移动
var dir = (player.global_position - global_position).normalized()
velocity = dir * chase_speed
else:
velocity.x = speed
move_and_slide()
func _on_detect_body_entered(body):
if body.is_in_group("player"):
chasing = true
func _on_detect_body_exited(body):
if body.is_in_group("player"):
chasing = false
玩家加入分组操作
- 选中玩家根节点 Player
- 检查器顶部 Node → Groups(组) 标签
- 添加组名
player - 这样敌人就能用 is_in_group("player") 识别玩家
💡 组(Group)是 Godot 的「标签」机制,用于批量找到特定节点。
⚠️
敌人追击方向不对?
方向 = (玩家位置 - 敌人位置).normalized(),注意顺序别反。
⚠️
is_in_group 判断失败?
确认玩家已在 Node 属性的 Groups 里添加了 player 组名。
🧪 动手试一试
🏋️ 课后练习
让敌人站在平台边缘自动掉头不坠落,且玩家靠近 200 像素内开始追击。
RayCast2D 朝下探测 + Area2D 感应玩家 + 组识别。
💡
RayCast2D 是「射线探测器」,朝一个方向打射线,撞到东西 is_colliding() 为 true。
💡
用组(Group)管理同类节点,比一个个 get_node 高效得多。
🎓 本课小结
敌人 AI:固定速度巡逻 + 撞墙/边缘掉头 + Area2D 感应玩家追击;玩家用组(group)标记便于识别。