gosu_android 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/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
|