refactoring input and also rearranging folders

This commit is contained in:
Gordon Pedersen 2023-03-27 10:28:26 +11:00
parent 4f81bab8ef
commit 045a6f4e20
15 changed files with 173 additions and 123 deletions

View file

@ -1,110 +0,0 @@
# efficient input helpers that all take `args.inputs`
PRIMARY_KEYS = [:j, :z, :space]
def primary_down?(inputs)
PRIMARY_KEYS.any? { |k| inputs.keyboard.key_down.send(k) } ||
inputs.controller_one.key_down&.a
end
def primary_down_or_held?(inputs)
primary_down?(inputs) ||
PRIMARY_KEYS.any? { |k| inputs.keyboard.key_held.send(k) } ||
(inputs.controller_one.connected &&
inputs.controller_one.key_held.a)
end
SECONDARY_KEYS = [:k, :x, :backspace]
def secondary_down?(inputs)
SECONDARY_KEYS.any? { |k| inputs.keyboard.key_down.send(k) } ||
(inputs.controller_one.connected &&
inputs.controller_one.key_down.b)
end
def secondary_down_or_held?(inputs)
secondary_down?(inputs) ||
SECONDARY_KEYS.any? { |k| inputs.keyboard.key_held.send(k) } ||
(inputs.controller_one.connected &&
inputs.controller_one.key_held.b)
end
PAUSE_KEYS= [:escape, :p]
def pause_down?(inputs)
PAUSE_KEYS.any? { |k| inputs.keyboard.key_down.send(k) } ||
inputs.controller_one.key_down&.start
end
# check for arrow keys, WASD, gamepad, and swipe up
def up?(args)
args.inputs.up || args.state.swipe.up
end
# check for arrow keys, WASD, gamepad, and swipe down
def down?(args)
args.inputs.down || args.state.swipe.down
end
# check for arrow keys, WASD, gamepad, and swipe left
def left?(args)
args.inputs.left || args.state.swipe.left
end
# check for arrow keys, WASD, gamepad, and swipe right
def right?(args)
args.inputs.right || args.state.swipe.right
end
# called by the main #tick method to keep track of swipes, you likely don't
# need to call this yourself
#
# to check for swipes outside of the directional methods above, use it like
# this:
#
# if args.state.swipe.up
# # do the thing
# end
#
def track_swipe(args)
return unless mobile?
reset_swipe(args) if args.state.swipe.nil? || args.state.swipe.stop_tick
swipe = args.state.swipe
if args.inputs.mouse.down
swipe.merge!({
start_tick: args.state.tick_count,
start_x: args.inputs.mouse.x,
start_y: args.inputs.mouse.y,
})
end
if swipe.start_tick && swipe.start_x && swipe.start_y
p1 = [swipe.start_x, swipe.start_y]
p2 = [args.inputs.mouse.x, args.inputs.mouse.y]
dist = args.geometry.distance(p1, p2)
if dist > 50 # min distance threshold
swipe.merge!({
stop_x: p2[0],
stop_y: p2[1],
})
angle = args.geometry.angle_from(p1, p2)
swipe.angle = angle
swipe.dist = dist
swipe.stop_tick = args.state.tick_count
if angle > 315 || swipe.angle < 45
swipe.left = true
elsif angle >= 45 && angle <= 135
swipe.down = true
elsif angle > 135 && angle < 225
swipe.right = true
elsif angle >= 225 && angle <= 315
swipe.up = true
end
end
end
end
# reset the currently tracked swipe
def reset_swipe(args)
args.state.swipe = { up: false, down: false, right: false, left: false }
end

48
app/keybindings.rb Normal file
View file

@ -0,0 +1,48 @@
# frozen_string_literal: true
# Set the default input / key bindings here
module Input
class << self
PRIMARY_KEYS = [:j, :z, :space]
SECONDARY_KEYS = [:k, :x, :backspace]
PAUSE_KEYS = [:escape, :p]
BINDINGS = {
primary: {
keyboard: %i[j z space],
controller_one: %i[a]
},
secondary: {
keyboard: %i[k x backspace],
controller_one: %i[b]
},
pause: {
keyboard: %i[escape p],
controller_one: %i[start]
},
rotate_left: {
keyboard: %i[q j z space],
controller_one: %i[a l1]
},
rotate_right: {
keyboard: %i[e x backspace],
controller_one: %i[b l2]
},
up: {
keyboard: %i[w up],
controller_one: %i[up]
},
down: {
keyboard: %i[s down],
controller_one: %i[down]
},
left: {
keyboard: %i[a left],
controller_one: %i[left]
},
right: {
keyboard: %i[d right],
controller_one: %i[right]
}
}
end
end

View file

@ -4,20 +4,23 @@
require 'lib/coalesce.rb' require 'lib/coalesce.rb'
# then, some basic classes required for lists of assets # then, some basic classes required for lists of assets
require 'app/sprite_instance.rb' require 'app/classes/sprite_instance.rb'
require 'app/sound_instance.rb' require 'app/classes/sound_instance.rb'
# then, asset lists # then, asset lists
require 'sprites/_list.rb' require 'sprites/_list.rb'
require 'sounds/_list.rb' require 'sounds/_list.rb'
require 'music/_list.rb' require 'music/_list.rb'
# then, default keybindings
require 'app/keybindings.rb'
# then, utility classes # then, utility classes
require 'app/input.rb' require 'app/util/sprite.rb'
require 'app/sprite.rb' require 'app/util/sound.rb'
require 'app/util.rb' require 'app/util/music.rb'
require 'app/sound.rb' require 'app/util/util.rb'
require 'app/music.rb' require 'app/util/input.rb'
require 'app/constants.rb' require 'app/constants.rb'
require 'app/menu.rb' require 'app/menu.rb'

