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.
Files changed (76) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +3 -0
  3. data/README.md +62 -0
  4. data/Rakefile +33 -23
  5. data/VERSION +1 -1
  6. data/ext/audio.c +473 -0
  7. data/ext/color.c +4 -4
  8. data/ext/event.c +25 -3
  9. data/ext/extconf.rb +35 -22
  10. data/ext/font.c +287 -0
  11. data/ext/image.c +682 -33
  12. data/ext/joystick.c +9 -9
  13. data/ext/ray.c +166 -55
  14. data/ext/ray.h +120 -9
  15. data/ext/ray_osx.m +161 -0
  16. data/ext/rect.c +31 -4
  17. data/lib/ray/audio.rb +52 -0
  18. data/lib/ray/color.rb +16 -0
  19. data/lib/ray/dsl.rb +1 -3
  20. data/lib/ray/dsl/event.rb +1 -39
  21. data/lib/ray/dsl/event_listener.rb +38 -0
  22. data/lib/ray/dsl/event_runner.rb +3 -1
  23. data/lib/ray/dsl/event_translator.rb +74 -8
  24. data/lib/ray/dsl/handler.rb +3 -33
  25. data/lib/ray/dsl/matcher.rb +129 -23
  26. data/lib/ray/font.rb +108 -0
  27. data/lib/ray/font_set.rb +37 -0
  28. data/lib/ray/game.rb +171 -34
  29. data/lib/ray/helper.rb +43 -5
  30. data/lib/ray/image.rb +90 -3
  31. data/lib/ray/image_set.rb +35 -0
  32. data/lib/ray/joystick.rb +30 -0
  33. data/lib/ray/music_set.rb +35 -0
  34. data/lib/ray/ray.rb +17 -9
  35. data/lib/ray/rect.rb +51 -0
  36. data/lib/ray/resource_set.rb +92 -0
  37. data/lib/ray/scene.rb +220 -51
  38. data/lib/ray/sound_set.rb +35 -0
  39. data/lib/ray/sprite.rb +184 -0
  40. data/psp/ext.c +4 -0
  41. data/samples/hello_world/hello.rb +35 -0
  42. data/samples/hello_world/hello_dsl.rb +24 -0
  43. data/samples/pong/pong.rb +128 -0
  44. data/samples/sokoban/level_1 +7 -0
  45. data/samples/sokoban/sokoban.rb +370 -0
  46. data/spec/ray/audio_spec.rb +146 -0
  47. data/spec/ray/color_spec.rb +13 -0
  48. data/spec/ray/event_spec.rb +57 -168
  49. data/spec/ray/font_spec.rb +93 -0
  50. data/spec/ray/image_set_spec.rb +48 -0
  51. data/spec/ray/image_spec.rb +130 -44
  52. data/spec/ray/joystick_spec.rb +13 -9
  53. data/spec/ray/matcher_spec.rb +32 -55
  54. data/spec/ray/ray_spec.rb +33 -31
  55. data/spec/ray/rect_spec.rb +80 -0
  56. data/spec/ray/resource_set_spec.rb +105 -0
  57. data/spec/ray/sprite_spec.rb +163 -0
  58. data/spec/res/VeraMono.ttf +0 -0
  59. data/spec/res/aqua2.bmp +0 -0
  60. data/spec/res/pop.wav +0 -0
  61. data/spec/spec.opts +4 -0
  62. data/spec/spec_helper.rb +8 -0
  63. data/yard_ext.rb +91 -0
  64. metadata +104 -38
  65. data/bin/ray +0 -5
  66. data/bin/ray_irb +0 -4
  67. data/ext/SDLMain.h +0 -17
  68. data/ext/SDLMain.m +0 -381
  69. data/lib/ray/config.rb +0 -84
  70. data/lib/ray/dsl/converter.rb +0 -65
  71. data/lib/ray/dsl/listener.rb +0 -30
  72. data/lib/ray/dsl/type.rb +0 -58
  73. data/spec/ray/config_spec.rb +0 -90
  74. data/spec/ray/conversion_spec.rb +0 -43
  75. data/spec/ray/type_spec.rb +0 -17
  76. data/spec_runner.rb +0 -27
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ if Ray.has_audio_support?
4
+ describe Ray::Audio do
5
+ it "should allow to set and get audio parameters" do
6
+ Ray.init(:mono => true,
7
+ :format => Ray::Audio::FORMAT_S8,
8
+ :frequency => 44100)
9
+
10
+ Ray::Audio.frequency.should == 44100
11
+ Ray::Audio.should be_mono
12
+ Ray::Audio.format.should == Ray::Audio::FORMAT_S8
13
+
14
+ Ray.stop
15
+ end
16
+
17
+ it "should allow to change the volume" do
18
+ Ray.init(:mono => true,
19
+ :format => Ray::Audio::FORMAT_S8,
20
+ :frequency => 44100)
21
+
22
+ Ray::Audio.volume = 50
23
+ Ray::Audio.volume.should be_close(50, 0.1)
24
+
25
+ Ray.stop
26
+ end
27
+ end
28
+
29
+ describe Ray::Sound do
30
+ before :all do
31
+ Ray.init
32
+ end
33
+
34
+ it "should allow to load sounds" do
35
+ lambda {
36
+ Ray::Sound.new(path_of("pop.wav"))
37
+ }.should_not raise_exception
38
+ end
39
+
40
+ it "should allow to load sounds from IO objects" do
41
+ lambda {
42
+ open(path_of("pop.wav")) do |io|
43
+ Ray::Sound.new(io)
44
+ end
45
+ }.should_not raise_exception
46
+ end
47
+
48
+ it "should allow to change the volume" do
49
+ sound = Ray::Sound.new(path_of("pop.wav"))
50
+ sound.volume = 50
51
+ sound.volume.should be_close(50, 0.1)
52
+ end
53
+
54
+ it "should make Ray play" do
55
+ sound = Ray::Sound.new(path_of("pop.wav"))
56
+
57
+ lambda { sound.play(1) }.should change {
58
+ Ray::Audio.playing?(1) && !Ray::Audio.paused?(1)
59
+ }.from(false).to(true)
60
+
61
+ Ray::Audio.stop(1)
62
+ end
63
+
64
+ it "can be paused" do
65
+ sound = Ray::Sound.new(path_of("pop.wav"))
66
+ sound.play(1)
67
+
68
+ lambda { Ray::Audio.pause(1) }.should change {
69
+ Ray::Audio.playing?(1) && !Ray::Audio.paused?(1)
70
+ }.from(true).to(false)
71
+ end
72
+
73
+ it "can be resumed" do
74
+ sound = Ray::Sound.new(path_of("pop.wav"))
75
+ sound.play(1)
76
+ Ray::Audio.pause(1)
77
+
78
+ lambda { Ray::Audio.resume(1) }.should change {
79
+ Ray::Audio.playing?(1) && !Ray::Audio.paused?(1)
80
+ }.from(false).to(true)
81
+
82
+ Ray::Audio.stop(1)
83
+ end
84
+
85
+ after :all do
86
+ Ray.stop
87
+ end
88
+ end
89
+
90
+ describe Ray::Music do
91
+ before :all do
92
+ Ray.init
93
+ end
94
+
95
+ it "should be able to create object from valid files" do
96
+ lambda {
97
+ Ray::Music.new(path_of("pop.wav"))
98
+ }.should_not raise_exception
99
+ end
100
+
101
+ it "should be able to create object from IO objects" do
102
+ lambda {
103
+ open(path_of("pop.wav")) { |io| Ray::Music.new(io) }
104
+ }.should_not raise_exception
105
+ end
106
+
107
+ it "should make Ray play" do
108
+ music = Ray::Music.new(path_of("pop.wav"))
109
+ music.play
110
+
111
+ Ray::Audio.should be_playing
112
+ Ray::Audio.stop
113
+ end
114
+
115
+ it "can be paused" do
116
+ music = Ray::Music.new(path_of("pop.wav"))
117
+ music.play
118
+ Ray::Audio.pause
119
+
120
+ Ray::Audio.should be_paused
121
+ end
122
+
123
+ it "can be resumed" do
124
+ music = Ray::Music.new(path_of("pop.wav"))
125
+ music.play
126
+
127
+ Ray::Audio.pause
128
+ Ray::Audio.resume
129
+
130
+ Ray::Audio.should_not be_paused
131
+ Ray::Audio.stop
132
+ end
133
+
134
+ it "can be stopped" do
135
+ music = Ray::Music.new(path_of("pop.wav"))
136
+ music.play
137
+
138
+ Ray::Audio.stop
139
+ Ray::Audio.should_not be_playing
140
+ end
141
+
142
+ after :all do
143
+ Ray.stop
144
+ end
145
+ end
146
+ end
@@ -1,3 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
1
3
  describe Ray::Color do
