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,583 @@
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
+ require 'csv'
24
+ require 'forwardable'
25
+
26
+ module Miyako
27
+ #==マップチップ構造体に配列化メソッド(to_a)を定義するための構造体クラス
28
+ #インデックス参照メソッドを追加
29
+ class MapChipStruct < Struct
30
+ #===インスタンスを配列化する
31
+ #Map/FixedMap.newメソッド内部で、MapChip構造体と、その配列とのダックタイピングのために用意
32
+ #返却値:: 自分自身を[]囲んだオブジェクトを返す
33
+ def to_a
34
+ return [self]
35
+ end
36
+ end
37
+
38
+ #=マップチップ定義構造体
39
+ MapChip = MapChipStruct.new(:chip_image, :chips, :size, :chip_size, :access_types, :collision_table, :access_table)
40
+
41
+ #=マップチップ作成ファクトリクラス
42
+ class MapChipFactory
43
+ #===マップチップを作成するためのファクトリクラス
44
+ #_csv_filename_:: マップチップファイル名(CSVファイル)
45
+ #_use_alpha_:: 画像にαチャネルを使うかどうかのフラグ。trueのときは画像のαチャネルを使用、falseのときはカラーキーを使用。デフォルトはtrue
46
+ def MapChipFactory.load(csv_filename, use_alpha = true)
47
+ raise MiyakoIOError.no_file(csv_filename) unless File.exist?(csv_filename)
48
+ lines = CSV.read(csv_filename)
49
+ raise MiyakoFileFormatError, "This file is not Miyako Map Chip file! : #{csv_filename}" unless lines.shift[0] == "Miyako Mapchip"
50
+ spr = use_alpha ? Sprite.new({:filename => lines.shift[0], :type => :alpha_channel}) : Sprite.new({:file_name => lines.shift[0], :type => :color_key})
51
+ tmp = lines.shift
52
+ chip_size = Size.new(tmp[0].to_i, tmp[1].to_i)
53
+ size = Size.new(spr.w / chip_size.w, spr.h / chip_size.h)
54
+ chips = size.w * size.h
55
+ access_types = lines.shift[0].to_i
56
+ collision_table = Array.new(access_types){|at|
57
+ Array.new(chips){|n| Collision.new(lines.shift.map{|s| s.to_i}) }
58
+ }
59
+ access_table = Array.new(access_types){|at|
60
+ Array.new(chips){|n|
61
+ lines.shift.map{|s|
62
+ v = eval(s)
63
+ next v if (v == true || v == false)
64
+ v = v.to_i
65
+ next false if v == 0
66
+ true
67
+ }
68
+ }
69
+ }
70
+ return MapChip.new(spr, chips, size, chip_size, access_types, collision_table, access_table)
71
+ end
72
+ end
73
+
74
+ #==アクセス方向定義クラス
75
+ #マップチップのアクセステーブルを参照する際に、状態(入る(:in)・出る(:out))と
76
+ #方向(:left, :right, :up, :down)から、アクセステーブルの指標を取得する必要がある。
77
+ #このクラスでは、その指標を取得するメソッドを用意している
78
+ class AccessIndex
79
+ @@accesses = {
80
+ in: { right: 2, left: 4, up: 6, down: 0},
81
+ out: { right: 3, left: 5, up: 1, down: 7}
82
+ }
83
+ @@accesses2 = {
84
+ in: [[-1,0,6],[2,-1,-1],[4,-1,-1]],
85
+ out: [[-1,7,1],[3,-1,-1],[5,-1,-1]]
86
+ }
87
+
88
+ #===状態と方向からアクセステーブルの指標を取得する
89
+ #アクセステーブルには、2種類の状態(入る=:in, 出る=:out)と、
90
+ #4種類の方向(左=:left, 右=:right, 上=:up, 下=:down)から構成される
91
+ #配列となっている。本メソッドで、状態・方向に対応するシンボルから配列の要素指標を取得する。
92
+ #指定外のシンボルを渡すと例外が発生する
93
+ #_state_:: 状態を示すシンボル(:in, :out)
94
+ #_direction_:: 方向を示すシンボル(:left, :right, :up, :down)
95
+ #返却値:: アクセステーブルの指標番号(整数)
96
+ def AccessIndex.index(state, direction)
97
+ raise MiyakoValueError, "can't find AcceessIndex state symbol! #{state}" unless @@accesses.has_key?(state)
98
+ raise MiyakoValueError, "can't find AcceessIndex direction symbol! #{direction}" unless @@accesses[state].has_key?(direction)
99
+ return @@accesses[state][direction]
100
+ end
101
+
102
+ #===状態と移動量からアクセステーブルの指標を取得する
103
+ #アクセステーブルには、2種類の状態(入る=:in, 出る=:out)と、移動量(dx,dy)から構成される
104
+ #配列となっている。本メソッドで、状態に対応するシンボル、整数から配列の要素指標を取得する。
105
+ #指定外のシンボルを渡すと例外が発生する
106
+ #_state_:: 状態を示すシンボル(:in, :out)
107
+ #_dx_:: x方向移動量
108
+ #_dy_:: y方向移動量
109
+ #返却値:: アクセステーブルの指標番号(整数)。何も移動しない場合は-1が返る
110
+ def AccessIndex.index2(state, dx, dy)
111
+ raise MiyakoValueError, "can't find AcceessIndex state symbol! #{state}" unless @@accesses.has_key?(state)
112
+ return @@accesses2[state][dx < -1 ? -1 : dx > 1 ? 1 : 0][dy < -1 ? -1 : dy > 1 ? 1 : 0]
113
+ end
114
+ end
115
+
116
+ #==マップ定義クラス
117
+ class Map
118
+ include SpriteBase
119
+ include Animation
120
+
121
+ @@idx_ix = [-1, 2, 4]
122
+ @@idx_iy = [-1, 0, 6]
123
+
124
+ attr_accessor :visible #レンダリングの可否(true->描画 false->非描画)
125
+ attr_reader :map_layers, :mapchips, :pos, :size, :w, :h
126
+
127
+ class MapLayer #:nodoc: all
128
+ include SpriteBase
129
+ include Animation
130
+ extend Forwardable
131
+
132
+ attr_accessor :visible #レンダリングの可否(true->描画 false->非描画)
133
+ attr_reader :mapchip, :mapchip_units, :pos, :size
134
+
135
+ def round(v, max) #:nodoc:
136
+ v = max + (v % max) if v < 0
137
+ v %= max if v >= max
138
+ return v
139
+ end
140
+
141
+ def resize #:nodoc:
142
+ @cw = (Screen.w + @ow - 1)/ @ow + 1
143
+ @ch = (Screen.h + @oh - 1)/ @oh + 1
144
+ end
145
+
146
+ def initialize(mapchip, mapdat, layer_size) #:nodoc:
147
+ @mapchip = mapchip
148
+ @pos = Point.new(0, 0)
149
+ @size = layer_size.dup
150
+ @ow = @mapchip.chip_size.w
151
+ @oh = @mapchip.chip_size.h
152
+ @real_size = Size.new(@size.w * @ow, @size.h * @oh)
153
+ @mapdat = mapdat
154
+ @baseimg = @mapchip.chip_image
155
+ @divpx = get_div_array(0, @real_size.w, @ow)
156
+ @divpy = get_div_array(0, @real_size.h, @oh)
157
+ @modpx = get_mod_array(0, @real_size.w, @ow)
158
+ @modpy = get_mod_array(0, @real_size.h, @oh)
159
+ @modpx2 = get_mod_array(0, @size.w * 2 + 1, @size.w)
160
+ @modpy2 = get_mod_array(0, @size.h * 2 + 1, @size.h)
161
+ @cdivsx = get_div_array(0, @mapchip.chips, @mapchip.size.w)
162
+ @cmodsx = get_mod_array(0, @mapchip.chips, @mapchip.size.w)
163
+ @cdivsy = get_div_array(0, @mapchip.chips, @mapchip.size.h)
164
+ @cmodsy = get_mod_array(0, @mapchip.chips, @mapchip.size.h)
165
+ @cdivsx = @cdivsx.map{|v| v * @ow }
166
+ @cdivsy = @cdivsy.map{|v| v * @oh }
167
+ @cmodsx = @cmodsx.map{|v| v * @ow }
168
+ @cmodsy = @cmodsy.map{|v| v * @oh }
169
+ @mapchip_units = Array.new(@mapchip.chips){|idx|
170
+ SpriteUnitFactory.create(:bitmap=>@baseimg.bitmap,
171
+ :ox => (idx % @mapchip.size.w) * @ow,
172
+ :oy => (idx / @mapchip.size.w) * @oh,
173
+ :ow => @ow,
174
+ :oh => @oh)
175
+ }
176
+ @visible = true
177
+ resize
178
+ end
179
+
180
+ def initialize_copy(obj) #:nodoc:
181
+ @mapchip = @mapchip.dup
182
+ @size = @size.dup
183
+ @mapchip_unit = @mapchip_unit.dup
184
+ @divpx = get_div_array(0, @real_size.w, @ow)
185
+ @divpy = get_div_array(0, @real_size.h, @oh)
186
+ @modpx = get_mod_array(0, @real_size.w, @ow)
187
+ @modpy = get_mod_array(0, @real_size.h, @oh)
188
+ @modpx2 = get_mod_array(0, @size.w * 2 + 1, @size.w)
189
+ @modpy2 = get_mod_array(0, @size.h * 2 + 1, @size.h)
190
+ @cdivsx = get_div_array(0, @mapchip.chips, @mapchip.size.w)
191
+ @cmodsx = get_mod_array(0, @mapchip.chips, @mapchip.size.w)
192
+ @cdivsy = get_div_array(0, @mapchip.chips, @mapchip.size.h)
193
+ @cmodsy = get_mod_array(0, @mapchip.chips, @mapchip.size.h)
194
+ @cdivsx = @cdivsx.map{|v| v * @ow }
195
+ @cdivsy = @cdivsy.map{|v| v * @oh }
196
+ @cmodsx = @cmodsx.map{|v| v * @ow }
197
+ @cmodsy = @cmodsy.map{|v| v * @oh }
198
+ end
199
+
200
+ def get_div_array(s, t, v) #:nodoc:
201
+ a = Array.new
202
+ (s..t).each{|i| a.push(i / v)}
203
+ return a
204
+ end
205
+
206
+ def get_mod_array(s, t, v) #:nodoc:
207
+ a = Array.new
208
+ (s..t).each{|i| a.push(i % v)}
209
+ return a
210
+ end
211
+
212
+ def convert_position(x, y) #:nodoc:
213
+ return Point.new(@modpx2[round(x, @size.w)],
214
+ @modpy2[round(y, @size.h)])
215
+ end
216
+
217
+ #===実座標を使用して、指定のレイヤー・位置のマップチップ番号を取得
218
+ #イベントレイヤーでの番号はイベント番号と一致する
219
+ #_x_:: マップチップ単位での位置(ピクセル単位)
220
+ #_y_:: マップチップ単位での位置(ピクセル単位)
221
+ #返却値:: マップチップ番号(マップチップが設定されている時は0以上の整数、設定されていない場合は-1が返る)
222
+ def get_code(x, y)
223
+ pos = convert_position(x / @mapchip.chip_size[0], y / @mapchip.chip_size[1])
224
+ return @mapdat[pos.y][pos.x]
225
+ end
226
+
227
+ #===指定の矩形のキャラクタに掛かるマップチップの左上位置の組み合わせを返す
228
+ #但し、引数には、Rect(x,y,w,h)形式のインスタンスを渡す
229
+ #_rect_:: キャラクタの矩形
230
+ #返却値:: マップチップ左上位置の配列(キャラクタに掛かる位置の組み合わせ)
231
+ def product_position(rect)
232
+ return Utility.product_position(rect, @mapchip.chip_size)
233
+ end
234
+
235
+ #===指定の矩形のキャラクタに掛かるマップチップの左上位置の組み合わせを返す
236
+ #但し、引数には、Square([x1,y1,x2,y2])形式のインスタンスを渡す
237
+ #_square_:: キャラクタの矩形
238
+ #返却値:: マップチップ左上位置の配列(キャラクタに掛かる位置の組み合わせ)
239
+ def product_position_by_square(square)
240
+ return Utility.product_position_by_square(square, @mapchip.chip_size)
241
+ end
242
+
243
+ #===キャラクタとマップチップが重なっているかどうか問い合わせる
244
+ #指定の矩形のキャラクタが、指定の位置のマップチップのコリジョンと重なっているかどうか問い合わせる
245
+ #引数は、Rect(x,y,w,h)形式(Rect構造体、[x,y,w,h]の配列)で渡す
246
+ #指定の位置のマップチップ番号が-1(未定義)のときはnilを返す
247
+ #_type_:: 移動形式(0以上の整数)
248
+ #_pos_:: 調査対象のマップチップの位置
249
+ #_collision_:: キャラクタのコリジョン
250
+ #_rect_:: キャラクタの矩形
251
+ #返却値:: コリジョンが重なっていれば、そのときのマップチップ番号を返す。重なっていなければnilを返す
252
+ def collision?(type, pos, collision, rect)
253
+ code = get_code(*pos.to_a)
254
+ return nil if code == -1
255
+ return @mapchip.collision_table[type][code].collision?(pos, collision, rect) ? code : nil
256
+ end
257
+
258
+ #===キャラクタとマップチップが隣り合っているかどうか問い合わせる
259
+ #指定の矩形のキャラクタが、指定の位置のマップチップのコリジョンと隣り合っているかどうか問い合わせる
260
+ #引数は、Rect(x,y,w,h)形式(Rect構造体、[x,y,w,h]の配列)で渡す
261
+ #指定の位置のマップチップ番号が-1(未定義)のときはnilを返す
262
+ #_type_:: 移動形式(0以上の整数)
263
+ #_pos_:: 調査対象のマップチップの位置
264
+ #_collision_:: キャラクタのコリジョン
265
+ #_rect_:: キャラクタの矩形
266
+ #返却値:: コリジョンが隣り合っていれば、そのときのマップチップ番号を返す。隣り合っていなければnilを返す
267
+ def meet?(type, pos, collision, rect)
268
+ code = get_code(*pos.to_a)
269
+ return nil if code == -1
270
+ return @mapchip.collision_table[type][code].meet?(pos, collision, rect) ? code : nil
271
+ end
272
+
273
+ #===キャラクタとマップチップが覆い被さっているかどうか問い合わせる
274
+ #指定の矩形のキャラクタが、指定の位置のマップチップのコリジョンを覆い被さっているかどうか問い合わせる
275
+ #引数は、Rect(x,y,w,h)形式(Rect構造体、[x,y,w,h]の配列)で渡す
276
+ #指定の位置のマップチップ番号が-1(未定義)のときはnilを返す
277
+ #_type_:: 移動形式(0以上の整数)
278
+ #_pos_:: 調査対象のマップチップの位置
279
+ #_collision_:: キャラクタのコリジョン
280
+ #_rect_:: キャラクタの矩形
281
+ #返却値:: どちらかのコリジョンが覆い被さっていれば、そのときのマップチップ番号を返す。
282
+ #被さっていなければnilを返す
283
+ def cover?(type, pos, collision, rect)
284
+ code = get_code(*pos.to_a)
285
+ return nil if code == -1
286
+ return @mapchip.collision_table[type][code].cover?(pos, collision, rect) ? code : nil
287
+ end
288
+
289
+ #===キャラクタとマップチップが重なっているかどうか問い合わせる
290
+ #指定の位置と方向で、指定の位置のマップチップ上で移動できるかどうか問い合わせる
291
+ #指定の位置のマップチップ番号が-1(未定義)のとき、移動していない(dx==0 and dy==0)ときはtrueを返す
292
+ #_type_:: 移動形式(0以上の整数)
293
+ #_inout_:: 入退形式(:in もしくは :out)
294
+ #_pos_:: 調査対象のマップチップの位置
295
+ #_dx_:: 移動量(x座標)
296
+ #_dy_:: 移動量(y座標)
297
+ #返却値:: 移動可能ならばtrueを返す
298
+ def can_access?(type, inout, pos, dx, dy)
299
+ code = get_code(pos[0]+dx, pos[1]+dy)
300
+ return true if code == -1
301
+ index = AccessIndex.index2(inout, dx, dy)
302
+ return true if index == -1
303
+ return @mapchip.access_table[type][code][index]
304
+ end
305
+
306
+ def dispose #:nodoc:
307
+ @mapdat = nil
308
+ @baseimg = nil
309
+ end
310
+
311
+ #===マップレイヤーを画面に描画する
312
+ #転送する画像は、マップ上のから(-margin.x, -margin.y)(単位:ピクセル)の位置に対応するチップを左上にして描画する
313
+ #ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る)
314
+ #(ブロック引数のインスタンスは複写しているので、メソッドの引数として渡した値が持つSpriteUnitには影響しない)
315
+ #ブロックの引数は、|画面のSpriteUnit|となる。
316
+ #visibleメソッドの値がfalseのときは描画されない。
317
+ #返却値:: 自分自身を返す
318
+ def render
319
+ end
320
+
321
+ #===マップレイヤーを画像に転送する
322
+ #転送する画像は、マップ上のから(-margin.x, -margin.y)(単位:ピクセル)の位置に対応するチップを左上にして描画する
323
+ #ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る)
324
+ #(ブロック引数のインスタンスは複写しているので、メソッドの引数として渡した値が持つSpriteUnitには影響しない)
325
+ #ブロックの引数は、|転送先のSpriteUnit|となる。
326
+ #visibleメソッドの値がfalseのときは描画されない。
327
+ #_dst_:: 転送先ビットマップ(to_unitメソッドを呼び出すことが出来る/値がnilではないインスタンス)
328
+ #返却値:: 自分自身を返す
329
+ def render_to(dst)
330
+ end
331
+ end
332
+
333
+ #===インスタンスを生成する
334
+ #レイヤーごとにMapChip構造体を用意する。
335
+ #但し、すべてのレイヤーに同一のMapChip構造体を使うときは、単体で渡すことも可能
336
+ #第1引数にto_aメソッドが実装されていれば、配列化した要素をMapChip構造体として各レイヤに渡す
337
+ #また、各レイヤにMapChip構造体を渡すとき、レイヤ数より要素数が少ないときは、先頭に戻って繰り返し渡す仕様になっている
338
+ #各MapChip構造体のマップチップの大きさを同じにしておく必要がある
339
+ #_mapchips_:: マップチップ構造体群(MapChip構造体単体もしくは配列)
340
+ #_layer_csv_:: レイヤーファイル(CSVファイル)
341
+ #_event_manager_:: MapEventManagerクラスのインスタンス
342
+ #返却値:: 生成したインスタンス
343
+ def initialize(mapchips, layer_csv, event_manager)
344
+ raise MiyakoIOError.no_file(layer_csv) unless File.exist?(layer_csv)
345
+ @event_layers = []
346
+ @em = event_manager.dup
347
+ @em.set(self)
348
+ @mapchips = mapchips.to_a
349
+ @visible = true
350
+ @pos = Point.new(0, 0)
351
+ layer_data = CSV.readlines(layer_csv)
352
+ raise MiyakoFileFormatError, "This file is not Miyako Map Layer file! : #{layer_csv}" unless layer_data.shift[0] == "Miyako Maplayer"
353
+
354
+ tmp = layer_data.shift # 空行の空読み込み
355
+
356
+ @size = Size.new(*(tmp[0..1].map{|v| v.to_i}))
357
+ @w = @size.w
358
+ @h = @size.h
359
+
360
+ layers = layer_data.shift[0].to_i
361
+
362
+ evlist = []
363
+ brlist = []
364
+ layers.times{|n|
365
+ name = layer_data.shift[0]
366
+ values = []
367
+ @size.h.times{|y|
368
+ values << layer_data.shift.map{|m| m.to_i}
369
+ }
370
+ if name == "<event>"
371
+ evlist << values
372
+ else
373
+ brlist << values
374
+ end
375
+ }
376
+
377
+ evlist.each{|events|
378
+ event_layer = Array.new
379
+ events.each_with_index{|ly, y|
380
+ ly.each_with_index{|code, x|
381
+ next unless @em.include?(code)
382
+ event_layer.push(@em.create(code, x * @mapchips.first.chip_size.w, y * @mapchips.first.chip_size.h))
383
+ }
384
+ }
385
+ @event_layers << event_layer
386
+ }
387
+
388
+ mc = @mapchips.cycle
389
+ @mapchips = mc.take(layers)
390
+ @map_layers = []
391
+ brlist.each{|br|
392
+ br = br.map{|b| b.map{|bb| bb >= @mapchips.first.chips ? -1 : bb } }
393
+ @map_layers.push(MapLayer.new(mc.next, br, @size))
394
+ }
395
+ end
396
+
397
+ def initialize_copy(obj) #:nodoc:
398
+ @map_layers = @map_layers.dup
399
+ @event_layers = @event_layers.dup
400
+ @em = em.dup
401
+ @mapchips = @mapchips.dup
402
+ @size = @size.dup
403
+ @pos = @pos.dup
404
+ end
405
+
406
+ #===マップにイベントを追加する
407
+ #_idx_:: 追加するイベントレイヤの指標
408
+ #_code_:: イベント番号(Map.newメソッドで渡したイベント番号に対応)
409
+ #_x_:: マップ上の位置(x方向)
410
+ #_y_:: マップ常温位置(y方向)
411
+ #返却値:: 自分自身を返す
412
+ def add_event(idx, code, x, y)
413
+ return self unless @em.include?(code)
414
+ @event_layers[idx].push(@em.create(code, x, y))
415
+ return self
416
+ end
417
+
418
+ #===マップを移動(移動量指定)
419
+ #_dx_:: 移動量(x方向)
420
+ #_dy_:: 移動量(y方向)
421
+ #返却値:: 自分自身を返す
422
+ def move!(dx,dy)
423
+ @pos.move!(dx, dy)
424
+ @map_layers.each{|l| l.pos.move!(dx, dy) }
425
+ return self
426
+ end
427
+
428
+ #===マップを移動(移動先指定)
429
+ #_dx_:: 移動先(x方向)
430
+ #_dy_:: 移動先(y方向)
431
+ #返却値:: 自分自身を返す
432
+ def move_to!(x,y)
433
+ @pos.move_to!(x, y)
434
+ @map_layers.each{|l| l.pos.move_to!(x, y) }
435
+ return self
436
+ end
437
+
438
+ #===マップを移動(移動量指定)位置を求める
439
+ #ただし、自分自身の位置は変わらない
440
+ #_dx_:: 移動量(x方向)
441
+ #_dy_:: 移動量(y方向)
442
+ #返却値:: 変更した位置のインスタンス(Position構造体)
443
+ def move(dx,dy)
444
+ @pos.move(dx, dy)
445
+ end
446
+
447
+ #===マップを移動(移動先指定)位置を求める
448
+ #ただし、自分自身の位置は変わらない
449
+ #_dx_:: 移動先(x方向)
450
+ #_dy_:: 移動先(y方向)
451
+ #返却値:: 変更した位置のインスタンス(Position構造体)
452
+ def move_to(x,y)
453
+ @pos.move_to(x, y)
454
+ end
455
+
456
+ #===画像の表示矩形を取得する
457
+ #Mapの大きさを矩形で取得する。値は、Screen.rectメソッドの値と同じ。
458
+ #返却値:: 生成された矩形
459
+ def rect
460
+ return Screen.rect
461
+ end
462
+
463
+ #===現在の画面の最大の大きさを矩形で取得する
464
+ #但し、Mapの場合は最大の大きさ=画面の大きさなので、rectと同じ値が得られる
465
+ #返却値:: 画像の大きさ(Rect構造体のインスタンス)
466
+ def broad_rect
467
+ return self.rect
468
+ end
469
+
470
+ #===スプライトに変換した画像を表示する
471
+ #すべてのパーツを貼り付けた、1枚のスプライトを返す
472
+ #引数1個のブロックを渡せば、スプライトに補正をかけることが出来る
473
+ #返却値:: 描画したスプライト
474
+ def to_sprite
475
+ rect = self.broad_rect
476
+ sprite = Sprite.new(:size=>rect.to_a[2,2], :type=>:ac)
477
+ Drawing.fill(sprite, [0,0,0])
478
+ Bitmap.ck_to_ac!(sprite, [0,0,0])
479
+ self.render_to(sprite){|sunit, dunit| sunit.x -= rect.x; sunit.y -= rect.y }
480
+ yield sprite if block_given?
481
+ return sprite
482
+ end
483
+
484
+ #===SpriteUnit構造体を生成する
485
+ #いったんSpriteインスタンスを作成し、それをもとにSpriteUnit構造体を生成する。
486
+ #返却値:: 生成したSpriteUnit構造体
487
+ def to_unit
488
+ return self.to_sprite.to_unit
489
+ end
490
+
491
+ #===設定したマージンを各レイヤーに同期させる
492
+ #マージンを設定した後は必ずこのメソッドを呼び出すこと
493
+ #返却値:: 自分自身を返す
494
+ def [](idx)
495
+ return @map_layers[idx]
496
+ end
497
+
498
+ #===実座標を使用して、指定のレイヤー・位置のマップチップ番号を取得
499
+ #イベントレイヤーでの番号はイベント番号と一致する
500
+ #ブロックを渡すと、求めたマップチップ番号をブロック引数として受け取る評価を行える
501
+ #_idx_:: マップレイヤー配列のインデックス
502
+ #_x_:: マップチップ単位での位置(ピクセル単位)
503
+ #_y_:: マップチップ単位での位置(ピクセル単位)
504
+ #返却値:: マップチップ番号(マップチップが設定されている時は0以上の整数、設定されていない場合は-1が返る)
505
+ def get_code(idx, x = 0, y = 0)
506
+ code = @map_layers[idx].get_code(x, y)
507
+ yield code if block_given?
508
+ return code
509
+ end
510
+
511
+ #===対象のマップチップ番号の画像を置き換える
512
+ #_idx_:: 置き換えるマップチップレイヤー番号
513
+ #_code_:: 置き換えるマップチップ番号
514
+ #_base_:: 置き換え対象の画像・アニメーション
515
+ #返却値:: 自分自身を返す
516
+ def set_mapchip_base(idx, code, base)
517
+ @map_layers[idx].mapchip_units[code] = base
518
+ return self
519
+ end
520
+
521
+ #===マップチップ1枚の大きさを取得する
522
+ #マップチップの大きさが32×32ピクセルの場合は、[32,32]のSize構造体が返る
523
+ #返却値:: マップチップのサイズ(Size構造体)
524
+ def chip_size
525
+ return @mapchips.first.chip_size
526
+ end
527
+
528
+ #===すべてのマップイベントを終了させる
529
+ #マップに登録しているイベントすべてのfinalメソッドを呼び出す
530
+ def final
531
+ @event_layers.each{|ee| ee.each{|e| e.final }}
532
+ end
533
+
534
+ #===マップ情報を解放する
535
+ def dispose
536
+ @map_layers.each{|l|
537
+ l.dispose
538
+ l = nil
539
+ }
540
+ @map_layers = Array.new
541
+
542
+ @event_layers.each{|ee|
543
+ ee.each{|e| e.dispose }
544
+ ee.clear
545
+ }
546
+ @event_layers.clear
547
+
548
+ @mapchips.clear
549
+ @mapchips = nil
550
+ end
551
+
552
+ #===マップに登録しているイベントインスタンス(マップイベント)を取得する
553
+ #返却値:: マップイベントの配列
554
+ def events
555
+ return @event_layers
556
+ end
557
+
558
+ #===マップを画面に描画する
559
+ #転送する画像は、マップ上のから(-margin.x, -margin.y)(単位:ピクセル)の位置に対応するチップを左上にして描画する
560
+ #各レイヤ-を、レイヤーインデックス番号の若い順に描画する
561
+ #但し、マップイベントは描画しない
562
+ #ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る)
563
+ #(ブロック引数のインスタンスは複写しているので、メソッドの引数として渡した値が持つSpriteUnitには影響しない)
564
+ #ブロックの引数は、|画面のSpriteUnit|となる。
565
+ #visibleメソッドの値がfalseのときは描画されない。
566
+ #返却値:: 自分自身を返す
567
+ def render
568
+ end
569
+
570
+ #===マップを画像に描画する
571
+ #転送する画像は、マップ上のから(-margin.x, -margin.y)(単位:ピクセル)の位置に対応するチップを左上にして描画する
572
+ #各レイヤ-を、レイヤーインデックス番号の若い順に描画する
573
+ #但し、マップイベントは描画しない
574
+ #ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る)
575
+ #(ブロック引数のインスタンスは複写しているので、メソッドの引数として渡した値が持つSpriteUnitには影響しない)
576
+ #ブロックの引数は、|転送先のSpriteUnit|となる。
577
+ #visibleメソッドの値がfalseのときは描画されない。
578
+ #_dst_:: 転送先ビットマップ(to_unitメソッドを呼び出すことが出来る/値がnilではないインスタンス)
579
+ #返却値:: 自分自身を返す
580
+ def render_to(dst)
581
+ end
582
+ end
583
+ end