author_engine 0.5.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/assets/ui/cursor.png +0 -0
- data/author_engine.gemspec +6 -6
- data/lib/author_engine/cli.rb +9 -0
- data/lib/author_engine/collision_detection/collision_detection.rb +28 -19
- data/lib/author_engine/containers/loader.rb +41 -11
- data/lib/author_engine/game/common/parts/collision_detection.rb +7 -7
- data/lib/author_engine/game/common/parts/common.rb +16 -1
- data/lib/author_engine/game/game.rb +18 -13
- data/lib/author_engine/game/gosu/parts/graphics.rb +9 -9
- data/lib/author_engine/game/opal/exporter.rb +55 -50
- data/lib/author_engine/game/opal/game_runner.rb +182 -89
- data/lib/author_engine/game/opal/parts/graphics.rb +18 -18
- data/lib/author_engine/game/opal/touch_button.rb +38 -17
- data/lib/author_engine/game/opal/touch_handler.rb +20 -3
- data/lib/author_engine/game/opal/touch_joystick.rb +118 -0
- data/lib/author_engine/level_picker.rb +1 -1
- data/lib/author_engine/opal.rb +2 -0
- data/lib/author_engine/save_file.rb +86 -8
- data/lib/author_engine/version.rb +1 -1
- data/lib/author_engine/views/level_editor.rb +7 -11
- data/lib/author_engine/views/play_viewer.rb +1 -1
- data/lib/author_engine/views/sprite_editor.rb +5 -1
- data/lib/author_engine/window.rb +3 -4
- data/screenshots/level_editor.png +0 -0
- data/vendor/opal-parser.min.js +1 -0
- data/vendor/opal.min.js +1 -0
- metadata +22 -18
- data/Gemfile.lock +0 -37
@@ -17,66 +17,88 @@ class AuthorEngine
|
|
17
17
|
@save_file = AuthorEngine::SaveFile.new(nil)
|
18
18
|
@save_file.load(false, project_string)
|
19
19
|
|
20
|
-
size = 16
|
21
|
-
|
22
|
-
@levels = @save_file.levels
|
23
|
-
@levels.each {|level| level.each {|sprite| sprite.x = sprite.x * size; sprite.y = sprite.y * size}}
|
24
|
-
|
25
20
|
@sprites = []
|
26
21
|
@spritesheet = nil
|
27
22
|
@spritesheet_width = @save_file.sprites.columns
|
28
23
|
@spritesheet_height = @save_file.sprites.rows
|
29
24
|
@sprite_size = 16
|
30
25
|
|
31
|
-
@fps = 0
|
32
|
-
@counted_frames = 0
|
33
|
-
@frame_count_stated_at = 0
|
34
|
-
|
35
26
|
@game = Game.new(code: @save_file.code)
|
36
|
-
build_spritesheet_and_sprites_list
|
37
27
|
resize_canvas
|
38
28
|
|
39
|
-
@
|
40
|
-
@
|
41
|
-
|
42
|
-
@levels.each {|level| @collision_detection.add_level(level) }
|
43
|
-
|
44
|
-
@game.init
|
29
|
+
@fps = 0
|
30
|
+
@counted_frames = 0
|
31
|
+
@frame_count_stated_at = 0
|
45
32
|
|
46
33
|
@show_touch_controls = false
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
34
|
+
|
35
|
+
@game_loaded = false
|
36
|
+
|
37
|
+
@loader_tasks = [
|
38
|
+
[
|
39
|
+
"Loading levels",
|
40
|
+
proc {
|
41
|
+
@levels = @save_file.levels
|
42
|
+
@levels.each {|level| level.each {|sprite| sprite.x = sprite.x * @sprite_size; sprite.y = sprite.y * @sprite_size}}
|
43
|
+
}
|
44
|
+
],
|
45
|
+
|
46
|
+
[
|
47
|
+
"Evaluating game",
|
48
|
+
proc {
|
49
|
+
@game.authorengine_eval_code
|
50
|
+
},
|
51
|
+
],
|
52
|
+
|
53
|
+
[
|
54
|
+
"Loading sprites",
|
55
|
+
proc {
|
56
|
+
build_spritesheet_and_sprites_list
|
57
|
+
},
|
58
|
+
],
|
59
|
+
|
60
|
+
[
|
61
|
+
"Setting up collision detection",
|
62
|
+
proc {
|
63
|
+
@collision_detection = AuthorEngine::CollisionDetection.new(@sprites, @levels, @save_file.sprites)
|
64
|
+
@game.authorengine_collision_detection = @collision_detection
|
65
|
+
},
|
66
|
+
],
|
67
|
+
|
68
|
+
[
|
69
|
+
"Initializing game",
|
70
|
+
proc {
|
71
|
+
@game.init
|
72
|
+
},
|
73
|
+
],
|
74
|
+
|
75
|
+
[
|
76
|
+
"Setting up touch controls",
|
77
|
+
proc {
|
78
|
+
@touch_joystick = TouchJoystick.new(radius: 50)
|
79
|
+
@touch_buttons = []
|
80
|
+
@touch_buttons.push(
|
81
|
+
TouchButton.new(
|
82
|
+
label: "X", color: @game.red, width: 50, height: 50, for_key: "x"
|
83
|
+
),
|
84
|
+
TouchButton.new(
|
85
|
+
label: "Y", color: @game.yellow, width: 50, height: 50, for_key: "y"
|
86
|
+
)
|
87
|
+
)
|
88
|
+
|
89
|
+
@fullscreen_button = TouchButton.new(label: "Fullscreen", color: @game.black, width: 100, height: 50)
|
90
|
+
touch_handler_setup
|
91
|
+
reposition_touch_controls
|
92
|
+
},
|
93
|
+
],
|
94
|
+
|
95
|
+
[
|
96
|
+
"Loading done",
|
97
|
+
proc {
|
98
|
+
@game_loaded = true
|
99
|
+
},
|
100
|
+
],
|
101
|
+
]
|
80
102
|
|
81
103
|
return self
|
82
104
|
end
|
@@ -94,7 +116,14 @@ class AuthorEngine
|
|
94
116
|
|
95
117
|
def run_game
|
96
118
|
`window.requestAnimationFrame(function() {#{run_game}})` # placed here to ensure next frame is called even if draw or update throw an error
|
97
|
-
|
119
|
+
width = `window.innerWidth`
|
120
|
+
height = `window.innerHeight`
|
121
|
+
game_width = 128 * @game.authorengine_scale
|
122
|
+
game_height = 128 * @game.authorengine_scale
|
123
|
+
|
124
|
+
area_width = (`window.innerWidth` - game_width) / 2
|
125
|
+
|
126
|
+
`#{@game.authorengine_canvas_context}.clearRect(#{area_width},0, #{game_width}, #{game_height})`
|
98
127
|
|
99
128
|
@counted_frames+=1
|
100
129
|
|
@@ -104,25 +133,22 @@ class AuthorEngine
|
|
104
133
|
@counted_frames = 0
|
105
134
|
end
|
106
135
|
|
136
|
+
`#{@game.authorengine_canvas_context}.save()`
|
137
|
+
`#{@game.authorengine_canvas_context}.translate(window.innerWidth/2 - #{game_height/2}, 0)`
|
138
|
+
`#{@game.authorengine_canvas_context}.scale(#{@game.authorengine_scale}, #{@game.authorengine_scale})`
|
139
|
+
`#{@game.authorengine_canvas_context}.save()`
|
107
140
|
|
108
|
-
|
109
|
-
|
141
|
+
region = `new Path2D()`
|
142
|
+
`#{region}.rect(0, 0, 128, 128)`
|
143
|
+
`#{@game.authorengine_canvas_context}.clip(#{region})`
|
144
|
+
`#{@game.authorengine_canvas_context}.save()`
|
110
145
|
|
111
|
-
# `#{@canvas_context}.setTransform(1, 0, 0, 1, 0, 0)`
|
112
|
-
`#{@game.canvas_context}.save()`
|
113
|
-
`#{@game.canvas_context}.translate(window.innerWidth/2 - #{width/2}, 0)`
|
114
|
-
`#{@game.canvas_context}.scale(#{@game.scale}, #{@game.scale})`
|
115
|
-
`#{@game.canvas_context}.save()`
|
116
146
|
|
117
|
-
|
118
|
-
`#{region}.rect(0, 0, 128, 128)`
|
119
|
-
`#{@game.canvas_context}.clip(#{region})`
|
120
|
-
`#{@game.canvas_context}.save()`
|
147
|
+
if @game_loaded or @loader_tasks.empty?
|
121
148
|
draw
|
122
|
-
|
123
|
-
`#{@game.
|
124
|
-
`#{@game.
|
125
|
-
`#{@game.canvas_context}.restore()`
|
149
|
+
`#{@game.authorengine_canvas_context}.restore()`
|
150
|
+
`#{@game.authorengine_canvas_context}.restore()`
|
151
|
+
`#{@game.authorengine_canvas_context}.restore()`
|
126
152
|
|
127
153
|
update
|
128
154
|
|
@@ -130,31 +156,89 @@ class AuthorEngine
|
|
130
156
|
draw_touch_controls
|
131
157
|
update_touch_controls
|
132
158
|
end
|
159
|
+
|
133
160
|
else
|
134
|
-
@
|
135
|
-
@game.
|
161
|
+
task = @loader_tasks.shift
|
162
|
+
@game.rect(0, 0, @game.width, @game.height, @game.dark_purple)
|
163
|
+
@game.text("AuthorEngine v#{AuthorEngine::VERSION}", 2, @game.height / 2 - 20, 10)
|
164
|
+
@game.text("#{task[0]}...", 6, @game.height / 2 - 4, 8, 0, @game.light_gray)
|
165
|
+
@game.text("Empowered by Opal v#{Opal::VERSION}, a Ruby interpeter.", 4, @game.height - 6, 4, 0, @game.indigo)
|
166
|
+
|
167
|
+
`#{@game.authorengine_canvas_context}.restore()`
|
168
|
+
`#{@game.authorengine_canvas_context}.restore()`
|
169
|
+
`#{@game.authorengine_canvas_context}.restore()`
|
170
|
+
|
171
|
+
task[1].call
|
136
172
|
end
|
137
173
|
|
138
174
|
return nil
|
139
175
|
end
|
140
176
|
|
141
177
|
def draw_touch_controls
|
178
|
+
@fullscreen_button.draw
|
142
179
|
@touch_buttons.each(&:draw)
|
180
|
+
@touch_joystick.draw
|
143
181
|
end
|
144
182
|
|
145
183
|
def update_touch_controls
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
184
|
+
@touch_buttons.each { |button| button.trigger?(@current_touches) }
|
185
|
+
@touch_joystick.update(@current_touches)
|
186
|
+
end
|
187
|
+
|
188
|
+
def reposition_touch_controls
|
189
|
+
return nil unless @touch_joystick
|
190
|
+
|
191
|
+
width = `window.innerWidth`
|
192
|
+
height = `window.innerHeight`
|
193
|
+
game_width = 128 * @game.authorengine_scale
|
194
|
+
game_height = 128 * @game.authorengine_scale
|
195
|
+
|
196
|
+
# place controls under game
|
197
|
+
if width < height
|
198
|
+
area_width = width
|
199
|
+
area_height = height - game_height
|
200
|
+
|
201
|
+
puts "space: width #{area_width} x height #{area_height}"
|
202
|
+
|
203
|
+
@touch_joystick.x = @touch_joystick.radius + @touch_joystick.radius
|
204
|
+
@touch_joystick.y = game_height + area_height / 2
|
205
|
+
|
206
|
+
padding = 10
|
207
|
+
last_x = 20
|
208
|
+
@touch_buttons.reverse.each do |button|
|
209
|
+
button.x = width - (last_x + button.width)
|
210
|
+
button.y = (height - area_height) + area_height / 2 - button.height / 2
|
211
|
+
|
212
|
+
last_x += button.width + padding
|
154
213
|
end
|
214
|
+
|
215
|
+
@fullscreen_button.x = width - (width / 2 + @fullscreen_button.width / 2)
|
216
|
+
@fullscreen_button.y = height - @fullscreen_button.height
|
217
|
+
|
218
|
+
# place controls beside game
|
219
|
+
else
|
220
|
+
area_width = (`window.innerWidth` - game_width) / 2
|
221
|
+
area_height = game_height
|
222
|
+
|
223
|
+
puts "space: width #{area_width} x height #{area_height}"
|
224
|
+
|
225
|
+
@touch_joystick.x = @touch_joystick.radius + @touch_joystick.radius
|
226
|
+
@touch_joystick.y = game_height / 2
|
227
|
+
|
228
|
+
padding = 10
|
229
|
+
last_x = 50
|
230
|
+
@touch_buttons.reverse.each do |button|
|
231
|
+
button.x = width - (last_x + button.width)
|
232
|
+
button.y = game_height / 2 - button.height / 2
|
233
|
+
|
234
|
+
last_x += button.width + padding
|
235
|
+
end
|
236
|
+
|
237
|
+
@fullscreen_button.x = width - @fullscreen_button.width
|
238
|
+
@fullscreen_button.y = 0
|
155
239
|
end
|
156
240
|
|
157
|
-
|
241
|
+
return nil
|
158
242
|
end
|
159
243
|
|
160
244
|
def resize_canvas
|
@@ -162,17 +246,20 @@ class AuthorEngine
|
|
162
246
|
height = `window.innerHeight`
|
163
247
|
|
164
248
|
if width < height
|
165
|
-
@game.
|
249
|
+
@game.authorengine_scale = `#{width} / 128.0`
|
166
250
|
else
|
167
|
-
@game.
|
251
|
+
@game.authorengine_scale = `#{height} / 128.0`
|
168
252
|
end
|
169
253
|
|
170
|
-
`#{@game.
|
171
|
-
`#{@game.
|
172
|
-
`#{@game.
|
173
|
-
`#{@game.
|
254
|
+
`#{@game.authorengine_canvas}.width = #{width}`
|
255
|
+
`#{@game.authorengine_canvas}.height = #{height}`
|
256
|
+
`#{@game.authorengine_canvas}.style.width = #{width}`
|
257
|
+
`#{@game.authorengine_canvas}.style.height = #{height}`
|
258
|
+
|
259
|
+
`#{@game.authorengine_canvas_context}.imageSmoothingEnabled = false`
|
174
260
|
|
175
|
-
|
261
|
+
reposition_touch_controls
|
262
|
+
`#{@game.authorengine_canvas_context}.clearRect(0, 0, window.innerWidth, window.innerHeight)`
|
176
263
|
return nil
|
177
264
|
end
|
178
265
|
|
@@ -212,7 +299,6 @@ class AuthorEngine
|
|
212
299
|
(width/size).times do |x|
|
213
300
|
`#{temp_canvas_context}.clearRect(0,0, #{size}, #{size})`
|
214
301
|
`#{temp_canvas_context}.drawImage(#{@spritesheet}, #{x * size}, #{y * size}, #{size}, #{size}, 0, 0, #{size}, #{size})`
|
215
|
-
@collision_detection.add_sprite(`#{temp_canvas_context}.getImageData(0,0, #{size}, #{size}).data`)
|
216
302
|
|
217
303
|
`createImageBitmap(#{@spritesheet}, #{x * size}, #{y * size}, #{size}, #{size}).then(sprite => { #{@sprites.push(`sprite`)} })`
|
218
304
|
end
|
@@ -221,19 +307,26 @@ class AuthorEngine
|
|
221
307
|
return nil
|
222
308
|
end
|
223
309
|
|
310
|
+
def fullscreen_changed
|
311
|
+
resize_canvas
|
312
|
+
end
|
313
|
+
|
224
314
|
def show(update_interval = (1000.0 / 60))
|
225
315
|
return unless RUBY_ENGINE == "opal"
|
226
316
|
|
227
317
|
`window.addEventListener('resize', () => { #{resize_canvas} })`
|
228
|
-
`document.addEventListener('keydown', (event) => { #{AuthorEngine::Part::OpalInput::KEY_STATES[`event.key`] = true} })`
|
318
|
+
`document.addEventListener('keydown', (event) => { #{@show_touch_controls = false; AuthorEngine::Part::OpalInput::KEY_STATES[`event.key`] = true} })`
|
229
319
|
`document.addEventListener('keyup', (event) => { #{AuthorEngine::Part::OpalInput::KEY_STATES[`event.key`] = false} })`
|
230
320
|
|
231
|
-
`#{@game.
|
232
|
-
`#{@game.
|
233
|
-
`#{@game.
|
234
|
-
`#{@game.
|
321
|
+
`#{@game.authorengine_canvas}.addEventListener('touchstart', (event) => { #{@show_touch_controls = true; handle_touch_start(`event`)} })`
|
322
|
+
`#{@game.authorengine_canvas}.addEventListener('touchmove', (event) => { #{handle_touch_move(`event`)} })`
|
323
|
+
`#{@game.authorengine_canvas}.addEventListener('touchcancel', (event) => { #{handle_touch_cancel(`event`)} })`
|
324
|
+
`#{@game.authorengine_canvas}.addEventListener('touchend', (event) => { #{handle_touch_end(`event`)} })`
|
325
|
+
|
326
|
+
`#{@game.authorengine_canvas}.addEventListener('fullscreenchange', () => { #{fullscreen_changed} })`
|
235
327
|
|
236
328
|
`document.getElementById('loading').style.display = "none"`
|
329
|
+
|
237
330
|
`window.requestAnimationFrame(function() {#{run_game}})`
|
238
331
|
return nil
|
239
332
|
end
|
@@ -2,8 +2,8 @@ class AuthorEngine
|
|
2
2
|
class Part
|
3
3
|
module OpalGraphics
|
4
4
|
def rect(x = 0, y = 0, width = 1, height = 1, color = "white", z = 0)
|
5
|
-
`#{@
|
6
|
-
`#{@
|
5
|
+
`#{@authorengine_canvas_context}.fillStyle = #{color}`
|
6
|
+
`#{@authorengine_canvas_context}.fillRect(#{x}, #{y}, #{width}, #{height})`
|
7
7
|
return nil
|
8
8
|
end
|
9
9
|
|
@@ -11,25 +11,25 @@ class AuthorEngine
|
|
11
11
|
size = 16 # sprite size
|
12
12
|
sprites = AuthorEngine::GameRunner.instance.sprites
|
13
13
|
|
14
|
-
`#{@
|
14
|
+
`#{@authorengine_canvas_context}.save()`
|
15
15
|
if alpha <= 0
|
16
16
|
alpha = 0
|
17
17
|
else
|
18
18
|
alpha = (alpha / 255.0)
|
19
19
|
end
|
20
|
-
`#{@
|
20
|
+
`#{@authorengine_canvas_context}.globalAlpha = #{alpha}`
|
21
21
|
|
22
|
-
`#{@
|
22
|
+
`#{@authorengine_canvas_context}.drawImage(#{sprites[sprite_sheet_index]}, #{x}, #{y})`
|
23
23
|
|
24
|
-
`#{@
|
24
|
+
`#{@authorengine_canvas_context}.restore()`
|
25
25
|
end
|
26
26
|
|
27
27
|
def text(string, x = 0, y = 0, size = 4, z = 0, color = "white")
|
28
28
|
font = "#{size}px Connection, Consolas"
|
29
|
-
`#{@
|
30
|
-
`#{@
|
31
|
-
`#{@
|
32
|
-
`#{@
|
29
|
+
`#{@authorengine_canvas_context}.font = #{font}`
|
30
|
+
`#{@authorengine_canvas_context}.fillStyle = #{color}`
|
31
|
+
`#{@authorengine_canvas_context}.textBaseline = "top"`
|
32
|
+
`#{@authorengine_canvas_context}.fillText(#{string}, #{x}, #{y})`
|
33
33
|
end
|
34
34
|
|
35
35
|
def level(index, z = 0)
|
@@ -45,24 +45,24 @@ class AuthorEngine
|
|
45
45
|
_level = AuthorEngine::GameRunner.instance.levels[level]
|
46
46
|
raise "No level at '#{index}'!" unless _level
|
47
47
|
raise "No sprite at '#{current_sprite}'!" unless AuthorEngine::GameRunner.instance.sprites[current_sprite]
|
48
|
-
raise "No sprite at '#{
|
48
|
+
raise "No sprite at '#{replacement_sprite}'!" unless AuthorEngine::GameRunner.instance.sprites[replacement_sprite]
|
49
49
|
|
50
50
|
_level.each {|sprite| sprite.sprite = replacement_sprite if sprite.sprite == current_sprite}
|
51
51
|
end
|
52
52
|
|
53
53
|
def translate(x, y, &block)
|
54
|
-
`#{@
|
55
|
-
`#{@
|
54
|
+
`#{@authorengine_canvas_context}.save()`
|
55
|
+
`#{@authorengine_canvas_context}.translate(#{x}, #{y})`
|
56
56
|
block.call if block
|
57
|
-
`#{@
|
57
|
+
`#{@authorengine_canvas_context}.restore()`
|
58
58
|
end
|
59
59
|
|
60
60
|
def rotate(angle, x = 0, y = 0, &block)
|
61
|
-
`#{@
|
62
|
-
`#{@
|
63
|
-
`#{@
|
61
|
+
`#{@authorengine_canvas_context}.save()`
|
62
|
+
`#{@authorengine_canvas_context}.translate(#{x}, #{y})`
|
63
|
+
`#{@authorengine_canvas_context}.rotate(#{angle})`
|
64
64
|
block.call if block
|
65
|
-
`#{@
|
65
|
+
`#{@authorengine_canvas_context}.restore()`
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -1,36 +1,57 @@
|
|
1
1
|
class AuthorEngine
|
2
2
|
class TouchButton
|
3
|
-
|
4
|
-
|
3
|
+
attr_accessor :x, :y
|
4
|
+
attr_reader :width, :height
|
5
|
+
def initialize(label:, color:, x: 0, y: 0, width:, height:, for_key: nil, &block)
|
5
6
|
@label, @color, @x, @y, @width, @height = label, color, x, y, width, height
|
6
|
-
@
|
7
|
+
@for_key = for_key
|
8
|
+
@block = block
|
9
|
+
|
10
|
+
@buttons = AuthorEngine::Part::OpalInput::BUTTONS
|
11
|
+
@key_states = AuthorEngine::Part::OpalInput::KEY_STATES
|
7
12
|
|
8
13
|
@game = AuthorEngine::GameRunner.instance.game
|
9
|
-
@game_width = 128 * @game.
|
14
|
+
@game_width = 128 * @game.authorengine_scale
|
10
15
|
@game_x = `window.innerWidth/2 - #{@game_width/2}`
|
16
|
+
end
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@x = @game_x+@game_width+@x
|
16
|
-
else
|
17
|
-
raise "side must be :left or :right"
|
18
|
-
end
|
18
|
+
def draw
|
19
|
+
`#{@game.authorengine_canvas_context}.fillStyle = #{@color}`
|
20
|
+
`#{@game.authorengine_canvas_context}.fillRect(#{@x}, #{@y}, #{@width}, #{@height})`
|
19
21
|
|
20
|
-
|
22
|
+
font = "#{@height}px Connection, Consolas"
|
23
|
+
`#{@game.authorengine_canvas_context}.font = #{font}`
|
24
|
+
`#{@game.authorengine_canvas_context}.fillStyle = "white"`
|
25
|
+
`#{@game.authorengine_canvas_context}.textBaseline = "top"`
|
26
|
+
`#{@game.authorengine_canvas_context}.fillText(#{@label}, #{@x}, #{@y}, #{@width})`
|
21
27
|
end
|
22
28
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
29
|
+
def trigger?(touches)
|
30
|
+
triggered = false
|
31
|
+
|
32
|
+
touches.detect do |id, touch|
|
33
|
+
if touch.x.between?(@x, @x+@width) && touch.y.between?(@y, @y+@height)
|
34
|
+
triggered = true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
if @for_key
|
40
|
+
active if triggered
|
41
|
+
inactive unless triggered
|
42
|
+
else
|
43
|
+
@block.call if @block && triggered
|
44
|
+
end
|
45
|
+
|
46
|
+
return triggered
|
26
47
|
end
|
27
48
|
|
28
49
|
def active
|
29
|
-
@
|
50
|
+
@key_states[@buttons[@for_key]] = true
|
30
51
|
end
|
31
52
|
|
32
53
|
def inactive
|
33
|
-
@
|
54
|
+
@key_states[@buttons[@for_key]] = false
|
34
55
|
end
|
35
56
|
end
|
36
57
|
end
|