ray 0.0.0.pre2 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|