cyross-ruby-miyako 2.0.0

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.
Files changed (125) hide show
  1. data/README +977 -0
  2. data/Rakefile +7 -0
  3. data/img/cursor.png +0 -0
  4. data/img/cursors.png +0 -0
  5. data/img/dice.png +0 -0
  6. data/img/wait_cursor.png +0 -0
  7. data/img/win_base.png +0 -0
  8. data/img/window.png +0 -0
  9. data/install_miyako.rb +75 -0
  10. data/lib/Miyako/API/audio.rb +198 -0
  11. data/lib/Miyako/API/basic_data.rb +431 -0
  12. data/lib/Miyako/API/bitmap.rb +35 -0
  13. data/lib/Miyako/API/choices.rb +308 -0
  14. data/lib/Miyako/API/collision.rb +444 -0
  15. data/lib/Miyako/API/diagram.rb +573 -0
  16. data/lib/Miyako/API/drawing.rb +110 -0
  17. data/lib/Miyako/API/fixedmap.rb +315 -0
  18. data/lib/Miyako/API/font.rb +384 -0
  19. data/lib/Miyako/API/input.rb +440 -0
  20. data/lib/Miyako/API/layout.rb +451 -0
  21. data/lib/Miyako/API/map.rb +403 -0
  22. data/lib/Miyako/API/map_event.rb +198 -0
  23. data/lib/Miyako/API/modules.rb +109 -0
  24. data/lib/Miyako/API/movie.rb +151 -0
  25. data/lib/Miyako/API/parts.rb +154 -0
  26. data/lib/Miyako/API/plane.rb +131 -0
  27. data/lib/Miyako/API/screen.rb +257 -0
  28. data/lib/Miyako/API/shape.rb +362 -0
  29. data/lib/Miyako/API/sprite.rb +338 -0
  30. data/lib/Miyako/API/sprite_animation.rb +461 -0
  31. data/lib/Miyako/API/spriteunit.rb +113 -0
  32. data/lib/Miyako/API/story.rb +224 -0
  33. data/lib/Miyako/API/textbox.rb +496 -0
  34. data/lib/Miyako/API/viewport.rb +435 -0
  35. data/lib/Miyako/API/yuki.rb +779 -0
  36. data/lib/Miyako/EXT/miyako_cairo.rb +60 -0
  37. data/lib/Miyako/EXT/raster_scroll.rb +138 -0
  38. data/lib/Miyako/EXT/slides.rb +136 -0
  39. data/lib/Miyako/miyako.rb +172 -0
  40. data/miyako.png +0 -0
  41. data/miyako_banner.png +0 -0
  42. data/miyako_no_katana/extconf.rb +34 -0
  43. data/miyako_no_katana/miyako_no_katana.c +3301 -0
  44. data/sample/Animation1/m1ku.rb +89 -0
  45. data/sample/Animation1/m1ku_arm_0.png +0 -0
  46. data/sample/Animation1/m1ku_arm_1.png +0 -0
  47. data/sample/Animation1/m1ku_arm_2.png +0 -0
  48. data/sample/Animation1/m1ku_arm_3.png +0 -0
  49. data/sample/Animation1/m1ku_back.jpg +0 -0
  50. data/sample/Animation1/m1ku_body.png +0 -0
  51. data/sample/Animation1/m1ku_eye_0.png +0 -0
  52. data/sample/Animation1/m1ku_eye_1.png +0 -0
  53. data/sample/Animation1/m1ku_eye_2.png +0 -0
  54. data/sample/Animation1/m1ku_eye_3.png +0 -0
  55. data/sample/Animation1/m1ku_hair_front.png +0 -0
  56. data/sample/Animation1/m1ku_hair_rear.png +0 -0
  57. data/sample/Animation1/readme.txt +72 -0
  58. data/sample/Animation2/lex.rb +95 -0
  59. data/sample/Animation2/lex_back.png +0 -0
  60. data/sample/Animation2/lex_body.png +0 -0
  61. data/sample/Animation2/lex_roadroller.png +0 -0
  62. data/sample/Animation2/lex_wheel_0.png +0 -0
  63. data/sample/Animation2/lex_wheel_1.png +0 -0
  64. data/sample/Animation2/lex_wheel_2.png +0 -0
  65. data/sample/Animation2/readme.txt +72 -0
  66. data/sample/Animation2/song_title.png +0 -0
  67. data/sample/Diagram_sample/back.png +0 -0
  68. data/sample/Diagram_sample/chr01.png +0 -0
  69. data/sample/Diagram_sample/chr02.png +0 -0
  70. data/sample/Diagram_sample/cursor.png +0 -0
  71. data/sample/Diagram_sample/diagram_sample_yuki2.rb +283 -0
  72. data/sample/Diagram_sample/readme.txt +87 -0
  73. data/sample/Diagram_sample/wait_cursor.png +0 -0
  74. data/sample/Room3/blue.rb +250 -0
  75. data/sample/Room3/ending.rb +175 -0
  76. data/sample/Room3/green.rb +185 -0
  77. data/sample/Room3/image/akamatsu.png +0 -0
  78. data/sample/Room3/image/aoyama.png +0 -0
  79. data/sample/Room3/image/congra.png +0 -0
  80. data/sample/Room3/image/congratulation.png +0 -0
  81. data/sample/Room3/image/congratulation_bg.png +0 -0
  82. data/sample/Room3/image/cursor.png +0 -0
  83. data/sample/Room3/image/midori.png +0 -0
  84. data/sample/Room3/image/mittsu_no_oheya.png +0 -0
  85. data/sample/Room3/image/mittsu_no_oheya_logo.png +0 -0
  86. data/sample/Room3/image/room_blue.png +0 -0
  87. data/sample/Room3/image/room_green.png +0 -0
  88. data/sample/Room3/image/room_red.png +0 -0
  89. data/sample/Room3/image/start.png +0 -0
  90. data/sample/Room3/image/three_doors.png +0 -0
  91. data/sample/Room3/image/wait_cursor.png +0 -0
  92. data/sample/Room3/main.rb +102 -0
  93. data/sample/Room3/main_component.rb +58 -0
  94. data/sample/Room3/readme.txt +76 -0
  95. data/sample/Room3/red.rb +200 -0
  96. data/sample/Room3/room3.rb +26 -0
  97. data/sample/Room3/title.rb +171 -0
  98. data/sample/fixed_map_test/cursor.png +0 -0
  99. data/sample/fixed_map_test/fixed_map_sample.rb +149 -0
  100. data/sample/fixed_map_test/map.csv +19 -0
  101. data/sample/fixed_map_test/map_01.png +0 -0
  102. data/sample/fixed_map_test/map_sample.rb +121 -0
  103. data/sample/fixed_map_test/mapchip.csv +23 -0
  104. data/sample/fixed_map_test/monster.png +0 -0
  105. data/sample/fixed_map_test/readme.txt +72 -0
  106. data/sample/map_test/chara.rb +50 -0
  107. data/sample/map_test/chr1.png +0 -0
  108. data/sample/map_test/cursor.png +0 -0
  109. data/sample/map_test/main_parts.rb +48 -0
  110. data/sample/map_test/main_scene.rb +137 -0
  111. data/sample/map_test/map.png +0 -0
  112. data/sample/map_test/map2.png +0 -0
  113. data/sample/map_test/map_layer.csv +127 -0
  114. data/sample/map_test/map_manager.rb +92 -0
  115. data/sample/map_test/map_test.rb +23 -0
  116. data/sample/map_test/mapchip.csv +21 -0
  117. data/sample/map_test/oasis.rb +65 -0
  118. data/sample/map_test/readme.txt +87 -0
  119. data/sample/map_test/route.rb +144 -0
  120. data/sample/map_test/sea.png +0 -0
  121. data/sample/map_test/town.rb +68 -0
  122. data/sample/map_test/wait_cursor.png +0 -0
  123. data/sample/map_test/window.png +0 -0
  124. data/win/miyako_no_katana.so +0 -0
  125. metadata +194 -0