View file

@ -93,7 +93,7 @@ module Menu
end end
end end
if primary_down?(args.inputs) if Input.pressed?(args, :primary)
Sound.play(args, :select) Sound.play(args, :select)
options[menu_state.current_option_i][:on_select].call(args) options[menu_state.current_option_i][:on_select].call(args)
end end

View file

@ -13,7 +13,7 @@ module Scene
end end
# auto-pause & input-based pause # auto-pause & input-based pause
if !args.state.has_focus || pause_down?(args) if !args.state.has_focus || Input.pressed?(args, :pause)
return pause(args) return pause(args)
end end

View file

@ -30,7 +30,7 @@ module Scene
Music.pause(args) unless Music.stopped(args) Music.pause(args) unless Music.stopped(args)
if secondary_down?(args.inputs) if Input.pressed?(args, :secondary)
Sound.play(args, :select) Sound.play(args, :select)
options.find { |o| o[:key] == :resume }[:on_select].call(args) options.find { |o| o[:key] == :resume }[:on_select].call(args)

View file

@ -49,7 +49,7 @@ module Scene
Menu.tick(args, :settings, options) Menu.tick(args, :settings, options)
if secondary_down?(args.inputs) if Input.pressed?(args, :secondary)
Sound.play(args, :select) Sound.play(args, :select)
options.find { |o| o[:key] == :back }[:on_select].call(args) options.find { |o| o[:key] == :back }[:on_select].call(args)
end end

View file

@ -1,6 +1,6 @@
# Code that only gets run once on game start # Code that only gets run once on game start
def init(args) def init(args)
reset_swipe(args) Input.reset_swipe(args)
GameSetting.load_settings(args) GameSetting.load_settings(args)
end end
@ -13,7 +13,7 @@ def tick(args)
args.state.has_focus ||= true args.state.has_focus ||= true
Scene.push(args, :main_menu, reset: true) if !args.state.scene Scene.push(args, :main_menu, reset: true) if !args.state.scene
track_swipe(args) if mobile? Input.track_swipe(args) if mobile?
Scene.send("tick_#{args.state.scene}", args) Scene.send("tick_#{args.state.scene}", args)

109
app/util/input.rb Normal file
View file

@ -0,0 +1,109 @@
# frozen_string_literal: true
# Module for managing inputs.
module Input
class << self
def input_interaction?(args, input, interaction)
BINDINGS[input].any? do |source, bindings|
bindings.any? do |k|
args.inputs.send(source).send(interaction).send(k)
end
end
end
def pressed?(args, input)
input_interaction?(args, input, :key_down)
end
def held?(args, input)
input_interaction?(args, input, :key_held)
end
def released?(args, input)
input_interaction?(args, input, :key_up)
end
def pressed_or_held?(args, input)
pressed?(args, input) || held?(args, input)
end
# check for arrow keys, WASD, gamepad, and swipe up
def up?(args)
args.inputs.up || args.state.swipe.up
end
# check for arrow keys, WASD, gamepad, and swipe down
def down?(args)
args.inputs.down || args.state.swipe.down
end
# check for arrow keys, WASD, gamepad, and swipe left
def left?(args)
args.inputs.left || args.state.swipe.left
end
# check for arrow keys, WASD, gamepad, and swipe right
def right?(args)
args.inputs.right || args.state.swipe.right
end
# called by the main #tick method to keep track of swipes, you likely don't
# need to call this yourself
#
# to check for swipes outside of the directional methods above, use it like
# this:
#
# if args.state.swipe.up
# # do the thing
# end
#
def track_swipe(args)
return unless mobile?
reset_swipe(args) if args.state.swipe.nil? || args.state.swipe.stop_tick
swipe = args.state.swipe
if args.inputs.mouse.down
swipe.merge!({
start_tick: args.state.tick_count,
start_x: args.inputs.mouse.x,
start_y: args.inputs.mouse.y,
})
end
if swipe.start_tick && swipe.start_x && swipe.start_y
p1 = [swipe.start_x, swipe.start_y]
p2 = [args.inputs.mouse.x, args.inputs.mouse.y]
dist = args.geometry.distance(p1, p2)
if dist > 50 # min distance threshold
swipe.merge!({
stop_x: p2[0],
stop_y: p2[1],
})
angle = args.geometry.angle_from(p1, p2)
swipe.angle = angle
swipe.dist = dist
swipe.stop_tick = args.state.tick_count
if angle > 315 || swipe.angle < 45
swipe.left = true
elsif angle >= 45 && angle <= 135
swipe.down = true
elsif angle > 135 && angle < 225
swipe.right = true
elsif angle >= 225 && angle <= 315
swipe.up = true
end
end
end
end
# reset the currently tracked swipe
def reset_swipe(args)
args.state.swipe = { up: false, down: false, right: false, left: false }
end
end
end