author_engine 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +7 -0
- data/API.md +81 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +26 -0
- data/LICENSE.txt +21 -0
- data/README.md +38 -0
- data/Rakefile +10 -0
- data/SAVEFILE.md +23 -0
- data/assets/fonts/Connection.otf +0 -0
- data/assets/fonts/ConnectionBold.otf +0 -0
- data/assets/fonts/README.md +3 -0
- data/assets/fonts/SIL Open Font License.txt +94 -0
- data/assets/ui/bucket_icon.png +0 -0
- data/assets/ui/code_icon.png +0 -0
- data/assets/ui/error_icon.png +0 -0
- data/assets/ui/level_icon.png +0 -0
- data/assets/ui/loading_icon.png +0 -0
- data/assets/ui/lock_icon.png +0 -0
- data/assets/ui/pencil_icon.png +0 -0
- data/assets/ui/play_icon.png +0 -0
- data/assets/ui/sprite_icon.png +0 -0
- data/assets/ui/unlock_icon.png +0 -0
- data/author_engine.gemspec +41 -0
- data/bin/author_engine +4 -0
- data/lib/author_engine/button.rb +154 -0
- data/lib/author_engine/code_editor/cursor.rb +339 -0
- data/lib/author_engine/code_editor/highlighting.rb +49 -0
- data/lib/author_engine/container.rb +24 -0
- data/lib/author_engine/containers/editor.rb +97 -0
- data/lib/author_engine/containers/loader.rb +105 -0
- data/lib/author_engine/game/game.rb +26 -0
- data/lib/author_engine/game/parts/colors.rb +59 -0
- data/lib/author_engine/game/parts/common.rb +13 -0
- data/lib/author_engine/game/parts/graphics.rb +41 -0
- data/lib/author_engine/game/parts/input.rb +25 -0
- data/lib/author_engine/image.rb +53 -0
- data/lib/author_engine/palette.rb +114 -0
- data/lib/author_engine/save_file.rb +134 -0
- data/lib/author_engine/sprite.rb +4 -0
- data/lib/author_engine/sprite_picker.rb +154 -0
- data/lib/author_engine/support.rb +22 -0
- data/lib/author_engine/text.rb +41 -0
- data/lib/author_engine/version.rb +3 -0
- data/lib/author_engine/view.rb +55 -0
- data/lib/author_engine/views/code_editor.rb +154 -0
- data/lib/author_engine/views/level_editor.rb +7 -0
- data/lib/author_engine/views/play_viewer.rb +163 -0
- data/lib/author_engine/views/sprite_editor.rb +333 -0
- data/lib/author_engine/window.rb +132 -0
- data/lib/author_engine.rb +32 -0
- data/test_3.authorengine +519 -0
- data/testing.authorengine +578 -0
- metadata +169 -0
@@ -0,0 +1,339 @@
|
|
1
|
+
class AuthorEngine
|
2
|
+
class CodeEditor < View
|
3
|
+
class Cursor
|
4
|
+
include AuthorEngine::Support
|
5
|
+
include AuthorEngine::Part::Colors
|
6
|
+
|
7
|
+
attr_reader :active_line, :line_x
|
8
|
+
def initialize(view:, text_input:, text:)
|
9
|
+
@view = view
|
10
|
+
@text_input = text_input
|
11
|
+
@text = text
|
12
|
+
|
13
|
+
@x, @y = 0, 0
|
14
|
+
|
15
|
+
@last_blink = Gosu.milliseconds
|
16
|
+
@blink_interval = 250
|
17
|
+
@show = false
|
18
|
+
|
19
|
+
@newline_data = {}
|
20
|
+
@active_line = 0
|
21
|
+
@active_line_history_size = 2
|
22
|
+
@active_line_history_index = 0
|
23
|
+
@active_line_history = []
|
24
|
+
|
25
|
+
@highlight_color = Gosu::Color.rgba(dark_gray.red, dark_gray.green, dark_gray.blue, 100)
|
26
|
+
@selection_color = window.lighten(Gosu::Color.rgba(@view.background.red, @view.background.green, @view.background.blue, 100), 100)
|
27
|
+
|
28
|
+
@repeatable_keys = [
|
29
|
+
{
|
30
|
+
key: Gosu::KbUp,
|
31
|
+
down: false,
|
32
|
+
repeat_delay: 50,
|
33
|
+
last_repeat: 0,
|
34
|
+
action: proc {move(:up)}
|
35
|
+
},
|
36
|
+
{
|
37
|
+
key: Gosu::KbDown,
|
38
|
+
down: false,
|
39
|
+
repeat_delay: 50,
|
40
|
+
last_repeat: 0,
|
41
|
+
action: proc {move(:down)}
|
42
|
+
}
|
43
|
+
]
|
44
|
+
|
45
|
+
caret_stay_left_of_last_newline
|
46
|
+
end
|
47
|
+
|
48
|
+
def draw
|
49
|
+
highlight_activeline
|
50
|
+
highlight_selection
|
51
|
+
Gosu.draw_rect(@text.x + @x, @y, 1, @text.height, light_gray) if @show
|
52
|
+
end
|
53
|
+
|
54
|
+
def update
|
55
|
+
if (Gosu.milliseconds - @last_blink) > @blink_interval
|
56
|
+
@last_blink = Gosu.milliseconds
|
57
|
+
@show = !@show
|
58
|
+
end
|
59
|
+
|
60
|
+
update_caret
|
61
|
+
|
62
|
+
update_active_line_history
|
63
|
+
|
64
|
+
@repeatable_keys.each do |key|
|
65
|
+
if key[:down]
|
66
|
+
if Gosu.milliseconds > key[:last_repeat] + key[:repeat_delay]
|
67
|
+
key[:action].call
|
68
|
+
key[:last_repeat] = Gosu.milliseconds
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def button_down(id)
|
75
|
+
@repeatable_keys.detect do |key|
|
76
|
+
if key[:key] == id
|
77
|
+
key[:down] = true
|
78
|
+
key[:last_repeat] = Gosu.milliseconds + key[:repeat_delay]
|
79
|
+
return true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
case id
|
84
|
+
when Gosu::KbA
|
85
|
+
select_all if window.control_button_down?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def button_up(id)
|
90
|
+
@repeatable_keys.detect do |key|
|
91
|
+
if key[:key] == id
|
92
|
+
key[:down] = false
|
93
|
+
return true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# FIXME: Can't seem to get cursor position before it's set to 0...
|
98
|
+
# CAUTION: This randomly started working!
|
99
|
+
# And then stopped...?
|
100
|
+
|
101
|
+
caret_stay_left_of_last_newline
|
102
|
+
|
103
|
+
case id
|
104
|
+
when Gosu::MsLeft
|
105
|
+
return unless @view.mouse_inside_view?
|
106
|
+
|
107
|
+
index = row_at(window.mouse_y)
|
108
|
+
line = @newline_data.dig(index)
|
109
|
+
return unless line # no line at index
|
110
|
+
right_offset = column_at((window.mouse_x + @view.x_offset.abs) - @text.x, window.mouse_y)
|
111
|
+
pos = (line[:position_end_of_line] - line[:text_length]) + right_offset
|
112
|
+
|
113
|
+
set_position(pos)
|
114
|
+
|
115
|
+
# TODO: move to button_down? to fix popping to the top and back
|
116
|
+
when Gosu::KbHome
|
117
|
+
line = @newline_data[last_active_line(0)]
|
118
|
+
pos = line[:position_end_of_line] - line[:text_length]
|
119
|
+
|
120
|
+
set_position(pos)
|
121
|
+
|
122
|
+
# TODO: move to button_down? to fix popping to the bottom and back
|
123
|
+
when Gosu::KbEnd
|
124
|
+
line = @newline_data[last_active_line(@newline_data.size-1)]
|
125
|
+
pos = line[:position_end_of_line]
|
126
|
+
|
127
|
+
set_position(pos)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# returns the line of lines from the top that y is at
|
132
|
+
def row_at(y)
|
133
|
+
return (((y.to_f - window.container.header_height.to_f) - @view.y_offset.to_f) / @text.height).floor
|
134
|
+
end
|
135
|
+
|
136
|
+
# returns the column for x on line y
|
137
|
+
def column_at(x, y, y_is_line = false)
|
138
|
+
x = @text.x if x < x-@text.x
|
139
|
+
line = @newline_data.dig(row_at(y)) unless y_is_line
|
140
|
+
line = @newline_data.dig(y) if y_is_line
|
141
|
+
column= 0
|
142
|
+
return unless line
|
143
|
+
|
144
|
+
text = line[:text]
|
145
|
+
buffer= ""
|
146
|
+
local_x=0
|
147
|
+
|
148
|
+
text.size.times do |i|
|
149
|
+
local_x = @text.font.text_width(buffer)
|
150
|
+
|
151
|
+
break if local_x >= x
|
152
|
+
column+=1
|
153
|
+
buffer+=text.chars[i]
|
154
|
+
end
|
155
|
+
|
156
|
+
return column
|
157
|
+
end
|
158
|
+
|
159
|
+
def build_newline_data
|
160
|
+
i = 0
|
161
|
+
virt_caret = 0
|
162
|
+
|
163
|
+
@text_input.text.each_line do |line|
|
164
|
+
virt_caret += line.length
|
165
|
+
@newline_data[i] = {position_end_of_line: virt_caret-1, text: line.chomp, text_length: line.chomp.length} # go behind newline
|
166
|
+
|
167
|
+
i+=1
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
def calculate_active_line
|
173
|
+
sub_text = @text_input.text[0..position]
|
174
|
+
@active_line = sub_text.lines.size-1
|
175
|
+
end
|
176
|
+
|
177
|
+
def calculate_x_and_y
|
178
|
+
@y = @text.y + (@active_line * @text.height)
|
179
|
+
|
180
|
+
if position == 0
|
181
|
+
@x = 0
|
182
|
+
return
|
183
|
+
end
|
184
|
+
|
185
|
+
line = @text_input.text[0..position-1].lines[@active_line]
|
186
|
+
sub_text = ""
|
187
|
+
if line
|
188
|
+
sub_text = line[0..position-1]
|
189
|
+
end
|
190
|
+
|
191
|
+
@x = @text.font.markup_width(sub_text)
|
192
|
+
end
|
193
|
+
|
194
|
+
def calculate_x_offset
|
195
|
+
two_zeros = @text.font.text_width("00")
|
196
|
+
if @x + two_zeros > @view.width - @text.x
|
197
|
+
@view.x_offset = (@view.width - @text.x) - (@x + two_zeros)
|
198
|
+
else
|
199
|
+
@view.x_offset = 0
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def update_caret
|
204
|
+
build_newline_data
|
205
|
+
calculate_active_line
|
206
|
+
|
207
|
+
calculate_x_and_y
|
208
|
+
calculate_x_offset
|
209
|
+
calculate_y_offset
|
210
|
+
end
|
211
|
+
|
212
|
+
def caret_stay_left_of_last_newline
|
213
|
+
@text_input.text+="\n" unless @text_input.text.end_with?("\n")
|
214
|
+
|
215
|
+
eof = @text_input.text.chomp.length
|
216
|
+
set_position(eof) if position > eof
|
217
|
+
end
|
218
|
+
|
219
|
+
def calculate_y_offset
|
220
|
+
y_offset = @view.height - ((@text.y - (window.container.header_height - (@text.height*2))) + (@active_line * @text.height))
|
221
|
+
|
222
|
+
if y_offset > 0 # top is visible, reset to 0 to prevent inverse scrolling
|
223
|
+
y_offset = 0
|
224
|
+
else
|
225
|
+
# FIXME
|
226
|
+
top = (@text.y + @view.y_offset.abs) + @text.height
|
227
|
+
bottom = (@text.y + @view.y_offset.abs + @view.height) - @text.height * 2
|
228
|
+
|
229
|
+
if (@y).between?(top, bottom) # don't follow cursor up if not at top of screen
|
230
|
+
y_offset = @view.y_offset
|
231
|
+
elsif @y < top && y_offset <= 0
|
232
|
+
y_offset = @view.y_offset + @text.height
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
@view.y_offset = y_offset
|
237
|
+
end
|
238
|
+
|
239
|
+
def update_active_line_history
|
240
|
+
@active_line_history_index = 0 unless @active_line_history_index < @active_line_history_size
|
241
|
+
|
242
|
+
unless @active_line_history[@active_line_history_index-1] == @active_line
|
243
|
+
@active_line_history[@active_line_history_index] = @active_line
|
244
|
+
@active_line_history_index+=1
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
# poison: line index at which home is 0 and end is @newline_data.size-1
|
250
|
+
def last_active_line(poison)
|
251
|
+
candidate = @active_line
|
252
|
+
|
253
|
+
# p poison
|
254
|
+
|
255
|
+
list = @active_line_history.reject{|l| l == poison}
|
256
|
+
return candidate unless list
|
257
|
+
|
258
|
+
# p @active_line_history,list
|
259
|
+
|
260
|
+
candidate = list.reverse.first if list.size > 0
|
261
|
+
|
262
|
+
return candidate
|
263
|
+
end
|
264
|
+
|
265
|
+
def highlight_activeline
|
266
|
+
Gosu.draw_rect(0 - @view.x_offset, @y, @view.width, @text.height, @highlight_color)
|
267
|
+
end
|
268
|
+
|
269
|
+
def highlight_selection
|
270
|
+
return if @text_input.selection_start == position
|
271
|
+
|
272
|
+
line = @newline_data[@active_line]
|
273
|
+
selection_x = 0
|
274
|
+
if @text_input.selection_start < position
|
275
|
+
selection_x = @text.font.text_width(@text_input.text[@text_input.selection_start..position-1])
|
276
|
+
|
277
|
+
Gosu.draw_rect((@x + @text.x) - selection_x, @text.y + (@active_line * @text.height), selection_x, @text.height, @selection_color)
|
278
|
+
else
|
279
|
+
selection_x = @text.font.text_width(@text_input.text[position..@text_input.selection_start-1])
|
280
|
+
|
281
|
+
Gosu.draw_rect((@x + @text.x), @text.y + (@active_line * @text.height), selection_x, @text.height, @selection_color)
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
def position
|
287
|
+
@text_input.caret_pos
|
288
|
+
end
|
289
|
+
|
290
|
+
def set_position(int)
|
291
|
+
@text_input.caret_pos = int
|
292
|
+
@text_input.selection_start = int # See: https://github.com/gosu/gosu/issues/228
|
293
|
+
end
|
294
|
+
|
295
|
+
def select_all
|
296
|
+
@text_input.selection_start = 0
|
297
|
+
@text_input.caret_pos = @text_input.text.length-1
|
298
|
+
end
|
299
|
+
|
300
|
+
def move(direction)
|
301
|
+
pos = @text_input.caret_pos
|
302
|
+
line = nil
|
303
|
+
|
304
|
+
if direction == :up
|
305
|
+
return if @active_line == 0
|
306
|
+
line = @newline_data.dig(@active_line-1)
|
307
|
+
return unless line # no line at index
|
308
|
+
# current_offset = column_at(@x, (@active_line), true) # current line offset
|
309
|
+
above_offset = column_at(@x, (@active_line-1), true) # line up offset
|
310
|
+
|
311
|
+
# right_offset = current_offset
|
312
|
+
# right_offset = above_offset if current_offset >= above_offset
|
313
|
+
right_offset = above_offset
|
314
|
+
|
315
|
+
pos = (line[:position_end_of_line] - line[:text_length]) + right_offset
|
316
|
+
|
317
|
+
elsif direction == :down
|
318
|
+
return if @text_input.caret_pos == @text_input.text.size
|
319
|
+
return unless @newline_data[@active_line+1]
|
320
|
+
line = @newline_data.dig(@active_line+1)
|
321
|
+
return unless line # no line at index
|
322
|
+
# current_offset = column_at(@x, (@active_line), true) # current line offset
|
323
|
+
below_offset = column_at(@x, (@active_line+1), true) # line down offset
|
324
|
+
|
325
|
+
# right_offset = current_offset
|
326
|
+
# right_offset = below_offset if current_offset >= below_offset
|
327
|
+
right_offset = below_offset
|
328
|
+
|
329
|
+
pos = (line[:position_end_of_line] - line[:text_length]) + right_offset
|
330
|
+
|
331
|
+
else
|
332
|
+
raise ":up or :down please."
|
333
|
+
end
|
334
|
+
|
335
|
+
set_position(pos)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class AuthorEngine
|
2
|
+
class CodeEditor < View
|
3
|
+
class Highlighting
|
4
|
+
include AuthorEngine::Part::Colors
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@highlight_colors = {
|
8
|
+
instance_variable: xml_color(green),
|
9
|
+
keyword: xml_color(red),
|
10
|
+
method: xml_color(yellow),
|
11
|
+
ident: xml_color(yellow),
|
12
|
+
comment: xml_color(dark_gray),
|
13
|
+
constant: xml_color(orange),
|
14
|
+
|
15
|
+
delimiter: xml_color(blue),
|
16
|
+
content: xml_color(blue),
|
17
|
+
integer: xml_color(blue),
|
18
|
+
float: xml_color(blue),
|
19
|
+
symbol: xml_color(blue),
|
20
|
+
}
|
21
|
+
|
22
|
+
@last_text = ""
|
23
|
+
end
|
24
|
+
|
25
|
+
def highlight(string:, text:)
|
26
|
+
return unless @last_text != string
|
27
|
+
@last_text = string
|
28
|
+
|
29
|
+
buffer = ""
|
30
|
+
|
31
|
+
tokens = CodeRay.scan(string, :ruby).tokens
|
32
|
+
tokens.each_with_index do |token, index|
|
33
|
+
buffer = "#{buffer}#{style(text: token, token: tokens[index+1])}" if token.is_a?(String)
|
34
|
+
end
|
35
|
+
|
36
|
+
text.message = buffer
|
37
|
+
end
|
38
|
+
|
39
|
+
def style(text:, token:)
|
40
|
+
color = @highlight_colors.dig(token)
|
41
|
+
if color
|
42
|
+
return "<c=#{color}>#{text}</c>"
|
43
|
+
else
|
44
|
+
return text
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class AuthorEngine
|
2
|
+
class Container
|
3
|
+
include Support
|
4
|
+
include AuthorEngine::Part::Colors
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup
|
10
|
+
end
|
11
|
+
|
12
|
+
def draw
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
end
|
17
|
+
|
18
|
+
def button_down(id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def button_up(id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
class AuthorEngine
|
2
|
+
class Editor < Container
|
3
|
+
attr_reader :header_height, :savefile
|
4
|
+
|
5
|
+
def initialize(savefile)
|
6
|
+
@savefile = savefile
|
7
|
+
|
8
|
+
@scale_x = window.scale_x
|
9
|
+
@scale_y = window.scale_y
|
10
|
+
|
11
|
+
@active_view = nil
|
12
|
+
@header_height= (16 * @scale_y)+(@scale_y*2)
|
13
|
+
@header_color = Gosu::Color.rgba(dark_green.red, dark_green.green, dark_green.blue, 100)#Gosu::Color.rgba(25, 255, 25, 100)
|
14
|
+
@title = Text.new(message: "AuthorEngine", x: (1.0*@scale_x))
|
15
|
+
@title.y = @header_height/2 - @title.height/2
|
16
|
+
@views = []
|
17
|
+
@buttons = []
|
18
|
+
|
19
|
+
@locked = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup
|
23
|
+
add_buttons
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_buttons
|
27
|
+
@play_viewer = PlayViewer.new(x: 0, y: @header_height+1, width: window.width, height: window.height-@header_height, background: dark_purple)
|
28
|
+
@sprite_editor = SpriteEditor.new(x: 0, y: @header_height+1, width: window.width, height: window.height-@header_height, background: indigo)
|
29
|
+
@level_editor = LevelEditor.new(x: 0, y: @header_height+1, width: window.width, height: window.height-@header_height, background: brown)
|
30
|
+
@code_editor = CodeEditor.new(x: 0, y: @header_height+1, width: window.width, height: window.height-@header_height, background: black)
|
31
|
+
|
32
|
+
@buttons << Button.new(image: "assets/ui/play_icon.png", tooltip: "Play", tag: :play_viewer, color: @header_color) {@active_view = @play_viewer; @active_view.focus; @code_editor.blur}
|
33
|
+
@buttons << Button.new(image: "assets/ui/sprite_icon.png", tooltip: "Sprite Editor", tag: :sprite_editor, color: @header_color) {@active_view = @sprite_editor; @active_view.focus; @code_editor.blur}
|
34
|
+
@buttons << Button.new(image: "assets/ui/level_icon.png", tooltip: "Level Editor", tag: :level_editor, color: @header_color) {@active_view = @level_editor; @active_view.focus; @code_editor.blur}
|
35
|
+
@buttons << Button.new(image: "assets/ui/code_icon.png", tooltip: "Code Editor", tag: :code_editor, color: @header_color) {@active_view = @code_editor; @active_view.focus}
|
36
|
+
|
37
|
+
@active_view = @play_viewer
|
38
|
+
# @active_view.focus
|
39
|
+
position_buttons
|
40
|
+
end
|
41
|
+
|
42
|
+
def position_buttons
|
43
|
+
total_width = 0
|
44
|
+
@buttons.each do |b|
|
45
|
+
total_width+=b.width
|
46
|
+
end
|
47
|
+
raise "Header buttons are to wide (#{total_width})" if total_width > window.width
|
48
|
+
|
49
|
+
|
50
|
+
origin = window.width - total_width
|
51
|
+
x_offset = 0
|
52
|
+
@buttons.each_with_index do |b, i|
|
53
|
+
b.x = origin + x_offset
|
54
|
+
x_offset+=b.width
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def lock; @locked = true; end
|
59
|
+
def unlock; @locked = false; end
|
60
|
+
|
61
|
+
def draw
|
62
|
+
unless @locked
|
63
|
+
Gosu.draw_rect(0, 0, window.width, @header_height, @header_color)
|
64
|
+
@title.draw
|
65
|
+
@buttons.each(&:draw)
|
66
|
+
end
|
67
|
+
|
68
|
+
@active_view.draw if @active_view
|
69
|
+
end
|
70
|
+
|
71
|
+
def update
|
72
|
+
@active_view.update if @active_view
|
73
|
+
end
|
74
|
+
|
75
|
+
def close
|
76
|
+
@savefile.save
|
77
|
+
|
78
|
+
window.close!
|
79
|
+
end
|
80
|
+
|
81
|
+
def button_down(id)
|
82
|
+
@savefile.save if window.control_button_down? && id == Gosu::KbS
|
83
|
+
if window.control_button_down? && id == Gosu::KbO
|
84
|
+
@savefile.save
|
85
|
+
window.container = Loader.new
|
86
|
+
end
|
87
|
+
|
88
|
+
@active_view.button_down(id) if @active_view
|
89
|
+
end
|
90
|
+
|
91
|
+
def button_up(id)
|
92
|
+
@buttons.each {|b| b.button_up(id)} unless @locked
|
93
|
+
|
94
|
+
@active_view.button_up(id) if @active_view
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
class AuthorEngine
|
2
|
+
class Loader < Container
|
3
|
+
Project = Struct.new(:name, :block)
|
4
|
+
def setup
|
5
|
+
@root_directory = Dir.pwd#"#{Dir.home}/AuthorEngineProjects"
|
6
|
+
Dir.mkdir(@root_directory) unless File.exists?(@root_directory)
|
7
|
+
|
8
|
+
@list = []
|
9
|
+
@files = Dir.glob(@root_directory+"/*.authorengine")
|
10
|
+
@font = Gosu::Font.new((6 * window.square_scale).floor, name: AuthorEngine::Text::FONT_DEFAULT)
|
11
|
+
|
12
|
+
@files.each do |file|
|
13
|
+
@list << Project.new(file, proc {load(file)})
|
14
|
+
end
|
15
|
+
|
16
|
+
@index = ((@list.size)/2.0).floor
|
17
|
+
@list.rotate!(@index)
|
18
|
+
@height = (@list.size-1)*@font.height
|
19
|
+
|
20
|
+
@last_index = @index
|
21
|
+
@entering_name = false
|
22
|
+
|
23
|
+
@header_color = Gosu::Color.rgba(dark_green.red, dark_green.green, dark_green.blue, 100)
|
24
|
+
@new_button = Button.new(label: "New Project", color: @header_color) do
|
25
|
+
window.text_input = Gosu::TextInput.new
|
26
|
+
@entering_name = true
|
27
|
+
end
|
28
|
+
@new_button.x = window.width - @new_button.width
|
29
|
+
end
|
30
|
+
|
31
|
+
def load(filename)
|
32
|
+
p filename
|
33
|
+
savefile = SaveFile.new(filename)
|
34
|
+
window.container = Editor.new(savefile)
|
35
|
+
end
|
36
|
+
|
37
|
+
def draw
|
38
|
+
Gosu.draw_rect(0, 0, window.width, window.height, window.darken(dark_gray, 50))
|
39
|
+
|
40
|
+
if @entering_name
|
41
|
+
draw_inputter
|
42
|
+
else
|
43
|
+
draw_loader
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def draw_inputter
|
48
|
+
x = window.width/2 - @font.text_width(window.text_input.text+".authorengine")/2
|
49
|
+
y = window.height/2 - @font.height/2
|
50
|
+
@font.draw_text(window.text_input.text+".authorengine", x, y, 0)
|
51
|
+
end
|
52
|
+
|
53
|
+
def draw_loader
|
54
|
+
Gosu.draw_rect(0, @new_button.y, window.width, @new_button.height, @header_color)
|
55
|
+
@font.draw_text("AuthorEngine", 1*window.square_scale,@font.height/2,0)
|
56
|
+
@new_button.draw
|
57
|
+
@font.draw_text(@list[@index].name, 0, 0, 0) if @list[@index]
|
58
|
+
|
59
|
+
Gosu.clip_to(0, @font.height*2, window.width, window.height-(@font.height*4)) do
|
60
|
+
y = (window.height/2-@font.height) - (@height/2)
|
61
|
+
|
62
|
+
@list.each_with_index do |project, index|
|
63
|
+
label = project.name.sub(@root_directory+"/", '')
|
64
|
+
x = window.width/2 - @font.text_width(label)/2
|
65
|
+
if project == @list[@index]
|
66
|
+
Gosu.draw_rect(0, y, window.width, @font.height, red)
|
67
|
+
end
|
68
|
+
@font.draw_text(label, x, y, 0)
|
69
|
+
y+=@font.height
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def update
|
75
|
+
end
|
76
|
+
|
77
|
+
def close
|
78
|
+
window.close!
|
79
|
+
end
|
80
|
+
|
81
|
+
def button_up(id)
|
82
|
+
@new_button.button_up(id)
|
83
|
+
|
84
|
+
case id
|
85
|
+
when Gosu::KbUp
|
86
|
+
# @list.rotate!(-1)
|
87
|
+
# @index-=1
|
88
|
+
# @index = (@index % @list.size-1)*-1
|
89
|
+
# p @index
|
90
|
+
when Gosu::KbDown
|
91
|
+
@list.rotate!(1)
|
92
|
+
@index+=1
|
93
|
+
@index = 0 if @list.size == 0
|
94
|
+
@index = @index % @list.size-1 if @list.size != 0
|
95
|
+
when Gosu::KbEnter, Gosu::KbReturn
|
96
|
+
if @entering_name
|
97
|
+
SaveFile.create(window.text_input.text.strip+".authorengine")
|
98
|
+
load(window.text_input.text.strip+".authorengine")
|
99
|
+
else
|
100
|
+
@list[@index].block.call if @list[@index]&.block
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class AuthorEngine
|
2
|
+
class Game
|
3
|
+
include AuthorEngine::Part::Common
|
4
|
+
include AuthorEngine::Part::Colors
|
5
|
+
include AuthorEngine::Part::Graphics
|
6
|
+
include AuthorEngine::Part::Input
|
7
|
+
|
8
|
+
def initialize(code:)
|
9
|
+
@background_color = Gosu::Color::BLACK
|
10
|
+
self.instance_eval(code)
|
11
|
+
end
|
12
|
+
|
13
|
+
def draw_background
|
14
|
+
Gosu.draw_rect(0, 0, Window::VIEW_WIDTH, Window::VIEW_HEIGHT, @background_color)
|
15
|
+
end
|
16
|
+
|
17
|
+
def init
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw
|
21
|
+
end
|
22
|
+
|
23
|
+
def update
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class AuthorEngine
|
2
|
+
class Part
|
3
|
+
module Colors
|
4
|
+
COLORS = {
|
5
|
+
0 => Gosu::Color.rgb(0,0,0),
|
6
|
+
1 => Gosu::Color.rgb(29, 43, 83),
|
7
|
+
2 => Gosu::Color.rgb(126, 37, 83),
|
8
|
+
3 => Gosu::Color.rgb(0, 135, 81),
|
9
|
+
|
10
|
+
4 => Gosu::Color.rgb(171, 82, 54),
|
11
|
+
5 => Gosu::Color.rgb(95, 87, 79),
|
12
|
+
6 => Gosu::Color.rgb(194, 195, 199),
|
13
|
+
7 => Gosu::Color.rgb(255, 241, 232),
|
14
|
+
|
15
|
+
8 => Gosu::Color.rgb(255, 0, 77),
|
16
|
+
9 => Gosu::Color.rgb(255, 163, 0),
|
17
|
+
10 => Gosu::Color.rgb(225, 236, 39),
|
18
|
+
11 => Gosu::Color.rgb(0, 228, 54),
|
19
|
+
|
20
|
+
12 => Gosu::Color.rgb(41, 173, 255),
|
21
|
+
13 => Gosu::Color.rgb(131, 118, 156),
|
22
|
+
14 => Gosu::Color.rgb(225, 119, 168),
|
23
|
+
15 => Gosu::Color.rgb(255, 204, 170)
|
24
|
+
}
|
25
|
+
|
26
|
+
def black; COLORS.dig(0); end
|
27
|
+
def dark_blue; COLORS.dig(1); end
|
28
|
+
def dark_purple; COLORS.dig(2); end
|
29
|
+
def dark_green; COLORS.dig(3); end
|
30
|
+
|
31
|
+
def brown; COLORS.dig(4); end
|
32
|
+
def dark_gray; COLORS.dig(5); end
|
33
|
+
def light_gray; COLORS.dig(6); end
|
34
|
+
def white; COLORS.dig(7); end
|
35
|
+
|
36
|
+
def red; COLORS.dig(8); end
|
37
|
+
def orange; COLORS.dig(9); end
|
38
|
+
def yellow; COLORS.dig(10); end
|
39
|
+
def green; COLORS.dig(11); end
|
40
|
+
|
41
|
+
def blue; COLORS.dig(12); end
|
42
|
+
def indigo; COLORS.dig(13); end
|
43
|
+
def pink; COLORS.dig(14); end
|
44
|
+
def peach; COLORS.dig(15); end
|
45
|
+
|
46
|
+
def xml_color(color)
|
47
|
+
red = color.red.to_s(16)
|
48
|
+
green = color.green.to_s(16)
|
49
|
+
blue = color.blue.to_s(16)
|
50
|
+
|
51
|
+
red = "0#{red}" if color.red < 10
|
52
|
+
green = "0#{green}" if color.green < 10
|
53
|
+
blue = "0#{blue}" if color.blue < 10
|
54
|
+
|
55
|
+
return "#{red}#{green}#{blue}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|