2
4
  describe "#initialize" do
3
5
  it "should accept 3 integers" do
@@ -41,4 +43,15 @@ describe Ray::Color do
41
43
  end
42
44
  end
43
45
  end
46
+
47
+ describe "#==" do
48
+ it "should return true if both colors are identical" do
49
+ Ray::Color.new(10, 15, 20, 30).should == Ray::Color.new(10, 15, 20, 30)
50
+ Ray::Color.new(10, 15, 20, 30).should_not == Ray::Color.new(1, 15, 2, 3)
51
+ end
52
+
53
+ it "should not raise an exception if the argument isn't a color" do
54
+ Ray::Color.new(1, 1, 1, 1).should_not == 1
55
+ end
56
+ end
44
57
  end
@@ -1,16 +1,11 @@
1
- describe "the event DSL" do
2
- context "when someone listens to an event" do
3
- before :all do
4
- Ray.describe_matcher(:more_than, :integer) do |x|
5
- lambda { |i| i > x }
6
- end
7
- end
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
8
2
 
9
- before :each do
3
+ describe Ray::DSL do
4
+ before :each do
10
5
  @runner = Ray::DSL::EventRunner.new
11
6
 
12
7
  @obj = Object.new
13
- @obj.extend Ray::DSL::Listener
8
+ @obj.extend Ray::DSL::EventListener
14
9
  @obj.extend Ray::DSL::EventRaiser
