bathtub 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
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
+