summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Harley2020-07-12 14:41:13 +0100
committerTom Harley2020-07-12 14:41:13 +0100
commitbbd2bff9735f37195c51d57e3c501ae894fee3e9 (patch)
tree86b173b4bd93fcbb66c55e6cd1c0955a584cd306
parentInitial commit (diff)
downloadtyping-twister-bbd2bff9735f37195c51d57e3c501ae894fee3e9.tar.gz
typing-twister-bbd2bff9735f37195c51d57e3c501ae894fee3e9.zip

Lots of changes lol

-rw-r--r--main.rb242
1 files changed, 175 insertions, 67 deletions
diff --git a/main.rb b/main.rb
index 0a8cf78..abfbfb3 100644
--- a/main.rb
+++ b/main.rb
@@ -1,39 +1,137 @@
# vim: ft=ruby ts=2 sw=2 et tw=72
+def dist(a, b)
+ dx = b.x - a.x
+ dy = b.y - a.y
+ Math.sqrt(dx * dx + dy * dy)
+end
+
+def key_dist(state, a, b)
+ dist(state.key_positions[a][:pos], state.key_positions[b][:pos])
+end
+
def offset(pos, off)
x, y, *rest = pos
[x + off.x, y + off.y, *rest]
end
def colour_key(state, key, colour)
- puts "colour_key: #{state.key_positions[key]}"
+ x = 3
pos = offset(state.key_positions[key][:pos], state.keyboard.pos)
- [*pos, *colour].solid
+ [pos.x + x, pos.y + x, pos.w - x * 2, pos.h - x * 2, *colour].solid
+end
+
+def pressed_keys(state, keys)
+ blue = [50, 50, 187, 200]
+ cyan = [50, 187, 187, 200]
+
+ valid_keys = keys
+ .select { |key| state.keys.include? key }
+ .reject { |key| key == state.failed_challenge[:key] }
+
+ valid_keys.map { |key|
+ colour = state.past_challenges.any? { |ch| ch[:key] == key } ? blue : cyan
+ colour_key(state, key, colour)
+ }
+end
+
+def edge_keys(state)
+ green = [50, 187, 50, 200]
+ grey = [0, 0, 0, 100]
+
+ state.key_positions
+ .reject { |_k, v| v[:game] }
+ .reject { |k, _v| k == :space }
+ .map { |k, _v| colour_key(state, k, grey) }
+ .append(colour_key(state, :space, state.playing ? grey : green))
end
def make_background(grid)
[*grid.rect, 80, 80, 150].solid
end
-def new_challenge(state, reset: false)
+def new_challenge(state, outputs, reset: false, sound: true)
if reset then
state.past_challenges = []
+ state.score = 0
+ (outputs.sounds << "sfx/game_start.wav") if sound
else
state.past_challenges << state.challenge
+ state.score += 1
+ (outputs.sounds << "sfx/correct.wav") if sound
end
hand = state.hands.sample
- finger = state.fingers.sample
+
+ puts hand
+
+ unused_fingers = state.fingers
+ .reject { |f| state.past_challenges
+ .any? { |ch| f == ch[:finger] && hand == ch[:hand] } }
+
+ fingers_but_most_recent = state.fingers - [state.challenge[:finger]]
+
+ puts "unused fingers: #{unused_fingers}"
+
+ finger_choice = case [0, unused_fingers.length].sample
+ when 0
+ fingers_but_most_recent
+ else
+ unused_fingers
+ end
+
+ puts "finger choice: #{finger_choice}"
+
+ finger = finger_choice.sample
+
+ finger = (state.fingers - [state.challenge[:finger]]).sample
+ puts finger
+ adj_fingers = case finger
+ when "little finger"
+ ["ring finger"]
+ when "ring finger"
+ ["little finger", "middle finger"]
+ when "middle finger"
+ ["ring finger", "index finger"]
+ when "index finger"
+ ["middle finger", "thumb"]
+ when "thumb"
+ ["index finger"]
+ end
+
+ puts adj_fingers.to_s
+
+ adj_finger_keys = state.past_challenges
+ .select { |ch| adj_fingers.include? ch[:finger] }
+ .select { |ch| hand == ch[:hand] }
+ .map { |ch| ch[:key] }
+
+ puts adj_finger_keys.to_s
+
+ available_keys = state.keys
+ .reject { |key| state.past_challenges.any? { |ch| key == ch[:key] } }
+
+ puts "available keys: #{available_keys.to_s}"
+
+ nearby_keys = available_keys
+ .select { |key| adj_finger_keys
+ .all? { |k2| key_dist(state, key, k2) < 250 } }
+
+ puts "nearby_keys: #{nearby_keys.to_s}"
+
+ key = (nearby_keys or available_keys).sample
+
+ puts "chosen key: #{key or "nil"}"
+
+ # key = state.keys
+ # .reject { |key| state.past_challenges.any? { |ch| key == ch[:key] } }
+ # .sample
# remove old challenge that used the same finger
state.past_challenges
.reject! { |ch| ch[:finger] == finger && ch[:hand] == hand }
- key = state.keys
- .reject { |key| state.past_challenges.any? { |ch| key == ch[:key] } }
- .sample
-
state.challenge = {
hand: hand,
finger: finger,
@@ -58,6 +156,7 @@ end
def erroneous_press?(state, keys_pressed)
err = (keys_pressed - [:char, :raw_key])
+ .select { |key| state.keys.include? key }
.detect { |key| key != state.challenge[:key] }
return nil unless err
@@ -68,10 +167,12 @@ def erroneous_press?(state, keys_pressed)
}
end
-def game_over(state, ch)
+def game_over(state, outputs, ch)
state.playing = false
state.failed_challenge = ch
+ outputs.sounds << "sfx/incorrect.wav"
+
puts "game_over: #{ch.to_s}"
state.challenge_string = case ch[:fail_reason]
when :lift
@@ -88,13 +189,24 @@ def make_challenge_text(state, grid)
x: grid.center.x,
y: 600,
text: state.challenge_string,
- size_enum: 1,
+ size_enum: 3,
alignment_enum: 1,
font: "fonts/kenney_bold.ttf"
}.label
end
-def initialise(state, grid)
+def make_score_text(state, grid)
+ {
+ x: grid.center.x,
+ y: 555,
+ text: state.score,
+ size_enum: 10,
+ alignment_enum: 1,
+ font: "fonts/kenney_bold.ttf"
+ }.label
+end
+
+def initialise(state, outputs, grid)
return if state.initialised
state.initialised = true
@@ -103,20 +215,20 @@ def initialise(state, grid)
normal_size = [54, 54]
state.key_positions = {
- backtick: { pos: [ 0, 216, *normal_size], game: false },
- one: { pos: [ 54, 216, *normal_size], game: true },
- two: { pos: [108, 216, *normal_size], game: true },
- three: { pos: [162, 216, *normal_size], game: true },
- four: { pos: [216, 216, *normal_size], game: true },
- five: { pos: [270, 216, *normal_size], game: true },
- six: { pos: [324, 216, *normal_size], game: true },
- seven: { pos: [378, 216, *normal_size], game: true },
- eight: { pos: [432, 216, *normal_size], game: true },
- nine: { pos: [486, 216, *normal_size], game: true },
- zero: { pos: [540, 216, *normal_size], game: true },
- hyphen: { pos: [594, 216, *normal_size], game: true },
- equal_sign: { pos: [648, 216, *normal_size], game: true },
- backspace: { pos: [702, 216, 108, 54], game: false },
+ backtick: { pos: [ 0, 216, *normal_size], game: false },
+ one: { pos: [ 54, 216, *normal_size], game: true },
+ two: { pos: [108, 216, *normal_size], game: true },
+ three: { pos: [162, 216, *normal_size], game: true },
+ four: { pos: [216, 216, *normal_size], game: true },
+ five: { pos: [270, 216, *normal_size], game: true },
+ six: { pos: [324, 216, *normal_size], game: true },
+ seven: { pos: [378, 216, *normal_size], game: true },
+ eight: { pos: [432, 216, *normal_size], game: true },
+ nine: { pos: [486, 216, *normal_size], game: true },
+ zero: { pos: [540, 216, *normal_size], game: true },
+ hyphen: { pos: [594, 216, *normal_size], game: true },
+ equal_sign: { pos: [648, 216, *normal_size], game: true },
+ backspace: { pos: [702, 216, 108, 54], game: false },
tab: { pos: [ 0, 162, 81, 54], game: false },
q: { pos: [ 81, 162, *normal_size], game: true },
@@ -133,21 +245,21 @@ def initialise(state, grid)
close_square_brace: { pos: [675, 162, *normal_size], game: true },
back_slash: { pos: [729, 162, 81, 54], game: false },
- caps_lock: { pos: [ 0, 108, 95, 54], game: false },
- a: { pos: [ 95, 108, *normal_size], game: true },
- s: { pos: [149, 108, *normal_size], game: true },
- d: { pos: [203, 108, *normal_size], game: true },
- f: { pos: [257, 108, *normal_size], game: true },
- g: { pos: [311, 108, *normal_size], game: true },
- h: { pos: [365, 108, *normal_size], game: true },
- j: { pos: [419, 108, *normal_size], game: true },
- k: { pos: [473, 108, *normal_size], game: true },
- l: { pos: [527, 108, *normal_size], game: true },
- semicolon: { pos: [581, 108, *normal_size], game: true },
- single_quote: { pos: [635, 108, *normal_size], game: true },
- enter: { pos: [689, 108, 121, 54], game: false },
-
- left_shift: { pos: [0, 54, 122, 54], game: false },
+ caps_lock: { pos: [ 0, 108, 95, 54], game: false },
+ a: { pos: [ 95, 108, *normal_size], game: true },
+ s: { pos: [149, 108, *normal_size], game: true },
+ d: { pos: [203, 108, *normal_size], game: true },
+ f: { pos: [257, 108, *normal_size], game: true },
+ g: { pos: [311, 108, *normal_size], game: true },
+ h: { pos: [365, 108, *normal_size], game: true },
+ j: { pos: [419, 108, *normal_size], game: true },
+ k: { pos: [473, 108, *normal_size], game: true },
+ l: { pos: [527, 108, *normal_size], game: true },
+ semicolon: { pos: [581, 108, *normal_size], game: true },
+ single_quotation_mark: { pos: [635, 108, *normal_size], game: true },
+ enter: { pos: [689, 108, 121, 54], game: false },
+
+ left_shift: { pos: [ 0, 54, 122, 54], game: false },
z: { pos: [122, 54, *normal_size], game: true },
x: { pos: [176, 54, *normal_size], game: true },
c: { pos: [230, 54, *normal_size], game: true },
@@ -158,27 +270,22 @@ def initialise(state, grid)
comma: { pos: [500, 54, *normal_size], game: true },
period: { pos: [554, 54, *normal_size], game: true },
forward_slash: { pos: [608, 54, *normal_size], game: true },
- right_shift: { pos: [662, 54, *normal_size], game: false },
+ right_shift: { pos: [662, 54, 148, 54], game: false },
left_control: { pos: [ 0, 0, 68, 54], game: false },
left_meta: { pos: [ 68, 0, 67, 54], game: false },
left_alt: { pos: [135, 0, 68, 54], game: false },
space: { pos: [203, 0, 337, 54], game: false },
- right_alt: { pos: [560, 0, 68, 54], game: false },
- right_meta: { pos: [614, 0, 67, 0], game: false },
- menu: { pos: [681, 0, 68, 54], game: false },
- right_control: { pos: [735, 0, 67, 54], game: false }
+ right_alt: { pos: [540, 0, 68, 54], game: false },
+ right_meta: { pos: [608, 0, 67, 54], game: false },
+ menu: { pos: [675, 0, 68, 54], game: false },
+ right_control: { pos: [743, 0, 67, 54], game: false }
}
- puts "huh"
-
state.keys = state.key_positions
- .select { |key| puts key ; key[1][:game] }
+ .select { |_k, v| v[:game] }
.keys
- puts "huh"
- puts "state.keys: #{state.keys.to_s}"
-
state.keyboard.pos = offset(grid.center, [-405, -135])
state.keyboard.img = "sprites/keyboard-us.png"
state.keyboard.key_img = "sprites/keys-us.png"
@@ -196,14 +303,16 @@ def initialise(state, grid)
"right hand"
]
- new_challenge(state, reset: true)
+ new_challenge(state, outputs, reset: true, sound: false)
+
+ outputs.sounds << "music/playing.ogg"
end
def tick(args)
grid, inputs, state, outputs, runtime, passes = args.destructure
gtk = args.gtk
- initialise(state, grid)
+ initialise(state, outputs, grid)
outputs.primitives << make_background(grid)
@@ -225,16 +334,13 @@ def tick(args)
erroneous_press?(state, truthies[:down])
if failed_challenge then
- game_over(state, failed_challenge)
+ game_over(state, outputs, failed_challenge)
else
- new_challenge(state) if truthies[:down]
+ new_challenge(state, outputs) if truthies[:down]
.any? { |key| key == state.challenge[:key] }
- outputs.primitives <<
- truthies[:held]
- .select { |key| state.key_positions[key][:game] }
- .map { |key| colour_key(state, key, blue) }
+ outputs.primitives << pressed_keys(state, truthies[:held])
outputs.primitives << colour_key(state, state.challenge[:key], green)
@@ -243,29 +349,31 @@ def tick(args)
else
- puts state.past_held_keys
- puts state.past_held_keys
- .select { |key| state.key_positions.has_key? key }
-
- outputs.primitives << state.past_held_keys
- .select { |key| state.key_positions.has_key? key }
- .map { |key| puts key.to_s ; colour_key(state, key, blue) }
+ outputs.primitives << pressed_keys(state, state.past_held_keys)
outputs.primitives << colour_key(state, state.failed_challenge[:key], red)
if inputs.keyboard.key_down.space then
- new_challenge(state, reset: true)
+ new_challenge(state, outputs, reset: true)
state.playing = true
end
end
+ outputs.primitives << edge_keys(state)
+
outputs.primitives << make_challenge_text(state, grid)
+ if state.score > 0 then
+ outputs.primitives << make_score_text(state, grid)
+ end
+
outputs.primitives <<
[*state.keyboard.pos, 810, 270, state.keyboard.key_img].sprite
outputs.debug << [30, 50, inputs.keyboard.key_held.truthy_keys.to_s].label
outputs.debug << [30, 75, state.past_held_keys.to_s].label
outputs.debug << [30, 100, state.challenge.to_s].label
+ outputs.debug <<
+ [30, 125, state.past_challenges.map { |ch| ch[:key] }.to_s].label
end