rubygame 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CREDITS +50 -0
  2. data/Changelog +162 -0
  3. data/LICENSE +504 -0
  4. data/README +122 -0
  5. data/Rakefile +380 -0
  6. data/TODO +45 -0
  7. data/doc/extended_readme.rdoc +49 -0
  8. data/doc/getting_started.rdoc +47 -0
  9. data/doc/macosx_install.rdoc +74 -0
  10. data/doc/windows_install.rdoc +124 -0
  11. data/ext/rubygame/MANIFEST +25 -0
  12. data/ext/rubygame/rubygame_event.c +644 -0
  13. data/ext/rubygame/rubygame_event.h +48 -0
  14. data/ext/rubygame/rubygame_gfx.c +951 -0
  15. data/ext/rubygame/rubygame_gfx.h +102 -0
  16. data/ext/rubygame/rubygame_gl.c +154 -0
  17. data/ext/rubygame/rubygame_gl.h +32 -0
  18. data/ext/rubygame/rubygame_image.c +108 -0
  19. data/ext/rubygame/rubygame_image.h +41 -0
  20. data/ext/rubygame/rubygame_joystick.c +247 -0
  21. data/ext/rubygame/rubygame_joystick.h +41 -0
  22. data/ext/rubygame/rubygame_main.c +155 -0
  23. data/ext/rubygame/rubygame_main.h +33 -0
  24. data/ext/rubygame/rubygame_mixer.c +764 -0
  25. data/ext/rubygame/rubygame_mixer.h +62 -0
  26. data/ext/rubygame/rubygame_screen.c +420 -0
  27. data/ext/rubygame/rubygame_screen.h +41 -0
  28. data/ext/rubygame/rubygame_shared.c +152 -0
  29. data/ext/rubygame/rubygame_shared.h +54 -0
  30. data/ext/rubygame/rubygame_surface.c +1107 -0
  31. data/ext/rubygame/rubygame_surface.h +62 -0
  32. data/ext/rubygame/rubygame_time.c +183 -0
  33. data/ext/rubygame/rubygame_time.h +32 -0
  34. data/ext/rubygame/rubygame_ttf.c +600 -0
  35. data/ext/rubygame/rubygame_ttf.h +69 -0
  36. data/lib/rubygame.rb +40 -0
  37. data/lib/rubygame/MANIFEST +12 -0
  38. data/lib/rubygame/clock.rb +128 -0
  39. data/lib/rubygame/constants.rb +238 -0
  40. data/lib/rubygame/event.rb +313 -0
  41. data/lib/rubygame/ftor.rb +370 -0
  42. data/lib/rubygame/hotspot.rb +265 -0
  43. data/lib/rubygame/keyconstants.rb +237 -0
  44. data/lib/rubygame/mediabag.rb +94 -0
  45. data/lib/rubygame/queue.rb +288 -0
  46. data/lib/rubygame/rect.rb +614 -0
  47. data/lib/rubygame/sfont.rb +223 -0
  48. data/lib/rubygame/sprite.rb +477 -0
  49. data/samples/FreeSans.ttf +0 -0
  50. data/samples/GPL.txt +340 -0
  51. data/samples/README +40 -0
  52. data/samples/chimp.bmp +0 -0
  53. data/samples/chimp.rb +313 -0
  54. data/samples/demo_gl.rb +151 -0
  55. data/samples/demo_gl_tex.rb +197 -0
  56. data/samples/demo_music.rb +75 -0
  57. data/samples/demo_rubygame.rb +279 -0
  58. data/samples/demo_sfont.rb +52 -0
  59. data/samples/demo_ttf.rb +193 -0
  60. data/samples/demo_utf8.rb +53 -0
  61. data/samples/fist.bmp +0 -0
  62. data/samples/load_and_blit.rb +22 -0
  63. data/samples/panda.png +0 -0
  64. data/samples/punch.wav +0 -0
  65. data/samples/ruby.png +0 -0
  66. data/samples/term16.png +0 -0
  67. data/samples/whiff.wav +0 -0
  68. metadata +123 -0
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This demonstrates the use of ruby-opengl alongside rubygame to produce
4
+ # hardware-accelerated three-dimensional graphics.
5
+ #
6
+ # Please note that rubygame itself does not perform any OpenGL functions,
7
+ # it only allows ruby-opengl to use the Screen as its viewport. You MUST
8
+ # have ruby-opengl installed to run this demo!
9
+
10
+ require 'rubygame'
11
+
12
+ begin
13
+ require 'opengl'
14
+ rescue LoadError
15
+ puts "ATTENTION: This demo requires the opengl extension for ruby."
16
+ raise
17
+ end
18
+
19
+ WIDE = 640
20
+ HIGH = 480
21
+
22
+ Rubygame.init
23
+
24
+ Rubygame::GL.set_attrib(Rubygame::GL::RED_SIZE, 5)
25
+ Rubygame::GL.set_attrib(Rubygame::GL::GREEN_SIZE, 5)
26
+ Rubygame::GL.set_attrib(Rubygame::GL::BLUE_SIZE, 5)
27
+ Rubygame::GL.set_attrib(Rubygame::GL::DEPTH_SIZE, 16)
28
+ Rubygame::GL.set_attrib(Rubygame::GL::DOUBLEBUFFER, 1)
29
+
30
+ Rubygame::Screen.set_mode([WIDE,HIGH], 16, [Rubygame::OPENGL])
31
+ queue = Rubygame::EventQueue.new()
32
+ clock = Rubygame::Clock.new { |c| c.target_framerate = 60 }
33
+
34
+ ObjectSpace.garbage_collect
35
+ GL::Viewport( 0, 0, WIDE, HIGH )
36
+
37
+ GL::MatrixMode( GL::PROJECTION )
38
+ GL::LoadIdentity( )
39
+ GLU::Perspective( 35, WIDE/(HIGH.to_f), 3, 10)
40
+
41
+ GL::MatrixMode( GL::MODELVIEW )
42
+ GL::LoadIdentity( )
43
+
44
+ GL::Enable(GL::DEPTH_TEST)
45
+ GL::DepthFunc(GL::LESS)
46
+
47
+ GL::ShadeModel(GL::FLAT)
48
+
49
+ color =
50
+ [[ 1.0, 1.0, 0.0],
51
+ [ 1.0, 0.0, 0.0],
52
+ [ 0.0, 0.0, 0.0],
53
+ [ 0.0, 1.0, 0.0],
54
+ [ 0.0, 1.0, 1.0],
55
+ [ 1.0, 1.0, 1.0],
56
+ [ 1.0, 0.0, 1.0],
57
+ [ 0.0, 0.0, 1.0]]
58
+
59
+ cube =
60
+ [[ 0.5, 0.5, -0.5],
61
+ [ 0.5, -0.5, -0.5],
62
+ [-0.5, -0.5, -0.5],
63
+ [-0.5, 0.5, -0.5],
64
+ [-0.5, 0.5, 0.5],
65
+ [ 0.5, 0.5, 0.5],
66
+ [ 0.5, -0.5, 0.5],
67
+ [-0.5, -0.5, 0.5]]
68
+
69
+ cube_list = 1
70
+
71
+ GL::NewList(cube_list,GL::COMPILE_AND_EXECUTE)
72
+ GL::PushMatrix()
73
+ GL::Begin(GL::QUADS)
74
+ GL::Color(1.0, 0.0, 0.0);
75
+ GL::Vertex(cube[0]);
76
+ GL::Vertex(cube[1]);
77
+ GL::Vertex(cube[2]);
78
+ GL::Vertex(cube[3]);
79
+
80
+ GL::Color(0.0, 1.0, 0.0);
81
+ GL::Vertex(cube[3]);
82
+ GL::Vertex(cube[4]);
83
+ GL::Vertex(cube[7]);
84
+ GL::Vertex(cube[2]);
85
+
86
+ GL::Color(0.0, 0.0, 1.0);
87
+ GL::Vertex(cube[0]);
88
+ GL::Vertex(cube[5]);
89
+ GL::Vertex(cube[6]);
90
+ GL::Vertex(cube[1]);
91
+
92
+ GL::Color(0.0, 1.0, 1.0);
93
+ GL::Vertex(cube[5]);
94
+ GL::Vertex(cube[4]);
95
+ GL::Vertex(cube[7]);
96
+ GL::Vertex(cube[6]);
97
+
98
+ GL::Color(1.0, 1.0, 0.0);
99
+ GL::Vertex(cube[5]);
100
+ GL::Vertex(cube[0]);
101
+ GL::Vertex(cube[3]);
102
+ GL::Vertex(cube[4]);
103
+
104
+ GL::Color(1.0, 0.0, 1.0);
105
+ GL::Vertex(cube[6]);
106
+ GL::Vertex(cube[1]);
107
+ GL::Vertex(cube[2]);
108
+ GL::Vertex(cube[7]);
109
+ GL::PopMatrix()
110
+ GL::End()
111
+ GL::EndList()
112
+
113
+ angle = 0
114
+
115
+ catch(:rubygame_quit) do
116
+ loop do
117
+ queue.each do |event|
118
+ case event
119
+ when Rubygame::KeyDownEvent
120
+ case event.key
121
+ when Rubygame::K_ESCAPE
122
+ throw :rubygame_quit
123
+ when Rubygame::K_Q
124
+ throw :rubygame_quit
125
+ end
126
+ when Rubygame::QuitEvent
127
+ throw :rubygame_quit
128
+ end
129
+ end
130
+
131
+ GL.ClearColor(0.0, 0.0, 0.0, 1.0);
132
+ GL.Clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
133
+
134
+ GL::MatrixMode(GL::MODELVIEW);
135
+ GL::LoadIdentity( )
136
+ GL::Translate(0, 0, -4)
137
+ GL::Rotate(45, 0, 1, 0)
138
+ GL::Rotate(45, 1, 0, 0)
139
+ GL::Rotate(angle, 0.0, 0.0, 1.0)
140
+ GL::Rotate(angle*2, 0.0, 1.0, 0.0)
141
+
142
+ GL::CallList(cube_list)
143
+
144
+ Rubygame::GL.swap_buffers()
145
+ ObjectSpace.garbage_collect
146
+
147
+ angle += clock.tick()/50.0
148
+ angle -= 360 if angle >= 360
149
+
150
+ end
151
+ end
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This demonstrates the use of ruby-opengl alongside rubygame to produce
4
+ # hardware-accelerated three-dimensional graphics. Additionally, it
5
+ # demonstrates the use of rubygame Surfaces as OpenGL textures.
6
+ #
7
+ # Please note that rubygame itself does not perform any OpenGL functions,
8
+ # it only allows ruby-opengl to use the Screen as its viewport. You MUST
9
+ # have ruby-opengl installed to run this demo!
10
+
11
+ require 'rubygame'
12
+
13
+ begin
14
+ require 'opengl'
15
+ rescue LoadError
16
+ puts "ATTENTION: This demo requires the opengl extension for ruby."
17
+ raise
18
+ end
19
+
20
+ WIDE = 640
21
+ HIGH = 480
22
+ SCALE = 500.0
23
+ shadedCube=true
24
+ TEXTURE = "ruby.png"
25
+
26
+ Rubygame.init
27
+
28
+ Rubygame::GL.set_attrib(Rubygame::GL::RED_SIZE, 5)
29
+ Rubygame::GL.set_attrib(Rubygame::GL::GREEN_SIZE, 5)
30
+ Rubygame::GL.set_attrib(Rubygame::GL::BLUE_SIZE, 5)
31
+ Rubygame::GL.set_attrib(Rubygame::GL::DEPTH_SIZE, 16)
32
+ Rubygame::GL.set_attrib(Rubygame::GL::DOUBLEBUFFER, 1)
33
+
34
+ Rubygame::Screen.set_mode([WIDE,HIGH], 16, [Rubygame::OPENGL])
35
+ queue = Rubygame::EventQueue.new()
36
+ clock = Rubygame::Clock.new { |c| c.target_framerate = 60 }
37
+
38
+ ObjectSpace.garbage_collect
39
+ GL::Viewport( 0, 0, WIDE, HIGH )
40
+
41
+ GL::MatrixMode( GL::PROJECTION )
42
+ GL::LoadIdentity( )
43
+ GLU::Perspective( 35, WIDE/(HIGH.to_f), 3, 10)
44
+
45
+ GL::MatrixMode( GL::MODELVIEW )
46
+ GL::LoadIdentity( )
47
+
48
+ GL::Enable(GL::DEPTH_TEST)
49
+ GL::DepthFunc(GL::LESS)
50
+
51
+ GL::ShadeModel(GL::FLAT)
52
+
53
+ surface = Rubygame::Surface.load_image(TEXTURE)
54
+
55
+ tex_id = GL::GenTextures(1)
56
+ GL::BindTexture(GL::TEXTURE_2D, tex_id[0])
57
+ GL::TexImage2D(GL::TEXTURE_2D, 0, GL::RGB, surface.w, surface.h, 0, GL::RGB,
58
+ GL::UNSIGNED_BYTE, surface.pixels)
59
+ GL::TexParameter(GL::TEXTURE_2D,GL::TEXTURE_MIN_FILTER,GL::NEAREST);
60
+ GL::TexParameter(GL::TEXTURE_2D,GL::TEXTURE_MAG_FILTER,GL::LINEAR);
61
+
62
+ color =
63
+ [[ 1.0, 1.0, 0.0],
64
+ [ 1.0, 0.0, 0.0],
65
+ [ 0.0, 0.0, 0.0],
66
+ [ 0.0, 1.0, 0.0],
67
+ [ 0.0, 1.0, 1.0],
68
+ [ 1.0, 1.0, 1.0],
69
+ [ 1.0, 0.0, 1.0],
70
+ [ 0.0, 0.0, 1.0]]
71
+
72
+ cube =
73
+ [[ 0.5, 0.5, -0.5],
74
+ [ 0.5, -0.5, -0.5],
75
+ [-0.5, -0.5, -0.5],
76
+ [-0.5, 0.5, -0.5],
77
+ [-0.5, 0.5, 0.5],
78
+ [ 0.5, 0.5, 0.5],
79
+ [ 0.5, -0.5, 0.5],
80
+ [-0.5, -0.5, 0.5]]
81
+
82
+ cube_st =
83
+ [[[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]],
84
+ [[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]],
85
+ [[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]],
86
+ [[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]],
87
+ [[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]],
88
+ [[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]],
89
+ [[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]],
90
+ [[ 1, 1], [ 1, 0], [ 0, 0], [ 0, 1]]]
91
+
92
+ cube_list = 1
93
+
94
+ GL::NewList(cube_list,GL::COMPILE_AND_EXECUTE)
95
+ GL::PushMatrix()
96
+ GL::Enable(GL::TEXTURE_2D)
97
+ GL::BindTexture(GL::TEXTURE_2D, tex_id[0])
98
+
99
+ GL::Begin(GL::QUADS)
100
+
101
+ GL::TexCoord(cube_st[0][0]);
102
+ GL::Vertex(cube[0]);
103
+ GL::TexCoord(cube_st[0][1]);
104
+ GL::Vertex(cube[1]);
105
+ GL::TexCoord(cube_st[0][2]);
106
+ GL::Vertex(cube[2]);
107
+ GL::TexCoord(cube_st[0][3]);
108
+ GL::Vertex(cube[3]);
109
+
110
+ GL::TexCoord(cube_st[1][0]);
111
+ GL::Vertex(cube[3]);
112
+ GL::TexCoord(cube_st[1][1]);
113
+ GL::Vertex(cube[4]);
114
+ GL::TexCoord(cube_st[1][2]);
115
+ GL::Vertex(cube[7]);
116
+ GL::TexCoord(cube_st[1][3]);
117
+ GL::Vertex(cube[2]);
118
+
119
+ GL::TexCoord(cube_st[2][0]);
120
+ GL::Vertex(cube[0]);
121
+ GL::TexCoord(cube_st[2][1]);
122
+ GL::Vertex(cube[5]);
123
+ GL::TexCoord(cube_st[2][2]);
124
+ GL::Vertex(cube[6]);
125
+ GL::TexCoord(cube_st[2][3]);
126
+ GL::Vertex(cube[1]);
127
+
128
+ GL::TexCoord(cube_st[3][0]);
129
+ GL::Vertex(cube[5]);
130
+ GL::TexCoord(cube_st[3][1]);
131
+ GL::Vertex(cube[4]);
132
+ GL::TexCoord(cube_st[3][2]);
133
+ GL::Vertex(cube[7]);
134
+ GL::TexCoord(cube_st[3][3]);
135
+ GL::Vertex(cube[6]);
136
+
137
+ GL::TexCoord(cube_st[4][0]);
138
+ GL::Vertex(cube[5]);
139
+ GL::TexCoord(cube_st[4][1]);
140
+ GL::Vertex(cube[0]);
141
+ GL::TexCoord(cube_st[4][2]);
142
+ GL::Vertex(cube[3]);
143
+ GL::TexCoord(cube_st[4][3]);
144
+ GL::Vertex(cube[4]);
145
+
146
+ GL::TexCoord(cube_st[5][0]);
147
+ GL::Vertex(cube[6]);
148
+ GL::TexCoord(cube_st[5][1]);
149
+ GL::Vertex(cube[1]);
150
+ GL::TexCoord(cube_st[5][2]);
151
+ GL::Vertex(cube[2]);
152
+ GL::TexCoord(cube_st[5][3]);
153
+ GL::Vertex(cube[7]);
154
+ GL::PopMatrix()
155
+ GL::End()
156
+ GL::EndList()
157
+
158
+ angle = 0
159
+
160
+ catch(:rubygame_quit) do
161
+ loop do
162
+ queue.each do |event|
163
+ case event
164
+ when Rubygame::KeyDownEvent
165
+ case event.key
166
+ when Rubygame::K_ESCAPE
167
+ throw :rubygame_quit
168
+ when Rubygame::K_Q
169
+ throw :rubygame_quit
170
+ end
171
+ when Rubygame::QuitEvent
172
+ throw :rubygame_quit
173
+ end
174
+ end
175
+
176
+
177
+ GL.ClearColor(0.0, 0.0, 0.0, 1.0);
178
+ GL.Clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
179
+
180
+ GL::MatrixMode(GL::MODELVIEW);
181
+ GL::LoadIdentity( )
182
+ GL::Translate(0, 0, -4)
183
+ GL::Rotate(45, 0, 1, 0)
184
+ GL::Rotate(45, 1, 0, 0)
185
+ GL::Rotate(angle, 0.0, 0.0, 1.0)
186
+ GL::Rotate(angle*2, 0.0, 1.0, 0.0)
187
+
188
+ GL::CallList(cube_list)
189
+
190
+ Rubygame::GL.swap_buffers()
191
+ ObjectSpace.garbage_collect
192
+
193
+ angle += clock.tick()/50.0
194
+ angle -= 360 if angle >= 360
195
+
196
+ end
197
+ end
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygame'
4
+
5
+ Rubygame.init()
6
+
7
+ def test_music()
8
+ mix = Rubygame::Mixer
9
+
10
+ # Use the lines below to get rid of artsd and contact ALSA directly on Linux.
11
+ # ARTSD happens to be buggy on my old, old linux distro.
12
+ if false
13
+ if RUBY_PLATFORM =~ /linux/
14
+ `killall artsd`
15
+ ENV['SDL_AUDIODRIVER'] = "alsa"
16
+ end
17
+ end
18
+
19
+ mix.open_audio
20
+ puts "Using audio driver:" + mix.driver_name
21
+ music = mix::Music
22
+
23
+ if ARGV[0]
24
+ file = ARGV[0]
25
+ else
26
+ file = "song.ogg"
27
+ puts "If you want, you could give a filename as an argument to this script."
28
+ end
29
+
30
+ mus = music.load_audio(file);
31
+
32
+ puts "Testing fading in over 3 seconds, repeating forever."
33
+ mus.fade_in(3, -1);
34
+ puts('ERROR: Music not fading in') unless mus.fading?(:in)
35
+ sleep 3
36
+
37
+ puts "Playing for 2 seconds."
38
+ sleep 2
39
+
40
+ puts "Lowering volume to half for 3 seconds."
41
+ mus.volume = 0.5;
42
+ puts "ERROR: Volume wasn't adjusted" unless mus.volume == 0.5
43
+ sleep 3
44
+
45
+ puts "Restoring volume to full."
46
+ mus.volume = 1.0;
47
+ sleep 2
48
+
49
+ puts "Pausing for 1 seconds."
50
+ mus.pause
51
+ puts "ERROR: Music not paused." unless mus.paused?
52
+ sleep 1
53
+
54
+ puts "Resuming."
55
+ mus.resume
56
+ puts "ERROR: Music not resumed" unless mus.playing?
57
+
58
+ puts "Playing for 2 seconds."
59
+ sleep 2
60
+
61
+ puts "Fading out over 2 seconds."
62
+ mus.fade_out(2);
63
+ puts "ERROR: Music not fading out " unless mus.fading?(:out)
64
+
65
+ while mus.playing? or mus.fading? == :out do Thread.pass end
66
+ # Test playing of music to the end
67
+
68
+ puts "ERROR: Music not ended" if mus.playing?
69
+ mix.close_audio
70
+ end
71
+
72
+ music_thread = Thread.new do test_music() end
73
+ music_thread.join
74
+ Rubygame.quit()
75
+
@@ -0,0 +1,279 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This program is released to the PUBLIC DOMAIN.
4
+ # It is distributed in the hope that it will be useful,
5
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
6
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7
+
8
+ # This script is messy, but it demonstrates almost all of
9
+ # Rubygame's features, so it acts as a test program to see
10
+ # whether your installation of Rubygame is working.
11
+
12
+ require "rubygame"
13
+ include Rubygame
14
+
15
+ $stdout.sync = true
16
+
17
+ # Use smooth scaling/rotating? You can toggle this with S key
18
+ $smooth = false
19
+
20
+ Rubygame.init()
21
+
22
+ queue = EventQueue.new() # new EventQueue with autofetch
23
+ queue.ignore = [MouseMotionEvent]
24
+ clock = Clock.new()
25
+ clock.target_framerate = 50
26
+
27
+ unless ($gfx_ok = (VERSIONS[:sdl_gfx] != nil))
28
+ raise "SDL_gfx is not available. Bailing out."
29
+ end
30
+
31
+ class Panda
32
+ include Sprites::Sprite
33
+ @@pandapic = Surface.load_image("panda.png")
34
+ @@pandapic.set_colorkey(@@pandapic.get_at(0,0))
35
+ attr_accessor :vx, :vy, :speed
36
+ def initialize(x,y)
37
+ super()
38
+ @vx, @vy = 0,0
39
+ @speed = 40
40
+ @image = @@pandapic
41
+ @rect = Rect.new(x,y,*@@pandapic.size)
42
+ end
43
+
44
+ def update_image(time)
45
+ # do nothing in base class, rotate/zoom image in subs
46
+ end
47
+
48
+ def update(time)
49
+ x,y = @rect.center
50
+ self.update_image(time)
51
+ @rect.size = @image.size
52
+
53
+ base = @speed * time/1000.0
54
+ @rect.centerx = x + @vx * base
55
+ @rect.centery = y + @vy * base
56
+ end
57
+
58
+ end
59
+
60
+ class SpinnyPanda < Panda
61
+ attr_accessor :rate
62
+ def initialize(x,y,rate=0.1)
63
+ super(x,y)
64
+ @rate = rate
65
+ @angle = 0
66
+ end
67
+
68
+ def update_image(time)
69
+ @angle += (@rate * time) % 360
70
+ @image = @@pandapic.rotozoom(@angle,1,$smooth)
71
+ end
72
+ end
73
+
74
+ class ExpandaPanda < Panda
75
+ attr_accessor :rate
76
+ def initialize(x,y,rate=0.1)
77
+ super(x,y)
78
+ @rate = rate
79
+ @delta = 0
80
+ end
81
+
82
+ def update_image(time)
83
+ @delta = (@delta + time*@rate/36) % (Math::PI*2)
84
+ zoom = 1 + Math.sin(@delta)/2
85
+ @image = @@pandapic.zoom(zoom,$smooth)
86
+ end
87
+ end
88
+
89
+ class WobblyPanda < Panda
90
+ attr_accessor :rate
91
+ def initialize(x,y,rate=0.1)
92
+ super(x,y)
93
+ @rate = rate
94
+ @delta = 0
95
+ end
96
+
97
+ def update_image(time)
98
+ @delta = (@delta + time*@rate/36) % (Math::PI*2)
99
+ zoomx = (1.5 + Math.sin(@delta)/6) * @@pandapic.width
100
+ zoomy = (1.5 + Math.cos(@delta)/5) * @@pandapic.height
101
+ @image = @@pandapic.zoom_to(zoomx,zoomy,$smooth)
102
+ end
103
+ end
104
+
105
+ pandas = Sprites::Group.new
106
+ pandas.extend(Sprites::UpdateGroup)
107
+ pandas.extend(Sprites::DepthSortGroup)
108
+
109
+ # Create the SDL window
110
+ screen = Screen.set_mode([320,240])
111
+ screen.title = "Rubygame test"
112
+ screen.show_cursor = false;
113
+
114
+ # Create the very cute panda objects!
115
+ panda1 = SpinnyPanda.new(100,50)
116
+ panda2 = ExpandaPanda.new(150,50)
117
+ panda3 = WobblyPanda.new(200,50,0.5)
118
+
119
+ panda1.depth = 0 # in between the others
120
+ panda2.depth = 10 # behind both of the others
121
+ panda3.depth = -10 # in front of both of the others
122
+
123
+ # Put the pandas in a sprite group
124
+ pandas.push(panda1,panda2,panda3)
125
+
126
+ # Make the background surface
127
+ background = Surface.new(screen.size)
128
+
129
+ # Create and test a new surface
130
+ a = Surface.new([100,100])
131
+
132
+ # Draw a bunch of shapes on the new surface to try out the drawing module
133
+ a.fill([70,70,255])
134
+ rect1 = Rect.new([3,3,94,94])
135
+ a.fill([40,40,1500],rect1)
136
+ a.draw_box_s([30,30],[70,70],[0,0,0])
137
+ a.draw_box([31,31],[69,69],[255,255,255])
138
+ a.draw_circle_s([50,50],10,[100,150,200])
139
+ # Two diagonal white lines, the right anti-aliased, the left not.
140
+ a.draw_line([31,69],[49,31],[255,255,255])
141
+ a.draw_line_a([49,31],[69,69],[255,255,255])
142
+ # Finally, copy this interesting surface onto the background image
143
+ a.blit(background,[50,50],[0,0,90,80])
144
+
145
+ # Draw some shapes on the background for fun
146
+ # ... a filled pentagon with a lighter border
147
+ background.draw_polygon_s(\
148
+ [[50,150],[100,140],[150,160],[120,180],[60,170]],\
149
+ [100,100,100])
150
+ background.draw_polygon_a(\
151
+ [[50,150],[100,140],[150,160],[120,180],[60,170]],\
152
+ [200,200,200])
153
+ # ... a pepperoni pizza!! (if you use your imagination...)
154
+ background.draw_arc_s([250,200],34,[210,150],[180,130,50])
155
+ background.draw_arc_s([250,200],30,[210,150],[230,180,80])
156
+ background.draw_circle_s([240,180],4,[200,50,10])
157
+ background.draw_circle_s([265,185],4,[200,50,10])
158
+ background.draw_circle_s([258,200],4,[200,50,10])
159
+ background.draw_circle_s([240,215],4,[200,50,10])
160
+ background.draw_circle_s([260,220],4,[200,50,10])
161
+
162
+ # _Try_ to make an anti-aliased, filled ellipse, but it doesn't work well.
163
+ # If you look closely at the white ellipse, you can see that it isn't
164
+ # AA on the left and right side, and there are some black specks on the top
165
+ # and bottom where the two ellipses don't quite match.
166
+ background.draw_ellipse_s([200,150],[30,25],[250,250,250])
167
+ background.draw_ellipse_a([200,150],[30,25],[250,250,250])
168
+
169
+ # Let's make some labels
170
+ require "rubygame/sfont"
171
+ sfont = SFont.new("term16.png")
172
+ sfont.render("Arrow keys move the spinning panda!").blit(background,[10,10])
173
+
174
+ TTF.setup()
175
+ ttfont = TTF.new("FreeSans.ttf",20)
176
+ ttfont.render("This is some TTF text!",true,[250,250,250]).blit(background,[20,200])
177
+
178
+
179
+ # Create another surface to test transparency blitting
180
+ b = Surface.new([200,50])
181
+ b.fill([150,20,40])
182
+ b.set_alpha(123)# approx. half transparent
183
+ b.blit(background,[20,40])
184
+ background.blit(screen,[0,0])
185
+
186
+ # Refresh the screen once. During the loop, we'll use 'dirty rect' updating
187
+ # to refresh only the parts of the screen that have changed.
188
+ screen.update()
189
+
190
+ if Joystick.num_joysticks > 0
191
+ Joystick.new(0) # So that joystick events will appear on the queue
192
+ end
193
+
194
+ update_time = 0
195
+ framerate = 0
196
+
197
+ catch(:rubygame_quit) do
198
+ loop do
199
+ queue.each do |event|
200
+ case event
201
+ when KeyDownEvent
202
+ case event.key
203
+ when K_ESCAPE
204
+ throw :rubygame_quit
205
+ when K_Q
206
+ throw :rubygame_quit
207
+ when K_UP
208
+ panda1.vy = -1
209
+ when K_DOWN
210
+ panda1.vy = 1
211
+ when K_LEFT
212
+ panda1.vx = -1
213
+ when K_RIGHT
214
+ panda1.vx = 1
215
+ when K_S
216
+ $smooth = !$smooth
217
+ puts "#{$smooth?'En':'Dis'}abling smooth scale/rotate."
218
+ else
219
+ print "%s"%[event.string]
220
+ end
221
+ when KeyUpEvent
222
+ case event.key
223
+ when K_UP
224
+ panda1.vy = 0
225
+ when K_DOWN
226
+ panda1.vy = 0
227
+ when K_LEFT
228
+ panda1.vx = 0
229
+ when K_RIGHT
230
+ panda1.vx = 0
231
+ end
232
+ when ActiveEvent
233
+ # ActiveEvent appears when the window gains or loses focus.
234
+ # This helps to ensure everything is refreshed after the Rubygame
235
+ # window has been covered up by a different window.
236
+ screen.update()
237
+ when QuitEvent
238
+ throw :rubygame_quit
239
+ when MouseDownEvent
240
+ puts "click: [%d,%d]"%event.pos
241
+ when JoyDownEvent
242
+ case event.button
243
+ when 4; panda1.speed = 80
244
+ when 5; panda2.speed = 80
245
+ end
246
+ #puts "jdown: %d"%[event.button]
247
+ when JoyUpEvent
248
+ case event.button
249
+ when 4; panda1.speed = 40
250
+ when 5; panda2.speed = 40
251
+ end
252
+ #puts "jup: %d"%[event.button]
253
+ when JoyAxisEvent
254
+ # max = 32767
255
+ case(event.axis)
256
+ when 0; panda1.vx = event.value / 32767.0
257
+ when 1; panda1.vy = event.value / 32767.0
258
+ when 2; panda2.vx = event.value / 32767.0
259
+ when 3; panda2.vy = event.value / 32767.0
260
+ end
261
+ #puts "jaxis: %d %d"%[event.axis,event.value]
262
+ end
263
+ end
264
+
265
+ pandas.undraw(screen,background)
266
+ pandas.update(update_time)
267
+ dirty_rects = pandas.draw(screen)
268
+ screen.update_rects(dirty_rects)
269
+
270
+ update_time = clock.tick()
271
+ unless framerate == clock.framerate
272
+ framerate = clock.framerate
273
+ screen.title = "Rubygame test [%d fps]"%framerate
274
+ end
275
+ end
276
+ end
277
+
278
+ puts "Quitting!"
279
+ Rubygame.quit()