Skip to content

Instantly share code, notes, and snippets.

@bohman
Created October 26, 2024 10:56
Show Gist options
  • Save bohman/33aa2504858c3b6414911f2046f86053 to your computer and use it in GitHub Desktop.
Save bohman/33aa2504858c3b6414911f2046f86053 to your computer and use it in GitHub Desktop.
extends Node
###
#
# Input Controller
#
# Register this script as an autoloader and use it to
# keep track of global inputs and input types.
#
###
signal input_type_changed
#
# Settings
#
# We make some pragmatic assumptions:
#
# - All input images are the same size to make
# it easy to switch between them
#
# - An action will be represented by a single
# key representation. TODO: this is something
# that should be re-examined. It will show the
# wrong key on a DVORAK, for instance.
#
var input_image_size = Vector2(64, 64)
var key_images = {
'ui_accept' = {
'mouse' = null,
'keyboard' = 'keyboard_space.png',
'controller' = 'switch_buttons_down_outline.png',
},
'ui_cancel' = {
'mouse' = null,
'keyboard' = 'keyboard_escape.png',
'controller' = 'switch_buttons_right_outline.png',
},
'yad_scroll_up_right' = {
'mouse' = null,
'keyboard' = 'keyboard_w.png',
'controller' = 'playstation_trigger_r1_alternative.png',
},
'yad_scroll_up_left' = {
'mouse' = null,
'keyboard' = 'keyboard_q.png',
'controller' = 'playstation_trigger_l1_alternative.png',
},
'yad_scroll_down_right' = {
'mouse' = null,
'keyboard' = 'keyboard_s.png',
'controller' = 'playstation_trigger_r2_alternative.png',
},
'yad_scroll_down_left' = {
'mouse' = null,
'keyboard' = 'keyboard_a.png',
'controller' = 'playstation_trigger_l2_alternative.png',
}
}
#
# Stores the current input type
# TODO: We could make this tighter with enums
#
var current_input_type: String = 'mouse':
set(new_value):
if new_value != current_input_type:
current_input_type = new_value
input_type_changed.emit()
#
# A reference that stores all texture_rects
# we create with this script. Whenever input
# type changes, we loop through these and
# update their textures.
#
var texture_rects = {}
#
# Actions that aren't continuous can be handled here
#
func _input(event) -> void:
_set_current_input_based_on_event(event)
if Input.is_action_just_pressed("ui_cancel"):
SignalBus.toggle_menu.emit()
#
# Actions that are continuous need to be handled here
#
func _physics_process(_delta) -> void:
if Input.is_action_pressed("yad_scroll_up_left"):
SignalBus.scroll_up_left.emit()
if Input.is_action_pressed("yad_scroll_down_left"):
SignalBus.scroll_down_left.emit()
if Input.is_action_pressed("yad_scroll_up_right"):
SignalBus.scroll_up_right.emit()
if Input.is_action_pressed("yad_scroll_down_right"):
SignalBus.scroll_down_right.emit()
#
# Ready
#
func _ready() -> void:
input_type_changed.connect(_on_input_type_changed)
#
# Signal reactions
#
func _on_input_type_changed() -> void:
_update_texture_rects()
#
# Helpers
#
func _set_current_input_based_on_event(event) -> void:
if event is InputEventKey:
current_input_type = 'keyboard'
elif event is InputEventMouseButton || event is InputEventMouseMotion:
current_input_type = 'mouse'
elif event is InputEventJoypadMotion || event is InputEventJoypadButton:
current_input_type = 'controller'
func _update_texture_rects() -> void:
for instance_id in texture_rects.keys():
var texture_rect = texture_rects[instance_id]
if !is_instance_valid(texture_rect):
texture_rects.erase(instance_id)
continue
var action = texture_rect.get_meta('input_action')
var image_texture = get_key_texture(action)
texture_rect.set_texture(image_texture)
func get_key_image_string(action = ''):
if action == '' || !key_images.has(action):
return null
if !key_images[action].has(current_input_type):
return null
return key_images[action][current_input_type]
func get_key_texture(action = '') -> Texture:
var image = get_key_image_string(action)
if image == null:
return null
var path = 'res://images/input/' + current_input_type + '/' + image
var texture = load(path)
return texture
func create_texture_rect(action = '') -> TextureRect:
var texture_rect = TextureRect.new()
texture_rect.set_meta('input_action', action)
texture_rect.z_index = 50
texture_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
texture_rect.pivot_offset = input_image_size / 2
var texture = get_key_texture(action)
texture_rect.set_texture(texture)
var instance_id = texture_rect.get_instance_id()
texture_rects[instance_id] = texture_rect
return texture_rects[instance_id]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment