概述
之前代码中,我们总会去判断按键的输入,然而由于Input又臭又长的函数名和必须赋予的动作名称,代码看起来很不美观。所以这节我们使用Godot的自动加载功能,也就是创建单例的方法来将按键处理封装为一个简单的全局对象,然后再调用其中封装的函数来重构我们的代码。
mInput.gd
![]() |
![]() |
|---|---|
# mInput.gd 加载为单例,全局可用。extends Node# 将会使用到的动作名称保存到相应的变量var left_action = "ui_left"var right_action = "ui_right"var up_action = "ui_up"var down_action = "ui_down"var jump_action = "ui_accept"# 封装Input.is_action_just_pressed()func just_pressed(action:String) -> bool:return Input.is_action_just_pressed(action)# 封装Input.is_action_pressed()func pressed(action:String) -> bool:return Input.is_action_pressed(action)# 跳跃func input_jump() -> bool:return just_pressed(jump_action)# 获取水平方向上的方向或按键力度func get_x():return Input.get_axis(left_action,right_action)# 获取垂直方向上的方向或按键力度func get_y():return Input.get_axis(left_action,right_action)# 获取上下左右按键所取得的方向向量。func get_dir():return Input.get_vector(left_action,right_action,up_action,down_action)
代码分析
可以看到,首先我们使用变量来存储我们将要用到的动作名称,然后我们封装了Input.is_action_just_pressed和Input.is_action_pressed,最后再封装各种函数来对应我们常用的输入,比如,跳跃、左右移动或上下移动以及在平面移动时获取的方向或力度以及方向向量。
用自动加载创建单例
我们在项目设置、自动加载下添加我们的mInput.gd代码为单例MInput。
用单例重构代码
此时我们就可以在本项目的任何场景中将MInput作为一个全局对象直接访问了,当然也包括它的各种成员变量和方法。所谓单例就是在整个声明周期中只有一个实例的类,简单的也可以理解为全局对象。
此时,我们再次重构上一节的代码:
代码
![]() |
![]() |
![]() |
|---|---|---|
原始代码
extends KinematicBody2Dvar speed = 60.0 # 速度 像素/秒var velocity = Vector2.ZERO # 速度向量var gravity = 3000 # 重力加速度var jump_force = 3000.0 # 单次跳跃高度var is_jumping = falseenum states {ON_FLOOR, # 在地面上IN_AIR # 在空中}var _state = states.IN_AIRfunc _physics_process(delta):velocity = Vector2.ZEROmatch _state:# 在地面states.ON_FLOOR:# 边缘掉落if not is_on_floor():change_state_to(states.ON_FLOOR)is_jumping = falsereturn# 左右移动velocity.x = MInput.get_x() * speed# 实现下落 -- 用于边缘下落velocity.y += gravity * delta# 跳跃if MInput.input_jump():velocity.y = -jump_forcechange_state_to(states.IN_AIR)is_jumping = truevelocity = move_and_slide(velocity,Vector2.UP)# 在空中states.IN_AIR:# 掉到地板if is_on_floor():change_state_to(states.ON_FLOOR)is_jumping = falsereturn# 左右移动velocity.x = MInput.get_x() * speed# 实现下落 -- 用于边缘下落velocity.y += gravity * delta# 跳跃 -- 二级跳if is_jumping and MInput.input_jump():velocity.y = -jump_forcechange_state_to(states.IN_AIR)is_jumping = falsevelocity = move_and_slide(velocity,Vector2.UP)pass# 更改状态func change_state_to(new_state:int):_state = new_state# 根据不同的状态,进行一些额外配置match _state:states.IN_AIR:passstates.ON_FLOOR:pass
总结
可以看到,通过调用MInput单例(或者你可以叫全局对象),你可以避开以往又臭又长的按键检测代码。
当然,本节的按键处理单例还只是个初步的玩法,你完全可以更进一步的封装来彻底简化Input和InputMap相关的代码。当然,这种模式也是可以跨游戏项目复用的,基本原理有了,具体怎么写怎么实现都无所谓了。