@@ -0,0 +1,224 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ =begin
4
+ --
5
+ Miyako v2.0
6
+ Copyright (C) 2007-2008 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
+ module Miyako
25
+
26
+ #==シーン実行クラス
27
+ #用意したシーンインスタンスを実行
28
+ class Story
29
+ #===あとで書く
30
+ #返却値:: あとで書く
31
+ def prev_label
32
+ return @prev_label
33
+ end
34
+
35
+ #===あとで書く
36
+ #返却値:: あとで書く
37
+ def next_label
38
+ return @next_label
39
+ end
40
+
41
+ #===あとで書く
42
+ #返却値:: あとで書く
43
+ def upper_label
44
+ return @stack.empty? ? nil : @stack.last[0]
45
+ end
46
+
47
+ #===インスタンスの作成
48
+ #
49
+ #返却値:: あとで書く
50
+ def initialize
51
+ @prev_label = nil
52
+ @next_label = nil
53
+
54
+ @stack = Array.new
55
+
56
+ @scene_cache = Hash.new
57
+ @scene_cache_list = Array.new
58
+ @scene_cache_max = 20
59
+ end
60
+
61
+ def get_scene(n, s) #:nodoc:
62
+ class_symbol = n.to_s
63
+ if @scene_cache_list.length == @scene_cache_max
64
+ del_symbol = @scene_cache_list.shift
65
+ @scene_cache[del_symbol].dispose
66
+ @scene_cache.delete(del_symbol)
67
+ end
68
+ @scene_cache_list.delete(class_symbol)
69
+ @scene_cache_list.push(class_symbol)
70
+ @scene_cache[class_symbol] ||= n.new(self)
71
+ return @scene_cache[class_symbol]
72
+ end
73
+
74
+ #===あとで書く
75
+ #_n_:: あとで書く
76
+ #返却値:: あとで書く
77
+ def run(n)
78
+ return nil if n == nil
79
+ u = nil
80
+ on = nil
81
+ @stack = Array.new # reset
82
+ while n != nil
83
+ @prev_label = on
84
+ on = n
85
+
86
+ raise MiyakoError, "Illegal Script-label name! : #{n}" unless Scene.has_scene?(n.to_s)
87
+ u = get_scene(n, @stack.size) if u == nil
88
+ u.init_inner(@prev_label, self.upper_label)
89
+ u.setup
90
+
91
+ loop do
92
+ Input.update
93
+ Screen.clear
94
+ n = u.update
95
+ break unless n && on.eql?(n)
96
+ u.render
97
+ Screen.render
98
+ end
99
+ u.next = n
100
+ @next_label = n
101
+ u.final
102
+ if n == nil
103
+ if u.scene_type == :sub_routine && @stack.empty? == false
104
+ n, u = @stack.pop
105
+ next
106
+ end
107
+ break
108
+ elsif n.new(self, false).scene_type == :sub_routine
109
+ @stack.push([on, u])
110
+ u = nil
111
+ else
112
+ u = nil
113
+ end
114
+ end
115
+ @scene_cache_list.each{|sy| @scene_cache[sy].dispose }
116
+ @scene_cache.clear
117
+ @scene_cache_list.clear
118
+ end
119
+
120
+ #===あとで書く
121
+ def dispose
122
+ @scene_cache.keys.each{|k| @scene_cache[del_symbol].dispose }
123
+ end
124
+
125
+ #==シーンモジュール
126
+ #本モジュールをmixinすることにより、シーンを示すインスタンスを作??することができる
127
+ module Scene
128
+ @@scenes = {}
129
+
130
+ def Scene.included(c) #:nodoc:
131
+ @@scenes[c.to_s] = c
132
+ end
133
+
134
+ def Scene.scenes #:nodoc:
135
+ return @@scenes
136
+ end
137
+
138
+ def Scene.has_scene?(s) #:nodoc:
139
+ return @@scenes.has_key?(s)
140
+ end
141
+
142
+ #===あとで書く
143
+ #返却値:: あとで書く
144
+ def scene_type
145
+ return :scene
146
+ end
147
+
148
+ def initialize(story, check_only=false) #:nodoc:
149
+ return if check_only
150
+ @story = story
151
+ @now = self.class
152
+ @prev = nil
153
+ @upper = nil
154
+ @next = nil
155
+ self.init
156
+ end
157
+
158
+ def init_inner(p, u) #:nodoc:
159
+ @prev = p
160
+ @upper = u
161
+ end
162
+
163
+ #===あとで書く
164
+ #返却値:: あとで書く
165
+ def init
166
+ end
167
+
168
+ #===あとで書く
169
+ #返却値:: あとで書く
170
+ def setup
171
+ end
172
+
173
+ #===あとで書く
174
+ #返却値:: あとで書く
175
+ def update
176
+ return @now
177
+ end
178
+
179
+ #===あとで書く
180
+ #返却値:: あとで書く
181
+ def render
182
+ end
183
+
184
+ #===あとで書く
185
+ #返却値:: あとで書く
186
+ def final
187
+ end
188
+
189
+ #===あとで書く
190
+ #返却値:: あとで書く
191
+ def dispose
192
+ end
193
+
194
+ def next=(label) #:nodoc:
195
+ @next = label
196
+ end
197
+
198
+ #===あとで書く
199
+ #返却値:: あとで書く
200
+ def notice
201
+ return ""
202
+ end
203
+
204
+ #===あとで書く
205
+ #返却値:: あとで書く
206
+ def Scene.listup
207
+ list = Array.new
208
+ sns = @@scenes
209
+ sns.keys.sort.each{|k| list.push("#{k}, #{sns[k]}, \"#{sns[k].notice}\"\n") }
210
+ return list
211
+ end
212
+
213
+ #===あとで書く
214
+ #_csvname_:: あとで書く
215
+ #返却値:: あとで書く
216
+ def Scene.listup2csv(csvfname)
217
+ csvfname += ".csv" if csvfname !~ /\.csv$/
218
+ list = self.listup
219
+ File.open(csvfname, "w"){|f| list.each{|l| f.print l } }
220
+ end
221
+
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,496 @@
1
+ # -*- encoding: utf-8 -*-
2
+ =begin
3
+ --
4
+ Miyako v2.0
5
+ Copyright (C) 2007-2008 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
+ module Miyako
24
+ #==テキストボックスを構成するクラス
25
+ #テキスト表示部、ウェイトカーソル、選択カーソルで構成される
26
+ class TextBox
27
+ include SpriteBase
28
+ include Animation
29
+ include Layout
30
+ extend Forwardable
31
+
32
+ @@windows = Array.new
33
+ @@select_margin = {:left => 1, :over => 0}
34
+
35
+ attr_accessor :textarea
36
+ attr_accessor :pause_type, :select_type, :waiting, :selecting
37
+ attr_accessor :font, :margin
38
+ attr_reader :wait_cursor, :select_cursor, :choices
39
+ attr_reader :draw_type, :locate, :size, :max_height
40
+
41
+ #===インスタンスの作成
42
+ #テキストボックスを生成する。パラメータは以下の通り。
43
+ #(括弧内は省略形)
44
+ #:font:: 描画フォント(Fontクラスのインスタンス) デフォルトはFont.sans_serif
45
+ #:size:: 描画文字数(2要素の配列またはSize構造体のインスタンス) デフォルトはSize(20,8)
46
+ #:wait_cursor(:wc):: ボタン入力待ちを示すカーソル(SpriteもしくはSpriteAnimationクラスのインスタンス)
47
+ #:select_cursor(:sc):: 選択カーソル(SpriteもしくはSpriteAnimationクラスのインスタンス)
48
+ #:page_size:: 一度にテキストボックスに表示させる選択肢の数(縦方向、デフォルトは8)
49
+ #
50
+ #_params_:: 生成時のパラメータ(ハッシュ引数)
51
+ #返却値:: TextBoxクラスのインスタンス
52
+ def initialize(params = {})
53
+ init_layout
54
+ @font = params[:font] || Font.sans_serif
55
+ @max_height = @font.line_height
56
+ @locate = Point.new(0, 0)
57
+
58
+ @base = params[:size] || Size.new(20, 8)
59
+ @size = Size.new(@font.size * @base[0] +
60
+ (@font.use_shadow ? @font.shadow_margin[0] : 0),
61
+ @font.line_height *
62
+ @base[1] - @font.vspace)
63
+ @pos = Point.new(0, 0)
64
+ set_layout_size(*@size)
65
+
66
+ @margin = 0
67
+
68
+ @textarea = Sprite.new({:size => @size, :type => :ac, :is_fill => true})
69
+
70
+ @wait_cursor = params[:wait_cursor] || params[:wc] || nil
71
+ @select_cursor = params[:select_cursor] || params[:sc] || nil
72
+
73
+ @command_page_size = params[:page_size] || @base[1]
74
+
75
+ @choices = Choices.new
76
+ @now_choice = nil
77
+
78
+ @pause_type = :bottom
79
+ @waiting = false
80
+ @select_type = :left
81
+ @selecting = false
82
+
83
+ @textarea.snap(self)
84
+ @textarea.centering
85
+
86
+ @@windows.push(self)
87
+
88
+ @move_list = [[lambda{ },
89
+ lambda{ @choices.right },
90
+ lambda{ @choices.left }],
91
+ [lambda{ @choices.down },
92
+ lambda{ },
93
+ lambda{ }],
94
+ [lambda{ @choices.up },
95
+ lambda{ },
96
+ lambda{ }]]
97
+
98
+ end
99
+
100
+ #===表示可能な文字行数を取得する
101
+ #返却値:: 表示可能な行数
102
+ def rows
103
+ return @base.h
104
+ end
105
+
106
+ #===一列に表示可能な文字数を取得する
107
+ #返却される値は全角文字の数だが、半角文字も全角文字1文字と計算されるので注意
108
+ #返却値:: 表示可能な文字数
109
+ def columns
110
+ return @base.w
111
+ end
112
+
113
+ #===一列に表示可能な文字数と行数を取得する
114
+ #文字数はcolumns、行数はrowsの値と同一
115
+ #Size構造体のインスタンスとして取得
116
+ #返却値:: 表示可能な文字数と行数
117
+ def text_size
118
+ return Size.new(@base.w, @base.h)
119
+ end
120
+
121
+ def update #:nodoc:
122
+ end
123
+
124
+ #===テキストボックスの表示を更新する
125
+ #テキストボックス・選択カーソル・選択肢・ウェイトカーソルのアニメーションを更新する
126
+ #返却値:: 常にfalseを返す
127
+ def update_animation
128
+ @textarea.update_animation
129
+ @wait_cursor.update_animation if (@wait_cursor && @waiting)
130
+ if @selecting
131
+ @choices.update_animation
132
+ @select_cursor.update_animation if @select_cursor
133
+ end
134
+ return false
135
+ end
136
+
137
+ #===スプライトに変換した画像を表示する
138
+ #すべてのパーツを貼り付けた、1枚のスプライトを返す
139
+ #返却値:: 描画したスプライト
140
+ def to_sprite
141
+ rect = self.broad_rect
142
+ sprite = Sprite.new(:size=>rect.to_a[2,2], :type=>:ac)
143
+ self.render_to(sprite){|sunit, dunit| sunit.x -= rect.x; sunit.y -= rect.y }
144
+ return sprite
145
+ end
146
+
147
+ #===現在の画面の最大の大きさを矩形で取得する
148
+ #テキストボックスの状態により、取得できる矩形の大きさが変わる
149
+ #返却値:: 生成された矩形(Rect構造体のインスタンス)
150
+ def broad_rect
151
+ rect = self.rect.to_a
152
+ rect_list = []
153
+ rect_list << @wait_cursor.broad_rect if (@wait_cursor && @waiting)
154
+ if @selecting
155
+ rect_list << @choices.broad_rect
156
+ rect_list << @select_cursor.broad_rect if @select_cursor
157
+ end
158
+ return self.rect if rect_list.length == 0
159
+ rect_list = rect.zip(*rect_list)
160
+ # width -> right
161
+ rect_list[2] = rect_list[2].zip(rect_list[0]).map{|xw| xw[0] + xw[1]}
162
+ # height -> bottom
163
+ rect_list[3] = rect_list[3].zip(rect_list[1]).map{|xw| xw[0] + xw[1]}
164
+ x, y = rect_list[0].min, rect_list[1].min
165
+ return Rect.new(x, y, rect_list[2].max - x, rect_list[3].max - y)
166
+ end
167
+
168
+ #===画面に描画する
169
+ #現在のテキストエリア・カーソルを、現在の状態で描画する
170
+ #ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る。
171
+ #ブロックの引数は、|インスタンスのSpriteUnit, 画面のSpriteUnit|となる。
172
+ #返却値:: 自分自身を返す
173
+ def render(&block)
174
+ @textarea.render(&block)
175
+ @wait_cursor.render(&block) if (@wait_cursor && @waiting)
176
+ if @selecting
177
+ @choices.render(&block)
178
+ @select_cursor.render(&block) if @select_cursor
179
+ end
180
+ return self
181
+ end
182
+
183
+ #===画面に描画する
184
+ #現在のテキストエリア・カーソルを、現在の状態で描画する
185
+ #ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る。
186
+ #ブロックの引数は、|インスタンスのSpriteUnit, 転送先のSpriteUnit|となる。
187
+ #返却値:: 自分自身を返す
188
+ def render_to(dst, &block)
189
+ @textarea.render_to(dst, &block)
190
+ @wait_cursor.render(dst, &block) if (@wait_cursor && @waiting)
191
+ if @selecting
192
+ @choices.render(dst, &block)
193
+ @select_cursor.render(dst, &block) if @select_cursor
194
+ end
195
+ return self
196
+ end
197
+
198
+ #===文字の描画位置にマージンを設定する
199
+ #marginで指定したピクセルぶん、下に描画する
200
+ #ブロックを渡すと、ブロックを評価している間だけマージンが有効になる
201
+ #_margin_:: 設定するマージン
202
+ #返却値:: 自分自身を返す
203
+ def margin_during(margin)
204
+ raise MiyakoError, "not given block!" unless block_given?
205
+ omargin, @margin = @margin, margin
206
+ yield
207
+ @margin = omargin
208
+ return self
209
+ end
210
+
211
+ #===指定した高さで描画する際のマージンを求める
212
+ #現在のフォントの設定で指定の文字列を描画したとき、予想される描画サイズを返す。実際に描画は行われない。
213
+ #第1引数に渡す"align"は、以下の3種類のシンボルのどれかを渡す
214
+ #:top:: 上側に描画(マージンはゼロ)
215
+ #:middle:: 中間に描画
216
+ #:bottom:: 下部に描画
217
+ #
218
+ #_align_:: 描画位置
219
+ #_height_:: 描画する高さ(デフォルトは、描画した最大の高さ)
220
+ #返却値:: マージンの値
221
+ def margin_height(align, height = @max_height)
222
+ return @font.margin_height(align, height)
223
+ end
224
+
225
+ #===ブロックを評価している間、文字色を変更する
226
+ #_color_:: 変更する文字色([r,g,b]の3要素の配列(値:0~255))
227
+ #返却値:: 自分自身を返す
228
+ def color_during(color)
229
+ raise MiyakoError, "not given block!" unless block_given?
230
+ @font.color_during(color){ yield }
231
+ return self
232
+ end
233
+
234
+ #===ブロックを評価している間、フォントサイズを変更する
235
+ #_size_:: 変更するフォントサイズ
236
+ #返却値:: 自分自身を返す
237
+ def font_size_during(size)
238
+ raise MiyakoError, "not given block!" unless block_given?
239
+ @font.size_during(size){ yield }
240
+ return self
241
+ end
242
+
243
+ #===ブロックを評価している間、太字に変更する
244
+ #文字が領域外にはみ出る場合があるので注意!
245
+ #返却値:: 自分自身を返す
246
+ def font_bold
247
+ raise MiyakoError, "not given block!" unless block_given?
248
+ @font.bold{ yield }
249
+ return self
250
+ end
251
+
252
+ #===ブロックを評価している間、斜体文字に変更する
253
+ #文字が領域外にはみ出る場合があるので注意!
254
+ #返却値:: 自分自身を返す
255
+ def font_italic
256
+ raise MiyakoError, "not given block!" unless block_given?
257
+ @font.italic{ yield }
258
+ return self
259
+ end
260
+
261
+ #===ブロックを評価している間、下線付き文字に変更する
262
+ #返却値:: 自分自身を返す
263
+ def font_under_line
264
+ raise MiyakoError, "not given block!" unless block_given?
265
+ @font.under_line{ yield }
266
+ return self
267
+ end
268
+
269
+ #===テキストエリアに文字を描画する
270
+ #_text_:: 描画する文字列
271
+ #返却値:: 自分自身を返す
272
+ def draw_text(text)
273
+ @locate.x = @font.draw_text(@textarea, text, @locate.x, @locate.y + @margin)
274
+ @max_height = [@max_height, @font.line_height].max
275
+ return self
276
+ end
277
+
278
+ #===あとで書く
279
+ #_choices_:: あとで書く
280
+ #返却値:: あとで書く
281
+ def create_choices_chain(choices)
282
+ choices = choices.map{|v|
283
+ @font.color = Color[:white]
284
+ body = v[0].to_sprite(@font)
285
+ @font.color = Color[:red]
286
+ body_selected = v[1] ? v[1].to_sprite(@font) : body
287
+ choice = Choices.create_choice(body, body_selected)
288
+ choice.result = v[2]
289
+ next choice
290
+ }
291
+ if block_given?
292
+ return yield(choices)
293
+ end
294
+ list = []
295
+ pos = 0
296
+ choices2 = []
297
+ while cpart = choices[pos, @command_page_size]
298
+ break if cpart.length == 0
299
+ choices2.push(cpart)
300
+ pos += @command_page_size
301
+ end
302
+ choices2.each_with_index{|cc, x|
303
+ len = cc.length
304
+ right = choices2[(x + 1) % choices2.length]
305
+ left = choices2[x - 1]
306
+ yp = @textarea.y + @locate.y
307
+ cc.each_with_index{|v, y|
308
+ v.down = cc[(y + 1) % len]
309
+ v.up = cc[y - 1]
310
+ v.right = (y >= right.length ? right.last : right[y])
311
+ v.left = (y >= left.length ? left.last : left[y])
312
+ v.body.move_to(@textarea.x +
313
+ @locate.x +
314
+ @select_cursor.ow *
315
+ @@select_margin[@select_type],
316
+ yp)
317
+ if v.body_selected
318
+ v.body_selected.move_to(@textarea.x +
319
+ @locate.x +
320
+ @select_cursor.ow *
321
+ @@select_margin[@select_type],
322
+ yp)
323
+ end
324
+ yp += v.body.oh
325
+ }
326
+ list.push(cc)
327
+ }
328
+ return list
329
+ end
330
+
331
+ #===コマンド選択を設定する
332
+ #コマンド選択処理に移る(self#selecting?メソッドがtrueになる)
333
+ #引数choicesは配列だが、要素は、[コマンド文字列・画像,選択時コマンド文字列・画像,選択した結果(オブジェクト)]
334
+ #として構成されている
335
+ #body_selectedをnilにした場合は、bodyと同一となる
336
+ #body_selectedを文字列を指定した場合は、文字色が赤色になることに注意
337
+ #_choices_:: 選択肢の配列
338
+ #返却値:: 自分自身を返す
339
+ def command(choices)
340
+ @choices.clear
341
+ choices.each{|cc| @choices.create_choices(cc) }
342
+ start_command
343
+ return self
344
+ end
345
+
346
+ #===コマンド選択を開始する
347
+ #但し、commandメソッドを呼び出したときは自動的に呼ばれるので注意
348
+ #返却値:: 自分自身を返す
349
+ def start_command
350
+ raise MiyakoError, "don't set Choice!" if @choices.length == 0
351
+ @choices.start_choice
352
+ if @select_cursor
353
+ @select_cursor.move_to(@choices.body.x -
354
+ @select_cursor.ow *
355
+ @@select_margin[@select_type],
356
+ @choices.body.y +
357
+ (@choices.body.oh - @select_cursor.oh) / 2)
358
+ @select_cursor.start
359
+ end
360
+ @choices.start
361
+ @selecting = true
362
+ return self
363
+ end
364
+
365
+ #===コマンド選択を終了する
366
+ #返却値:: 自分自身を返す
367
+ def finish_command
368
+ @choices.stop
369
+ @select_cursor.stop
370
+ @selecting = false
371
+ return self
372
+ end
373
+
374
+ #===あとで書く
375
+ #_dx_:: あとで書く
376
+ #_dy_:: あとで書く
377
+ #返却値:: あとで書く
378
+ def move_cursor(dx, dy)
379
+ @move_list[dy][dx].call
380
+ if @select_cursor
381
+ @select_cursor.move_to(@choices.body.x -
382
+ @select_cursor.ow *
383
+ @@select_margin[@select_type],
384
+ @choices.body.y +
385
+ (@choices.body.oh - @select_cursor.oh) / 2)
386
+ end
387
+ return self
388
+ end
389
+
390
+ #===あとで書く
391
+ #返却値:: あとで書く
392
+ def update_layout_position
393
+ @pos.move_to(*@layout.pos)
394
+ end
395
+
396
+ #===入力待ち状態(ポーズ)にする
397
+ #ポーズカーソルを表示する。pause?メソッドの結果がtrueになる
398
+ #ポーズカーソルの位置は、pause_type=メソッドの結果に依る(デフォルトは:bottom)
399
+ #返却値:: 自分自身を返す
400
+ def pause
401
+ @waiting = true
402
+ return self unless @wait_cursor
403
+ case @pause_type
404
+ when :bottom
405
+ @wait_cursor.move_to(@textarea.x +
406
+ (@textarea.w - @wait_cursor.ow) / 2,
407
+ @textarea.y + @textarea.h - @wait_cursor.oh)
408
+ when :out
409
+ @wait_cursor.move_to(@textarea.x +
410
+ (@textarea.w - @wait_cursor.ow) / 2,
411
+ @textarea.y + @textarea.h)
412
+ when :last
413
+ @wait_cursor.move_to(@textarea.x + @locate.x, @textarea.y + @locate.y)
414
+ end
415
+ @wait_cursor.start
416
+ return self
417
+ end
418
+
419
+ #===入力待ち状態を解除する
420
+ #同時に、ポーズカーソルを隠蔽する。pause?メソッドの結果がfalseになる
421
+ #返却値:: 自分自身を返す
422
+ def release
423
+ @waiting = false
424
+ @wait_cursor.stop if @wait_cursor
425
+ return self
426
+ end
427
+
428
+ #===入力待ち状態かを確認する
429
+ #返却値:: 入力待ち状態の時はtrueを返す
430
+ def pause?
431
+ return @waiting
432
+ end
433
+
434
+ #===あとで書く
435
+ #返却値:: あとで書く
436
+ def selecting?
437
+ return @selecting
438
+ end
439
+
440
+ #===あとで書く
441
+ #返却値:: あとで書く
442
+ def result
443
+ return @choices.result
444
+ end
445
+
446
+ #===あとで書く
447
+ #返却値:: あとで書く
448
+ def clear
449
+ @textarea.bitmap.fillRect(0, 0, @size[0], @size[1], [0, 0, 0, 0])
450
+ @locate = Point.new(0, 0)
451
+ @max_height = @font.line_height
452
+ return self
453
+ end
454
+
455
+ #===縦方向のスペースを空ける
456
+ #現在描画可能な位置から、指定したピクセルで下方向に移動する
457
+ #但し、文字の大きさもピクセル数に含むことに注意すること
458
+ #_height_:: スペースを空けるピクセル数
459
+ #返却値:: 自分自身を返す
460
+ def cr(height = @max_height)
461
+ @locate.x = 0
462
+ @locate.y += height
463
+ @max_height = @font.line_height
464
+ return self
465
+ end
466
+
467
+ #===横方向のスペースを空ける
468
+ #現在描画可能な位置から、指定したピクセルで右方向に移動する
469
+ #_length_:: スペースを空けるピクセル数
470
+ #返却値:: 自分自身を返す
471
+ def space(length)
472
+ @locate.x += length
473
+ return self
474
+ end
475
+
476
+ #===ブロックで指定した描画処理を非同期に行う
477
+ #ブロックを渡すと、描画処理を非同期に行う。
478
+ #更新処理はスレッドを使うが、現在、終了を確認する方法が無いため、扱いに注意すること
479
+ #(確実にスレッド処理が終わるコードになっているか確認すること)
480
+ #返却値:: 自分自身を返す
481
+ def exec
482
+ Thread.new(Proc.new){|proc| proc.call } if block_given?
483
+ return self
484
+ end
485
+
486
+ #===あとで書く
487
+ #返却値:: あとで書く
488
+ def dispose
489
+ @textarea.dispose
490
+ @textarea = nil
491
+ @@windows.delete(self)
492
+ end
493
+
494
+ def_delegators(:@pos, :x, :y)
495
+ end
496
+ end