gosu_android 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README.md +35 -0
- data/bin/gosu_android +11 -0
- data/examples/arkanoid.rb +105 -0
- data/examples/pong_activity.rb +99 -0
- data/examples/test-game.rb +114 -0
- data/lib/gosu.java.jar +0 -0
- data/lib/gosu_android.rb +1 -0
- data/lib/gosu_android/audio/audio.rb +159 -0
- data/lib/gosu_android/commands/base.rb +200 -0
- data/lib/gosu_android/description.rb +5 -0
- data/lib/gosu_android/graphics/bitmap.rb +12 -0
- data/lib/gosu_android/graphics/bitmapUtils.rb +51 -0
- data/lib/gosu_android/graphics/blockAllocator.rb +107 -0
- data/lib/gosu_android/graphics/color.rb +27 -0
- data/lib/gosu_android/graphics/common.rb +21 -0
- data/lib/gosu_android/graphics/drawOp.rb +6 -0
- data/lib/gosu_android/graphics/drawOpQueue.rb +39 -0
- data/lib/gosu_android/graphics/font.rb +61 -0
- data/lib/gosu_android/graphics/graphics.rb +227 -0
- data/lib/gosu_android/graphics/graphicsBase.rb +27 -0
- data/lib/gosu_android/graphics/image.rb +151 -0
- data/lib/gosu_android/graphics/imageData.rb +23 -0
- data/lib/gosu_android/graphics/largeImageData.rb +116 -0
- data/lib/gosu_android/graphics/renderState.rb +5 -0
- data/lib/gosu_android/graphics/texChunk.rb +68 -0
- data/lib/gosu_android/graphics/texture.rb +86 -0
- data/lib/gosu_android/input/buttons.rb +128 -0
- data/lib/gosu_android/input/input.rb +120 -0
- data/lib/gosu_android/main-window.rb +314 -0
- data/lib/gosu_android/math.rb +21 -0
- data/lib/gosu_android/physics/physicsManager.rb +57 -0
- data/lib/gosu_android/physics/physicsObject.rb +113 -0
- data/lib/gosu_android/requires.rb +40 -0
- data/lib/gosu_android/timing.rb +8 -0
- data/lib/gosu_android/version.rb +3 -0
- data/res/drawable-nodpi/ball.png +0 -0
- data/res/drawable-nodpi/bar.png +0 -0
- data/res/drawable-nodpi/bar_hor.png +0 -0
- data/res/drawable-nodpi/character_atlas8.png +0 -0
- data/res/drawable-nodpi/ship.png +0 -0
- data/res/drawable-nodpi/space.png +0 -0
- data/res/drawable-nodpi/star.png +0 -0
- data/res/raw/beep.wav +0 -0
- data/res/raw/chriss_onac_tempo_red.mp3 +0 -0
- metadata +127 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012 Garoe Dorta
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
Gosu-Android
|
2
|
+
============
|
3
|
+
A Gosu implementation for Adroid devices.
|
4
|
+
|
5
|
+
Installation
|
6
|
+
-----------
|
7
|
+
Sadly right now you need to manually copy every file to every ruboto proyect you want to use it.
|
8
|
+
|
9
|
+
- Download the sources
|
10
|
+
- Copy the `lib` folder and the `gosu.rb` to the `proyect_name/src/` folder inside your [ruboto](http://github.com/ruboto/ruboto) proyect.
|
11
|
+
- Copy the `gosu.java.jar` in the `proyect_name/libs/` folder.
|
12
|
+
- Place the `res` files in the `proyect_name/res` folder.
|
13
|
+
- It is very important that you do not copy the `java` files in your proyect folder, they are included for developers only.
|
14
|
+
|
15
|
+
|
16
|
+
General Information
|
17
|
+
-------------------
|
18
|
+
* This is still an early effort, so there are a number of features that had not yet been added.
|
19
|
+
* There are some known bugs that I hope to fix soon.
|
20
|
+
* In its current status there are some small changes to Gosu Window initialization, check examples.
|
21
|
+
* A new object with some basic physics has been added.
|
22
|
+
|
23
|
+
Troubleshooting
|
24
|
+
-------------------
|
25
|
+
* If you're using Ruboto 0.10.4 or earlier, you may get an error when trying to require the gosu libraries: `(SystemStackError) stack level too deep` in `require 'gosu'`. If this happens:
|
26
|
+
* Replace `require 'gosu'` with `with_large_stack { require 'gosu' }`. If it still doesn't work:
|
27
|
+
* Try `with_large_stack(256)
|
28
|
+
require 'gosu'
|
29
|
+
end`. If it still doesn't work, try again with `512` instead of `256`.
|
30
|
+
* Alternatively, update to the latest Ruboto (0.11 or better).
|
31
|
+
* Relevant Ruboto issues:
|
32
|
+
* https://github.com/ruboto/ruboto/issues/359
|
33
|
+
* https://github.com/ruboto/ruboto/issues/375
|
34
|
+
* When using several audio files double check that all have the same codification or you could get: `E/MediaPlayer(16127): Unable to to create media player`
|
35
|
+
* http://forums.pragprog.com/forums/152/topics/9144
|
data/bin/gosu_android
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'gosu_android'
|
2
|
+
|
3
|
+
class GameWindow < Gosu::Window
|
4
|
+
def initialize
|
5
|
+
super 600, 480, false, 30
|
6
|
+
self.caption = "Gosu Arkanoid"
|
7
|
+
self.physics_manager.gravity_y = 0
|
8
|
+
@score = 0
|
9
|
+
@song = Gosu::Song.new(self, Ruboto::R::raw::chriss_onac_tempo_red)
|
10
|
+
@beep = Gosu::Sample.new(self, Ruboto::R::raw::beep)
|
11
|
+
@p1x = 0
|
12
|
+
|
13
|
+
@ball = Gosu::Square.new(self, Ruboto::R::drawable::ball, 100, 200, 0, 50, 20, 100, 100)
|
14
|
+
|
15
|
+
@player_x = 300
|
16
|
+
@player_y = 473
|
17
|
+
@size = 110
|
18
|
+
# 25 is to compesate square size of the ball
|
19
|
+
@size2 = @size/2 - 25
|
20
|
+
@player = Gosu::Plane.new(self,Ruboto::R::drawable::bar_hor, [@player_x, @player_y], [@player_x + @size, @player_y], 0)
|
21
|
+
|
22
|
+
#Left plane
|
23
|
+
@p1 = Gosu::Plane.new(self, Ruboto::R::drawable::bar, [0, 0], [0, 480], 0)
|
24
|
+
#Top plane
|
25
|
+
@p2 = Gosu::Plane.new(self, Ruboto::R::drawable::bar, [600, 0], [0, 0], 0)
|
26
|
+
#Right plane
|
27
|
+
@p3 = Gosu::Plane.new(self,Ruboto::R::drawable::bar, [600, 480], [600, 0], 0)
|
28
|
+
|
29
|
+
@blocks = []
|
30
|
+
@blocks_position = []
|
31
|
+
block_x = 150
|
32
|
+
block_y = 120
|
33
|
+
img = Ruboto::R::drawable::bar_hor
|
34
|
+
2.times do |i|
|
35
|
+
3.times do |j|
|
36
|
+
@blocks.push Gosu::Plane.new(self, img, [block_x + (@size + 30)*i , block_y + 30*j ], [block_x + (@size + 30)*(i + 1), block_y + 30*j ], 0)
|
37
|
+
@blocks_position.push [block_x + (@size + 30)*i, block_y + 30*j]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
6.times do |i|
|
42
|
+
self.apply_physics @blocks[i]
|
43
|
+
end
|
44
|
+
|
45
|
+
self.apply_physics @ball
|
46
|
+
self.apply_physics @player
|
47
|
+
self.apply_physics @p1
|
48
|
+
self.apply_physics @p2
|
49
|
+
self.apply_physics @p3
|
50
|
+
@font = Gosu::Font.new(self, Gosu::default_font_name, 20)
|
51
|
+
@song.play true
|
52
|
+
end
|
53
|
+
|
54
|
+
def update
|
55
|
+
if @ball.center[1] > 480
|
56
|
+
@ball.position[1] = 200
|
57
|
+
@ball.velocity[1] = -@ball.velocity[0]
|
58
|
+
@beep.play
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def object_collided( x, y, other_object )
|
63
|
+
if(@blocks.include? other_object )
|
64
|
+
@score += 1
|
65
|
+
self.stop_physics other_object
|
66
|
+
@blocks_position.delete_at(@blocks.index other_object)
|
67
|
+
@blocks.delete other_object
|
68
|
+
end
|
69
|
+
@beep.play
|
70
|
+
end
|
71
|
+
|
72
|
+
def touch_moved(touch)
|
73
|
+
touch.y = touch.y - @size2
|
74
|
+
@player_x = touch.x
|
75
|
+
@player.bottom_limit[0] = @player_x
|
76
|
+
@player.top_limit[0] = @player_x + @size
|
77
|
+
end
|
78
|
+
|
79
|
+
def draw
|
80
|
+
@blocks.each_index do |i|
|
81
|
+
@blocks[i].draw(@blocks_position[i][0], @blocks_position[i][1], 0)
|
82
|
+
end
|
83
|
+
|
84
|
+
@ball.draw
|
85
|
+
@player.draw(@player_x, @player_y, 0)
|
86
|
+
@font.draw("Score: #{@score}", 10, 10, 3, 1.0, 1.0, 0xffffff00)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
class GosuActivity
|
92
|
+
def on_create(bundle)
|
93
|
+
super(bundle)
|
94
|
+
Gosu::AndroidInitializer.instance.start(self)
|
95
|
+
rescue Exception => e
|
96
|
+
puts "#{ e } (#{ e.class } #{e.message} #{e.backtrace.inspect} )!"
|
97
|
+
end
|
98
|
+
|
99
|
+
def on_ready
|
100
|
+
window = GameWindow.new
|
101
|
+
window.show
|
102
|
+
rescue Exception => e
|
103
|
+
puts "#{ e } (#{ e.class } #{e.message} #{e.backtrace.inspect} )!"
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'gosu_android'
|
2
|
+
|
3
|
+
class GameWindow < Gosu::Window
|
4
|
+
def initialize
|
5
|
+
super 600, 480, false, 50
|
6
|
+
self.caption = "Gosu Pong Game"
|
7
|
+
self.physics_manager.gravity_y = 0
|
8
|
+
@p1score = 0
|
9
|
+
@p2score = 0
|
10
|
+
@song = Gosu::Song.new(self, Ruboto::R::raw::chriss_onac_tempo_red)
|
11
|
+
@beep = Gosu::Sample.new(self, Ruboto::R::raw::beep)
|
12
|
+
@p1x = 0
|
13
|
+
# 25 is to compesate square size of the ball
|
14
|
+
@p1y = 250 + 25
|
15
|
+
@p3x = 593
|
16
|
+
@p3y = 100 + 25
|
17
|
+
@size = 110
|
18
|
+
@size2 = @size/2 - 25
|
19
|
+
@squ = Gosu::Square.new(self, Ruboto::R::drawable::ball, 100, 200, 0, 50, 20, 100, 100)
|
20
|
+
#Left plane
|
21
|
+
@p1 = Gosu::Plane.new(self, Ruboto::R::drawable::bar, [@p1x,@p1y], [@p1x, @p1y + @size] ,0)
|
22
|
+
#Top plane
|
23
|
+
@p2 = Gosu::Plane.new(self, Ruboto::R::drawable::bar, [600,0], [0,0], 0 )
|
24
|
+
#Right plane
|
25
|
+
@p3 = Gosu::Plane.new(self,Ruboto::R::drawable::bar, [@p3x,@p3y + @size], [@p3x,@p3y], 0)
|
26
|
+
#Bottom plane
|
27
|
+
@p4 = Gosu::Plane.new(self,Ruboto::R::drawable::bar, [0,480], [600,480], 0)
|
28
|
+
self.apply_physics @squ
|
29
|
+
self.apply_physics @p1
|
30
|
+
self.apply_physics @p2
|
31
|
+
self.apply_physics @p3
|
32
|
+
self.apply_physics @p4
|
33
|
+
@font = Gosu::Font.new(self, Gosu::default_font_name, 20)
|
34
|
+
@song.play true
|
35
|
+
end
|
36
|
+
|
37
|
+
def update
|
38
|
+
if @squ.center[0] < 0
|
39
|
+
#Player 1 lost
|
40
|
+
@p1score += 1
|
41
|
+
#Reset the ball
|
42
|
+
@squ.position[0] = 300
|
43
|
+
@squ.velocity[0] = -@squ.velocity[0]
|
44
|
+
@beep.play
|
45
|
+
else
|
46
|
+
if @squ.center[0] > 600
|
47
|
+
#Player2 lost
|
48
|
+
@p2score += 1
|
49
|
+
#Reset the ball
|
50
|
+
@squ.position[0] = 300
|
51
|
+
@squ.velocity[0] = -@squ.velocity[0]
|
52
|
+
@beep.play
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def object_collided( x, y, other_object )
|
58
|
+
@beep.play
|
59
|
+
end
|
60
|
+
|
61
|
+
def touch_moved(touch)
|
62
|
+
touch.y = touch.y - @size2
|
63
|
+
if touch.x < 300
|
64
|
+
#Player1
|
65
|
+
@p1y = touch.y
|
66
|
+
@p1.bottom_limit[1] = @p1y + @size
|
67
|
+
@p1.top_limit[1] = @p1y
|
68
|
+
else
|
69
|
+
#Player2
|
70
|
+
@p3y = touch.y
|
71
|
+
@p3.bottom_limit[1] = @p3y + @size
|
72
|
+
@p3.top_limit[1] = @p3y
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def draw
|
77
|
+
@squ.draw
|
78
|
+
@p1.draw(@p1x,@p1y,0)
|
79
|
+
@p3.draw(@p3x,@p3y,0)
|
80
|
+
@font.draw("Score: A #{@p1score} B #{@p2score} ", 10, 10, 3, 1.0, 1.0, 0xffffff00)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
class GosuActivity
|
86
|
+
def on_create(bundle)
|
87
|
+
super(bundle)
|
88
|
+
Gosu::AndroidInitializer.instance.start(self)
|
89
|
+
rescue Exception => e
|
90
|
+
puts "#{ e } (#{ e.class } #{e.message} #{e.backtrace.inspect} )!"
|
91
|
+
end
|
92
|
+
|
93
|
+
def on_ready
|
94
|
+
window = GameWindow.new
|
95
|
+
window.show
|
96
|
+
rescue Exception => e
|
97
|
+
puts "#{ e } (#{ e.class } #{e.message} #{e.backtrace.inspect} )!"
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'gosu_android'
|
2
|
+
|
3
|
+
module ZOrder
|
4
|
+
Background, Stars, Player, UI = *0..3
|
5
|
+
end
|
6
|
+
|
7
|
+
class Player
|
8
|
+
attr_reader :score
|
9
|
+
|
10
|
+
def initialize(window)
|
11
|
+
@image = Gosu::Image.new(window, "/mnt/sdcard/jruby/media/Starfighter.bmp", false)
|
12
|
+
@beep = Gosu::Sample.new(window, "/mnt/sdcard/jruby/media/Beep.wav")
|
13
|
+
@x = @y = @vel_x = @vel_y = @angle = 0.0
|
14
|
+
@score = 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def warp(x, y)
|
18
|
+
@x, @y = x, y
|
19
|
+
end
|
20
|
+
|
21
|
+
def draw
|
22
|
+
@image.draw_rot(@x, @y, ZOrder::Player, @angle)
|
23
|
+
end
|
24
|
+
|
25
|
+
def collect_stars(stars)
|
26
|
+
stars.reject! do |star|
|
27
|
+
if Gosu::distance(@x, @y, star.x, star.y) < 35 then
|
28
|
+
@score += 10
|
29
|
+
@beep.play
|
30
|
+
true
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Star
|
39
|
+
attr_reader :x, :y
|
40
|
+
|
41
|
+
def initialize(animation)
|
42
|
+
@animation = animation
|
43
|
+
@color = Gosu::Color.new(0xff000000)
|
44
|
+
@color.red = rand(256 - 40) + 40
|
45
|
+
@color.green = rand(256 - 40) + 40
|
46
|
+
@color.blue = rand(256 - 40) + 40
|
47
|
+
@x = rand * 640
|
48
|
+
@y = rand * 480
|
49
|
+
end
|
50
|
+
|
51
|
+
def draw
|
52
|
+
img = @animation[Gosu::milliseconds / 100 % @animation.size]
|
53
|
+
img.draw(@x - img.width / 2.0, @y - img.height / 2.0,
|
54
|
+
ZOrder::Stars, 1, 1, @color, Gosu::AM_ADD)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class GameWindow < Gosu::Window
|
59
|
+
def initialize
|
60
|
+
super(640, 480, false)
|
61
|
+
self.caption = "Gosu Tutorial Game"
|
62
|
+
|
63
|
+
#@background_image = Gosu::Image.new(self, "media/Space.png", true)
|
64
|
+
|
65
|
+
@player = Player.new(self)
|
66
|
+
@player.warp(320, 240)
|
67
|
+
|
68
|
+
@star_anim = Gosu::Image::load_tiles(self, "/mnt/sdcard/jruby/media/Star.png", 25, 25, false)
|
69
|
+
@stars = Array.new
|
70
|
+
|
71
|
+
#@font = Gosu::Font.new(self, Gosu::default_font_name, 20)
|
72
|
+
end
|
73
|
+
|
74
|
+
def update
|
75
|
+
@player.collect_stars(@stars)
|
76
|
+
#Normally 25 stars
|
77
|
+
if rand(100) < 4 and @stars.size < 5 then
|
78
|
+
@stars.push(Star.new(@star_anim))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def touch_moved(touch)
|
83
|
+
@player.warp(touch.x, touch.y)
|
84
|
+
end
|
85
|
+
|
86
|
+
def draw
|
87
|
+
#@background_image.draw(0, 0, ZOrder::Background)
|
88
|
+
@player.draw
|
89
|
+
@stars.each { |star| star.draw }
|
90
|
+
#@font.draw("Score: #{@player.score}", 10, 10, ZOrder::UI, 1.0, 1.0, 0xffffff00)
|
91
|
+
end
|
92
|
+
|
93
|
+
def button_down(id)
|
94
|
+
if id == Gosu::KbEscape then
|
95
|
+
close
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class TestGameActivity
|
101
|
+
def on_create(bundle)
|
102
|
+
super(bundle)
|
103
|
+
Gosu::AndroidInitializer.instance.start(self)
|
104
|
+
rescue Exception => e
|
105
|
+
puts "#{ e } (#{ e.class } #{e.message} #{e.backtrace.inspect} )!"
|
106
|
+
end
|
107
|
+
|
108
|
+
def on_ready
|
109
|
+
window = GameWindow.new
|
110
|
+
window.show
|
111
|
+
rescue Exception => e
|
112
|
+
puts "#{ e } (#{ e.class } #{e.message} #{e.backtrace.inspect} )!"
|
113
|
+
end
|
114
|
+
end
|
data/lib/gosu.java.jar
ADDED
Binary file
|
data/lib/gosu_android.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'gosu_android/main-window'
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'gosu_android/requires'
|
2
|
+
|
3
|
+
module Gosu
|
4
|
+
MAX_SAMPLES = 10
|
5
|
+
class SampleInstance
|
6
|
+
def initialize
|
7
|
+
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class AudioFocusListener
|
12
|
+
def onAudioFocusChange focusChange
|
13
|
+
puts "In focus change #{focusChange}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def toString
|
17
|
+
self.class.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#TODO ManageAudioFocus, when app loses, stop song
|
22
|
+
#TODO Raise a warning is the file could not be loaded
|
23
|
+
class Sample
|
24
|
+
|
25
|
+
#Constructs a sample that can be played on the specified audio
|
26
|
+
#system and loads the sample from a file.
|
27
|
+
def initialize(window, filename)
|
28
|
+
@window = window
|
29
|
+
#Set finalize
|
30
|
+
ObjectSpace.define_finalizer(self, self.class.method(:finalize).to_proc)
|
31
|
+
if not defined? @@pool
|
32
|
+
@@pool = JavaImports::SoundPool.new(MAX_SAMPLES, JavaImports::AudioManager::STREAM_MUSIC, 0)
|
33
|
+
end
|
34
|
+
|
35
|
+
if(filename.class == Fixnum )
|
36
|
+
@id = @@pool.load( @window.activity.getApplicationContext, filename, 1 )
|
37
|
+
else
|
38
|
+
@id = @@pool.load(filename, 1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#Plays the sample without panning.
|
43
|
+
#\param volume Can be anything from 0.0 (silence) to 1.0 (full
|
44
|
+
#volume).
|
45
|
+
#\param speed Playback speed is only limited by the underlying audio library,
|
46
|
+
#and can accept very high or low values. Use 1.0 for
|
47
|
+
#normal playback speed.
|
48
|
+
def play(volume = 1, speed = 1, looping = false)
|
49
|
+
if looping == false
|
50
|
+
@stream_id = @@pool.play(@id, volume, volume, 1, 0, 1.0)
|
51
|
+
else
|
52
|
+
@stream_id = @@pool.play(@id, volume, volume, 1, 1, 1.0)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#TODO Pan is not supported so it is ignored
|
57
|
+
def play_pan(pan = 0, volume = 1, speed = 1, looping = false)
|
58
|
+
if looping == false
|
59
|
+
@stream_id = @@pool.play(@id, volume, volume, 1, 0, 1.0)
|
60
|
+
else
|
61
|
+
@stream_id = @@pool.play(@id, volume, volume, 1, 1, 1.0)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def Sample.finalize(id)
|
66
|
+
@@pool.unload(@id)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
#TODO Error on playing several songs, bear in mind mediaplayer states
|
72
|
+
#FIXME Set listener for when the data finished loading asynchronously
|
73
|
+
# add some checks play is reached before that
|
74
|
+
class Song
|
75
|
+
attr_reader :current_song
|
76
|
+
def initialize(window, filename)
|
77
|
+
@window = window
|
78
|
+
if not defined? @@media_player
|
79
|
+
@@media_player = JavaImports::MediaPlayer.new
|
80
|
+
@@audio_focus_listener = AudioFocusListener.new
|
81
|
+
context = @window.activity.getApplicationContext
|
82
|
+
@@audio_manager = context.getSystemService(Context::AUDIO_SERVICE)
|
83
|
+
focus = @@audio_manager.requestAudioFocus(@@audio_focus_listener, JavaImports::AudioManager::STREAM_MUSIC, JavaImports::AudioManager::AUDIOFOCUS_GAIN)
|
84
|
+
else
|
85
|
+
@@media_player.reset
|
86
|
+
focus = @@audio_manager.requestAudioFocus(@@audio_focus_listener, JavaImports::AudioManager::STREAM_MUSIC, JavaImports::AudioManager::AUDIOFOCUS_GAIN)
|
87
|
+
end
|
88
|
+
|
89
|
+
if filename.class == Fixnum
|
90
|
+
afd = @window.activity.getApplicationContext.getResources.openRawResourceFd(filename)
|
91
|
+
filename = afd.getFileDescriptor
|
92
|
+
end
|
93
|
+
|
94
|
+
@@media_player.on_prepared_listener = (proc{media_player_ready})
|
95
|
+
@@media_player.setDataSource filename
|
96
|
+
@@media_player.prepareAsync
|
97
|
+
@player_ready = false
|
98
|
+
@window.media_player = @@media_player
|
99
|
+
@playing = false
|
100
|
+
@file_name = filename
|
101
|
+
|
102
|
+
if not defined? @@current_song
|
103
|
+
@@current_song = 0
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def media_player_ready
|
108
|
+
@player_ready = true
|
109
|
+
#Song should be playing but media player was not ready
|
110
|
+
#so start playing now
|
111
|
+
if @playing
|
112
|
+
@@media_player.start
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
#Starts or resumes playback of the song. This will stop all other
|
117
|
+
#songs and set the current song to this object.
|
118
|
+
def play(looping = false)
|
119
|
+
@@media_player.setLooping(looping)
|
120
|
+
if @player_ready
|
121
|
+
@@media_player.start
|
122
|
+
end
|
123
|
+
@@current_song = @file_name
|
124
|
+
@playing = true
|
125
|
+
end
|
126
|
+
|
127
|
+
#Pauses playback of the song. It is not considered being played.
|
128
|
+
#currentSong will stay the same.
|
129
|
+
def pause
|
130
|
+
if @player_ready
|
131
|
+
@@media_player.pause
|
132
|
+
end
|
133
|
+
@playing = false
|
134
|
+
end
|
135
|
+
|
136
|
+
#Returns true if the song is the current song, but in paused
|
137
|
+
#mode.
|
138
|
+
def paused?
|
139
|
+
not @playing and @@current_song == @file_name
|
140
|
+
end
|
141
|
+
|
142
|
+
#Returns true if the song is currently playing.
|
143
|
+
def playing?
|
144
|
+
@playing and @@current_song == @file_name
|
145
|
+
end
|
146
|
+
|
147
|
+
#Stops playback of this song if it is currently played or paused.
|
148
|
+
#Afterwards, current_song will return 0.
|
149
|
+
def stop
|
150
|
+
if @player_ready
|
151
|
+
@@media_player.pause
|
152
|
+
@@media_player.stop
|
153
|
+
end
|
154
|
+
@@current_song = 0
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|