RSokoban 0.73 → 0.74
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +16 -1
- data/README.rdoc +25 -8
- data/Rakefile +51 -0
- data/TODO +19 -41
- data/VERSION +1 -1
- data/bin/rsokoban +1 -3
- data/lib/rsokoban.rb +2 -0
- data/lib/rsokoban/exception.rb +4 -0
- data/lib/rsokoban/extensions.rb +26 -0
- data/lib/rsokoban/game.rb +161 -41
- data/lib/rsokoban/level.rb +54 -37
- data/lib/rsokoban/level_loader.rb +34 -11
- data/lib/rsokoban/move_recorder.rb +14 -2
- data/lib/rsokoban/move_result.rb +37 -0
- data/lib/rsokoban/ui/base_ui.rb +0 -3
- data/lib/rsokoban/ui/console.rb +2 -2
- data/lib/rsokoban/ui/curses_console.rb +0 -2
- data/lib/rsokoban/ui/player_action.rb +2 -2
- data/lib/rsokoban/ui/tk_box.rb +21 -0
- data/lib/rsokoban/ui/tk_dialogs.rb +240 -0
- data/lib/rsokoban/ui/tk_ui.rb +170 -269
- data/test/tc_extensions.rb +26 -0
- data/test/tc_game.rb +28 -0
- data/test/tc_level.rb +187 -112
- data/test/tc_level_loader.rb +12 -17
- data/test/tc_move_recorder.rb +41 -7
- data/test/tc_move_result.rb +45 -0
- data/test/test.rb +3 -0
- data/test/ui/tc_console.rb +3 -1
- metadata +10 -3
- data/RSokoban-0.73.gem +0 -0
data/lib/rsokoban/ui/tk_ui.rb
CHANGED
@@ -1,256 +1,148 @@
|
|
1
|
-
#require 'tk'
|
2
|
-
#require 'tkextlib/tkimg'
|
3
|
-
|
4
1
|
module RSokoban::UI
|
5
|
-
|
6
|
-
# I am an image of the game who knows how to display itself on an array
|
7
|
-
# of TkLabel items.
|
8
|
-
# @since 0.73
|
9
|
-
class Image
|
10
|
-
|
11
|
-
# @param [String] file path of image file
|
12
|
-
# @param [Array<Array<TkLabel>>] output an array to display myself
|
13
|
-
def initialize file, output
|
14
|
-
@box = TkPhotoImage.new('file' => file, 'height' => 0, 'width' => 0)
|
15
|
-
@output = output
|
16
|
-
end
|
17
|
-
|
18
|
-
# Display myself at x,y coordinate
|
19
|
-
def display_at x, y
|
20
|
-
@output[y][x].configure('image' => @box)
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
class LevelDialog < TkToplevel
|
26
|
-
def initialize(root, title)
|
27
|
-
super(root)
|
28
|
-
title(title)
|
29
|
-
minsize(200, 100)
|
30
|
-
@state = 'CANCEL'
|
31
|
-
grab
|
32
|
-
|
33
|
-
$spinval = TkVariable.new
|
34
|
-
@spin = TkSpinbox.new(self) do
|
35
|
-
textvariable($spinval)
|
36
|
-
grid('row'=>0, 'column'=>0)
|
37
|
-
end
|
38
|
-
@spin.to(999)
|
39
|
-
@spin.from(1)
|
40
|
-
|
41
|
-
@ok = TkButton.new(self) do
|
42
|
-
text 'OK'
|
43
|
-
grid('row'=>1, 'column'=>0)
|
44
|
-
end
|
45
|
-
@ok.command { ok_on_clic }
|
46
|
-
|
47
|
-
@cancel = TkButton.new(self) do
|
48
|
-
text 'Cancel'
|
49
|
-
grid('row'=>1, 'column'=>1)
|
50
|
-
end
|
51
|
-
@cancel.command { cancel_on_clic }
|
52
|
-
|
53
|
-
wait_destroy
|
54
|
-
end
|
55
|
-
|
56
|
-
def ok_on_clic
|
57
|
-
@state = 'OK'
|
58
|
-
destroy
|
59
|
-
end
|
60
|
-
|
61
|
-
def cancel_on_clic
|
62
|
-
@state = 'CANCEL'
|
63
|
-
destroy
|
64
|
-
end
|
65
|
-
|
66
|
-
def ok?
|
67
|
-
@state == 'OK'
|
68
|
-
end
|
69
|
-
|
70
|
-
def value
|
71
|
-
$spinval.to_i
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class SetDialog < TkToplevel
|
76
|
-
def initialize(root, title)
|
77
|
-
super(root)
|
78
|
-
title(title)
|
79
|
-
minsize(200, 100)
|
80
|
-
@state = 'CANCEL'
|
81
|
-
grab
|
82
|
-
|
83
|
-
@value = nil
|
84
|
-
@xsb = get_xsb
|
85
|
-
$listval = TkVariable.new(@xsb)
|
86
|
-
|
87
|
-
@list = TkListbox.new(self) do
|
88
|
-
width 20
|
89
|
-
height 8
|
90
|
-
listvariable $listval
|
91
|
-
grid('row'=>0, 'column'=>0)
|
92
|
-
end
|
93
|
-
|
94
|
-
@ok = TkButton.new(self) do
|
95
|
-
text 'OK'
|
96
|
-
grid('row'=>1, 'column'=>0)
|
97
|
-
end
|
98
|
-
@ok.command { ok_on_clic }
|
99
|
-
|
100
|
-
@cancel = TkButton.new(self) do
|
101
|
-
text 'Cancel'
|
102
|
-
grid('row'=>1, 'column'=>1)
|
103
|
-
end
|
104
|
-
@cancel.command { cancel_on_clic }
|
105
|
-
|
106
|
-
wait_destroy
|
107
|
-
end
|
108
|
-
|
109
|
-
def ok_on_clic
|
110
|
-
@state = 'OK'
|
111
|
-
idx = @list.curselection
|
112
|
-
unless idx.empty?
|
113
|
-
@value = @xsb[idx[0]]
|
114
|
-
end
|
115
|
-
destroy
|
116
|
-
end
|
117
|
-
|
118
|
-
def cancel_on_clic
|
119
|
-
@state = 'CANCEL'
|
120
|
-
destroy
|
121
|
-
end
|
122
|
-
|
123
|
-
def ok?
|
124
|
-
@state == 'OK'
|
125
|
-
end
|
126
|
-
|
127
|
-
def value
|
128
|
-
@value
|
129
|
-
end
|
130
|
-
|
131
|
-
def get_xsb
|
132
|
-
current = Dir.pwd
|
133
|
-
Dir.chdir $RSOKOBAN_DATA_PATH
|
134
|
-
ret = Dir.glob '*.xsb'
|
135
|
-
Dir.chdir current
|
136
|
-
ret
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
class HelpDialog < TkToplevel
|
141
|
-
def initialize(root, title)
|
142
|
-
super(root)
|
143
|
-
title(title)
|
144
|
-
minsize(200, 100)
|
145
|
-
|
146
|
-
text = TkText.new(self) do
|
147
|
-
borderwidth 1
|
148
|
-
font TkFont.new('times 12 bold')
|
149
|
-
grid('row' => 0, 'column' => 0)
|
150
|
-
end
|
151
|
-
|
152
|
-
help=<<EOS
|
153
|
-
Welcome to RSokoban !
|
154
|
-
|
155
|
-
Goal of Sokoban game is to place each crate on a storage location.
|
156
|
-
Move the man using the arrow keys.
|
157
|
-
For a more comprehensive help, please visit the wiki at https://github.com/lkdjiin/RSokoban/wiki.
|
158
|
-
EOS
|
159
|
-
|
160
|
-
text.insert 'end', help
|
161
|
-
|
162
|
-
@ok = TkButton.new(self) do
|
163
|
-
text 'OK'
|
164
|
-
grid('row'=>1, 'column'=>0)
|
165
|
-
end
|
166
|
-
@ok.command { ok_on_clic }
|
167
|
-
end
|
168
|
-
|
169
|
-
def ok_on_clic
|
170
|
-
destroy
|
171
|
-
end
|
172
|
-
end
|
173
2
|
|
174
3
|
# I am a GUI using tk library.
|
175
4
|
# @note I need the tk-img extension library.
|
176
5
|
# @since 0.73
|
177
|
-
# @todo
|
178
|
-
# and maybe Level and BaseUI.
|
179
|
-
# @todo need some more documentation
|
6
|
+
# @todo need some examples and more documentation for private methods
|
180
7
|
class TkUI
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
@
|
8
|
+
include RSokoban
|
9
|
+
|
10
|
+
# Build and initialize a GUI with the Tk tool kit.
|
11
|
+
# @param [Game] game Where we get the logic.
|
12
|
+
def initialize game
|
13
|
+
@game = game
|
187
14
|
@last_move = :up
|
188
15
|
@tk_map = []
|
189
16
|
init_gui
|
190
|
-
|
17
|
+
start_level
|
18
|
+
end
|
19
|
+
|
20
|
+
# Start the event loop.
|
21
|
+
# @since 0.74
|
22
|
+
def run
|
191
23
|
Tk.mainloop
|
192
24
|
end
|
193
25
|
|
194
26
|
private
|
195
27
|
|
196
28
|
def next_level
|
197
|
-
|
198
|
-
|
29
|
+
begin
|
30
|
+
@game.next_level
|
31
|
+
init_level
|
32
|
+
rescue LevelNumberTooHighError
|
33
|
+
Tk::messageBox :message => "Sorry, no level ##{@game.level_number} in this set."
|
34
|
+
end
|
199
35
|
end
|
200
36
|
|
201
37
|
def start_level
|
202
38
|
begin
|
203
|
-
@
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
display
|
208
|
-
rescue RSokoban::LevelNumberTooHighError
|
209
|
-
Tk::messageBox :message => "Sorry, no level ##{@level_number} in this set."
|
39
|
+
@game.start_level
|
40
|
+
init_level
|
41
|
+
rescue LevelNumberTooHighError
|
42
|
+
Tk::messageBox :message => "Sorry, no level ##{@game.level_number} in this set."
|
210
43
|
end
|
211
44
|
end
|
212
45
|
|
213
46
|
def load_level
|
214
|
-
d =
|
215
|
-
|
216
|
-
|
217
|
-
|
47
|
+
d = TkLevelDialog.new(@tk_root, "Load a level")
|
48
|
+
return unless d.ok?
|
49
|
+
begin
|
50
|
+
@game.load_level d.value
|
51
|
+
init_level
|
52
|
+
rescue LevelNumberTooHighError
|
53
|
+
Tk::messageBox :message => "Sorry, no level ##{@game.level_number} in this set."
|
218
54
|
end
|
219
55
|
end
|
220
56
|
|
221
57
|
def load_set
|
222
58
|
d = SetDialog.new(@tk_root, "Load a set")
|
223
|
-
|
224
|
-
if d.
|
225
|
-
|
226
|
-
|
227
|
-
|
59
|
+
return unless d.ok?
|
60
|
+
return if d.value.nil?
|
61
|
+
@game.load_a_new_set d.value
|
62
|
+
init_level
|
63
|
+
end
|
64
|
+
|
65
|
+
# For now, map size is restricted to 19x16 on screen.
|
66
|
+
def init_level
|
67
|
+
if @game.level_width > 19 or @game.level_height > 16
|
68
|
+
Tk::messageBox :message => "Sorry, level '#{@game.level_title}' is too big to be displayed."
|
69
|
+
@game.restart_set
|
70
|
+
end
|
71
|
+
reset_labels
|
72
|
+
reset_map
|
73
|
+
display_initial
|
74
|
+
end
|
75
|
+
|
76
|
+
# Update map rendering. We need only to update man's location and north, south, west
|
77
|
+
# and east of him. And because there walls all around the map, there is no needs to check
|
78
|
+
# for limits.
|
79
|
+
def display_update
|
80
|
+
x = @game.man_x
|
81
|
+
y = @game.man_y
|
82
|
+
update_array = [[x,y], [x+1,y], [x-1,y], [x,y+1], [x,y-1]]
|
83
|
+
update_array.each do |x, y|
|
84
|
+
case @game.map[y][x].chr
|
85
|
+
when WALL then @wall.display_at x, y
|
86
|
+
when FLOOR then @floor.display_at x, y
|
87
|
+
when CRATE then @crate.display_at x, y
|
88
|
+
when STORAGE then @store.display_at x, y
|
89
|
+
when MAN then display_man_at x, y
|
90
|
+
when MAN_ON_STORAGE then display_man_on_storage_at x, y
|
91
|
+
when CRATE_ON_STORAGE then @crate_store.display_at x, y
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def display_update_after_undo
|
97
|
+
x = @game.man_x
|
98
|
+
y = @game.man_y
|
99
|
+
update_array = [[x,y], [x+1,y], [x+2,y], [x-1,y], [x-2,y], [x,y+1], [x,y+2], [x,y-1], [x,y-2]]
|
100
|
+
update_array.each do |x, y|
|
101
|
+
next if x < 0 or y < 0
|
102
|
+
next if @game.map[y].nil? or @game.map[y][x].nil?
|
103
|
+
display_cell_taking_care_of_outside @game.map[y][x].chr, x, y
|
228
104
|
end
|
229
105
|
end
|
230
106
|
|
231
|
-
# Display the
|
232
|
-
def
|
107
|
+
# Display the initial map on screen.
|
108
|
+
def display_initial
|
233
109
|
y = 0
|
234
|
-
@
|
110
|
+
@game.map.each do |row|
|
235
111
|
# find first wall
|
236
112
|
x = row.index(RSokoban::WALL)
|
237
113
|
line = row.strip
|
238
114
|
line.each_char do |char|
|
239
|
-
|
240
|
-
when RSokoban::WALL then @wall.display_at x, y
|
241
|
-
when RSokoban::FLOOR then @floor.display_at x, y
|
242
|
-
when RSokoban::CRATE then @crate.display_at x, y
|
243
|
-
when RSokoban::STORAGE then @store.display_at x, y
|
244
|
-
when RSokoban::MAN then display_man_at x, y
|
245
|
-
when RSokoban::MAN_ON_STORAGE then display_man_on_storage_at x, y
|
246
|
-
when RSokoban::CRATE_ON_STORAGE then @crate_store.display_at x, y
|
247
|
-
end
|
115
|
+
display_cell_taking_care_of_outside char, x, y
|
248
116
|
x += 1
|
249
117
|
end
|
250
118
|
y += 1
|
251
119
|
end
|
252
120
|
end
|
253
121
|
|
122
|
+
def display_cell_taking_care_of_outside char, x, y
|
123
|
+
case char
|
124
|
+
when WALL then @wall.display_at x, y
|
125
|
+
when FLOOR then display_floor_at x, y
|
126
|
+
when CRATE then @crate.display_at x, y
|
127
|
+
when STORAGE then @store.display_at x, y
|
128
|
+
when MAN then display_man_at x, y
|
129
|
+
when MAN_ON_STORAGE then display_man_on_storage_at x, y
|
130
|
+
when CRATE_ON_STORAGE then @crate_store.display_at x, y
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def display_floor_at x, y
|
135
|
+
return if y == 0
|
136
|
+
height = y - 1
|
137
|
+
height.downto(0).each {|row|
|
138
|
+
break if @game.map[row][x].nil?
|
139
|
+
if [WALL, FLOOR, CRATE, STORAGE].include?(@game.map[row][x].chr)
|
140
|
+
@floor.display_at x, y
|
141
|
+
break
|
142
|
+
end
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
254
146
|
def display_man_at x, y
|
255
147
|
case @last_move
|
256
148
|
when :up then @man_up.display_at x, y
|
@@ -302,8 +194,10 @@ EOS
|
|
302
194
|
file.add :command, :label => 'Load level', :command => proc{load_level}, :accelerator => 'Ctrl+L'
|
303
195
|
file.add :command, :label => 'Load set', :command => proc{load_set}
|
304
196
|
file.add :separator
|
305
|
-
file.add :command, :label => 'Undo', :command => proc{undo}, :accelerator => 'Ctrl+
|
197
|
+
file.add :command, :label => 'Undo', :command => proc{undo}, :accelerator => 'Ctrl+Z'
|
198
|
+
file.add :command, :label => 'Redo', :command => proc{my_redo}, :accelerator => 'Ctrl+Y'
|
306
199
|
file.add :command, :label => 'Restart level', :command => proc{start_level}, :accelerator => 'Ctrl+R'
|
200
|
+
file.add :command, :label => 'Next level', :command => proc{next_level}, :accelerator => 'Ctrl+N'
|
307
201
|
file.add :separator
|
308
202
|
file.add :command, :label => 'Quit', :command => proc{exit}
|
309
203
|
|
@@ -313,33 +207,33 @@ EOS
|
|
313
207
|
end
|
314
208
|
|
315
209
|
def init_labels
|
316
|
-
@
|
317
|
-
|
210
|
+
@tk_frame_label = TkFrame.new(@tk_root) do
|
211
|
+
grid('row' => 0, 'column' => 0, 'columnspan' => 19, 'sticky' => 'w')
|
212
|
+
padx 5
|
213
|
+
pady 5
|
318
214
|
end
|
319
|
-
@
|
320
|
-
|
215
|
+
@tk_label_set = TkLabel.new(@tk_frame_label) do
|
216
|
+
grid('row' => 0, 'column' => 0, 'sticky' => 'w')
|
321
217
|
end
|
322
|
-
@
|
323
|
-
grid('row'=>
|
218
|
+
@tk_label_level = TkLabel.new(@tk_frame_label) do
|
219
|
+
grid('row'=>1, 'column'=> 0, 'sticky' => 'w')
|
324
220
|
end
|
325
|
-
@
|
326
|
-
|
327
|
-
grid('row'=>4, 'column'=>0, 'columnspan' => 19)
|
221
|
+
@tk_label_move = TkLabel.new(@tk_frame_label) do
|
222
|
+
grid('row'=>2, 'column'=>0, 'sticky' => 'w')
|
328
223
|
end
|
329
|
-
reset_labels
|
330
224
|
end
|
331
225
|
|
332
226
|
def reset_labels
|
333
|
-
@tk_label_set.configure('text' => "Set: #{@
|
334
|
-
@tk_label_level.configure('text' => "Level: #{@
|
227
|
+
@tk_label_set.configure('text' => "Set: #{@game.set_title}")
|
228
|
+
@tk_label_level.configure('text' => "Level: #{@game.level_title} (#{@game.level_number}/#{@game.set_size})")
|
335
229
|
update_move_information
|
336
230
|
end
|
337
231
|
|
338
232
|
def update_move_information
|
339
|
-
@tk_label_move.configure('text' => "Move: #{@
|
233
|
+
@tk_label_move.configure('text' => "Move: #{@game.move_number}")
|
340
234
|
end
|
341
235
|
|
342
|
-
# Build the map of labels.
|
236
|
+
# Build the map of labels. TkBoxs of the game will be displayed on those labels.
|
343
237
|
def init_map
|
344
238
|
row_in_grid = 5
|
345
239
|
(0...16).each {|row_index|
|
@@ -367,24 +261,33 @@ EOS
|
|
367
261
|
end
|
368
262
|
|
369
263
|
def init_buttons
|
370
|
-
@
|
264
|
+
@tk_frame_button = TkFrame.new(@tk_root) do
|
265
|
+
grid('row' => 1, 'column' => 0, 'columnspan' => 19, 'sticky' => 'w')
|
266
|
+
padx 5
|
267
|
+
pady 5
|
268
|
+
end
|
269
|
+
@tk_undo_button = TkButton.new(@tk_frame_button) do
|
371
270
|
text 'Undo'
|
372
|
-
grid('row'=>
|
271
|
+
grid('row'=> 0, 'column'=> 0)
|
272
|
+
end
|
273
|
+
@tk_redo_button = TkButton.new(@tk_frame_button) do
|
274
|
+
text 'Redo'
|
275
|
+
grid('row'=> 0, 'column'=> 1)
|
373
276
|
end
|
374
277
|
|
375
|
-
@tk_retry_button = TkButton.new(@
|
278
|
+
@tk_retry_button = TkButton.new(@tk_frame_button) do
|
376
279
|
text 'Retry'
|
377
|
-
grid('row'=>
|
280
|
+
grid('row'=> 0, 'column'=> 2)
|
378
281
|
end
|
379
282
|
|
380
|
-
@tk_level_button = TkButton.new(@
|
283
|
+
@tk_level_button = TkButton.new(@tk_frame_button) do
|
381
284
|
text 'Level'
|
382
|
-
grid('row'=>
|
285
|
+
grid('row'=> 0, 'column'=> 3)
|
383
286
|
end
|
384
287
|
|
385
|
-
@
|
386
|
-
text '
|
387
|
-
grid('row'=>
|
288
|
+
@tk_next_level_button = TkButton.new(@tk_frame_button) do
|
289
|
+
text 'Next'
|
290
|
+
grid('row'=> 0, 'column'=> 4)
|
388
291
|
end
|
389
292
|
end
|
390
293
|
|
@@ -394,36 +297,41 @@ EOS
|
|
394
297
|
@tk_root.bind('Down') { move :down }
|
395
298
|
@tk_root.bind('Left') { move :left }
|
396
299
|
@tk_root.bind('Right') { move :right }
|
397
|
-
@tk_root.bind('Control-
|
300
|
+
@tk_root.bind('Control-z') { undo }
|
301
|
+
@tk_root.bind('Control-y') { my_redo }
|
398
302
|
@tk_root.bind('Control-r') { start_level }
|
399
303
|
@tk_root.bind('Control-l') { load_level }
|
304
|
+
@tk_root.bind('Control-n') { next_level }
|
400
305
|
@tk_root.bind('F1') { help }
|
401
306
|
@tk_undo_button.command { undo }
|
307
|
+
@tk_redo_button.command { my_redo }
|
402
308
|
@tk_retry_button.command { start_level }
|
403
309
|
@tk_level_button.command { load_level }
|
404
|
-
@
|
310
|
+
@tk_next_level_button.command { next_level }
|
405
311
|
end
|
406
312
|
|
407
313
|
def undo
|
408
|
-
result = @
|
409
|
-
@move = get_move_number_from_result_of_last_move result
|
314
|
+
result = @game.undo
|
410
315
|
update_move_information
|
411
|
-
|
316
|
+
display_update_after_undo
|
317
|
+
end
|
318
|
+
|
319
|
+
def my_redo
|
320
|
+
result = @game.redo
|
321
|
+
update_move_information
|
322
|
+
display_update_after_undo
|
412
323
|
end
|
413
324
|
|
414
325
|
# Send the move to Level and process response.
|
415
|
-
# @
|
416
|
-
# in the 4 direction. This is a bad thing ! Level#move should returns a hash
|
417
|
-
# with all needed information (status, move number, last move, error message, etc.)
|
326
|
+
# @param [:ip, :down, :left, :right]
|
418
327
|
def move symb
|
419
328
|
@last_move = symb
|
420
|
-
result = @
|
421
|
-
unless result.
|
422
|
-
@move = get_move_number_from_result_of_last_move result
|
329
|
+
result = @game.move symb
|
330
|
+
unless result.error?
|
423
331
|
update_move_information
|
424
|
-
|
332
|
+
display_update
|
425
333
|
end
|
426
|
-
if result.
|
334
|
+
if result.win?
|
427
335
|
response = Tk::messageBox :type => 'yesno', :message => "Level completed !\nPlay next level ?",
|
428
336
|
:icon => 'question', :title => 'You win !', :parent => @tk_root, :default => 'yes'
|
429
337
|
next_level if response == 'yes'
|
@@ -431,29 +339,22 @@ EOS
|
|
431
339
|
end
|
432
340
|
end
|
433
341
|
|
434
|
-
# Assuming that result start with 'OK' or 'WIN'
|
435
|
-
# @return [Fixnum] current move number
|
436
|
-
def get_move_number_from_result_of_last_move result
|
437
|
-
move_index = result =~ /\d+/
|
438
|
-
result[move_index..-1].to_i
|
439
|
-
end
|
440
|
-
|
441
342
|
def preload_images
|
442
343
|
dir = $RSOKOBAN_PATH + '/skins/default/'
|
443
|
-
@wall =
|
444
|
-
@crate =
|
445
|
-
@floor =
|
446
|
-
@store =
|
447
|
-
@man_up =
|
448
|
-
@man_down =
|
449
|
-
@man_left =
|
450
|
-
@man_right =
|
451
|
-
@crate_store =
|
452
|
-
@man_store_up =
|
453
|
-
@man_store_down =
|
454
|
-
@man_store_left =
|
455
|
-
@man_store_right =
|
456
|
-
@outside =
|
344
|
+
@wall = TkBox.new(dir + 'wall.bmp', @tk_map)
|
345
|
+
@crate = TkBox.new(dir + 'crate.bmp', @tk_map)
|
346
|
+
@floor = TkBox.new(dir + 'floor.bmp', @tk_map)
|
347
|
+
@store = TkBox.new(dir + 'store.bmp', @tk_map)
|
348
|
+
@man_up = TkBox.new(dir + 'man_up.bmp', @tk_map)
|
349
|
+
@man_down = TkBox.new(dir + 'man_down.bmp', @tk_map)
|
350
|
+
@man_left = TkBox.new(dir + 'man_left.bmp', @tk_map)
|
351
|
+
@man_right = TkBox.new(dir + 'man_right.bmp', @tk_map)
|
352
|
+
@crate_store = TkBox.new(dir + 'crate_store.bmp', @tk_map)
|
353
|
+
@man_store_up = TkBox.new(dir + 'man_store_up.bmp', @tk_map)
|
354
|
+
@man_store_down = TkBox.new(dir + 'man_store_down.bmp', @tk_map)
|
355
|
+
@man_store_left = TkBox.new(dir + 'man_store_left.bmp', @tk_map)
|
356
|
+
@man_store_right = TkBox.new(dir + 'man_store_right.bmp', @tk_map)
|
357
|
+
@outside = TkBox.new(dir + 'outside.bmp', @tk_map)
|
457
358
|
end
|
458
359
|
|
459
360
|
def help
|