bathtub 0.5.2

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/SDL.dll ADDED
Binary file
Binary file
Binary file
data/SGE.dll ADDED
Binary file
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.2
Binary file
@@ -0,0 +1,232 @@
1
+ #
2
+ # character.rb
3
+ #
4
+
5
+ class Combo
6
+ include Task
7
+
8
+ def self.load
9
+ @@font = SDL::TTF.open("image/curving.ttf", 20)
10
+ end
11
+ attr_accessor :x,:y,:value
12
+
13
+ def init
14
+ @step = 0
15
+ end
16
+
17
+ def act(dt,i)
18
+ @step += dt
19
+ @active = false if @step > 500
20
+ end
21
+
22
+ def draw(i)
23
+ @@font.drawBlendedUTF8(i.scr,"#{@value} COMBO", @x,@y-(@step/10) , 255,100,100)
24
+ end
25
+
26
+ end
27
+
28
+ class Bath
29
+ extend SingleTask
30
+
31
+ Shibuki = Struct.new(:x,:y,:step)
32
+
33
+ WAIT_STAFF_ANIM = 80
34
+ MOVE_WAIT = 3
35
+
36
+ STAFF_IMGS = 4
37
+ SHIBUKI_IMGS = 3
38
+ Y0 = 342
39
+
40
+ attr_reader :x,:y
41
+
42
+ def init
43
+ @img_bath = SDL::Surface.loadBMP("image/bath.bmp")
44
+ @img_bath.setColorKey(SDL::SRCCOLORKEY,[255,0,255])
45
+ @img_rstaff = Util.cut_image(56,67,STAFF_IMGS, SDL::Surface.loadBMP("image/staff.bmp"), 0,0, [255,0,255])
46
+ @img_lstaff = Util.cut_image(56,67,STAFF_IMGS, SDL::Surface.loadBMP("image/staff.bmp"), 0,67, [255,0,255])
47
+ @img_shibuki = Util.cut_image(94,105,SHIBUKI_IMGS, SDL::Surface.loadBMP("image/shibuki.bmp"),0,0,[255,255,255])
48
+ Sound.open(:scratch, "BB_Scratch_19.wav", 40)
49
+ @movetimer = Timer.new(MOVE_WAIT)
50
+ @staff_anim_timer = Timer.new(WAIT_STAFF_ANIM)
51
+ @shibuki_timer = Timer.new(80)
52
+ end
53
+
54
+ def enabled
55
+ @movestep = (GameMain.mode==:endless ? 3 : 2)
56
+ end
57
+
58
+ def reset
59
+ @staffimg = 0
60
+ @x = 320 #�o�X�^�u�̒��S���W
61
+ @y = Y0
62
+ @dir = 1 #1:right -1:left
63
+ @effects = []
64
+ end
65
+
66
+ def shibuki
67
+ @effects << Shibuki.new(0,0,0)
68
+ end
69
+
70
+ def act(dt,i)
71
+ act_move(dt,i) unless Gameover.active?
72
+ act_shibuki(dt)
73
+ end
74
+
75
+ def act_move(dt,i)
76
+ if i.key.right
77
+ newdir = 1
78
+ elsif i.key.left
79
+ newdir = -1
80
+ elsif i.keydown.button
81
+ newdir = -@dir
82
+ else
83
+ newdir = @dir
84
+ end
85
+
86
+ if newdir != @dir
87
+ #Sound.play(:scratch)
88
+ @dir = newdir
89
+ end
90
+
91
+ @staff_anim_timer.wait(dt){
92
+ @staffimg+=1
93
+ @staffimg=0 if @staffimg>=STAFF_IMGS
94
+ }
95
+
96
+ @movetimer.wait(dt){
97
+ @x += @dir * @movestep
98
+ @x = 0 if @x<0
99
+ @x = 639 if @x>639
100
+ }
101
+ end
102
+
103
+ def act_shibuki(dt)
104
+ @effects.each do |eff|
105
+ @shibuki_timer.wait(dt){
106
+ eff.step+=1
107
+ }
108
+ end
109
+ @effects.delete_if{|eff|
110
+ eff.step >= SHIBUKI_IMGS
111
+ }
112
+ end
113
+
114
+ def draw(i)
115
+ @effects.each{|eff| i.scr.put(@img_shibuki[eff.step], @x-55, @y-58)}
116
+
117
+ @x = 330 if NameEntry.active?
118
+
119
+ i.scr.put(@img_lstaff[@staffimg], @x-80, @y-14)
120
+ i.scr.put(@img_bath, @x-37, @y )
121
+ i.scr.put(@img_rstaff[@staffimg], @x+32, @y-14)
122
+ end
123
+
124
+ end
125
+
126
+
127
+ class Jumper
128
+ include Task
129
+
130
+ def self.load
131
+ @@img = SDL::Surface.loadBMP("image/hito.bmp")
132
+ @@img.setColorKey(SDL::SRCCOLORKEY,[255,0,255])
133
+ end
134
+
135
+ attr_accessor :x,:y
136
+ def init
137
+ case GameMain.mode
138
+ when :easy
139
+ speed = 11
140
+ when :normal
141
+ speed = 8
142
+ when :endless
143
+ speed = 7
144
+ end
145
+
146
+ @movetimer = Timer.new(speed)
147
+ @type = rand(2)
148
+ @missed = false
149
+
150
+ #���W�֘A
151
+ @t0=-20
152
+ @y0=260
153
+ @x=(@type==0 ? 0 : 640)
154
+ @y=0
155
+ @t=0
156
+ @vx=rand(6)+1
157
+ end
158
+ attr_accessor :missed
159
+
160
+ def act(dt,info)
161
+ @movetimer.wait(dt){
162
+ @t+=0.8
163
+ if @type==0
164
+ @x = @vx*@t
165
+ else # @type==1
166
+ @x = 640 - @vx*@t
167
+ end
168
+
169
+ @y = 480 - ( @y0 + 10*(@t-@t0) - 0.1*(@t-@t0)*(@t-@t0) )
170
+ }
171
+
172
+ if @x<0 || @x>=640 || @y>=480
173
+ @alive = false
174
+ end
175
+ end
176
+
177
+ def draw(i)
178
+ i.scr.put(@@img, @x - @@img.w/2, @y)
179
+ end
180
+
181
+ end
182
+
183
+ class Jumpers
184
+ extend SingleTask
185
+
186
+ def init
187
+ Sound.open(:zabun, "SplashA1@22.wav", 60)
188
+ Sound.open(:fall, "fall.wav", 60)
189
+ end
190
+
191
+ def reset
192
+ @items = []
193
+ @margin = (GameMain.mode==:easy ? 80 : 25)
194
+ end
195
+
196
+ def act(dt,i)
197
+ ret = 0 #0pts
198
+
199
+ #����
200
+ if @items.size<1 && !Gameover.active?
201
+ @items << Jumper.new
202
+ end
203
+
204
+ #����
205
+ @items.each do |item|
206
+ if item.y>=330 && item.alive && !item.missed
207
+ #����
208
+ if (Bath.instance.x-item.x).abs < @margin
209
+ #�����ρ[��
210
+ item.alive = false #����
211
+ i.score.incr #1 pts
212
+ Sound.play(:zabun)
213
+ Bath.instance.shibuki
214
+ if GameMain.mode==:endless && i.score.value > 0
215
+ c = Combo.new
216
+ c.x = Bath.instance.x; c.y = Bath.instance.y; c.value = i.score.value
217
+ end
218
+ elsif item.y>=360
219
+ #���ׂ�
220
+ Sound.play(:fall)
221
+ item.missed = true
222
+ i.score.miss #1miss
223
+ end
224
+ end
225
+ end
226
+
227
+ #�폜
228
+ @items.delete_if{|item| !item.alive}
229
+ end
230
+
231
+ end
232
+
@@ -0,0 +1,120 @@
1
+ require 'singleton'
2
+ require 'bathtub/misc.rb'
3
+ require 'bathtub/task.rb'
4
+ require 'bathtub/score.rb'
5
+ require 'bathtub/scene.rb'
6
+ require 'bathtub/graphic.rb'
7
+ require 'bathtub/character.rb'
8
+
9
+ class NullJoystick
10
+ def axis(a); 0; end
11
+ def hat(i); 0; end
12
+ def numButtons; 0; end
13
+ end
14
+
15
+ class Game
16
+
17
+ Key = Struct.new(:left,:right,:button,:other,:ctrl,:esc)
18
+ class Key
19
+ def reset
20
+ self.size.times{|i| self[i]=nil}
21
+ end
22
+ end
23
+
24
+ def initialize(screen)
25
+ @screen = screen
26
+ @joy = (SDL::Joystick.num > 0) ? SDL::Joystick.open(0) : NullJoystick.new
27
+
28
+ TaskManager.init
29
+
30
+ Background.new
31
+ Gameover.disable
32
+ Highscore.disable
33
+ ModeSelect.enable
34
+ GameMain.disable
35
+ @score = Score.instance
36
+ Jumper.load
37
+ Jumpers.disable
38
+ Bath.disable
39
+ Combo.load
40
+ NameEntry.disable
41
+ end
42
+
43
+ def run
44
+ TaskManager.reset
45
+ before = now = SDL.getTicks
46
+ info = Task::Info.new
47
+ info.scr = @screen
48
+ info.score = @score
49
+ info.key = Key.new
50
+ info.keydown = Key.new
51
+
52
+ while true
53
+ return if check_events(info.key, info.keydown)==nil
54
+
55
+ before=now; now=SDL.getTicks; dt=now-before
56
+ TaskManager.act(dt,info)
57
+
58
+ TaskManager.draw(info)
59
+ @screen.flip
60
+ end
61
+ end
62
+
63
+ def check_events(key,kd)
64
+ key.reset
65
+ kd.reset
66
+
67
+ #check keys
68
+ while (event=SDL::Event2.poll)
69
+ case event
70
+ when SDL::Event2::Quit
71
+ return nil
72
+ when SDL::Event2::JoyButtonDown
73
+ kd.button = true
74
+ when SDL::Event2::JoyAxis
75
+ if event.value < -512
76
+ kd.left = true
77
+ elsif event.value > 512
78
+ kd.right = true
79
+ end
80
+ when SDL::Event2::KeyDown
81
+ kd.other ||= []
82
+ kd.other << event.sym
83
+ case event.sym
84
+ when SDL::Key::ESCAPE
85
+ if GameMain.mode==:endless && GameMain.active?
86
+ kd.esc = true
87
+ else
88
+ return nil
89
+ end
90
+ when SDL::Key::RETURN, SDL::Key::SPACE
91
+ kd.button = true
92
+ when SDL::Key::LEFT, SDL::Key::UP, SDL::Key::H, SDL::Key::K
93
+ kd.left = true
94
+ when SDL::Key::RIGHT, SDL::Key::DOWN, SDL::Key::L, SDL::Key::J
95
+ kd.right = true
96
+ end
97
+ end
98
+ end
99
+
100
+ SDL::Key.scan; SDL::Joystick.updateAll
101
+ key.left = true if @joy.axis(0) < -512 || @joy.axis(1) < -512 ||
102
+ @joy.hat(0) == SDL::Joystick::HAT_LEFT || @joy.hat(0) == SDL::Joystick::HAT_UP
103
+ key.right = true if @joy.axis(0) > 512 || @joy.axis(1) > 512 ||
104
+ @joy.hat(0) == SDL::Joystick::HAT_RIGHT || @joy.hat(0) == SDL::Joystick::HAT_DOWN
105
+ @joy.numButtons.times{|i| key.button = true if @joy.button(i)}
106
+ [SDL::Key::RETURN, SDL::Key::SPACE].each{|k| key.button=true if SDL::Key.press?(k)}
107
+ [SDL::Key::LEFT, SDL::Key::UP].each{|k| key.left=true if SDL::Key.press?(k)}
108
+ [SDL::Key::RIGHT, SDL::Key::DOWN].each{|k| key.right=true if SDL::Key.press?(k)}
109
+ unless NameEntry.active?
110
+ [SDL::Key::H, SDL::Key::K].each{|k| key.left=true if SDL::Key.press?(k)}
111
+ [SDL::Key::L, SDL::Key::J].each{|k| key.right=true if SDL::Key.press?(k)}
112
+ end
113
+ key.ctrl = true if SDL::Key.press?(SDL::Key::LCTRL)
114
+
115
+ return true
116
+ end
117
+
118
+ end
119
+
120
+
@@ -0,0 +1,25 @@
1
+ #
2
+ # graphic.rb
3
+ #
4
+
5
+ class Background
6
+ include Task
7
+
8
+ def init
9
+ @img_back = SDL::Surface.loadBMP("image/back.bmp")
10
+ @img_logo = SDL::Surface.loadBMP("image/logo.bmp")
11
+ @img_logo.setColorKey(SDL::SRCCOLORKEY,[0,0,255])
12
+ @font = SDL::TTF.open("image/curving.ttf", 20)
13
+ end
14
+
15
+ def draw(i)
16
+ i.scr.fillRect(0,0,640,480,0)
17
+ i.scr.put(@img_back,0,0)
18
+ if GameMain.active?
19
+ i.scr.put(@img_logo,520,382)
20
+ @font.drawBlendedUTF8(i.scr, GameMain.mode.to_s.upcase, 550,455, 255,80,80)
21
+ end
22
+ end
23
+
24
+ end
25
+
@@ -0,0 +1,35 @@
1
+ # main.rb
2
+
3
+ require 'sdl'
4
+ require 'bathtub/game.rb'
5
+
6
+ class Main
7
+
8
+ TITLE = "�o�X�^�u�꒼��"
9
+ VERSION = "0.51"
10
+
11
+ def initialize(fullscreen=false)
12
+ SDL.init(SDL::INIT_VIDEO|SDL::INIT_AUDIO|SDL::INIT_JOYSTICK)
13
+ SDL::TTF.init
14
+ SDL::Mixer.open
15
+
16
+ SDL::WM.icon = SDL::Surface.loadBMP("image/icon-16168.bmp")
17
+ #screen
18
+ if fullscreen
19
+ screen = SDL::setVideoMode(640,480,16,SDL::SWSURFACE|SDL::FULLSCREEN) #|SDL::DOUBLEBUF
20
+ SDL::Mouse.hide
21
+ else
22
+ screen = SDL::setVideoMode(640,480,16,SDL::SWSURFACE) #|SDL::DOUBLEBUF)
23
+ end
24
+ #SDL::WM.setCaption(TITLE+" "+VERSION, TITLE)
25
+
26
+ #init game
27
+ @game = Game.new(screen)
28
+ end
29
+
30
+ def run
31
+ @game.run
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,83 @@
1
+ #
2
+ # misc.rb
3
+ #
4
+
5
+ class Consts
6
+ LIVES = 2
7
+ end
8
+
9
+ #----------------------------------------------------------------------------------
10
+
11
+ class Timer
12
+ def reset
13
+ @ct=0
14
+ end
15
+
16
+ def initialize(waittime)
17
+ set_wait(waittime)
18
+ reset
19
+ end
20
+
21
+ def wait(dt)
22
+ @ct+=dt
23
+ while @ct>=@waittime do
24
+ @ct-=@waittime
25
+ yield
26
+ @ct=0 if @ct<@waittime
27
+ end
28
+ end
29
+
30
+ def set_wait(t)
31
+ raise ArgumentError,"waittime must be positive" if t<=0
32
+ @waittime = t
33
+ end
34
+ end
35
+
36
+ #----------------------------------------------------------------------------------
37
+ module Sound
38
+
39
+ class << Sound
40
+ def open(sym,fname,vol=nil)
41
+ if fname=~/\.wav\z/
42
+ @@waves ||= {}
43
+ @@waves[sym] = [SDL::Mixer::Wave.load("sound/"+fname), @@waves.size]
44
+ @@waves[sym][0].setVolume(vol) if vol
45
+ else
46
+ @@bgm ||= {}
47
+ #@@bgm[sym] = SDL::Mixer::Music.load("sound/"+fname)
48
+ end
49
+ end
50
+
51
+ def play(sym)
52
+ if @@waves.key? sym
53
+ SDL::Mixer.playChannel(@@waves[sym][1], #channel
54
+ @@waves[sym][0], #wave
55
+ 0)
56
+ else
57
+ #SDL::Mixer.playMusic(@@bgm[sym],-1)
58
+ end
59
+ end
60
+
61
+ def stop_music
62
+ SDL::Mixer.haltMusic
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ #------------------------------------------------------------------------------
69
+ module Util
70
+ def self.cut_image(w,h,n,img, ofsx=0, ofsy=0, colkey=nil)
71
+ ret = []
72
+ n.times do |i|
73
+ surf = img.copyRect(i*w+ofsx,0+ofsy, w,h)
74
+ surf.setColorKey(SDL::SRCCOLORKEY, colkey) if colkey!=nil
75
+ ret << surf
76
+ end
77
+ ret
78
+ end
79
+ end
80
+
81
+
82
+ #----------------------------------------------------------------------------------
83
+ #----------------------------------------------------------------------------------
@@ -0,0 +1,223 @@
1
+ #
2
+ # scene.rb
3
+ #
4
+
5
+ class GameMain
6
+ extend SingleTask
7
+
8
+ def init
9
+ Sound.open(:bgm, "blacksamba.it")
10
+ Sound.open(:bgm2, "clambient.it")
11
+ @mode = nil
12
+ end
13
+ attr_accessor :mode
14
+
15
+ class << GameMain
16
+ def set_mode(mode); self.instance.mode = mode; end
17
+ def mode; self.instance.mode; end
18
+ end
19
+
20
+ def enabled
21
+ (@mode==:endless) ? Sound.play(:bgm2) : Sound.play(:bgm)
22
+ Bath.enable
23
+ Jumpers.enable
24
+ TaskManager.reset
25
+ end
26
+
27
+ def disabled
28
+ Sound.stop_music
29
+ Jumpers.disable
30
+ end
31
+
32
+ def act(dt,i)
33
+ if @mode==:endless && i.keydown.esc
34
+ GameMain.disable
35
+ Gameover.enable
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ class ModeSelect
42
+ extend SingleTask
43
+
44
+ MODES = [:easy, :normal, :endless]
45
+ HEIGHT = [180,220,260]
46
+ LEFT = 100
47
+
48
+ def init
49
+ @font=SDL::TTF.open("image/boxfont2.ttf", 40)
50
+ @movetimer = Timer.new(100)
51
+ @cur = 0
52
+ end
53
+
54
+ def enabled
55
+ Highscore.enable
56
+ Highscore.instance.show = MODES[@cur]
57
+ end
58
+
59
+ def act(dt,i)
60
+ if i.keydown.left
61
+ @cur-=1
62
+ @cur = MODES.size-1 if @cur<0
63
+ Highscore.instance.show = MODES[@cur]
64
+ elsif i.keydown.right
65
+ @cur+=1
66
+ @cur = 0 if @cur>MODES.size-1
67
+ Highscore.instance.show = MODES[@cur]
68
+ elsif i.keydown.button
69
+ self.disable
70
+ Highscore.disable
71
+ GameMain.set_mode(MODES[@cur])
72
+ GameMain.enable
73
+ end
74
+ end
75
+
76
+ def draw(i)
77
+ @font.drawBlendedUTF8(i.scr, " EASY", LEFT,HEIGHT[0], 0,0,0)
78
+ @font.drawBlendedUTF8(i.scr, " NORMAL", LEFT,HEIGHT[1], 0,0,0)
79
+ @font.drawBlendedUTF8(i.scr, " ENDLESS", LEFT,HEIGHT[2], 0,0,0)
80
+ @font.drawBlendedUTF8(i.scr, "*", LEFT,HEIGHT[@cur], 0,0,0)
81
+ end
82
+
83
+ end
84
+
85
+ class Gameover
86
+ extend SingleTask
87
+
88
+ def init
89
+ @font = SDL::TTF.open("image/boxfont2.ttf", 48)
90
+ @flashtimer = Timer.new(700)
91
+ @draw = true
92
+ end
93
+
94
+ def act(dt,i)
95
+ @flashtimer.wait(dt){
96
+ @draw = (@draw ? false : true)
97
+ }
98
+ if i.keydown.button
99
+ i.keydown.reset
100
+ self.disable
101
+ Bath.disable
102
+ newscore = (GameMain.mode==:endless ? i.score.max : i.score.value)
103
+ if Highscore.instance.high?(newscore)
104
+ NameEntry.enable
105
+ else
106
+ ModeSelect.enable
107
+ end
108
+ end
109
+ end
110
+
111
+ def draw(i)
112
+ @font.drawBlendedUTF8(i.scr,"HIT ENTER KEY", 160,220 , 0,0,0) if @draw
113
+ end
114
+
115
+ end
116
+
117
+ class NameEntry
118
+ extend SingleTask
119
+
120
+ CHARS = []
121
+ 26.times{|i| CHARS << ?A+i}
122
+ 10.times{|i| CHARS << ?0+i}
123
+ CHARS << -1 # 'BS'
124
+ CHARS << -2 # 'END'
125
+
126
+ R = 160
127
+ BASE = Math::PI / 2
128
+ RAD = Math::PI * 2 / CHARS.size
129
+
130
+ def init
131
+ @font_small = SDL::TTF.open("image/curving.ttf", 10)
132
+ @font = SDL::TTF.open("image/curving.ttf", 24)
133
+ @font_big = SDL::TTF.open("image/curving.ttf", 30)
134
+ @waittimer = Timer.new(100)
135
+ @name = ""
136
+ @cur = 0
137
+ end
138
+
139
+ def enabled
140
+ Bath.enable
141
+ Jumpers.disable
142
+ end
143
+
144
+ def act(dt,i)
145
+ if i.keydown.other
146
+ i.keydown.other.each do |sym|
147
+ case sym
148
+ when SDL::Key::BACKSPACE, SDL::Key::DELETE
149
+ @name.chop!
150
+ when (SDL::Key::A..SDL::Key::Z)
151
+ if sym==SDL::Key::H && i.key.ctrl
152
+ @name.chop!
153
+ else
154
+ @cur = sym - SDL::Key::A
155
+ @name << (?A + @cur).chr
156
+ end
157
+ when (SDL::Key::K0..SDL::Key::K9)
158
+ @cur = sym - SDL::Key::K0
159
+ @name << (?0 + @cur).chr
160
+ when (SDL::Key::KP0..SDL::Key::KP9)
161
+ @cur = sym - SDL::Key::KP0
162
+ @name << (?0 + @cur).chr
163
+ end
164
+ end
165
+ end
166
+
167
+ if i.keydown.button
168
+ case CHARS[@cur]
169
+ when -1 # BS
170
+ @name.chop!
171
+ when -2 # END
172
+ newscore = (GameMain.mode==:endless ? i.score.max : i.score.value)
173
+ Highscore.instance.add( newscore, @name.dup )
174
+ self.disable
175
+ Bath.disable
176
+ ModeSelect.enable
177
+ else
178
+ if i.keydown.other && i.keydown.other.include?(SDL::Key::RETURN)
179
+ @cur = CHARS.size-1
180
+ else
181
+ @name << CHARS[@cur].chr
182
+ end
183
+ end
184
+ end
185
+
186
+ @waittimer.wait(dt){
187
+ if i.key.left
188
+ @cur -= 1
189
+ @cur = CHARS.size-1 if @cur<0
190
+ elsif i.key.right
191
+ @cur += 1
192
+ @cur = 0 if @cur>CHARS.size-1
193
+ end
194
+ }
195
+ end
196
+
197
+ def draw(i)
198
+ CHARS.each_with_index do |c,n|
199
+ x = 320 + (R * Math.sin(RAD*(n-@cur)))
200
+ y = 200 + (R * Math.cos(RAD*(n-@cur)))
201
+ color = (n==@cur) ? [255,80,80] : [80,80,80]
202
+
203
+ if c==-1 # BS
204
+ @font_small.drawBlendedUTF8(i.scr, "D", x,y , *color)
205
+ @font_small.drawBlendedUTF8(i.scr, "E", x+5,y+5 , *color)
206
+ @font_small.drawBlendedUTF8(i.scr, "L", x+10,y+10 , *color)
207
+ elsif c==-2 # END
208
+ @font_small.drawBlendedUTF8(i.scr, "E", x,y , *color)
209
+ @font_small.drawBlendedUTF8(i.scr, "N", x+5,y+5 , *color)
210
+ @font_small.drawBlendedUTF8(i.scr, "D", x+10,y+10 , *color)
211
+ elsif n==@cur
212
+ @font_big.drawBlendedUTF8(i.scr, c.chr, x,y , *color)
213
+ else
214
+ @font.drawBlendedUTF8( i.scr, c.chr, x,y , *color)
215
+ end
216
+ end
217
+
218
+ x = 320 - @font_big.textSize(@name).first / 2
219
+ @font_big.drawBlendedUTF8(i.scr, @name, x,192 , 255,80,80)
220
+ end
221
+
222
+ end
223
+
@@ -0,0 +1,121 @@
1
+ #
2
+ # score.rb
3
+ #
4
+
5
+ class Score
6
+ extend SingleTask
7
+
8
+ def init
9
+ @font=SDL::TTF.open("image/boxfont2.ttf", 40)
10
+ end
11
+
12
+ def reset
13
+ @life = Consts::LIVES
14
+ @score = 0
15
+ @max = 0
16
+ end
17
+ attr_accessor :score
18
+ attr_reader :max
19
+
20
+ def value
21
+ @score
22
+ end
23
+
24
+ def incr
25
+ @score+=1
26
+ @max = @score if @max < @score
27
+ end
28
+
29
+ def miss
30
+ if GameMain.mode==:endless
31
+ @max = @score if @max < @score
32
+ @score = 0
33
+ else
34
+ @life -= 1
35
+ if @life < 0
36
+ GameMain.disable
37
+ Gameover.enable
38
+ @life = 0
39
+ end
40
+ end
41
+ end
42
+
43
+ def draw(i)
44
+ if GameMain.mode==:endless
45
+ @font.drawBlendedUTF8(i.scr," LIFE: .. MAXCOMBO:#{'%3d' % @max}", 0,0 , 0,0,0)
46
+ else
47
+ lifemeter = '*'*@life + ' '*(Consts::LIVES-@life)
48
+ @font.drawBlendedUTF8(i.scr," LIFE: #{lifemeter} SCORE:#{'%3d' % @score}", 0,0 , 0,0,0)
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+
56
+ module Enumerable
57
+ def stable_sort
58
+ i = 0
59
+ self.sort_by{|v| [v, i += 1]}
60
+ end
61
+ end
62
+
63
+
64
+ class Highscore
65
+ extend SingleTask
66
+
67
+ N = 5
68
+ FILE = "highscore.dat"
69
+
70
+ def init
71
+ @font = SDL::TTF.open("image/boxfont2.ttf", 25)
72
+ @scores = read() || Hash.new
73
+ ModeSelect::MODES.each do |mode|
74
+ @scores[mode] ||= []
75
+ end
76
+ @show = nil
77
+ end
78
+ attr_reader :scores
79
+ attr_writer :show
80
+
81
+ def high?(score)
82
+ p score, @scores
83
+ return false if score==0
84
+ mode = GameMain.mode
85
+ @scores[mode].empty? || @scores[mode].size < N || @scores[mode].last[0] < score
86
+ end
87
+
88
+ def add(score,name)
89
+ return unless high?(score)
90
+ mode = GameMain.mode
91
+ @scores[mode] << [score, name]
92
+ @scores[mode] = @scores[mode].stable_sort.reverse[0,N]
93
+ write
94
+ end
95
+
96
+ def read
97
+ ret = nil
98
+ if File.exist?(FILE)
99
+ open(FILE,"rb") do |f|
100
+ ret = Marshal.load(f)
101
+ end
102
+ end
103
+ ret
104
+ end
105
+
106
+ def write
107
+ open(FILE,"wb") do |f|
108
+ Marshal.dump(@scores,f)
109
+ end
110
+ end
111
+
112
+ def draw(i)
113
+ @font.drawBlendedUTF8(i.scr, "* HighScore *", 380,38, 0,0,255)
114
+ @scores[@show].each_with_index do |item,n|
115
+ score,name = *item
116
+ @font.drawBlendedUTF8(i.scr, "#{n+1}. #{score} (#{name})", 380,65+(20*n), 0,0,255)
117
+ end
118
+ end
119
+
120
+ end
121
+
@@ -0,0 +1,63 @@
1
+ #
2
+ # task.rb
3
+ #
4
+
5
+ class TaskManager
6
+
7
+ class << TaskManager
8
+ def init
9
+ @@task = []
10
+ end
11
+
12
+ def add_task(t)
13
+ @@task << t
14
+ end
15
+
16
+ def reset
17
+ @@task.each{|t| t.reset}
18
+ end
19
+ def draw(info)
20
+ @@task.each{|t| t.draw(info) if t.active?}
21
+ end
22
+ def act(dt,info)
23
+ @@task.each{|t| t.act(dt,info) if t.active?}
24
+ @@task.delete_if{|t| !t.alive}
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ module Task
31
+ Info = Struct.new(:key,:keydown,:scr,:score)
32
+
33
+ def initialize
34
+ @active = true
35
+ @alive = true
36
+ TaskManager.add_task(self)
37
+ init
38
+ end
39
+ attr_accessor :alive
40
+
41
+ def active?; @active; end
42
+ def enable; @active = true; enabled; end
43
+ def disable; @active = false; disabled; end
44
+
45
+ def enabled; end
46
+ def disabled; end
47
+
48
+ def init; end
49
+ def act(dt,info); end
50
+ def draw(info); end
51
+ def reset; end
52
+ end
53
+
54
+ module SingleTask
55
+ def self.extended(klass)
56
+ klass.__send__ :include, Singleton
57
+ klass.__send__ :include, Task
58
+ end
59
+
60
+ def active?; self.instance.active?; end
61
+ def enable; self.instance.enable; end
62
+ def disable; self.instance.disable; end
63
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Dir.chdir File.expand_path("..", File.dirname(__FILE__))
4
+ require 'bathtub/main'
5
+
6
+ Main.new(ARGV[0] == "-f").run
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,38 @@
1
+
2
+ �o �X �^ �u �� �� ��
3
+
4
+ C67 �o�[�W����
5
+
6
+ �y�O����z
7
+ ��N��C65�ɂ�EndEffector�́u���܂��v�Ƃ��Ď��^����Ă����o�X�^�u�꒼�����A
8
+ �P�N�̎����o�Ă����ɕ����I�i�������悤�Ȃ����ł��Ȃ��悤�ȕ��͋C�����y���݂��������B
9
+
10
+ �y�V�ѕ��z
11
+ ��������`���Ĕ��ł���l�X���A�o�X�^�u�ŃL���b�`���Ă��������B
12
+ �R��~�X��ƃQ�[���I�[�o�[�ł��B
13
+
14
+ EASY: �ȒP�ł��B
15
+ NORMAL: �ӂ‚��ł��B
16
+ ENDLESS: �u�I��肪�Ȃ��v�Ə����ăG���h���X�ł��B�O������ESC�L�[�ŏI�����Ă��������B :-P
17
+
18
+ �y����z
19
+ ���E�L�[�ňړ��B
20
+ �������́A�X�y�[�Xor�G���^�[�L�[�ŕ����]���B
21
+
22
+ �l�[���G���g���[�͍��E�ňړ��A�X�y�[�X�L�[�Ō���B�i���̓L�[�{�[�h���g���܂��j
23
+
24
+ �y�ӎ��z
25
+ �o�X�^�u�꒼����Ruby/SDL��p���Đ��삳��Aexerb��p���Ď��s�t�@�C����
26
+ ���܂����B
27
+ - �I�u�W�F�N�g�w���X�N���v�g����Ruby: http://www.ruby-lang.org/ja/
28
+ - SDL(Simple DirectMedia Layer): http://www.libsdl.org/
29
+ - Ruby/SDL: http://www.kmc.gr.jp/~ohai/rubysdl.html
30
+ - exerb: http://exerb.sourceforge.jp/
31
+
32
+ �܂��o�X�^�u�ɔ�э��ތ��ʉ���WEB WAVE LIB�l�̂��̂��g�킹�Ă�����Ă܂��B
33
+ - WEB WAVE LIB: http://www.s-t-t.com/wwl/
34
+
35
+ ----
36
+ yhara�i�� �I�j/ ����}�C�R���N���u
37
+ http://mono.kmc.gr.jp/~yhara/
38
+ mailto: yhara@kmc.gr.jp
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bathtub
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 2
10
+ version: 0.5.2
11
+ platform: ruby
12
+ authors:
13
+ - Yutaka HARA
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-28 00:00:00 +09:00
19
+ default_executable: bathtub
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rubysdl
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: An action game written with Ruby/SDL
36
+ email: yutaka.hara/at/gmail.com
37
+ executables:
38
+ - bathtub
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - SDL.dll
45
+ - SDL_mixer.dll
46
+ - SDL_ttf.dll
47
+ - SGE.dll
48
+ - VERSION
49
+ - bathtub.exe
50
+ - bathtub/character.rb
51
+ - bathtub/game.rb
52
+ - bathtub/graphic.rb
53
+ - bathtub/main.rb
54
+ - bathtub/misc.rb
55
+ - bathtub/scene.rb
56
+ - bathtub/score.rb
57
+ - bathtub/task.rb
58
+ - bin/bathtub
59
+ - highscore.dat
60
+ - image/back.bmp
61
+ - image/bath.bmp
62
+ - image/boxfont2.ttf
63
+ - image/curving.ttf
64
+ - image/hito.bmp
65
+ - image/icon-16164.bmp
66
+ - image/icon-16168.bmp
67
+ - image/icon.bmp
68
+ - image/logo.bmp
69
+ - image/shibuki.bmp
70
+ - image/staff.bmp
71
+ - msvcr71.dll
72
+ - readme.txt
73
+ - sound/BB_Scratch_19.wav
74
+ - sound/SplashA1@22.wav
75
+ - sound/Stabs110.wav
76
+ - sound/Stabs63.wav
77
+ - sound/blacksamba.it
78
+ - sound/bom08.wav
79
+ - sound/clambient.it
80
+ - sound/fall.wav
81
+ - sound/get.wav
82
+ has_rdoc: true
83
+ homepage: http://github.com/yhara/bathtub
84
+ licenses: []
85
+
86
+ post_install_message:
87
+ rdoc_options:
88
+ - --charset=UTF-8
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 3
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 3
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ requirements: []
110
+
111
+ rubyforge_project:
112
+ rubygems_version: 1.3.7
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: An action game written with Ruby/SDL
116
+ test_files: []
117
+