15
10
  @obj.extend Ray::Matchers
16
11
 
@@ -18,174 +13,68 @@ describe "the event DSL" do
18
13
  @obj.raiser_runner = @runner
19
14
  end
20
15
 
21
- context "without any arguments" do
22
- it "should always send it" do
23
- var = 0
24
- @obj.on :foo do
25
- var += 1
26
- end
16
+ it "should send events with the same arguments and name as in #on" do
17
+ count = 0
18
+ @obj.on :right_event, "danger", "bar" do |*args|
19
+ args.should == ["danger", "bar"]
20
+ count += 1
21
+ end
22
+
23
+ [:right_event, :wrong_event].each do |name|
24
+ @obj.raise_event(name)
25
+ @obj.raise_event(name, "bar")
26
+ @obj.raise_event(name, "danger")
27
+ @obj.raise_event(name, "danger", "bar")
28
+ end
29
+
30
+ @runner.run
31
+ count.should == 1
32
+ end
33
+
34
+ it "should use === to see if an event can be raised" do
35
+ true_matcher = mock('true_matcher')
36
+ true_matcher.should_receive(:===).and_return(true)
27
37
 
28
- @obj.raise_event(:foo, "blabla")
29
- @obj.raise_event(:foo)
30
- @obj.raise_event(:foo, :error, 3, "read")
38
+ false_matcher = mock('false_matcher')
39
+ false_matcher.should_receive(:===).and_return(false)
31
40
 
32
- @runner.run
33
- var.should == 3
34
- end
41
+ worked = nil
42
+
43
+ @obj.on :event, true_matcher do
44
+ worked.should_not == false
45
+ worked = true
35
46
  end
36
47
 
