ray 0.0.0.pre2 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/README.md +62 -0
- data/Rakefile +33 -23
- data/VERSION +1 -1
- data/ext/audio.c +473 -0
- data/ext/color.c +4 -4
- data/ext/event.c +25 -3
- data/ext/extconf.rb +35 -22
- data/ext/font.c +287 -0
- data/ext/image.c +682 -33
- data/ext/joystick.c +9 -9
- data/ext/ray.c +166 -55
- data/ext/ray.h +120 -9
- data/ext/ray_osx.m +161 -0
- data/ext/rect.c +31 -4
- data/lib/ray/audio.rb +52 -0
- data/lib/ray/color.rb +16 -0
- data/lib/ray/dsl.rb +1 -3
- data/lib/ray/dsl/event.rb +1 -39
- data/lib/ray/dsl/event_listener.rb +38 -0
- data/lib/ray/dsl/event_runner.rb +3 -1
- data/lib/ray/dsl/event_translator.rb +74 -8
- data/lib/ray/dsl/handler.rb +3 -33
- data/lib/ray/dsl/matcher.rb +129 -23
- data/lib/ray/font.rb +108 -0
- data/lib/ray/font_set.rb +37 -0
- data/lib/ray/game.rb +171 -34
- data/lib/ray/helper.rb +43 -5
- data/lib/ray/image.rb +90 -3
- data/lib/ray/image_set.rb +35 -0
- data/lib/ray/joystick.rb +30 -0
- data/lib/ray/music_set.rb +35 -0
- data/lib/ray/ray.rb +17 -9
- data/lib/ray/rect.rb +51 -0
- data/lib/ray/resource_set.rb +92 -0
- data/lib/ray/scene.rb +220 -51
- data/lib/ray/sound_set.rb +35 -0
- data/lib/ray/sprite.rb +184 -0
- data/psp/ext.c +4 -0
- data/samples/hello_world/hello.rb +35 -0
- data/samples/hello_world/hello_dsl.rb +24 -0
- data/samples/pong/pong.rb +128 -0
- data/samples/sokoban/level_1 +7 -0
- data/samples/sokoban/sokoban.rb +370 -0
- data/spec/ray/audio_spec.rb +146 -0
- data/spec/ray/color_spec.rb +13 -0
- data/spec/ray/event_spec.rb +57 -168
- data/spec/ray/font_spec.rb +93 -0
- data/spec/ray/image_set_spec.rb +48 -0
- data/spec/ray/image_spec.rb +130 -44
- data/spec/ray/joystick_spec.rb +13 -9
- data/spec/ray/matcher_spec.rb +32 -55
- data/spec/ray/ray_spec.rb +33 -31
- data/spec/ray/rect_spec.rb +80 -0
- data/spec/ray/resource_set_spec.rb +105 -0
- data/spec/ray/sprite_spec.rb +163 -0
- data/spec/res/VeraMono.ttf +0 -0
- data/spec/res/aqua2.bmp +0 -0
- data/spec/res/pop.wav +0 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +8 -0
- data/yard_ext.rb +91 -0
- metadata +104 -38
- data/bin/ray +0 -5
- data/bin/ray_irb +0 -4
- data/ext/SDLMain.h +0 -17
- data/ext/SDLMain.m +0 -381
- data/lib/ray/config.rb +0 -84
- data/lib/ray/dsl/converter.rb +0 -65
- data/lib/ray/dsl/listener.rb +0 -30
- data/lib/ray/dsl/type.rb +0 -58
- data/spec/ray/config_spec.rb +0 -90
- data/spec/ray/conversion_spec.rb +0 -43
- data/spec/ray/type_spec.rb +0 -17
- data/spec_runner.rb +0 -27
data/psp/ext.c
CHANGED
@@ -208,6 +208,8 @@ VALUE Wlan_ip(VALUE self) {
|
|
208
208
|
Inits a builtin module. You should never call it by yourself.
|
209
209
|
This avoids to load unneeded module from the stdlib (Ray's are all loaded
|
210
210
|
anyway). For instance, the zlib library needs to be enabled by this function.
|
211
|
+
|
212
|
+
@note This method is only available on the PSP.
|
211
213
|
*/
|
212
214
|
VALUE ray_init_internal(VALUE self, VALUE module_name) {
|
213
215
|
VALUE rb_str = rb_obj_as_string(module_name);
|
@@ -265,6 +267,8 @@ VALUE ray_init_internal(VALUE self, VALUE module_name) {
|
|
265
267
|
|
266
268
|
Once you're connected, everything is transparent: you can use sockets as
|
267
269
|
usual.
|
270
|
+
|
271
|
+
@note This module is only available on the PSP.
|
268
272
|
*/
|
269
273
|
void Init_ray_psp() {
|
270
274
|
rb_define_module_function(ray_mRay, "init_internal", ray_init_internal, 1);
|
@@ -0,0 +1,35 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
2
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../ext")
|
3
|
+
|
4
|
+
def path_of(res)
|
5
|
+
File.expand_path(File.dirname(__FILE__) + "/../../spec/res/#{res}")
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'ray'
|
9
|
+
|
10
|
+
class HelloScene < Ray::Scene
|
11
|
+
scene_name :hello
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@font = font(path_of("VeraMono.ttf"), 12)
|
15
|
+
end
|
16
|
+
|
17
|
+
def render(win)
|
18
|
+
@font.draw("Hello world!", :on => win, :at => [0, 0])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class HelloWorld < Ray::Game
|
23
|
+
def initialize
|
24
|
+
super("Hello world!")
|
25
|
+
|
26
|
+
HelloScene.bind(self)
|
27
|
+
push_scene :hello
|
28
|
+
end
|
29
|
+
|
30
|
+
def register
|
31
|
+
add_hook :quit, method(:exit!)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
HelloWorld.new.run
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
2
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../ext")
|
3
|
+
|
4
|
+
def path_of(res)
|
5
|
+
File.expand_path(File.dirname(__FILE__) + "/../../spec/res/#{res}")
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'ray'
|
9
|
+
|
10
|
+
Ray::Game.new("Hello world!") do
|
11
|
+
register do
|
12
|
+
add_hook :quit, method(:exit!)
|
13
|
+
end
|
14
|
+
|
15
|
+
scene :hello do
|
16
|
+
@font = font(path_of("VeraMono.ttf"), 12)
|
17
|
+
|
18
|
+
render do |win|
|
19
|
+
@font.draw("Hello world", :on => win, :at => [0, 0])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
push_scene :hello
|
24
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
2
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../ext")
|
3
|
+
|
4
|
+
def path_of(res)
|
5
|
+
File.expand_path(File.dirname(__FILE__) + "/../../spec/res/#{res}")
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'ray'
|
9
|
+
|
10
|
+
module Pong
|
11
|
+
class Scene < Ray::Scene
|
12
|
+
scene_name :pong_scene
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@font = font(path_of("VeraMono.ttf"), 12)
|
16
|
+
|
17
|
+
player_img = Ray::Image.new(:w => 20, :h => 50)
|
18
|
+
player_img.draw_filled_rect(Ray::Rect.new(0, 0, 20, 50), Ray::Color.blue)
|
19
|
+
|
20
|
+
adv_img = Ray::Image.new(:w => 20, :h => 50)
|
21
|
+
adv_img.draw_filled_rect(Ray::Rect.new(0, 0, 20, 50), Ray::Color.red)
|
22
|
+
|
23
|
+
ball_img = Ray::Image.new(:w => 10, :h => 10)
|
24
|
+
ball_img.draw_filled_circle([5, 5], 5, Ray::Color.white)
|
25
|
+
|
26
|
+
@player = sprite(player_img)
|
27
|
+
@adv = sprite(adv_img)
|
28
|
+
@ball = sprite(ball_img)
|
29
|
+
|
30
|
+
screen = Ray.screen
|
31
|
+
width, height = screen.w, screen.h
|
32
|
+
|
33
|
+
@screen_rect = Ray::Rect.new(0, 0, width, height)
|
34
|
+
|
35
|
+
@player.y = (height / 2) - 25
|
36
|
+
@adv.y = (height / 2) - 25
|
37
|
+
|
38
|
+
@player.x = 30
|
39
|
+
@adv.x = width - 30
|
40
|
+
|
41
|
+
reset_ball
|
42
|
+
|
43
|
+
@scores = {:player => 0, :adv => 0}
|
44
|
+
end
|
45
|
+
|
46
|
+
def reset_ball
|
47
|
+
@ball.y = (@screen_rect.h / 2) - 5
|
48
|
+
@ball.x = (@screen_rect.w / 2) - 5
|
49
|
+
|
50
|
+
@ball_movement = [6, 6]
|
51
|
+
end
|
52
|
+
|
53
|
+
def register
|
54
|
+
self.loops_per_second = 60
|
55
|
+
|
56
|
+
on :point_gained do |by|
|
57
|
+
@scores[by] += 1
|
58
|
+
reset_ball
|
59
|
+
end
|
60
|
+
|
61
|
+
always do
|
62
|
+
if holding? key(:down)
|
63
|
+
@player.y += 4
|
64
|
+
@player.y -= 4 unless @player.inside? @screen_rect
|
65
|
+
elsif holding? key(:up)
|
66
|
+
@player.y -= 4
|
67
|
+
@player.y += 4 unless @player.inside? @screen_rect
|
68
|
+
end
|
69
|
+
|
70
|
+
if @ball.x >= @screen_rect.w
|
71
|
+
raise_event(:point_gained, :player)
|
72
|
+
elsif @ball.x <= 0
|
73
|
+
raise_event(:point_gained, :adv)
|
74
|
+
end
|
75
|
+
|
76
|
+
if @ball.collide?(@player) || @ball.collide?(@adv) ||
|
77
|
+
@ball.y >= @screen_rect.h || @ball.y <= 0
|
78
|
+
@ball_movement[-1] *= -1
|
79
|
+
@ball.y += @ball_movement.last
|
80
|
+
end
|
81
|
+
|
82
|
+
if @ball.collide?(@player) || @ball.collide?(@adv)
|
83
|
+
@ball_movement[0] *= -1
|
84
|
+
@ball.x += @ball_movement.first
|
85
|
+
end
|
86
|
+
|
87
|
+
adv_center = @adv.y + (@adv.image.h / 2)
|
88
|
+
if @ball.y > adv_center
|
89
|
+
@adv.y += 4
|
90
|
+
elsif @ball.y < adv_center
|
91
|
+
@adv.y -= 4
|
92
|
+
end
|
93
|
+
|
94
|
+
@ball.x += @ball_movement.first
|
95
|
+
@ball.y += @ball_movement.last
|
96
|
+
|
97
|
+
need_render!
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def render(win)
|
102
|
+
win.fill(Ray::Color.black)
|
103
|
+
|
104
|
+
@player.draw
|
105
|
+
@adv.draw
|
106
|
+
@ball.draw
|
107
|
+
|
108
|
+
@font.draw("#{@scores[:player]} - #{@scores[:adv]}",
|
109
|
+
:at => [0, 0], :on => win,
|
110
|
+
:color => Ray::Color.white)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class Game < Ray::Game
|
115
|
+
def initialize
|
116
|
+
super("Pong")
|
117
|
+
|
118
|
+
Scene.bind(self)
|
119
|
+
push_scene :pong_scene
|
120
|
+
end
|
121
|
+
|
122
|
+
def register
|
123
|
+
add_hook :quit, method(:exit!)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
Pong::Game.new.run
|
@@ -0,0 +1,370 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
2
|
+
$: << File.expand_path(File.dirname(__FILE__) + "/../../ext")
|
3
|
+
|
4
|
+
require 'ray'
|
5
|
+
|
6
|
+
module Sokoban
|
7
|
+
class InvalidLevel < StandardError; end
|
8
|
+
|
9
|
+
class Level
|
10
|
+
include Ray::Helper
|
11
|
+
include Enumerable
|
12
|
+
|
13
|
+
def self.open(filename)
|
14
|
+
level = Kernel.open(filename) { |io| new(io) }
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
yield level
|
18
|
+
else
|
19
|
+
level
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(io_or_string)
|
24
|
+
@solved = false
|
25
|
+
@moves = []
|
26
|
+
|
27
|
+
@content = io_or_string.is_a?(String) ? io_or_string : io_or_string.read
|
28
|
+
parse_content
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](x, y)
|
32
|
+
return :empty if x < 0 || y < 0
|
33
|
+
|
34
|
+
line = @objects[y]
|
35
|
+
return :empty unless line
|
36
|
+
|
37
|
+
line[x] || :empty
|
38
|
+
end
|
39
|
+
|
40
|
+
def []=(x, y, value)
|
41
|
+
@objects[y][x] = value
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_reader :character_pos
|
45
|
+
|
46
|
+
def can_move?(direction)
|
47
|
+
obj = next_obj = nil
|
48
|
+
obj, next_obj = next_objects(direction)
|
49
|
+
|
50
|
+
return true if obj == :empty || obj == :storage
|
51
|
+
return false if obj == :wall
|
52
|
+
|
53
|
+
# obj is a crate
|
54
|
+
return next_obj == :empty || next_obj == :storage
|
55
|
+
end
|
56
|
+
|
57
|
+
def move(direction)
|
58
|
+
make_move(direction)
|
59
|
+
end
|
60
|
+
|
61
|
+
def each(&block)
|
62
|
+
return to_enum unless block_given?
|
63
|
+
|
64
|
+
@objects.each do |ary|
|
65
|
+
ary.each(&block)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def each_with_pos
|
70
|
+
return to_enum(:each_with_pos) unless block_given?
|
71
|
+
|
72
|
+
@objects.each_with_index do |ary, y|
|
73
|
+
ary.each_with_index do |obj, x|
|
74
|
+
yield obj, x, y
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def reset
|
80
|
+
@moves.clear
|
81
|
+
parse_content
|
82
|
+
end
|
83
|
+
|
84
|
+
def undo
|
85
|
+
return if @moves.empty?
|
86
|
+
|
87
|
+
move = @moves.last
|
88
|
+
opposite_dir = case move[:direction]
|
89
|
+
when :left then :right
|
90
|
+
when :right then :left
|
91
|
+
when :up then :down
|
92
|
+
when :down then :up
|
93
|
+
end
|
94
|
+
|
95
|
+
x, y = character_pos
|
96
|
+
old_pos, = next_positions(move[:direction])
|
97
|
+
crate, = next_objects(move[:direction])
|
98
|
+
|
99
|
+
replacement = (self[x, y] == :man_on_storage) ? :crate_on_storage : :crate
|
100
|
+
|
101
|
+
make_move(opposite_dir, false, false)
|
102
|
+
|
103
|
+
if move[:moved_crate]
|
104
|
+
if crate == :crate
|
105
|
+
self[*old_pos] = :empty
|
106
|
+
self[x, y] = replacement
|
107
|
+
else
|
108
|
+
self[*old_pos] = :storage
|
109
|
+
self[x, y] = replacement
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
@moves.delete_at(-1)
|
114
|
+
check_solved
|
115
|
+
end
|
116
|
+
|
117
|
+
def score
|
118
|
+
@moves.size
|
119
|
+
end
|
120
|
+
|
121
|
+
def solved?
|
122
|
+
@solved
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
def char_to_object(char)
|
127
|
+
case char
|
128
|
+
when "@" then :man
|
129
|
+
when "o", "$" then :crate
|
130
|
+
when "#" then :wall
|
131
|
+
when "." then :storage
|
132
|
+
when "*" then :crate_on_storage
|
133
|
+
when "+" then :man_on_storage
|
134
|
+
when " " then :empty
|
135
|
+
else
|
136
|
+
raise InvalidLevel, "'#{char}' isn't a valid level character"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def find_character_pos
|
141
|
+
@objects.each_with_index do |ary, y|
|
142
|
+
ary.each_with_index do |obj, x|
|
143
|
+
return [x, y] if obj == :man || obj == :man_on_storage
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def parse_content
|
149
|
+
@objects = []
|
150
|
+
|
151
|
+
@content.each_line do |line|
|
152
|
+
@objects << []
|
153
|
+
|
154
|
+
line.chomp.each_char do |char|
|
155
|
+
@objects.last << char_to_object(char)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
@character_pos = find_character_pos
|
160
|
+
self
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_solved
|
164
|
+
if !include? :crate
|
165
|
+
@solved = true
|
166
|
+
raise_event(:level_solved, self)
|
167
|
+
else
|
168
|
+
@solved = false
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def next_positions(direction)
|
173
|
+
x, y = character_pos
|
174
|
+
|
175
|
+
case direction
|
176
|
+
when :left
|
177
|
+
(1..2).map { |i| [x - i, y] }
|
178
|
+
when :right
|
179
|
+
(1..2).map { |i| [x + i, y] }
|
180
|
+
when :up
|
181
|
+
(1..2).map { |i| [x, y - i] }
|
182
|
+
when :down
|
183
|
+
(1..2).map { |i| [x, y + i] }
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def next_objects(direction)
|
188
|
+
next_positions(direction).map { |(x, y)| self[x, y] }
|
189
|
+
end
|
190
|
+
|
191
|
+
def make_move(direction, check_for_solve = true, count_move = true)
|
192
|
+
x, y = character_pos
|
193
|
+
obj, next_obj = next_objects(direction)
|
194
|
+
first_pos, sec_pos = next_positions(direction)
|
195
|
+
|
196
|
+
on_storage = (self[x, y] == :man_on_storage)
|
197
|
+
replacement = on_storage ? :storage : :empty
|
198
|
+
|
199
|
+
@moves << {
|
200
|
+
:direction => direction,
|
201
|
+
:moved_crate => obj == :crate || obj == :crate_on_storage
|
202
|
+
} if count_move
|
203
|
+
|
204
|
+
if obj == :empty
|
205
|
+
self[*first_pos] = :man
|
206
|
+
self[x, y] = replacement
|
207
|
+
|
208
|
+
@character_pos = first_pos
|
209
|
+
elsif obj == :storage
|
210
|
+
self[*first_pos] = :man_on_storage
|
211
|
+
self[x, y] = replacement
|
212
|
+
|
213
|
+
@character_pos = first_pos
|
214
|
+
elsif obj == :crate
|
215
|
+
if next_obj == :empty
|
216
|
+
self[*sec_pos] = :crate
|
217
|
+
self[*first_pos] = :man
|
218
|
+
self[x, y] = replacement
|
219
|
+
|
220
|
+
@character_pos = first_pos
|
221
|
+
elsif next_obj == :storage
|
222
|
+
self[*sec_pos] = :crate_on_storage
|
223
|
+
self[*first_pos] = :man
|
224
|
+
self[x, y] = replacement
|
225
|
+
|
226
|
+
@character_pos = first_pos
|
227
|
+
end
|
228
|
+
elsif obj == :crate_on_storage
|
229
|
+
@moves[-1][:moved_crate] = true
|
230
|
+
|
231
|
+
if next_obj == :empty
|
232
|
+
self[*sec_pos] = :crate
|
233
|
+
self[*first_pos] = :man_on_storage
|
234
|
+
self[x, y] = replacement
|
235
|
+
|
236
|
+
@character_pos = first_pos
|
237
|
+
elsif next_obj == :storage
|
238
|
+
self[*sec_pos] = :crate_on_storage
|
239
|
+
self[*first_pos] = :man_on_storage
|
240
|
+
self[x, y] = replacement
|
241
|
+
|
242
|
+
@character_pos = first_pos
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
check_solved if check_for_solve
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
class LevelScene < Ray::Scene
|
251
|
+
scene_name :sokoban_level
|
252
|
+
|
253
|
+
TILE_WIDTH = 32
|
254
|
+
|
255
|
+
def setup(filename)
|
256
|
+
@filename = filename
|
257
|
+
@level = Level.open(filename)
|
258
|
+
|
259
|
+
self.loops_per_second = 60
|
260
|
+
end
|
261
|
+
|
262
|
+
def register
|
263
|
+
@level.event_runner = event_runner
|
264
|
+
|
265
|
+
[:left, :right, :up, :down].each do |dir|
|
266
|
+
on :key_press, key(dir) do
|
267
|
+
next if @level.solved?
|
268
|
+
|
269
|
+
if @level.can_move?(dir)
|
270
|
+
@level.move(dir)
|
271
|
+
need_render!
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
on :key_press, key(:r) do
|
277
|
+
next if @level.solved?
|
278
|
+
|
279
|
+
@level.reset
|
280
|
+
need_render!
|
281
|
+
end
|
282
|
+
|
283
|
+
on :key_press, key(:u) do
|
284
|
+
next if @level.solved?
|
285
|
+
|
286
|
+
@level.undo
|
287
|
+
need_render!
|
288
|
+
end
|
289
|
+
|
290
|
+
on :level_solved do
|
291
|
+
puts "Level solved!"
|
292
|
+
pop_scene
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def render(win)
|
297
|
+
reset_window(win)
|
298
|
+
|
299
|
+
@level.each_with_pos do |obj, x, y|
|
300
|
+
case obj
|
301
|
+
when :man then draw_man(win, x, y)
|
302
|
+
when :crate then draw_crate(win, x, y)
|
303
|
+
when :wall then draw_wall(win, x, y)
|
304
|
+
when :storage then draw_storage(win, x, y)
|
305
|
+
when :crate_on_storage then draw_crate_on_storage(win, x, y)
|
306
|
+
when :man_on_storage then draw_man_on_storage(win, x, y)
|
307
|
+
when :empty then draw_empty_tile(win, x, y)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def reset_window(win)
|
313
|
+
win.fill(Ray::Color.black)
|
314
|
+
end
|
315
|
+
|
316
|
+
def draw_man(win, x, y)
|
317
|
+
x, y = pos_to_coord(x, y)
|
318
|
+
win.draw_filled_rect([x, y, TILE_WIDTH, TILE_WIDTH], Ray::Color.white)
|
319
|
+
end
|
320
|
+
|
321
|
+
def draw_crate(win, x, y)
|
322
|
+
x, y = pos_to_coord(x, y)
|
323
|
+
win.draw_filled_rect([x, y, TILE_WIDTH, TILE_WIDTH], Ray::Color.gray)
|
324
|
+
end
|
325
|
+
|
326
|
+
def draw_wall(win, x, y)
|
327
|
+
x, y = pos_to_coord(x, y)
|
328
|
+
win.draw_filled_rect([x, y, TILE_WIDTH, TILE_WIDTH], Ray::Color.new(91, 59, 17))
|
329
|
+
end
|
330
|
+
|
331
|
+
def draw_storage(win, x, y)
|
332
|
+
x, y = pos_to_coord(x, y)
|
333
|
+
win.draw_filled_rect([x, y, TILE_WIDTH, TILE_WIDTH], Ray::Color.yellow)
|
334
|
+
end
|
335
|
+
|
336
|
+
def draw_crate_on_storage(win, x, y)
|
337
|
+
x, y = pos_to_coord(x, y)
|
338
|
+
win.draw_filled_rect([x, y, TILE_WIDTH, TILE_WIDTH], Ray::Color.green)
|
339
|
+
end
|
340
|
+
|
341
|
+
def draw_man_on_storage(win, x, y)
|
342
|
+
x, y = pos_to_coord(x, y)
|
343
|
+
win.draw_filled_rect([x, y, TILE_WIDTH, TILE_WIDTH], Ray::Color.red)
|
344
|
+
end
|
345
|
+
|
346
|
+
def draw_empty_tile(win, x, y)
|
347
|
+
x, y = pos_to_coord(x, y)
|
348
|
+
win.draw_filled_rect([x, y, TILE_WIDTH, TILE_WIDTH], Ray::Color.black)
|
349
|
+
end
|
350
|
+
|
351
|
+
def pos_to_coord(x, y)
|
352
|
+
[x * TILE_WIDTH, y * TILE_WIDTH]
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
class Game < Ray::Game
|
357
|
+
def initialize
|
358
|
+
super("Sokoban")
|
359
|
+
|
360
|
+
LevelScene.bind(self)
|
361
|
+
push_scene(:sokoban_level, File.expand_path(File.join(File.dirname(__FILE__), "level_1")))
|
362
|
+
end
|
363
|
+
|
364
|
+
def register
|
365
|
+
add_hook :quit, method(:exit!)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
Sokoban::Game.new.run
|