1 蝙蝠随机游荡

新建Node2D节点WanderController,保存到enemies目录下,用来保存小怪游荡的初始位置

建一个一次性计时器,勾选一次性和自动开始,等待时间为1

image-20240612124428864

蝙蝠游荡逻辑,WanderController.gd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
extends Node2D

@export var wander_range:int = 32

#小怪开始游离位置
@onready var start_position = global_position
#游离目标位置
@onready var target_position = global_position

@onready var timer: Timer = $Timer

#不加开始时不会移动,因为@onready var target_position = global_position
func _ready() -> void:
update_target_position()

func update_target_position():

#随机游荡位置
var target_vector = Vector2(randi_range(-wander_range,wander_range),randi_range(-wander_range,wander_range))
target_position = start_position + target_vector

#剩余时间
func get_time_left():
return timer.time_left

func start_wander_timer(duration):
timer.start(duration)

func _on_timer_timeout() -> void:
#更新目标位置
update_target_position()

2 蝙蝠随机切换状态

1
2
3
4
#蝙蝠获得随机状态	
func pick_new_state(state_list):
state_list.shuffle()
return state_list.pop_front()

3 应用闲逛

时间到,切换随机状态。

在蝙蝠的IDLE、WANDER状态里应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
	match state:
IDLE:
# 蝙蝠的击退速度
velocity=velocity.move_toward(Vector2.ZERO,FRICTION * delta)
seek_player()

if wander_controller.get_time_left() == 0:
state = pick_new_state([IDLE,WANDER])

......

WANDER:
seek_player()

if wander_controller.get_time_left() == 0:
state = pick_new_state([IDLE,WANDER])

#闲逛时长
wander_controller.start_wander_timer(randi_range(1,3))

#闲逛,目标不是玩家,而是wander的位置
var direction = global_position.direction_to(wander_controller.target_position)
velocity = velocity.move_toward(direction * MAX_SPEED ,ACCELERATION * delta)

#优化,快接近目标,就算结束
if global_position.distance_to(wander_controller.target_position) <= MAX_SPEED:

state = pick_new_state([IDLE,WANDER])
wander_controller.start_wander_timer(randi_range(1,3))

4 优化

随机初始状态

1
2
func _ready() -> void:
state = pick_new_state([IDLE,WANDER])

抽取一些重复的代码