37
- context "with some arguments" do
38
- it "should send the ones with the same arguments" do
39
- var = 0
40
- @obj.on :foo, "danger", "bar" do
41
- var += 1
42
- end
43
-
44
- @obj.raise_event(:foo)
45
- @obj.raise_event(:foo, "bar")
46
- @obj.raise_event(:foo, "danger")
47
- @obj.raise_event(:foo, "danger", "bar")
48
- @obj.raise_event(:foo, "danger", "bar", "test")
49
-
50
- @runner.run
51
- var.should == 1
52
- end
53
-
54
- context "if a matcher is one of them" do
55
- it "should send the events if it matches the argument" do
56
- count = 0
57
-
58
- @obj.instance_eval do
59
- on :foo, more_than(10) do |x|
60
- x.should > 10
61
- count += 1
62
- end
63
-
64
- raise_event(:foo, 5)
65
- raise_event(:foo, "a")
66
- raise_event(:foo, 15)
67
- end
68
-
69
- @runner.run
70
- count.should == 1
71
- end
72
- end
73
-
74
- context "if a regex is one of them" do
75
- it "should send the event if a string match it" do
76
- count = 0
77
-
78
- @obj.instance_eval do
79
- on :foo, /hello/ do |str|
80
- str.should =~ /hello/
81
- count += 1
82
- end
83
-
84
- raise_event(:foo, 0)
85
- raise_event(:foo, "wat?")
86
- raise_event(:foo, "Hey, hello you!")
87
- raise_event(:foo, /hey hello you/)
88
- end
89
-
90
- @runner.run
91
- count.should == 1
92
- end
93
-
94
- it "should send then event if the argument is the same regex" do
95
- count = 0
96
-
97
- @obj.instance_eval do
98
- on :foo, /hello/ do |reg|
99
- reg.should == /hello/
100
- count += 1
101
- end
102
-
103
- raise_event(:foo, 0)
104
- raise_event(:foo, 5.5)
105
- raise_event(:foo, "Goodbye!")
106
- raise_event(:foo, /hello/)
107
- end
108
-
109
- @runner.run
110
- count.should == 1
111
- end
112
- end
48
+ @obj.on :event, false_matcher do
49
+ worked = false
113
50
  end
114
51
 
115
- context "if the event was described" do
116
- before :all do
117
- Ray.describe_event(:weird_thing, :string, :integer)
118
- end
119
-
120
- it "should convert arguments at creation" do
121
- ev = Ray::DSL::Event.new(:weird_thing, [3, "3"])
122
- ev.args.should == ["3", 3]
123
- end
124
-
125
- it "should not raise an error if it can't convert objects" do
126
- ev = Ray::DSL::Event.new(:weird_thing, ["str", String])
127
- ev.args.should == ["str", String]
128
- end
129
-
130
- it "should always convert if a method like #to_i is available" do
131
- obj = Object.new
132
- class << obj; def to_i; 3; end; end
133
-
134
- ev = Ray::DSL::Event.new(:weird_thing, [String, obj])
135
- ev.args.should == ["String", 3]
136
- end
137
-
138
- it "should try to convert arguments for handlers" do
139
- count = 0
140
-
141
- @obj.instance_eval do
142
- on :weird_thing, 3 do |x|
143
- x.should == "3"
144
- count += 1
145
- end
146
-
147
- raise_event(:weird_thing, 0)
148
- raise_event(:weird_thing, 3)
149
- raise_event(:weird_thing, "3")
150
- raise_event(:weird_thing, String)
151
- end
152
-
153
- @runner.run
154
- count.should == 2
155
- end
156
-
157
- it "should not try to convert matchers and regexps in handlers" do
158
- count = 0
159
-
160
- Ray.describe_conversion(Ray::DSL::Matcher => :integer,
161
- Regexp => :string) {}
162
-
163
- Ray.describe_matcher(:more_than, :integer) do |x|
164
- lambda { |val| val > x }
165
- end
166
-
167
- @obj.instance_eval do
168
- on :weird_thing, /\d/, more_than(10) do |x, y|
169
- count += 1
170
- end
171
-
172
- raise_event(:weird_thing, "1", 15)
173
- end
174
-
175
- @runner.run
176
- count.should == 1
177
- end
52
+ @obj.raise_event(:event, :argument)
53
+ @runner.run
54
+
55
+ worked.should be_true
56
+ end
57
+
58
+ it "should pass the arguments of the event to the block" do
59
+ @obj.on :foo do |*args|
60
+ args.should == ["a", "b", "c"]
178
61
  end
