ruby-miyako 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +1115 -0
- data/Rakefile +7 -0
- data/defines.h +144 -0
- data/extconf.rb +44 -0
- data/extern.h +29 -0
- data/img/cursor.png +0 -0
- data/img/cursors.png +0 -0
- data/img/dice.png +0 -0
- data/img/wait_cursor.png +0 -0
- data/img/win_base.png +0 -0
- data/img/window.png +0 -0
- data/install_miyako.rb +87 -0
- data/lib/Miyako/API/audio.rb +584 -0
- data/lib/Miyako/API/basic_data.rb +1026 -0
- data/lib/Miyako/API/bitmap.rb +534 -0
- data/lib/Miyako/API/choices.rb +481 -0
- data/lib/Miyako/API/collision.rb +638 -0
- data/lib/Miyako/API/diagram.rb +586 -0
- data/lib/Miyako/API/drawing.rb +151 -0
- data/lib/Miyako/API/exceptions.rb +105 -0
- data/lib/Miyako/API/fixedmap.rb +462 -0
- data/lib/Miyako/API/font.rb +430 -0
- data/lib/Miyako/API/input.rb +456 -0
- data/lib/Miyako/API/layout.rb +644 -0
- data/lib/Miyako/API/map.rb +583 -0
- data/lib/Miyako/API/map_event.rb +222 -0
- data/lib/Miyako/API/modules.rb +357 -0
- data/lib/Miyako/API/movie.rb +166 -0
- data/lib/Miyako/API/parts.rb +188 -0
- data/lib/Miyako/API/plane.rb +205 -0
- data/lib/Miyako/API/screen.rb +341 -0
- data/lib/Miyako/API/shape.rb +443 -0
- data/lib/Miyako/API/sprite.rb +773 -0
- data/lib/Miyako/API/sprite_animation.rb +494 -0
- data/lib/Miyako/API/sprite_list.rb +1135 -0
- data/lib/Miyako/API/spriteunit.rb +168 -0
- data/lib/Miyako/API/story.rb +350 -0
- data/lib/Miyako/API/textbox.rb +773 -0
- data/lib/Miyako/API/utility.rb +419 -0
- data/lib/Miyako/API/viewport.rb +190 -0
- data/lib/Miyako/API/yuki.rb +1180 -0
- data/lib/Miyako/EXT/miyako_cairo.rb +62 -0
- data/lib/Miyako/EXT/raster_scroll.rb +138 -0
- data/lib/Miyako/EXT/slides.rb +157 -0
- data/lib/Miyako/miyako.rb +201 -0
- data/lib/Miyako/miyako_require_only.rb +35 -0
- data/logo/EGSR_logo.png +0 -0
- data/logo/EGSR_logo_bg.png +0 -0
- data/logo/EGSR_logo_fg.png +0 -0
- data/logo/EGSR_title_banner.png +0 -0
- data/logo/EGSR_title_logo.png +0 -0
- data/logo/miyako.png +0 -0
- data/logo/miyako_banner.png +0 -0
- data/logo/space.png +0 -0
- data/miyako_basicdata.c +484 -0
- data/miyako_bitmap.c +1225 -0
- data/miyako_collision.c +403 -0
- data/miyako_drawing.c +187 -0
- data/miyako_font.c +334 -0
- data/miyako_hsv.c +830 -0
- data/miyako_input_audio.c +254 -0
- data/miyako_layout.c +191 -0
- data/miyako_no_katana.c +1086 -0
- data/miyako_sprite2.c +431 -0
- data/miyako_transform.c +438 -0
- data/miyako_utility.c +288 -0
- data/sample/Animation1/m1ku.rb +68 -0
- data/sample/Animation1/m1ku_arm_0.png +0 -0
- data/sample/Animation1/m1ku_arm_1.png +0 -0
- data/sample/Animation1/m1ku_arm_2.png +0 -0
- data/sample/Animation1/m1ku_arm_3.png +0 -0
- data/sample/Animation1/m1ku_back.jpg +0 -0
- data/sample/Animation1/m1ku_body.png +0 -0
- data/sample/Animation1/m1ku_eye_0.png +0 -0
- data/sample/Animation1/m1ku_eye_1.png +0 -0
- data/sample/Animation1/m1ku_eye_2.png +0 -0
- data/sample/Animation1/m1ku_eye_3.png +0 -0
- data/sample/Animation1/m1ku_hair_front.png +0 -0
- data/sample/Animation1/m1ku_hair_rear.png +0 -0
- data/sample/Animation1/readme.txt +72 -0
- data/sample/Animation2/lex.rb +96 -0
- data/sample/Animation2/lex_back.png +0 -0
- data/sample/Animation2/lex_body.png +0 -0
- data/sample/Animation2/lex_roadroller.png +0 -0
- data/sample/Animation2/lex_wheel_0.png +0 -0
- data/sample/Animation2/lex_wheel_1.png +0 -0
- data/sample/Animation2/lex_wheel_2.png +0 -0
- data/sample/Animation2/readme.txt +72 -0
- data/sample/Animation2/song_title.png +0 -0
- data/sample/Diagram_sample/back.png +0 -0
- data/sample/Diagram_sample/chr01.png +0 -0
- data/sample/Diagram_sample/chr02.png +0 -0
- data/sample/Diagram_sample/cursor.png +0 -0
- data/sample/Diagram_sample/diagram_sample_yuki2.rb +329 -0
- data/sample/Diagram_sample/readme.txt +90 -0
- data/sample/Diagram_sample/wait_cursor.png +0 -0
- data/sample/Room3/blue.rb +297 -0
- data/sample/Room3/ending.rb +180 -0
- data/sample/Room3/green.rb +220 -0
- data/sample/Room3/image/akamatsu.png +0 -0
- data/sample/Room3/image/aoyama.png +0 -0
- data/sample/Room3/image/congra.png +0 -0
- data/sample/Room3/image/congratulation.png +0 -0
- data/sample/Room3/image/congratulation_bg.png +0 -0
- data/sample/Room3/image/cursor.png +0 -0
- data/sample/Room3/image/midori.png +0 -0
- data/sample/Room3/image/mittsu_no_oheya.png +0 -0
- data/sample/Room3/image/mittsu_no_oheya_logo.png +0 -0
- data/sample/Room3/image/room_blue.png +0 -0
- data/sample/Room3/image/room_green.png +0 -0
- data/sample/Room3/image/room_red.png +0 -0
- data/sample/Room3/image/start.png +0 -0
- data/sample/Room3/image/three_doors.png +0 -0
- data/sample/Room3/image/wait_cursor.png +0 -0
- data/sample/Room3/main.rb +120 -0
- data/sample/Room3/main_component.rb +59 -0
- data/sample/Room3/readme.txt +76 -0
- data/sample/Room3/red.rb +227 -0
- data/sample/Room3/room3.rb +25 -0
- data/sample/Room3/title.rb +184 -0
- data/sample/ball_action_sample.rb +204 -0
- data/sample/blit_rop.rb +70 -0
- data/sample/cairo_sample.rb +25 -0
- data/sample/circle_collision_test.rb +66 -0
- data/sample/collision_test.rb +33 -0
- data/sample/collision_test2.rb +108 -0
- data/sample/fixed_map_test/cursor.png +0 -0
- data/sample/fixed_map_test/fixed_map_sample.rb +140 -0
- data/sample/fixed_map_test/map.csv +19 -0
- data/sample/fixed_map_test/map_01.png +0 -0
- data/sample/fixed_map_test/mapchip.csv +23 -0
- data/sample/fixed_map_test/monster.png +0 -0
- data/sample/fixed_map_test/readme.txt +72 -0
- data/sample/map_test/chara.rb +58 -0
- data/sample/map_test/chr1.png +0 -0
- data/sample/map_test/cursor.png +0 -0
- data/sample/map_test/main_parts.rb +69 -0
- data/sample/map_test/main_scene.rb +153 -0
- data/sample/map_test/map.png +0 -0
- data/sample/map_test/map2.png +0 -0
- data/sample/map_test/map_layer.csv +127 -0
- data/sample/map_test/map_manager.rb +75 -0
- data/sample/map_test/map_test.rb +23 -0
- data/sample/map_test/mapchip.csv +21 -0
- data/sample/map_test/oasis.rb +71 -0
- data/sample/map_test/readme.txt +89 -0
- data/sample/map_test/route.rb +157 -0
- data/sample/map_test/sea.png +0 -0
- data/sample/map_test/town.rb +74 -0
- data/sample/map_test/wait_cursor.png +0 -0
- data/sample/map_test/window.png +0 -0
- data/sample/polygon_test.rb +35 -0
- data/sample/rasterscroll.rb +25 -0
- data/sample/takahashi.rb +42 -0
- data/sample/text.png +0 -0
- data/sample/textbox_sample.rb +192 -0
- data/sample/transform.rb +54 -0
- data/sample/utility_test.rb +73 -0
- data/sample/utility_test2.rb +61 -0
- data/sample/utility_test3.rb +64 -0
- data/sample/utility_test4.rb +73 -0
- data/uninstall_miyako.rb +19 -0
- data/win/miyako_no_katana.so +0 -0
- metadata +216 -0
@@ -0,0 +1,419 @@
|
|
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
|
+
module Miyako
|
24
|
+
#==ユーティリティモジュール
|
25
|
+
module Utility
|
26
|
+
def Utility.get_step_array_f(v1, v2, amount, skip_even = false) #:nodoc:
|
27
|
+
steps = []
|
28
|
+
amount = amount.abs
|
29
|
+
val = v1
|
30
|
+
if v1 < v2
|
31
|
+
loop do
|
32
|
+
val = val + amount
|
33
|
+
break if (skip_even && (v2-val).abs < Float::EPSILON)
|
34
|
+
break if val > v2
|
35
|
+
steps << val
|
36
|
+
end
|
37
|
+
else
|
38
|
+
loop do
|
39
|
+
val = val - amount
|
40
|
+
break if (skip_even && (v2-val).abs < Float::EPSILON)
|
41
|
+
break if val < v2
|
42
|
+
steps << val
|
43
|
+
end
|
44
|
+
end
|
45
|
+
return steps
|
46
|
+
end
|
47
|
+
|
48
|
+
def Utility.product_liner_inner_f(x1, y1, x2, y2, amount) #:nodoc:
|
49
|
+
array = nil
|
50
|
+
step_x = get_step_array_f(x1, x2, amount)
|
51
|
+
step_y = get_step_array_f(y1, y2, amount)
|
52
|
+
dx = x2 - x1
|
53
|
+
dy = y2 - y1
|
54
|
+
a = dx < Float::EPSILON ? dy.to_f : dy.to_f / dx.to_f
|
55
|
+
b = y1.to_f - a * x1.to_f
|
56
|
+
array = [[x1,y1] , [x2,y2]] + step_x.map{|x| [x, (a * x.to_f + b).to_i]}
|
57
|
+
array += step_y.map{|y| [((y.to_f - b) / a).to_i, y]} if (a.abs >= Float::EPSILON)
|
58
|
+
return array.uniq
|
59
|
+
end
|
60
|
+
|
61
|
+
#===矩形内の対角線の座標リストを実数で取得する
|
62
|
+
# (互換性維持のために残している)
|
63
|
+
# 矩形内の対角線の座標リストを取得する
|
64
|
+
# 引数には、Rect(x,y,w,h)形式のインスタンスを渡す
|
65
|
+
# 幅・高さはマイナスの値の設定が可能。
|
66
|
+
# 幅・高さのどちらかの値が0(Float::EPSILON未満)の場合は[]が返る
|
67
|
+
# 刻みの値は1以上の整数を渡す。0(Float::EPSILON未満)以下の場合は例外が発生する。
|
68
|
+
# 結果は[x,y]の配列となるが、正確さを優先したため、必ず刻みの値の間隔で並んでいない
|
69
|
+
#(刻みの値より小さい)ことがある
|
70
|
+
#_rect_:: 矩形情報
|
71
|
+
#_amount_:: 配列を作成する座標の刻み。デフォルトは1.0
|
72
|
+
#返却値:: 矩形左上位置[x,y]の配列(指定の矩形に掛かる位置の組み合わせ)
|
73
|
+
def Utility.product_liner_f(rect, amount = 1.0)
|
74
|
+
raise MiyakoValueError, "Illegal amount! #{amount}" if amount < Float::EPSILON
|
75
|
+
return [] if rect[2] < Float::EPSILON || rect[3] < Float::EPSILON
|
76
|
+
x1 = rect[0]
|
77
|
+
y1 = rect[1]
|
78
|
+
x2 = x1 + rect[2] - 1
|
79
|
+
y2 = y1 + rect[3] - 1
|
80
|
+
return product_liner_inner_f(x1, y1, x2, y2, amount)
|
81
|
+
end
|
82
|
+
|
83
|
+
#===矩形内の対角線の座標リストを実数で取得する
|
84
|
+
# (互換性維持のために残している)
|
85
|
+
# 矩形内の対角線の座標リストを取得する
|
86
|
+
# 引数には、Rect(x,y,w,h)形式のインスタンスを渡す
|
87
|
+
# 幅・高さはマイナスの値の設定が可能。
|
88
|
+
# 幅・高さのどちらかの値が0(Float::EPSILON未満)の場合は[]が返る
|
89
|
+
# 刻みの値は1以上の整数を渡す。0(Float::EPSILON未満)以下の場合は例外が発生する。
|
90
|
+
# 結果は[x,y]の配列となるが、正確さを優先したため、必ず刻みの値の間隔で並んでいない
|
91
|
+
#(刻みの値より小さい)ことがある
|
92
|
+
#_rect_:: 矩形情報
|
93
|
+
#_amount_:: 配列を作成する座標の刻み。デフォルトは1
|
94
|
+
#返却値:: 矩形左上位置[x,y]の配列(指定の矩形に掛かる位置の組み合わせ)
|
95
|
+
def Utility.product_liner_by_square_f(square, amount = 1.0)
|
96
|
+
raise MiyakoValueError, "Illegal amount! #{amount}" if amount < Float::EPSILON
|
97
|
+
return [] if (square[2] - square[0]) < Float::EPSILON || (square[3] - square[1]) < Float::EPSILON
|
98
|
+
return product_liner_inner_f(*square, amount)
|
99
|
+
end
|
100
|
+
|
101
|
+
def Utility.product_liner_inner(x1, y1, x2, y2, amount) #:nodoc:
|
102
|
+
array = nil
|
103
|
+
step_x = []
|
104
|
+
step_y = []
|
105
|
+
dx = x2 - x1
|
106
|
+
dy = y2 - y1
|
107
|
+
a = 0.0
|
108
|
+
if [x1, y1, x2, y2, amount].all?{|v| v.methods.include?(:step)}
|
109
|
+
step_x = x1 < x2 ? x1.step(x2, amount).to_a : x1.step(x2, -amount).to_a
|
110
|
+
step_y = y1 < y2 ? y1.step(y2, amount).to_a : y1.step(y2, -amount).to_a
|
111
|
+
a = dx == 0 ? dy.to_f : dy.to_f / dx.to_f
|
112
|
+
else
|
113
|
+
step_x = get_step_array_f(x1, x2, amount)
|
114
|
+
step_y = get_step_array_f(y1, y2, amount)
|
115
|
+
a = dx < Float::EPSILON ? dy.to_f : dy.to_f / dx.to_f
|
116
|
+
end
|
117
|
+
b = y1.to_f - a * x1.to_f
|
118
|
+
array = [[x1,y1] , [x2,y2]] + step_x.map{|x| [x, (a * x.to_f + b).to_i]}
|
119
|
+
array += step_y.map{|y| [((y.to_f - b) / a).to_i, y]} if (a.abs >= Float::EPSILON)
|
120
|
+
return array.uniq
|
121
|
+
end
|
122
|
+
|
123
|
+
#===矩形内の対角線の座標リストを取得する
|
124
|
+
# 矩形内の対角線の座標リストを取得する
|
125
|
+
# 引数には、Rect(x,y,w,h)形式のインスタンスを渡す
|
126
|
+
# 幅・高さはマイナスの値の設定が可能。
|
127
|
+
# 幅・高さのどちらかの値が0の場合は[]が返る
|
128
|
+
# 刻みの値は1以上の整数を渡す。0以下の場合は例外が発生する。
|
129
|
+
# 結果は[x,y]の配列となるが、正確さを優先したため、必ず刻みの値の間隔で並んでいない
|
130
|
+
#(刻みの値より小さいことがある)ことがある
|
131
|
+
#_rect_:: 矩形情報
|
132
|
+
#_amount_:: 配列を作成する座標の刻み。デフォルトは1
|
133
|
+
#返却値:: 矩形左上位置[x,y]の配列(指定の矩形に掛かる位置の組み合わせ)
|
134
|
+
def Utility.product_liner(rect, amount = 1)
|
135
|
+
raise MiyakoValueError, "Illegal amount! #{amount}" if amount <= 0
|
136
|
+
return [] if rect[2] == 0 || rect[3] == 0
|
137
|
+
x1 = rect[0]
|
138
|
+
y1 = rect[1]
|
139
|
+
x2 = x1 + rect[2] - 1
|
140
|
+
y2 = y1 + rect[3] - 1
|
141
|
+
return product_liner_inner(x1, y1, x2, y2, amount)
|
142
|
+
end
|
143
|
+
|
144
|
+
#===矩形内の対角線の座標リストを取得する
|
145
|
+
# 矩形内の対角線の座標リストを取得する
|
146
|
+
# 引数には、Rect(x,y,w,h)形式のインスタンスを渡す
|
147
|
+
# 幅・高さはマイナスの値の設定が可能。
|
148
|
+
# 幅・高さのどちらかの値が0の場合は[]が返る
|
149
|
+
# 刻みの値は1以上の整数を渡す。0以下の場合は例外が発生する。
|
150
|
+
# 結果は[x,y]の配列となるが、正確さを優先したため、必ず刻みの値の間隔で並んでいない
|
151
|
+
#(刻みの値より小さいことがある)ことがある
|
152
|
+
#_rect_:: 矩形情報
|
153
|
+
#_amount_:: 配列を作成する座標の刻み。デフォルトは1
|
154
|
+
#返却値:: 矩形左上位置[x,y]の配列(指定の矩形に掛かる位置の組み合わせ)
|
155
|
+
def Utility.product_liner_by_square(square, amount = 1)
|
156
|
+
raise MiyakoValueError, "Illegal amount! #{amount}" if amount <= 0
|
157
|
+
return [] if (square[2] - square[0]) == 0 || (square[3] - square[1]) == 0
|
158
|
+
return product_liner_inner(*square, amount)
|
159
|
+
end
|
160
|
+
|
161
|
+
def Utility.product_inner(x1, y1, x2, y2, size) #:nodoc:
|
162
|
+
x_array = ((x1 / size[0])..(x2 / size[0])).to_a.map{|e| e * size[0]}
|
163
|
+
y_array = ((y1 / size[1])..(y2 / size[1])).to_a.map{|e| e * size[1]}
|
164
|
+
return x_array.product(y_array)
|
165
|
+
end
|
166
|
+
|
167
|
+
#===指定の矩形が格子状のどこに重なっているかを返す
|
168
|
+
# position(Point([x,y])形式)を基準として、矩形rect(Rect([x,y,w,h])形式)が、格子状の並べた矩形
|
169
|
+
# (基準を[0,0]とした、大きさ[size,size]の矩形をタイル状に並べた物)にある場合、
|
170
|
+
#どの格子状の矩形が重なっているかを、矩形の左上座標の配列として渡す(x座標とy座標の組み合わせ)。
|
171
|
+
#
|
172
|
+
#_position_:: 基準位置
|
173
|
+
#_rect_:: 矩形情報
|
174
|
+
#返却値:: 矩形左上位置の配列(指定の矩形に掛かる位置の組み合わせ)
|
175
|
+
def Utility.product_position(position, rect, size)
|
176
|
+
return product_inner(
|
177
|
+
position[0] + rect[0],
|
178
|
+
position[1] + rect[1],
|
179
|
+
position[0] + rect[0] + rect[2] - 1,
|
180
|
+
position[1] + rect[1] + rect[3] - 1,
|
181
|
+
size
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
#===指定の矩形が格子状のどこに重なっているかを返す
|
186
|
+
# 矩形square(Square([x1,y1,x2,y2])形式)が、格子状の並べた矩形
|
187
|
+
# (基準を[0,0]とした、大きさ[size,size]の矩形をタイル状に並べた物)にある場合、
|
188
|
+
#どの格子状の矩形が重なっているかを、矩形の左上座標の配列として渡す(x座標とy座標の組み合わせ)。
|
189
|
+
#_square_:: 矩形情報
|
190
|
+
#返却値:: 矩形左上位置の配列(指定の矩形に掛かる位置の組み合わせ)
|
191
|
+
def Utility.product_position_by_square(square, size)
|
192
|
+
return product_inner(*square.to_a, size)
|
193
|
+
end
|
194
|
+
|
195
|
+
def Utility.product_inner_f(x1, y1, x2, y2, size, skip_even = false) #:nodoc:
|
196
|
+
sz = size[0].to_f
|
197
|
+
min = (x1.to_f/sz).floor.to_f * sz
|
198
|
+
x_array = [min] + get_step_array_f(min, x2.to_f, sz, skip_even)
|
199
|
+
sz = size[1].to_f
|
200
|
+
min = (y1.to_f/sz).floor.to_f * sz
|
201
|
+
y_array = [min] + get_step_array_f(min, y2.to_f, sz, skip_even)
|
202
|
+
return x_array.uniq.product(y_array.uniq)
|
203
|
+
end
|
204
|
+
|
205
|
+
#===指定の矩形が格子状のどこに重なっているかを返す(実数で指定)
|
206
|
+
#position(Point([x,y])形式)を基準として、矩形rect(Rect([x,y,w,h])形式)が、格子状の並べた矩形
|
207
|
+
#(基準を[0.0,0.0]とした、大きさ[size,size]の矩形をタイル状に並べた物)にある場合、
|
208
|
+
#どの格子状の矩形が重なっているかを、矩形の左上座標の配列として渡す(x座標とy座標の組み合わせ)。
|
209
|
+
#
|
210
|
+
#_position_:: 基準位置
|
211
|
+
#_rect_:: 矩形情報
|
212
|
+
#返却値:: 矩形左上位置の配列(指定の矩形に掛かる位置の組み合わせ)
|
213
|
+
def Utility.product_position_f(position, rect, size)
|
214
|
+
return product_inner_f(
|
215
|
+
position[0] + rect[0],
|
216
|
+
position[1] + rect[1],
|
217
|
+
position[0] + rect[0] + rect[2],
|
218
|
+
position[1] + rect[1] + rect[3],
|
219
|
+
size,
|
220
|
+
true
|
221
|
+
)
|
222
|
+
end
|
223
|
+
|
224
|
+
#===指定の矩形が格子状のどこに重なっているかを返す(実数で指定)
|
225
|
+
# 矩形square(Square([x1,y1,x2,y2])形式)が、格子状の並べた矩形
|
226
|
+
# (基準を[0.0,0.0]とした、大きさ[size,size]の矩形をタイル状に並べた物)にある場合、
|
227
|
+
#どの格子状の矩形が重なっているかを、矩形の左上座標の配列として渡す(x座標とy座標の組み合わせ)。
|
228
|
+
#_square_:: 矩形情報
|
229
|
+
#返却値:: 矩形左上位置の配列(指定の矩形に掛かる位置の組み合わせ)
|
230
|
+
def Utility.product_position_by_square_f(square, size)
|
231
|
+
return product_inner_f(*square.to_a, size)
|
232
|
+
end
|
233
|
+
|
234
|
+
#===2点間の距離を算出する
|
235
|
+
# 2点(点1、点2)がどの程度離れているかを算出する。
|
236
|
+
# 返ってくる値は、正の実数で返ってくる
|
237
|
+
#_point1_:: 点1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
238
|
+
#_point2_:: 点2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
239
|
+
#返却値:: 2点間の距離
|
240
|
+
def Utility.interval(point1, point2)
|
241
|
+
#2点間の距離を求める
|
242
|
+
d = Math.sqrt(((point1[0].to_f - point2[0].to_f) ** 2) +
|
243
|
+
((point1[1].to_f - point2[1].to_f) ** 2))
|
244
|
+
return d < Float::EPSILON ? 0.0 : d
|
245
|
+
end
|
246
|
+
|
247
|
+
#===2点間の傾きを角度で算出する
|
248
|
+
# 2点(点1、点2)がどの程度傾いているか算出する。傾きの中心は点1とする。
|
249
|
+
# 角度の単位は度(0.0<=θ<360.0)
|
250
|
+
# 返ってくる値は、正の実数で返ってくる
|
251
|
+
#_point1_:: 点1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
252
|
+
#_point2_:: 点2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
253
|
+
#返却値:: 2点間の傾き
|
254
|
+
def Utility.theta(point1, point2)
|
255
|
+
#2点間の距離を求める
|
256
|
+
d = Math.sqrt(((point1[0].to_f - point2[0].to_f) ** 2) +
|
257
|
+
((point1[1].to_f - point2[1].to_f) ** 2))
|
258
|
+
x = point2[0].to_f - point[1].to_f
|
259
|
+
# 傾き・幅が0のときは傾きは0度
|
260
|
+
return 0.0 if (x.abs < Float::EPSILON or d < Float::EPSILON)
|
261
|
+
theta = (Math.acos(x / d) / (2 * Math::PI)) * 360.0
|
262
|
+
return theta < Float::EPSILON ? 0.0 : theta
|
263
|
+
end
|
264
|
+
|
265
|
+
#===小線分を移動させたとき、大線分が範囲内かどうかを判別する
|
266
|
+
# 移動後の小線分が大線分の範囲内にあるかどうかをtrue/falseで取得する
|
267
|
+
#_mini_segment_:: 小線分の範囲。[min,max]で構成された2要素の配列
|
268
|
+
#_big_segment_:: 大線分の範囲。[min,max]で構成された2要素の配列
|
269
|
+
#_d_:: mini_segmentの移動量
|
270
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
271
|
+
#返却値:: 範囲内のときはtrue、範囲外の時はfalseを返す
|
272
|
+
def Utility.in_bounds?(mini_segment, big_segment, d, flag = false)
|
273
|
+
nx = mini_segment[0] + d
|
274
|
+
nx2 = mini_segment[1] + d
|
275
|
+
nx, nx2 = nx2, nx if nx > nx2
|
276
|
+
return flag ? (nx >= big_segment[0] && nx2 <= big_segment[1]) : (nx > big_segment[0] && (nx2 - 1) < big_segment[1])
|
277
|
+
end
|
278
|
+
|
279
|
+
#===小線分を移動させたとき、大線分が範囲内かどうかを判別して、その状態によって値を整数で返す
|
280
|
+
# 移動後の小線分の範囲が大線分の範囲内のときは0、
|
281
|
+
# マイナス方向で範囲外に出るときは-1、
|
282
|
+
# プラス方向で出るときは1を返す
|
283
|
+
#_mini_segment_:: 小線分の範囲。[min,max]で構成された2要素の配列
|
284
|
+
#_big_segment_:: 大線分の範囲。[min,max]で構成された2要素の配列
|
285
|
+
#_d_:: mini_segmentの移動量
|
286
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
287
|
+
#返却値:: 判別の結果
|
288
|
+
def Utility.in_bounds_ex?(mini_segment, big_segment, d, flag = false)
|
289
|
+
nx = mini_segment[0] + d
|
290
|
+
nx2 = mini_segment[1] + d - 1
|
291
|
+
nx, nx2 = nx2, nx if nx > nx2
|
292
|
+
return -1 if (nx < big_segment[0]) || (flag && (nx == big_segment[0]))
|
293
|
+
return (nx2 > big_segment[1]) || (flag && (nx2 == big_segment[1])) ? 1 : 0
|
294
|
+
end
|
295
|
+
|
296
|
+
#===移動先が表示範囲内かどうかを判別して、その状態によって値を整数で返す
|
297
|
+
# 移動後の小線分の範囲が大線分の範囲内のときは0、
|
298
|
+
# マイナス方向で範囲外に出るときは1、
|
299
|
+
# プラス方向で出るときは-1を返す
|
300
|
+
#_mini_segment_:: 小線分の範囲。[min,max]で構成された2要素の配列
|
301
|
+
#_big_segment_:: 大線分の範囲。[min,max]で構成された2要素の配列
|
302
|
+
#_d_:: mini_segmentの移動量
|
303
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
304
|
+
#返却値:: 判別の結果
|
305
|
+
def Utility.in_bounds_rev?(mini_segment, big_segment, d, flag = false)
|
306
|
+
nx = mini_segment[0] + d
|
307
|
+
nx2 = mini_segment[1] + d - 1
|
308
|
+
nx, nx2 = nx2, nx if nx > nx2
|
309
|
+
return 1 if (nx < big_segment[0]) || (flag && (nx == big_segment[0]))
|
310
|
+
return (nx2 > big_segment[1]) || (flag && (nx2 == big_segment[1])) ? -1 : 0
|
311
|
+
end
|
312
|
+
|
313
|
+
#===移動先が表示範囲内かどうかを判別して、その状態によって値を整数で返す
|
314
|
+
# 移動量が0のときは0、
|
315
|
+
# 移動後の小線分の範囲が大線分の範囲内のときは1、
|
316
|
+
# 範囲外に出るときは-1を返す
|
317
|
+
#_mini_segment_:: 小線分の範囲。[min,max]で構成された2要素の配列
|
318
|
+
#_big_segment_:: 大線分の範囲。[min,max]で構成された2要素の配列
|
319
|
+
#_d_:: mini_segmentの移動量
|
320
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
321
|
+
#返却値:: 判別の結果
|
322
|
+
def Utility.in_bounds_rev_ex?(mini_segment, big_segment, d, flag = false)
|
323
|
+
return 0 if d == 0
|
324
|
+
dir = (d <=> 0)
|
325
|
+
nx = mini_segment[0] + d
|
326
|
+
nx2 = mini_segment[1] + d - 1
|
327
|
+
nx, nx2 = nx2, nx if nx > nx2
|
328
|
+
return -dir if (nx < big_segment[0]) || (flag && (nx == big_segment[0]))
|
329
|
+
return (nx2 > big_segment[1]) || (flag && (nx2 == big_segment[1])) ? -dir : dir
|
330
|
+
end
|
331
|
+
|
332
|
+
#===小線分を移動させたとき、大線分が範囲内かどうかを判別する
|
333
|
+
# 移動後の小線分が大線分の範囲内にあるかどうかをtrue/falseで取得する
|
334
|
+
#_mini_pos_:: 小線分の開始点の位置
|
335
|
+
#_mini_size_:: 小線分の幅。0以上の整数
|
336
|
+
#_big_pos_:: 大線分の開始点の位置
|
337
|
+
#_big_size_:: 大線分の幅。1以上の整数
|
338
|
+
#_d_:: mini_segmentの移動量
|
339
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
340
|
+
#返却値:: 範囲内のときはtrue、範囲外の時はfalseを返す
|
341
|
+
def Utility.in_bounds_by_size?(pos1, size1, pos2, size2, d, flag = false)
|
342
|
+
raise MiyakoValueError, "illegal size1! #{size1}" if size1 < 0
|
343
|
+
raise MiyakoValueError, "illegal size2! #{size2}" if size2 <= 0
|
344
|
+
raise MiyakoValueError, "size1 is more than size2! #{size1}, #{size2}" if size1 > size2
|
345
|
+
min_x1 = pos1 + d
|
346
|
+
min_x2 = pos1 + size1 + d
|
347
|
+
min_x1, min_x2 = min_x2, min_x1 if min_x1 > min_x2
|
348
|
+
return flag ? (min_x1 >= pos2 && min_x2 <= pos2+size2) : (minx_x1 > pos2 && min_x2 < pos2+size2)
|
349
|
+
end
|
350
|
+
|
351
|
+
#===小線分を移動させたとき、大線分が範囲内かどうかを判別して、その状態によって値を整数で返す
|
352
|
+
# 移動後の小線分の範囲が大線分の範囲内のときは0、
|
353
|
+
# マイナス方向で範囲外に出るときは-1、
|
354
|
+
# プラス方向で出るときは1を返す
|
355
|
+
#_mini_pos_:: 小線分の開始点の位置
|
356
|
+
#_mini_size_:: 小線分の幅。0以上の整数
|
357
|
+
#_big_pos_:: 大線分の開始点の位置
|
358
|
+
#_big_size_:: 大線分の幅。1以上の整数
|
359
|
+
#_d_:: mini_segmentの移動量
|
360
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
361
|
+
#返却値:: 判別の結果
|
362
|
+
def Utility.in_bounds_ex_by_size?(pos1, size1, pos2, size2, d, flag = false)
|
363
|
+
raise MiyakoValueError, "illegal size1! #{size1}" if size1 < 0
|
364
|
+
raise MiyakoValueError, "illegal size2! #{size2}" if size2 <= 0
|
365
|
+
raise MiyakoValueError, "size1 is more than size2! #{size1}, #{size2}" if size1 > size2
|
366
|
+
min_x1 = pos1 + d
|
367
|
+
min_x2 = pos1 + size1 + d
|
368
|
+
min_x1, min_x2 = min_x2, min_x1 if min_x1 > min_x2
|
369
|
+
return -1 if (min_x1 < pos2) || (flag && (min_x1 == pos2))
|
370
|
+
return (min_x2 > pos2+size2) || (flag && (min_x2 == pos2+size2)) ? 1 : 0
|
371
|
+
end
|
372
|
+
|
373
|
+
#===移動先が表示範囲内かどうかを判別して、その状態によって値を整数で返す
|
374
|
+
# 移動後の小線分の範囲が大線分の範囲内のときは0、
|
375
|
+
# マイナス方向で範囲外に出るときは1、
|
376
|
+
# プラス方向で出るときは-1を返す
|
377
|
+
#_mini_pos_:: 小線分の開始点の位置
|
378
|
+
#_mini_size_:: 小線分の幅。0以上の整数
|
379
|
+
#_big_pos_:: 大線分の開始点の位置
|
380
|
+
#_big_size_:: 大線分の幅。1以上の整数
|
381
|
+
#_d_:: mini_segmentの移動量
|
382
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
383
|
+
#返却値:: 判別の結果
|
384
|
+
def Utility.in_bounds_rev_by_size?(pos1, size1, pos2, size2, d, flag = false)
|
385
|
+
raise MiyakoValueError, "illegal size1! #{size1}" if size1 < 0
|
386
|
+
raise MiyakoValueError, "illegal size2! #{size2}" if size2 <= 0
|
387
|
+
raise MiyakoValueError, "size1 is more than size2! #{size1}, #{size2}" if size1 > size2
|
388
|
+
min_x1 = pos1 + d
|
389
|
+
min_x2 = pos1 + size1 + d
|
390
|
+
min_x1, min_x2 = min_x2, min_x1 if min_x1 > min_x2
|
391
|
+
return 1 if (min_x1 < pos2) || (flag && (min_x1 == pos2))
|
392
|
+
return (min_x2 > pos2+size2) || (flag && (min_x2 == pos2+size2)) ? -1 : 0
|
393
|
+
end
|
394
|
+
|
395
|
+
#===移動先が表示範囲内かどうかを判別して、その状態によって値を整数で返す
|
396
|
+
# 移動量が0のときは0、
|
397
|
+
# 移動後の小線分の範囲が大線分の範囲内のときは1、
|
398
|
+
# 範囲外に出るときは-1を返す
|
399
|
+
#_mini_pos_:: 小線分の開始点の位置
|
400
|
+
#_mini_size_:: 小線分の幅。0以上の整数
|
401
|
+
#_big_pos_:: 大線分の開始点の位置
|
402
|
+
#_big_size_:: 大線分の幅。1以上の整数
|
403
|
+
#_d_:: mini_segmentの移動量
|
404
|
+
#_flag_:: 大線分の端いっぱいも範囲外に含めるときはtrueを設定する。デフォルトはfalse
|
405
|
+
#返却値:: 判別の結果
|
406
|
+
def Utility.in_bounds_rev_ex_by_size?(pos1, size1, pos2, size2, d, flag = false)
|
407
|
+
return 0 if d == 0
|
408
|
+
raise MiyakoValueError, "illegal size1! #{size1}" if size1 < 0
|
409
|
+
raise MiyakoValueError, "illegal size2! #{size2}" if size2 <= 0
|
410
|
+
raise MiyakoValueError, "size1 is more than size2! #{size1}, #{size2}" if size1 > size2
|
411
|
+
dir = (d <=> 0)
|
412
|
+
min_x1 = pos1 + d
|
413
|
+
min_x2 = pos1 + size1 + d
|
414
|
+
min_x1, min_x2 = min_x2, min_x1 if min_x1 > min_x2
|
415
|
+
return -dir if (min_x1 < pos2) || (flag && (min_x1 == pos2))
|
416
|
+
return (min_x2 > pos2+size2) || (flag && (min_x2 == pos2+size2)) ? -dir : dir
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
--
|
4
|
+
Miyako v2.1
|
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
|
+
# 画面全体を基準(640x480の画面のときは(0,0)-(639,479)の範囲)として、範囲を設定する
|
27
|
+
# 範囲の設定はいつでも行えるが、描画にはrenderメソッドを呼び出した時の値が反映される
|
28
|
+
class Viewport
|
29
|
+
include SpriteBase
|
30
|
+
include Animation
|
31
|
+
|
32
|
+
attr_accessor :visible #レンダリングの可否(true->描画 false->非描画)
|
33
|
+
|
34
|
+
#===ビューポートのインスタンスを生成する
|
35
|
+
#_x_:: ビューポートの左上位置(x座標)
|
36
|
+
#_y_:: ビューポートの左上位置(y座標)
|
37
|
+
#_w_:: ビューポートの幅(共に1以上、0以下のときはエラーが出る)
|
38
|
+
#_h_:: ビューポートの高さ(共に1以上、0以下のときはエラーが出る)
|
39
|
+
def initialize(x, y, w, h)
|
40
|
+
raise MiyakoValueError, "Illegal size! w:#{w} h:#{h}" if (w <= 0 || h <= 0)
|
41
|
+
@rect = Rect.new(x, y, w, h)
|
42
|
+
@sq = Rect.new(x, y, x+w-1, y+h-1)
|
43
|
+
@visible = true
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize_copy(obj) #:nodoc:
|
47
|
+
@rect = @rect.dup
|
48
|
+
@sq = @sq.dup
|
49
|
+
end
|
50
|
+
|
51
|
+
#===ビューポートの内容を画面に反映する
|
52
|
+
# ブロックが渡ってきたときは、範囲を変更して指定することが出来る(この変更は、本メソッドを呼ぶ時だけ有効)
|
53
|
+
# ブロックの引数は、|Rect構造体|が渡される。
|
54
|
+
#_block_:: 呼び出し時にブロック付き呼び出しが行われたときのブロック本体。
|
55
|
+
#呼び先に渡すことが出来る。ブロックがなければnilが入る
|
56
|
+
def render(&block)
|
57
|
+
return unless @visible
|
58
|
+
if block_given?
|
59
|
+
rect = @rect.dup
|
60
|
+
yield rect
|
61
|
+
Screen.bitmap.set_clip_rect(*rect)
|
62
|
+
else
|
63
|
+
Screen.bitmap.set_clip_rect(*@rect)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#===ビューポートの左上位置を変更する
|
68
|
+
# 移動量を指定して、位置を変更する
|
69
|
+
# ブロックを渡したとき、ブロックの評価した結果、偽になったときは移動させた値を元に戻す
|
70
|
+
#_dx_:: 移動量(x方向)
|
71
|
+
#_dy_:: 移動量(y方向)
|
72
|
+
#返却値:: 自分自身を返す
|
73
|
+
def move!(dx,dy)
|
74
|
+
orect = rect.to_a[0..1]
|
75
|
+
osq = sq.to_a[0..1]
|
76
|
+
@rect.move!(dx,dy)
|
77
|
+
@sq.move!(dx, dy)
|
78
|
+
if block_given?
|
79
|
+
unless yield(self)
|
80
|
+
@rect.move_to!(*orect)
|
81
|
+
@sq.move_to!(*osq)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
return self
|
85
|
+
end
|
86
|
+
|
87
|
+
#===ビューポートの左上位置を変更する
|
88
|
+
# 移動先を指定して、位置を変更する
|
89
|
+
# ブロックを渡したとき、ブロックの評価した結果、偽になったときは移動させた値を元に戻す
|
90
|
+
#_x_:: 移動先位置(x方向)
|
91
|
+
#_y_:: 移動先位置(y方向)
|
92
|
+
#返却値:: 自分自身を返す
|
93
|
+
def move_to!(x,y)
|
94
|
+
orect = rect.to_a[0..1]
|
95
|
+
osq = sq.to_a[0..1]
|
96
|
+
@rect.move_to!(x,y)
|
97
|
+
@sq.move_to!(x, y)
|
98
|
+
if block_given?
|
99
|
+
unless yield(self)
|
100
|
+
@rect.move_to!(*orect)
|
101
|
+
@sq.move_to!(*osq)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
#===ビューポートの大きさを変更する
|
107
|
+
# 変化量を指定して変更する
|
108
|
+
#_dw_:: 幅
|
109
|
+
#_dh_:: 高さ
|
110
|
+
#返却値:: 自分自身を返す
|
111
|
+
def resize!(dw,dh)
|
112
|
+
raise MiyakoValueError, "Illegal size! w:#{w} h:#{h}" if ((@rect.w + dw) <= 0 || (@rect.h + dh) <= 0)
|
113
|
+
@rect.resize!(dw, dh)
|
114
|
+
@sq.resize!(dw, dh)
|
115
|
+
return self
|
116
|
+
end
|
117
|
+
|
118
|
+
#===ビューポートの大きさを変更する
|
119
|
+
# 幅と高さを指定して変更する
|
120
|
+
#_w_:: 幅
|
121
|
+
#_h_:: 高さ
|
122
|
+
#返却値:: 自分自身を返す
|
123
|
+
def resize_to!(w,h)
|
124
|
+
raise MiyakoValueError, "Illegal size! w:#{w} h:#{h}" if (w <= 0 || h <= 0)
|
125
|
+
@rect.resize_to!(w,h)
|
126
|
+
@sq.resize_to!(w, h)
|
127
|
+
return self
|
128
|
+
end
|
129
|
+
|
130
|
+
#===ビューポートの左上位置を変更したときの位置を求める
|
131
|
+
#移動量を指定して、位置を変更する
|
132
|
+
#ただし、自分自身の位置は変わらない
|
133
|
+
#_dx_:: 移動量(x方向)
|
134
|
+
#_dy_:: 移動量(y方向)
|
135
|
+
#返却値:: 更新したインスタンス(Rect構造体)を返す
|
136
|
+
def move(dx,dy)
|
137
|
+
@rect.dup.move!(dx,dy)
|
138
|
+
end
|
139
|
+
|
140
|
+
#===ビューポートの左上位置を変更したときの位置を求める
|
141
|
+
#移動先を指定して、位置を変更する
|
142
|
+
#ただし、自分自身の位置は変わらない
|
143
|
+
#_x_:: 移動先位置(x方向)
|
144
|
+
#_y_:: 移動先位置(y方向)
|
145
|
+
#返却値:: 更新したインスタンス(Rect構造体)を返す
|
146
|
+
def move_to(x,y)
|
147
|
+
@rect.dup.move_to!(x,y)
|
148
|
+
end
|
149
|
+
|
150
|
+
#===ビューポートの大きさを変更したときの値を求める
|
151
|
+
#変化量を指定して変更する
|
152
|
+
#ただし、自分自身の位置は変わらない
|
153
|
+
#_dw_:: 幅
|
154
|
+
#_dh_:: 高さ
|
155
|
+
#返却値:: 更新したインスタンス(Rect構造体)を返す
|
156
|
+
def resize(dw,dh)
|
157
|
+
raise MiyakoValueError, "Illegal size! w:#{w} h:#{h}" if ((@rect.w + dw) <= 0 || (@rect.h + dh) <= 0)
|
158
|
+
@rect.dup.resize!(dw,dh)
|
159
|
+
end
|
160
|
+
|
161
|
+
#===ビューポートの大きさを変更したときの値を求める
|
162
|
+
#幅と高さを指定して変更する
|
163
|
+
#ただし、自分自身の位置は変わらない
|
164
|
+
#_w_:: 幅
|
165
|
+
#_h_:: 高さ
|
166
|
+
#返却値:: 更新したインスタンス(Rect構造体)を返す
|
167
|
+
def resize_to(w,h)
|
168
|
+
raise MiyakoValueError, "Illegal size! w:#{w} h:#{h}" if (w <= 0 || h <= 0)
|
169
|
+
@rect.dup.resize_to!(w,h)
|
170
|
+
end
|
171
|
+
|
172
|
+
#===インスタンスを解放する
|
173
|
+
def dispose
|
174
|
+
@rect = nil
|
175
|
+
@sq = nil
|
176
|
+
end
|
177
|
+
|
178
|
+
#===ビューポートのインスタンスを複製する
|
179
|
+
#返却値:: 自分自身の複製
|
180
|
+
def viewport
|
181
|
+
return self.dup
|
182
|
+
end
|
183
|
+
|
184
|
+
#===ビューポートのインスタンスを「左、右、上、下」の形式で取得する
|
185
|
+
#返却値:: ビューポートの矩形(Square構造体インスタンス)の複製
|
186
|
+
def square
|
187
|
+
return @sq.dup
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|