Godot在 Godot 中使用代理模式将一些通用的功能封装起来
Posted 张学徒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Godot在 Godot 中使用代理模式将一些通用的功能封装起来相关的知识,希望对你有一定的参考价值。
Godot 3.4
代理模式:“代理”,顾名思义,将事情代由其他人来管理,这样自己就省事了。代理模式可以将原对象交由代理对象进行管理。
在 Godot 我们可以将一些比较常用的功能做成一个代理,用时创建一个这个对象即可。
比如我们可能有各种各样的节点都需要移动功能,如果是节点类型相同我们可以继承,但是如果不同的话,我们就得一个重写里,但是我们又不想一个个都给它写一遍,那我们就可以写个代理进行控制,需要用到,就给它创建出来就使用了。
创建一个 Move.gd
脚本,代码如下
extends Reference
class_name Move
## 调用的move方法,引用的方法
var move : FuncRef
## 移动方向
var direction := Vector2(0,0)
## 操控的宿主
var host : Node
#================================================
# 内置方法
#================================================
## 构造方法(new 对象时传入的参数)
## @h:操控的对象
## @move_method:操控的move的方法
func _init(h: Node, move_method: String):
host = h
# 没有这个方法则报错
assert(host.has_method(move_method), "没有 %s 方法" % move_method)
# 等待这个节点加载到场景树中
if not host.is_inside_tree():
yield(host, "tree_entered")
# 连接场景物理帧,在 Reference 类中模拟 Node 类中的 _physics_process 线程
host.get_tree().connect("physics_frame", self, "_physics_process", [host.get_physics_process_delta_time()])
# 引用 host 的移动方法
move = funcref(host, move_method)
#================================================
# 自定义方法
#================================================
## 模拟 Node 中的 _physics_process 物理帧方法
func _physics_process(_delta: float) -> void:
# 获取用户移动方向(你也可以修改成其他项目设置里的键位映射的键值)
direction = get_input("ui_left","ui_right","ui_up","ui_down").normalized()
# 调用move方法,用于传入移动方向,所以创建的对象的方法必须是带有一个参数的方法
move.call_func(direction)
## 获取用户的输入
## @left 向左移动按键映射
## @right 向右移动按键映射
## @up 向上移动按键映射
## @down 向下移动按键映射
func get_input(left, right, up, down):
direction.x = Input.get_action_strength(right) - Input.get_action_strength(left)
direction.y = Input.get_action_strength(down) - Input.get_action_strength(up)
return direction
新建一个场景,然后保存,再将 文件系统 中的 icon.png 图标拖拽到场景中,给这个 icon 创建一个脚本,脚本名随意,然后在里面写如下代码
extends Sprite
## 移动速度
export var move_speed : int = 300
## 移动代理,操控 self (当前节点) 的 move 方法
var move : Move = Move.new(self, "move")
## 移动
func move(velocity: Vector2):
position += velocity * move_speed * get_physics_process_delta_time()
运行场景,按下小键盘方向键,即可操纵移动
也可以将节点换成 KinematicBody2D 节点,代码内容只需稍改一下即可
extends KinematicBody2D
## 移动速度
export var move_speed : int = 300
## 移动代理
var move : Move = Move.new(self, "move")
## 移动
func move(velocity: Vector2):
move_and_slide(velocity * move_speed)
这样就可以很方便的对对象进行扩展,很灵活,对象的耦合度也很低。这只是一个比较简单的示例,可能看不出优势,如果是个稍微复杂的功能,也许代理模式就能派上用场了。
你可以举一反三制作出更多功能,欢迎交流。
以上是关于Godot在 Godot 中使用代理模式将一些通用的功能封装起来的主要内容,如果未能解决你的问题,请参考以下文章