ruby-miyako 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/README +1115 -0
  2. data/Rakefile +7 -0
  3. data/defines.h +144 -0
  4. data/extconf.rb +44 -0
  5. data/extern.h +29 -0
  6. data/img/cursor.png +0 -0
  7. data/img/cursors.png +0 -0
  8. data/img/dice.png +0 -0
  9. data/img/wait_cursor.png +0 -0
  10. data/img/win_base.png +0 -0
  11. data/img/window.png +0 -0
  12. data/install_miyako.rb +87 -0
  13. data/lib/Miyako/API/audio.rb +584 -0
  14. data/lib/Miyako/API/basic_data.rb +1026 -0
  15. data/lib/Miyako/API/bitmap.rb +534 -0
  16. data/lib/Miyako/API/choices.rb +481 -0
  17. data/lib/Miyako/API/collision.rb +638 -0
  18. data/lib/Miyako/API/diagram.rb +586 -0
  19. data/lib/Miyako/API/drawing.rb +151 -0
  20. data/lib/Miyako/API/exceptions.rb +105 -0
  21. data/lib/Miyako/API/fixedmap.rb +462 -0
  22. data/lib/Miyako/API/font.rb +430 -0
  23. data/lib/Miyako/API/input.rb +456 -0
  24. data/lib/Miyako/API/layout.rb +644 -0
  25. data/lib/Miyako/API/map.rb +583 -0
  26. data/lib/Miyako/API/map_event.rb +222 -0
  27. data/lib/Miyako/API/modules.rb +357 -0
  28. data/lib/Miyako/API/movie.rb +166 -0
  29. data/lib/Miyako/API/parts.rb +188 -0
  30. data/lib/Miyako/API/plane.rb +205 -0
  31. data/lib/Miyako/API/screen.rb +341 -0
  32. data/lib/Miyako/API/shape.rb +443 -0
  33. data/lib/Miyako/API/sprite.rb +773 -0
  34. data/lib/Miyako/API/sprite_animation.rb +494 -0
  35. data/lib/Miyako/API/sprite_list.rb +1135 -0
  36. data/lib/Miyako/API/spriteunit.rb +168 -0
  37. data/lib/Miyako/API/story.rb +350 -0
  38. data/lib/Miyako/API/textbox.rb +773 -0
  39. data/lib/Miyako/API/utility.rb +419 -0
  40. data/lib/Miyako/API/viewport.rb +190 -0
  41. data/lib/Miyako/API/yuki.rb +1180 -0
  42. data/lib/Miyako/EXT/miyako_cairo.rb +62 -0
  43. data/lib/Miyako/EXT/raster_scroll.rb +138 -0
  44. data/lib/Miyako/EXT/slides.rb +157 -0
  45. data/lib/Miyako/miyako.rb +201 -0
  46. data/lib/Miyako/miyako_require_only.rb +35 -0
  47. data/logo/EGSR_logo.png +0 -0
  48. data/logo/EGSR_logo_bg.png +0 -0
  49. data/logo/EGSR_logo_fg.png +0 -0
  50. data/logo/EGSR_title_banner.png +0 -0
  51. data/logo/EGSR_title_logo.png +0 -0
  52. data/logo/miyako.png +0 -0
  53. data/logo/miyako_banner.png +0 -0
  54. data/logo/space.png +0 -0
  55. data/miyako_basicdata.c +484 -0
  56. data/miyako_bitmap.c +1225 -0
  57. data/miyako_collision.c +403 -0
  58. data/miyako_drawing.c +187 -0
  59. data/miyako_font.c +334 -0
  60. data/miyako_hsv.c +830 -0
  61. data/miyako_input_audio.c +254 -0
  62. data/miyako_layout.c +191 -0
  63. data/miyako_no_katana.c +1086 -0
  64. data/miyako_sprite2.c +431 -0
  65. data/miyako_transform.c +438 -0
  66. data/miyako_utility.c +288 -0
  67. data/sample/Animation1/m1ku.rb +68 -0
  68. data/sample/Animation1/m1ku_arm_0.png +0 -0
  69. data/sample/Animation1/m1ku_arm_1.png +0 -0
  70. data/sample/Animation1/m1ku_arm_2.png +0 -0
  71. data/sample/Animation1/m1ku_arm_3.png +0 -0
  72. data/sample/Animation1/m1ku_back.jpg +0 -0
  73. data/sample/Animation1/m1ku_body.png +0 -0
  74. data/sample/Animation1/m1ku_eye_0.png +0 -0
  75. data/sample/Animation1/m1ku_eye_1.png +0 -0
  76. data/sample/Animation1/m1ku_eye_2.png +0 -0
  77. data/sample/Animation1/m1ku_eye_3.png +0 -0
  78. data/sample/Animation1/m1ku_hair_front.png +0 -0
  79. data/sample/Animation1/m1ku_hair_rear.png +0 -0
  80. data/sample/Animation1/readme.txt +72 -0
  81. data/sample/Animation2/lex.rb +96 -0
  82. data/sample/Animation2/lex_back.png +0 -0
  83. data/sample/Animation2/lex_body.png +0 -0
  84. data/sample/Animation2/lex_roadroller.png +0 -0
  85. data/sample/Animation2/lex_wheel_0.png +0 -0
  86. data/sample/Animation2/lex_wheel_1.png +0 -0
  87. data/sample/Animation2/lex_wheel_2.png +0 -0
  88. data/sample/Animation2/readme.txt +72 -0
  89. data/sample/Animation2/song_title.png +0 -0
  90. data/sample/Diagram_sample/back.png +0 -0
  91. data/sample/Diagram_sample/chr01.png +0 -0
  92. data/sample/Diagram_sample/chr02.png +0 -0
  93. data/sample/Diagram_sample/cursor.png +0 -0
  94. data/sample/Diagram_sample/diagram_sample_yuki2.rb +329 -0
  95. data/sample/Diagram_sample/readme.txt +90 -0
  96. data/sample/Diagram_sample/wait_cursor.png +0 -0
  97. data/sample/Room3/blue.rb +297 -0
  98. data/sample/Room3/ending.rb +180 -0
  99. data/sample/Room3/green.rb +220 -0
  100. data/sample/Room3/image/akamatsu.png +0 -0
  101. data/sample/Room3/image/aoyama.png +0 -0
  102. data/sample/Room3/image/congra.png +0 -0
  103. data/sample/Room3/image/congratulation.png +0 -0
  104. data/sample/Room3/image/congratulation_bg.png +0 -0
  105. data/sample/Room3/image/cursor.png +0 -0
  106. data/sample/Room3/image/midori.png +0 -0
  107. data/sample/Room3/image/mittsu_no_oheya.png +0 -0
  108. data/sample/Room3/image/mittsu_no_oheya_logo.png +0 -0
  109. data/sample/Room3/image/room_blue.png +0 -0
  110. data/sample/Room3/image/room_green.png +0 -0
  111. data/sample/Room3/image/room_red.png +0 -0
  112. data/sample/Room3/image/start.png +0 -0
  113. data/sample/Room3/image/three_doors.png +0 -0
  114. data/sample/Room3/image/wait_cursor.png +0 -0
  115. data/sample/Room3/main.rb +120 -0
  116. data/sample/Room3/main_component.rb +59 -0
  117. data/sample/Room3/readme.txt +76 -0
  118. data/sample/Room3/red.rb +227 -0
  119. data/sample/Room3/room3.rb +25 -0
  120. data/sample/Room3/title.rb +184 -0
  121. data/sample/ball_action_sample.rb +204 -0
  122. data/sample/blit_rop.rb +70 -0
  123. data/sample/cairo_sample.rb +25 -0
  124. data/sample/circle_collision_test.rb +66 -0
  125. data/sample/collision_test.rb +33 -0
  126. data/sample/collision_test2.rb +108 -0
  127. data/sample/fixed_map_test/cursor.png +0 -0
  128. data/sample/fixed_map_test/fixed_map_sample.rb +140 -0
  129. data/sample/fixed_map_test/map.csv +19 -0
  130. data/sample/fixed_map_test/map_01.png +0 -0
  131. data/sample/fixed_map_test/mapchip.csv +23 -0
  132. data/sample/fixed_map_test/monster.png +0 -0
  133. data/sample/fixed_map_test/readme.txt +72 -0
  134. data/sample/map_test/chara.rb +58 -0
  135. data/sample/map_test/chr1.png +0 -0
  136. data/sample/map_test/cursor.png +0 -0
  137. data/sample/map_test/main_parts.rb +69 -0
  138. data/sample/map_test/main_scene.rb +153 -0
  139. data/sample/map_test/map.png +0 -0
  140. data/sample/map_test/map2.png +0 -0
  141. data/sample/map_test/map_layer.csv +127 -0
  142. data/sample/map_test/map_manager.rb +75 -0
  143. data/sample/map_test/map_test.rb +23 -0
  144. data/sample/map_test/mapchip.csv +21 -0
  145. data/sample/map_test/oasis.rb +71 -0
  146. data/sample/map_test/readme.txt +89 -0
  147. data/sample/map_test/route.rb +157 -0
  148. data/sample/map_test/sea.png +0 -0
  149. data/sample/map_test/town.rb +74 -0
  150. data/sample/map_test/wait_cursor.png +0 -0
  151. data/sample/map_test/window.png +0 -0
  152. data/sample/polygon_test.rb +35 -0
  153. data/sample/rasterscroll.rb +25 -0
  154. data/sample/takahashi.rb +42 -0
  155. data/sample/text.png +0 -0
  156. data/sample/textbox_sample.rb +192 -0
  157. data/sample/transform.rb +54 -0
  158. data/sample/utility_test.rb +73 -0
  159. data/sample/utility_test2.rb +61 -0
  160. data/sample/utility_test3.rb +64 -0
  161. data/sample/utility_test4.rb +73 -0
  162. data/uninstall_miyako.rb +19 -0
  163. data/win/miyako_no_katana.so +0 -0
  164. metadata +216 -0