179
62
 
180
- context "when the proc takes arguments" do
181
- it "should pass the arguments given to the event" do
182
- @obj.on :foo do |*args|
183
- args.should == ["a", "b", "c"]
184
- end
63
+ @obj.raise_event(:foo, "a", "b", "c")
64
+ @runner.run
65
+ end
185
66
 
186
- @obj.raise_event(:foo, "a", "b", "c")
187
- @runner.run
188
- end
67
+ it "should send events with more arguments than #on if they match" do
68
+ count = 0
69
+ @obj.on :foo do
70
+ count += 1
189
71
  end
72
+
73
+ @obj.raise_event(:foo, "blabla")
74
+ @obj.raise_event(:foo)
75
+ @obj.raise_event(:foo, :error, 3, "read")
76
+
77
+ @runner.run
78
+ count.should == 3
190
79
  end
191
80
  end
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ if Ray.has_font_support?
4
+ describe Ray::Font do
5
+ before :all do
6
+ Ray.init
7
+ end
8
+
9
+ it "should be able to load fonts from a file" do
10
+ lambda {
11
+ Ray::Font.new(path_of("VeraMono.ttf"), 12)
12
+ }.should_not raise_exception
13
+ end
14
+
15
+ it "should be able to load fonts from IO objects" do
16
+ lambda {
17
+ open(path_of("VeraMono.ttf")) { |io| Ray::Font.new(io, 12) }
18
+ }.should_not raise_exception
19
+ end
20
+
21
+ it "should create normal font" do
22
+ Ray::Font.new(path_of("VeraMono.ttf"), 12).should be_normal
23
+ end
24
+
25
+ it "should allow to change its style" do
26
+ font = Ray::Font.new(path_of("VeraMono.ttf"), 12)
27
+ font.style = Ray::Font::STYLE_BOLD | Ray::Font::STYLE_ITALIC
28
+
29
+ font.should be_italic
30
+ font.should be_bold
31
+ end
32
+
33
+ describe "#draw" do
34
+ before :all do
35
+ @win = Ray.create_window(:w => 100, :h => 100)
36
+ @font = Ray::Font.new(path_of("VeraMono.ttf"), 12)
37
+ end
38
+
39
+ it "should return an image when we don't say where to draw" do
40
+ @font.draw("Something").should be_a(Ray::Image)
41
+ end
42
+
43
+ it "should return the surface it drew on if it did" do
44
+ @font.draw("Something", :on => @win, :at => [0, 0]).should == @win
45
+ end
46
+ end
47
+
48
+ after :all do
49
+ Ray.stop
50
+ end
51
+ end
52
+
53
+ describe "String#draw" do
54
+ before :all do
55
+ Ray.init
56
+
57
+ @win = Ray.create_window(:w => 100, :h => 100)
58
+ @font = Ray::Font.new(path_of("VeraMono.ttf"), 12)
59
+ end
60
+
61
+ it "should be able to guess the size" do
62
+ lambda {
63
+ "Hello world!".draw(:font => @font)
64
+ }.should_not raise_exception
65
+ end
66
+
67
+ it "should use the specified width unless :on is specified" do
68
+ img = "Hello world!".draw(:font => @font, :w => 40)
69
+ img.w.should == 40
70
+ end
71
+
72
+ it "should require the font to be specified" do
73
+ lambda {
74
+ "Hello world".draw(:on => @win)
75
+ }.should raise_exception
76
+ end
77
+
78
+ it "should draw on multiple lines" do
79
+ img = "Hello\nworld".draw(:font => @font, :w => 100)
80
+ img.height.should == @font.line_skip * 2
81
+ end
82
+
83
+ it "should allow to specify an explicit size" do
84
+ img = "Hello\nworld".draw(:font => @font, :h => 100, :w => 50)
85
+ img.width.should == 50
86
+ img.height.should == 100
87
+ end
88
+
89
+ after :all do
90
+ Ray.stop
91
+ end
92
+ end
93
+ end