@@ -0,0 +1,168 @@
1
+ # -*- encoding: utf-8 -*-
2
+ =begin
3
+ --
4
+ Miyako v2.1
5
+ Copyright (C) 2007-2009 Cyross Makoto
6
+
7
+ This library is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU Lesser General Public
9
+ License as published by the Free Software Foundation; either
10
+ version 2.1 of the License, or (at your option) any later version.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public
18
+ License along with this library; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ ++
21
+ =end
22
+
23
+ # スプライト関連クラス群
24
+ module Miyako
25
+ #==SpriteUnitを生成するための構造体クラス
26
+ #Structクラスからの継承
27
+ #--
28
+ #SpriteUnit = Struct.new(:bitmap, :ox, :oy, :ow, :oh, :x, :y, :cx, :cy)
29
+ #++
30
+ class SpriteUnitBase < Struct
31
+ #===位置を変更する(変化量を指定)
32
+ #位置を右方向へdxピクセル、下方向へdyピクセル移動する
33
+ #ブロックを渡すと、ブロック評価中の位置を変更する
34
+ #_dx_:: 移動量(x方向)。単位はピクセル
35
+ #_dy_:: 移動量(y方向)。単位はピクセル
36
+ #返却値:: 自分自身を返す
37
+ def move!(dx, dy)
38
+ o = [self.x, self.y]
39
+ self.x+=dx
40
+ self.y+=dy
41
+ if block_given?
42
+ yield
43
+ self.x, self.y = o
44
+ end
45
+ return self
46
+ end
47
+
48
+ #===位置を変更する(位置指定)
49
+ #左上を(0.0)として、位置を右xピクセル、下yピクセルの位置移動する
50
+ #ブロックを渡すと、ブロック評価中の位置を変更する
51
+ #_x_:: 移動先位置(x方向)。単位はピクセル
52
+ #_y_:: 移動先位置(y方向)。単位はピクセル
53
+ #返却値:: 自分自身を返す
54
+ def move_to!(x, y)
55
+ o = [self.x, self.y]
56
+ self.x=x
57
+ self.y=y
58
+ if block_given?
59
+ yield
60
+ self.x, self.y = o
61
+ end
62
+ return self
63
+ end
64
+
65
+ #===位置を変更したときの値を求める(変化量を指定)
66
+ #位置を右方向へdxピクセル、下方向へdyピクセル移動する
67
+ #そのときの値をPosition構造体のインスタンスとして返す
68
+ #ただし、そのときの値が得られるだけで、自信の値に変更はない
69
+ #_dx_:: 移動量(x方向)。単位はピクセル
70
+ #_dy_:: 移動量(y方向)。単位はピクセル
71
+ #返却値:: 更新した位置を示すPosition構造体のインスタンス
72
+ def move(dx, dy)
73
+ Position.new(self.x+dx, self.y+dy)
74
+ end
75
+
76
+ #===位置を変更したときの値を求める(位置指定)
77
+ #左上を(0.0)として、位置を右xピクセル、下yピクセルの位置移動する
78
+ #そのときの値をPosition構造体のインスタンスとして返す
79
+ #ただし、そのときの値が得られるだけで、自信の値に変更はない
80
+ #_x_:: 移動先位置(x方向)。単位はピクセル
81
+ #_y_:: 移動先位置(y方向)。単位はピクセル
82
+ #返却値:: 更新した位置を示すPosition構造体のインスタンス
83
+ def move_to(x, y)
84
+ Position.new(x, y)
85
+ end
86
+
87
+ #===自分自身を返す
88
+ #SpriteUnit対応
89
+ #ダックタイピング用のメソッド
90
+ #得られるインスタンスは複写していないので、インスタンスの値を調整するには、dupメソッドで複製する必要がある
91
+ #返却値:: 自分自身
92
+ def to_unit
93
+ return self
94
+ end
95
+
96
+ #===スプライトを生成して返す
97
+ #ダックタイピング用のメソッド
98
+ #所持しているSpriteUnitから、Spriteクラスのインスタンスを生成する
99
+ #但し、bitmapの設定は:type=>:alpha_channelのみ
100
+ #引数1個のブロックを渡せば、スプライトに補正をかけることが出来る
101
+ #返却値:: 生成したスプライト
102
+ def to_sprite
103
+ sprite = Sprite.new(:unit=>self, :type=>:ac)
104
+ yield sprite if block_given?
105
+ return sprite
106
+ end
107
+
108
+ #===画像の表示矩形を取得する
109
+ #画像が表示されているときの矩形を取得する。矩形は、[x,y,ow,oh]で取得する。
110
+ #返却値:: 生成された矩形
111
+ def rect
112
+ return Rect.new(self.x, self.y, self.ow, self.oh)
113
+ end
114
+
115
+ #===現在の画面の最大の大きさを矩形で取得する
116
+ #但し、SpriteUnitの場合は最大の大きさ=画像の大きさなので、rectと同じ値が得られる
117
+ #返却値:: 画像の大きさ(Rect構造体のインスタンス)
118
+ def broad_rect
119
+ return self.rect
120
+ end
121
+ end
122
+
123
+ #==スプライト出力情報構造体
124
+ #基本的なことは、Sprite.renderで行うことが出来るが、凝った処理を行う場合は、SpriteUnitを使う
125
+ #--
126
+ #SpriteUnit = Struct.new([:dp], :bitmap, :ox, :oy, :ow, :oh, :x, :y, :cx, :cy)
127
+ #++
128
+ #([数字])は、配列として認識したときのインデックス番号に対応(Struct#[]メソッドを呼び出した時のインデックス)
129
+ #:bitmap([0]) -> 画像データ(SDL::Surfaceクラスのインスタンス)
130
+ #:ox([1]) -> 描画開始位置(x方向)
131
+ #:oy([2]) -> 描画開始位置(y方向)
132
+ #:ow([3]) -> 描画幅
133
+ #:oh([4]) -> 描画高さ
134
+ #:x([5]) -> 描画幅
135
+ #:y([6]) -> 描画高さ
136
+ #:cx([7]) -> 回転・拡大・縮小・鏡像の中心座標(x方向)
137
+ #:cy([8]) -> 回転・拡大・縮小・鏡像の中心座標(y方向)
138
+ SpriteUnit = SpriteUnitBase.new(:bitmap, :ox, :oy, :ow, :oh, :x, :y, :cx, :cy)
139
+
140
+ #==SpriteUnit生成ファクトリクラス
141
+ #SpriteUnit構造体のインスタンスを生成するためのクラス
142
+ class SpriteUnitFactory
143
+ PARAMS = [:bitmap, :ox, :oy, :ow, :oh, :x, :y, :cx, :cy]
144
+ #==SpriteUnitのインスタンスを生成する
145
+ #params: 初期化するSpriteUnit構造体の値。ハッシュ引数。引数のキーは、SpriteUnitのアクセサ名と同一。省略可能
146
+ def SpriteUnitFactory.create(params = nil)
147
+ unit = SpriteUnit.new(nil, 0, 0, 0, 0, 0, 0, 0, 0)
148
+ return SpriteUnitFactory.apply(unit, params)
149
+ end
150
+
151
+ #==SpriteUnitの各アクセサに対応した値を設定する
152
+ #(注)bitmapアクセサに値を設定する場合、ox,oy,ow,ohの値が自動的に、
153
+ #bitmapに対応する値(ox=0,oy=0,ow=bitmap.w,oh=bitmap.h)が設定される
154
+ #unit: 設定対象のSpriteUnit構造体
155
+ #params: 設定するSpriteUnit構造体の値。ハッシュ引数。引数のキーは、SpriteUnitのアクセサ名と同一
156
+ def SpriteUnitFactory.apply(unit, params)
157
+ if params && params.has_key?(:bitmap)
158
+ unit.bitmap = params[:bitmap]
159
+ unit.ox = 0
160
+ unit.oy = 0
161
+ unit.ow = unit.bitmap.w
162
+ unit.oh = unit.bitmap.h
163
+ end
164
+ PARAMS.each{|prm| unit[prm] = params[prm] if params.has_key?(prm) } if params
165
+ return unit
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,350 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ =begin
4
+ --
5
+ Miyako v2.1
6
+ Copyright (C) 2007-2009 Cyross Makoto
7
+
8
+ This library is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU Lesser General Public
10
+ License as published by the Free Software Foundation; either
11
+ version 2.1 of the License, or (at your option) any later version.
12
+
13
+ This library is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
+ Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public
19
+ License along with this library; if not, write to the Free Software
20
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
+ ++
22
+ =end
23
+
24
+ require 'singleton'
25
+
26
+ module Miyako
27
+ #==シーン実行クラス
28
+ #用意したシーンインスタンスを実行
29
+ class Story
30
+
31
+ @@sub_scenes = [:sub_scene, :sub_routine]
32
+ @@over_scenes = [:over_scene]
33
+
34
+ def prev_label #:nodoc:
35
+ return @prev_label
36
+ end
37
+
38
+ def next_label #:nodoc:
39
+ return @next_label
40
+ end
41
+
42
+ def upper_label #:nodoc:
43
+ return @stack.empty? ? nil : @stack.last[0]
44
+ end
45
+
46
+ #===インスタンスの作成
47
+ #ストーリー情報の初期か
48
+ #返却値:: 生成したインスタンス
49
+ def initialize
50
+ @prev_label = nil
51
+ @next_label = nil
52
+
53
+ @stack = []
54
+ @fibers = [nil]
55
+
56
+ @scene_cache = Hash.new
57
+ @scene_cache_list = Array.new
58
+ @scene_cache_max = 20
59
+
60
+ @fiber = Proc.new{|sc, num|
61
+ raise MiyakoValueError, "Illegal Script-label name! : #{sc}" unless Scene.has_scene?(sc.to_s)
62
+ fnum = nil
63
+ bk_nn = sc
64
+ uu = sc.new(self)
65
+ uu.init_inner(@prev_label, self.upper_label)
66
+ uu.setup
67
+ ret = true
68
+ while ret do
69
+ nn = uu.update
70
+ uu.render
71
+ if fnum && @fibers[fnum]
72
+ @fibers[fnum].resume(true)
73
+ elsif nn && !(nn.eql?(uu.class)) && @@over_scenes.include?(nn.scene_type)
74
+ @fibers << Fiber.new(&@fiber)
75
+ fnum = @fibers.length - 1
76
+ @fibers[fnum].resume(nn, fnum)
77
+ n = bk_nn
78
+ end
79
+ break unless nn
80
+ ret = Fiber.yield
81
+ end
82
+ uu.final
83
+ uu.dispose
84
+ if (fnum && @fibers[fnum])
85
+ @fibers[fnum].resume(nil)
86
+ @fibers[fnum] = nil
87
+ fnum = nil
88
+ end
89
+ @fibers[num] = nil
90
+ }
91
+ end
92
+
93
+ def initialize_copy(obj) #:nodoc:
94
+ @stack = @stack.dup
95
+ @fibers = @fibers.dup
96
+ @scene_cache = @scene_cache.dup
97
+ @scene_cache_list = @scene_cache_list.dup
98
+ end
99
+
100
+ def get_scene(n, s) #:nodoc:
101
+ class_symbol = n.to_s
102
+ if @scene_cache_list.length == @scene_cache_max
103
+ del_symbol = @scene_cache_list.shift
104
+ @scene_cache[del_symbol].dispose
105
+ @scene_cache.delete(del_symbol)
106
+ end
107
+ @scene_cache_list.delete(class_symbol)
108
+ @scene_cache_list.push(class_symbol)
109
+ @scene_cache[class_symbol] ||= n.new(self)
110
+ return @scene_cache[class_symbol]
111
+ end
112
+
113
+ #===Storyの実行を始める
114
+ #"obj.run(MainScene)"と記述すると、SceneモジュールをmixinしたMainSceneクラスのインスタンスを作成し、評価を始める
115
+ #_n_:: 最初に実行するシーン名(クラス名を定数で)
116
+ def run(n)
117
+ return nil if n == nil
118
+ u = nil
119
+ on = nil
120
+ @stack = Array.new # reset
121
+ while n != nil
122
+ @prev_label = on
123
+ on = n
124
+
125
+ raise MiyakoValueError, "Illegal Script-label name! : #{n}" unless Scene.has_scene?(n.to_s)
126
+ raise MiyakoValueError, "This scene cannot use for Standard Scene! : #{n}" if n.scene_type != :scene
127
+ u = get_scene(n, @stack.size) if u == nil
128
+ u.init_inner(@prev_label, self.upper_label)
129
+ u.setup
130
+
131
+ loop do
132
+ Audio.update
133
+ Input.update
134
+ Screen.clear
135
+ bk_n = on
136
+ n = u.update
137
+ u.render
138
+ if @fibers.first
139
+ raise MiyakoError, "Double over scene from root!" if n && @@over_scenes.include?(n.scene_type)
140
+ @fibers.first.resume(true, 0)
141
+ elsif n && @@over_scenes.include?(n.scene_type)
142
+ @fibers.clear
143
+ @fibers << Fiber.new(&@fiber)
144
+ @fibers.first.resume(n, 0)
145
+ n = bk_n
146
+ end
147
+ Screen.render
148
+ break unless n && on.eql?(n)
149
+ end
150
+ u.next = n
151
+ @next_label = n
152
+ u.final
153
+ if n.nil?
154
+ if @@sub_scenes.include?(u.class.scene_type) && @stack.empty? == false
155
+ n, u = @stack.pop
156
+ next
157
+ end
158
+ break
159
+ elsif @@sub_scenes.include?(n.scene_type)
160
+ @stack.push([on, u])
161
+ u = nil
162
+ else
163
+ u = nil
164
+ end
165
+ end
166
+ @fibers.each{|fiber| fiber.resume(nil) if fiber } if @fibers.length > 0
167
+ @scene_cache_list.each{|sy| @scene_cache[sy].dispose }
168
+ @scene_cache.clear
169
+ @scene_cache_list.clear
170
+ end
171
+
172
+ #==="over_scene"形式のシーンが実行中かどうか判別する
173
+ #返却値:: "over_scene"形式のシーンが実行中の時はtrueを返す
174
+ def over_scene_execute?
175
+ return @now_fiber != nil
176
+ end
177
+
178
+ #===内部の情報を解放する
179
+ def dispose
180
+ @scene_cache.keys.each{|k| @scene_cache[del_symbol].dispose }
181
+ end
182
+
183
+ #==シーン情報格納のための構造体
184
+ ScenePool = Struct.new(:story, :prev, :next, :upper)
185
+
186
+ #==シーンモジュール
187
+ #本モジュールをmixinすることにより、シーンを示すインスタンスを作成することができる
188
+ #mixinするときに気をつけなければいけないのは、本モジュールでは以下の
189
+ #モジュール変数を
190
+ #予約しているため、これらの変数の値を勝手に変えてはいけない
191
+ #・@@scenesモジュール変数(シーンクラス一覧が入っているハッシュ)
192
+ #・@@poolモジュール変数(シーン情報が入っているハッシュ)
193
+ #(互換性のために@nowを残しているが、now_sceneのみを使うときは値を上書きしてもかまわない))
194
+ #また、シーンには「シーン形式」がある。
195
+ #種類は、シーケンスな移動が出来る「通常シーン」、終了したときに移動元に戻る「サブシーン」、
196
+ #現在実行中のシーン上で並行に実行する「オーバーシーン」の3種類。
197
+ #デフォルトは「通常シーン」となっている。
198
+ #判別は、scene_typeクラスメソッドを呼び出すことで可能。デフォルトは、
199
+ #通常シーンを示すシンボル":scene"が返る。
200
+ #形式を変えるには、scene_typeクラスメソッドをオーバーライドし、返却値を変える。
201
+ #サブシーンの時はシンボル":sub_scene"、オーバーシーンのときは
202
+ #シンボル":over_scene"を返すように実装する
203
+ #(注1)同じクラス名のシーンを繰り返し実行したいときは、いったん別のダミーシーンを
204
+ #介してから元のシーンへ移動する必要がある
205
+ #(注2)オーバーシーン内では、シーンの移動が出来ないが、入れ子形式で
206
+ #別のオーバーシーンを積み上げる形なら移動可能。
207
+ module Scene
208
+ @@scenes = {}
209
+ @@pool = {}
210
+
211
+ def Scene.included(c) #:nodoc:
212
+ unless c.singleton_methods.include?(:scene_type)
213
+ def c.scene_type
214
+ return :scene
215
+ end
216
+ end
217
+ @@scenes[c.to_s] = c
218
+ end
219
+
220
+ def Scene.scenes #:nodoc:
221
+ return @@scenes
222
+ end
223
+
224
+ def Scene.has_scene?(s) #:nodoc:
225
+ return @@scenes.has_key?(s)
226
+ end
227
+
228
+ def initialize(story, check_only=false) #:nodoc:
229
+ return if check_only
230
+ @@pool[self.object_id] = ScenePool.new(story, nil, nil, nil)
231
+ @now = self.now_scene
232
+ self.init
233
+ end
234
+
235
+ def init_inner(p, u) #:nodoc:
236
+ @@pool[self.object_id].prev = p
237
+ @@pool[self.object_id].upper = u
238
+ end
239
+
240
+ #===前回実行したシーンを返す
241
+ #前回実行しているシーンをクラス名で返す
242
+ #但し、最初のシーンの場合はnilを返す
243
+ #返却値:: 前回実行したシーン名(Classクラスインスタンス)
244
+ def story
245
+ return @@pool[self.object_id].story
246
+ end
247
+
248
+ #===サブルーチンの呼び元シーンを返す
249
+ #サブルーチンを呼び出したシーンをクラス名で返す
250
+ #サブルーチンではないときはnilを返す
251
+ #返却値:: 前回実行したシーン名(Classクラスインスタンス)
252
+ def upper_scene
253
+ return @@pool[self.object_id].upper
254
+ end
255
+
256
+ def next_scene #:nodoc:
257
+ return @@pool[self.object_id].next
258
+ end
259
+
260
+ #===前回実行したシーンを返す
261
+ #前回実行しているシーンをクラス名で返す
262
+ #但し、最初のシーンの場合はnilを返す
263
+ #返却値:: 前回実行したシーン名(Classクラスインスタンス)
264
+ def prev_scene
265
+ return @@pool[self.object_id].prev
266
+ end
267
+
268
+ #===現在実行中のシーンを返す
269
+ #現在実行しているシーンをクラス名で返す
270
+ #返却値:: 前回実行したシーン名(Classクラスインスタンス)
271
+ def now_scene
272
+ return self.class
273
+ end
274
+
275
+ #===シーン内で使用するオブジェクトの初期化テンプレートメソッド
276
+ #シーン内で使用するインスタンスを生成するときなどにこのメソッドを実装する
277
+ def init
278
+ end
279
+
280
+ #===シーン内で使用するオブジェクトの初期設定テンプレートメソッド
281
+ #シーン内で使用するインスタンスの設定を行うときにこのメソッドを実装する
282
+ #(シーン生成時に生成したインスタンスはキャッシュされ、再利用することができることに注意)
283
+ def setup
284
+ end
285
+
286
+ #===シーンの情報を更新するテンプレートメソッド
287
+ #
288
+ #現在実行しているシーンを繰り返し実行する場合はインスタンス変数@nowを返すように実装する
289
+ #nilを返すとシーンの処理を終了する(元のStory#runメソッド呼び出しの次に処理が移る)
290
+ #但し、scene_typeメソッドの結果が:sub_routneのとき、移動元シーンに戻る
291
+ #返却値:: 移動先シーンクラス
292
+ def update
293
+ return now_scene
294
+ end
295
+
296
+ #===シーンで指定しているインスタンスを画面に描画するテンプレートメソッド
297
+ def render
298
+ end
299
+
300
+ #===シーン内で使用したオブジェクトの後始末を行うテンプレートメソッド
301
+ #ここでは、解放処理(dispose)ではなく、終了処理(値を変更するなど)に実装する
302
+ #setupメソッドと対になっているというイメージ
303
+ def final
304
+ end
305
+
306
+ #===シーンに使用したデータの解放を記述するテンプレートメソッド
307
+ #initメソッドと対になっているというイメージ
308
+ def dispose
309
+ end
310
+
311
+ def next=(label) #:nodoc:
312
+ @@pool[self.object_id].next = label
313
+ end
314
+
315
+ #==="over_scene"形式のシーンが実行中かどうか判別する
316
+ #返却値:: "over_scene"形式のシーンが実行中の時はtrueを返す
317
+ def over_scene_execute?
318
+ return @story.over_scene_execute?
319
+ end
320
+
321
+ #===シーンの解説を返す(テンプレートメソッド)
322
+ #Sceneモジュールをmixinしたとき、解説文を返す実装をしておくと、
323
+ #Scene.#lisutupメソッドを呼び出したときに、noticeメソッドの結果を取得できる
324
+ #返却値:: シーンの解説(文字列)
325
+ def notice
326
+ return ""
327
+ end
328
+
329
+ #===登録しているシーン一覧をリストアップする
330
+ #リストの内容は、"シーンクラス名(文字列),シーンクラス(ポインタ),
331
+ #解説(noticeメソッドの内容)"という書式で取得できる
332
+ #返却値:: リストアップしたシーンの配列
333
+ def Scene.listup
334
+ list = Array.new
335
+ sns = @@scenes
336
+ sns.keys.sort.each{|k| list.push("#{k}, #{sns[k]}, \"#{sns[k].notice}\"\n") }
337
+ return list
338
+ end
339
+
340
+ #===Scene.#listupメソッドの内容をCSVファイルに保存する
341
+ #_csvname_:: 保存するCSVファイルパス
342
+ def Scene.listup2csv(csvfname)
343
+ csvfname += ".csv" if csvfname !~ /\.csv$/
344
+ list = self.listup
345
+ File.open(csvfname, "w"){|f| list.each{|l| f.print l } }
346
+ end
347
+
348
+ end
349
+ end
350
+ end