dxopal 1.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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.ignore +5 -0
- data/.nojekyll +4 -0
- data/CHANGELOG.md +90 -0
- data/DEVELOPMENT.md +57 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +39 -0
- data/README.md +22 -0
- data/Rakefile +66 -0
- data/TODO.md +278 -0
- data/build/dxopal.js +46590 -0
- data/build/dxopal.min.js +1 -0
- data/config.ru +39 -0
- data/doc/api/DXOpal.html +129 -0
- data/doc/api/DXOpal/Font.html +485 -0
- data/doc/api/DXOpal/Image.html +2533 -0
- data/doc/api/DXOpal/Input.html +1086 -0
- data/doc/api/DXOpal/Input/MouseCodes.html +146 -0
- data/doc/api/DXOpal/RemoteResource.html +641 -0
- data/doc/api/DXOpal/Sound.html +568 -0
- data/doc/api/DXOpal/SoundEffect.html +444 -0
- data/doc/api/DXOpal/SoundEffect/WaveTypes.html +130 -0
- data/doc/api/DXOpal/Sprite.html +1419 -0
- data/doc/api/DXOpal/Window.html +1915 -0
- data/doc/api/_index.html +228 -0
- data/doc/api/class_list.html +51 -0
- data/doc/api/css/common.css +1 -0
- data/doc/api/css/full_list.css +58 -0
- data/doc/api/css/style.css +492 -0
- data/doc/api/file.CHANGELOG.html +162 -0
- data/doc/api/file.README.html +124 -0
- data/doc/api/file_list.html +61 -0
- data/doc/api/frames.html +17 -0
- data/doc/api/index.html +124 -0
- data/doc/api/js/app.js +248 -0
- data/doc/api/js/full_list.js +216 -0
- data/doc/api/js/jquery.js +4 -0
- data/doc/api/method_list.html +939 -0
- data/doc/api/top-level-namespace.html +110 -0
- data/doc/en/index.html +93 -0
- data/doc/ja/index.html +92 -0
- data/dxopal.gemspec +29 -0
- data/exe/dxopal +44 -0
- data/index.html +56 -0
- data/opal/dxopal.rb +54 -0
- data/opal/dxopal/constants/colors.rb +16 -0
- data/opal/dxopal/font.rb +20 -0
- data/opal/dxopal/image.rb +301 -0
- data/opal/dxopal/input.rb +170 -0
- data/opal/dxopal/input/key_codes.rb +168 -0
- data/opal/dxopal/remote_resource.rb +65 -0
- data/opal/dxopal/sound.rb +53 -0
- data/opal/dxopal/sound_effect.rb +84 -0
- data/opal/dxopal/sprite.rb +94 -0
- data/opal/dxopal/sprite/collision_area.rb +288 -0
- data/opal/dxopal/sprite/collision_check.rb +106 -0
- data/opal/dxopal/sprite/collision_checker.rb +169 -0
- data/opal/dxopal/sprite/physics.rb +82 -0
- data/opal/dxopal/version.rb +3 -0
- data/opal/dxopal/window.rb +173 -0
- data/template/index.html +13 -0
- data/template/main.rb +9 -0
- metadata +191 -0
@@ -0,0 +1,288 @@
|
|
1
|
+
require 'dxopal/sprite/collision_checker'
|
2
|
+
|
3
|
+
module DXOpal
|
4
|
+
class Sprite
|
5
|
+
# Methods of Sprite related to collision checking
|
6
|
+
module CollisionArea
|
7
|
+
class Base
|
8
|
+
# Sprite corresponds to this hitarea
|
9
|
+
attr_reader :sprite
|
10
|
+
|
11
|
+
# Return a string like "Point", "Rect", etc.
|
12
|
+
# Used for type checking in `collides?` (because Opal's Class#is_a? is not very fast)
|
13
|
+
def type
|
14
|
+
raise "override me"
|
15
|
+
end
|
16
|
+
|
17
|
+
def absolute(poss)
|
18
|
+
ox = @sprite.x
|
19
|
+
oy = @sprite.y
|
20
|
+
return poss.map{|(x, y)| [x+ox, y+oy]} if !@sprite.collision_sync
|
21
|
+
angle = @sprite.angle
|
22
|
+
cx = @sprite.center_x
|
23
|
+
cy = @sprite.center_y
|
24
|
+
sx = @sprite.scale_x
|
25
|
+
sy = @sprite.scale_y
|
26
|
+
|
27
|
+
ret = []
|
28
|
+
%x{
|
29
|
+
var rad = Math.PI / 180.0 * angle;
|
30
|
+
var sin = Math.sin(rad);
|
31
|
+
var cos = Math.cos(rad);
|
32
|
+
poss.forEach(function(pos){
|
33
|
+
var x = pos[0], y = pos[1];
|
34
|
+
x2 = (x - cx) * sx * cos - (y - cy) * sy * sin + cx + ox;
|
35
|
+
y2 = (x - cx) * sx * sin + (y - cy) * sy * cos + cy + oy;
|
36
|
+
ret.push([x2, y2]);
|
37
|
+
});
|
38
|
+
}
|
39
|
+
return ret
|
40
|
+
end
|
41
|
+
|
42
|
+
def absolute1(pos)
|
43
|
+
absolute([pos]).first
|
44
|
+
end
|
45
|
+
|
46
|
+
def transback(poss, sprite)
|
47
|
+
return poss if !sprite.collision_sync
|
48
|
+
angle = sprite.angle
|
49
|
+
cx = sprite.x + sprite.center_x
|
50
|
+
cy = sprite.y + sprite.center_y
|
51
|
+
sx = sprite.scale_x
|
52
|
+
sy = sprite.scale_y
|
53
|
+
|
54
|
+
ret = []
|
55
|
+
%x{
|
56
|
+
var rad = Math.PI / 180.0 * -angle;
|
57
|
+
var sin = Math.sin(rad);
|
58
|
+
var cos = Math.cos(rad);
|
59
|
+
poss.forEach(function(pos){
|
60
|
+
var x = pos[0], y = pos[1];
|
61
|
+
x2 = ((x - cx) * cos - (y - cy) * sin) / sx + cx;
|
62
|
+
y2 = ((x - cx) * sin + (y - cy) * cos) / sy + cy;
|
63
|
+
ret.push([x2, y2]);
|
64
|
+
});
|
65
|
+
}
|
66
|
+
return ret
|
67
|
+
end
|
68
|
+
|
69
|
+
def transback1(pos, sprite)
|
70
|
+
transback([pos], sprite).first
|
71
|
+
end
|
72
|
+
|
73
|
+
def aabb(poss)
|
74
|
+
x1 = y1 = Float::INFINITY
|
75
|
+
x2 = y2 = -Float::INFINITY
|
76
|
+
%x{
|
77
|
+
for(var i=0; i<poss.length; i++) {
|
78
|
+
if (poss[i][0] < x1) x1 = poss[i][0];
|
79
|
+
if (poss[i][1] < y1) y1 = poss[i][1];
|
80
|
+
if (poss[i][0] > x2) x2 = poss[i][0];
|
81
|
+
if (poss[i][1] > y2) y2 = poss[i][1];
|
82
|
+
}
|
83
|
+
}
|
84
|
+
return [[x1, y1], [x2, y2]]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class Point < Base
|
89
|
+
def initialize(sprite, x, y)
|
90
|
+
@sprite, @x, @y = sprite, x, y
|
91
|
+
super()
|
92
|
+
end
|
93
|
+
|
94
|
+
def type; :Point; end
|
95
|
+
|
96
|
+
def collides?(other)
|
97
|
+
case other.type
|
98
|
+
when :Point
|
99
|
+
self.absolute_pos == other.absolute_pos
|
100
|
+
when :Circle
|
101
|
+
x, y = *transback1(self.absolute_pos, other.sprite)
|
102
|
+
cx, cy = *other.absolute_norot_pos
|
103
|
+
`Opal.DXOpal.CCk.check_point_circle(x, y, cx, cy, #{other.r})`
|
104
|
+
when :Rect
|
105
|
+
x, y = *transback1(self.absolute_pos, other.sprite)
|
106
|
+
((x1, y1), (x2, y2)) = *other.absolute_norot_poss
|
107
|
+
`Opal.DXOpal.CCk.check_point_straight_rect(x, y, x1, y1, x2, y2)`
|
108
|
+
when :Triangle
|
109
|
+
x, y = *absolute_pos
|
110
|
+
(x1, y1), (x2, y2), (x3, y3) = *other.absolute_poss
|
111
|
+
`Opal.DXOpal.CCk.check_point_triangle(x, y, x1, y1, x2, y2, x3, y3)`
|
112
|
+
else raise
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Return [x, y]
|
117
|
+
def absolute_pos
|
118
|
+
absolute1([@x, @y])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class Circle < Base
|
123
|
+
def initialize(sprite, x, y, r)
|
124
|
+
@sprite, @x, @y, @r = sprite, x, y, r
|
125
|
+
super()
|
126
|
+
end
|
127
|
+
attr_reader :r
|
128
|
+
|
129
|
+
def type; :Circle; end
|
130
|
+
|
131
|
+
# Return true if this is not an ellipsis
|
132
|
+
def circle?
|
133
|
+
@sprite.scale_x == @sprite.scale_y
|
134
|
+
end
|
135
|
+
|
136
|
+
def collides?(other)
|
137
|
+
case other.type
|
138
|
+
when :Point
|
139
|
+
other.collides?(self)
|
140
|
+
when :Circle
|
141
|
+
collides_circle?(other)
|
142
|
+
when :Rect
|
143
|
+
cx, cy = *self.absolute_norot_pos
|
144
|
+
(x1, y1), (x2, y2), (x3, y3), (x4, y4) = *transback(other.absolute_poss, @sprite)
|
145
|
+
`Opal.DXOpal.CCk.check_circle_tilted_rect(cx, cy, #{@r}, x1, y1, x2, y2, x3, y3, x4, y4)`
|
146
|
+
when :Triangle
|
147
|
+
cx, cy = *self.absolute_norot_pos
|
148
|
+
(x1, y1), (x2, y2), (x3, y3) = *transback(other.absolute_poss, @sprite)
|
149
|
+
`Opal.DXOpal.CCk.check_circle_triangle(cx, cy, #{@r}, x1, y1, x2, y2, x3, y3)`
|
150
|
+
else raise
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Return [x, y]
|
155
|
+
def absolute_pos
|
156
|
+
absolute1([@x, @y])
|
157
|
+
end
|
158
|
+
|
159
|
+
def absolute_norot_pos
|
160
|
+
[@x + @sprite.x, @y + @sprite.y]
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def collides_circle?(other)
|
166
|
+
x1, y1 = *self.absolute_pos
|
167
|
+
r1 = @r
|
168
|
+
x2, y2 = *other.absolute_pos
|
169
|
+
r2 = other.r
|
170
|
+
if self.circle? && other.circle?
|
171
|
+
`Opal.DXOpal.CCk.check_circle_circle(x1, y1, #{@r}, x2, y2, #{other.r})`
|
172
|
+
else
|
173
|
+
if @sprite.collision_sync
|
174
|
+
scale_x1 = @sprite.scale_x
|
175
|
+
scale_y1 = @sprite.scale_y
|
176
|
+
angle1 = @sprite.angle * Math::PI / 180
|
177
|
+
else
|
178
|
+
scale_x1 = 1
|
179
|
+
scale_y1 = 1
|
180
|
+
angle1 = 0
|
181
|
+
end
|
182
|
+
if other.sprite.collision_sync
|
183
|
+
scale_x2 = other.sprite.scale_x
|
184
|
+
scale_y2 = other.sprite.scale_y
|
185
|
+
angle2 = other.sprite.angle * Math::PI / 180
|
186
|
+
else
|
187
|
+
scale_x2 = 1
|
188
|
+
scale_y2 = 1
|
189
|
+
angle2 = 0
|
190
|
+
end
|
191
|
+
ret = nil
|
192
|
+
%x{
|
193
|
+
var e1 = {
|
194
|
+
fRad_X: scale_x1 * r1,
|
195
|
+
fRad_Y: scale_y1 * r1,
|
196
|
+
fAngle: angle1,
|
197
|
+
fCx: x1,
|
198
|
+
fCy: y1,
|
199
|
+
}
|
200
|
+
var e2 = {
|
201
|
+
fRad_X: scale_x2 * r2,
|
202
|
+
fRad_Y: scale_y2 * r2,
|
203
|
+
fAngle: angle2,
|
204
|
+
fCx: x2,
|
205
|
+
fCy: y2,
|
206
|
+
}
|
207
|
+
ret = Opal.DXOpal.CCk.check_ellipse_ellipse(e1, e2);
|
208
|
+
}
|
209
|
+
ret
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class Rect < Base
|
215
|
+
def initialize(sprite, x1, y1, x2, y2)
|
216
|
+
@sprite, @x1, @y1, @x2, @y2 = sprite, x1, y1, x2, y2
|
217
|
+
@poss = [[x1, y1], [x2, y1], [x2, y2], [x1, y2]]
|
218
|
+
super()
|
219
|
+
end
|
220
|
+
|
221
|
+
def type; :Rect; end
|
222
|
+
|
223
|
+
def inspect
|
224
|
+
"#<CollisionArea::Rect(#{@x1}, #{@y1}, #{@x2}, #{@y2})>"
|
225
|
+
end
|
226
|
+
|
227
|
+
def collides?(other)
|
228
|
+
case other.type
|
229
|
+
when :Point, :Circle
|
230
|
+
other.collides?(self)
|
231
|
+
when :Rect
|
232
|
+
((ox1, oy1), (ox2, oy2)) = self.absolute_norot_poss
|
233
|
+
((dx1, dy1), (dx2, dy2)) = aabb(transback(other.absolute_poss, @sprite))
|
234
|
+
return false unless `Opal.DXOpal.CCk.check_rect_rect(ox1, oy1, ox2, oy2, dx1, dy1, dx2, dy2)`
|
235
|
+
|
236
|
+
((ox1, oy1), (ox2, oy2)) = other.absolute_norot_poss
|
237
|
+
((dx1, dy1), (dx2, dy2)) = aabb(transback(self.absolute_poss, other.sprite))
|
238
|
+
return false unless `Opal.DXOpal.CCk.check_rect_rect(ox1, oy1, ox2, oy2, dx1, dy1, dx2, dy2)`
|
239
|
+
true
|
240
|
+
when :Triangle
|
241
|
+
(ox1, oy1), (ox2, oy2), (ox3, oy3), (ox4, oy4) = *self.absolute_poss
|
242
|
+
(dx1, dy1), (dx2, dy2), (dx3, dy3) = *other.absolute_poss
|
243
|
+
`Opal.DXOpal.CCk.check_tilted_rect_triangle(ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4,
|
244
|
+
dx1, dy1, dx2, dy2, dx3, dy3)`
|
245
|
+
|
246
|
+
else raise
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def absolute_poss
|
251
|
+
absolute(@poss)
|
252
|
+
end
|
253
|
+
|
254
|
+
def absolute_norot_poss
|
255
|
+
[[@x1 + @sprite.x, @y1 + @sprite.y],
|
256
|
+
[@x2 + @sprite.x, @y2 + @sprite.y]]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
class Triangle < Base
|
261
|
+
def initialize(sprite, x1, y1, x2, y2, x3, y3)
|
262
|
+
@sprite = sprite
|
263
|
+
@poss = [[x1, y1], [x2, y2], [x3, y3]]
|
264
|
+
super()
|
265
|
+
end
|
266
|
+
|
267
|
+
def type; :Triangle; end
|
268
|
+
|
269
|
+
def collides?(other)
|
270
|
+
case other.type
|
271
|
+
when :Point, :Circle, :Rect
|
272
|
+
other.collides?(self)
|
273
|
+
when :Triangle
|
274
|
+
(ox1, oy1), (ox2, oy2), (ox3, oy3) = *self.absolute_poss
|
275
|
+
(dx1, dy1), (dx2, dy2), (dx3, dy3) = *other.absolute_poss
|
276
|
+
`Opal.DXOpal.CCk.check_triangle_triangle(ox1, oy1, ox2, oy2, ox3, oy3,
|
277
|
+
dx1, dy1, dx2, dy2, dx3, dy3)`
|
278
|
+
else raise
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def absolute_poss
|
283
|
+
absolute(@poss)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'dxopal/sprite/collision_area'
|
2
|
+
|
3
|
+
module DXOpal
|
4
|
+
class Sprite
|
5
|
+
# Methods of Sprite related to collision checking
|
6
|
+
module CollisionCheck
|
7
|
+
module ClassMethods
|
8
|
+
# TODO: implement arguments `shot` and `hit`
|
9
|
+
def check(offences, defences, shot=:shot, hit=:hit)
|
10
|
+
if offences.equal?(defences)
|
11
|
+
# any-vs-any mode
|
12
|
+
sprites = offences.select{|x| x.is_a?(Sprite)}
|
13
|
+
n = sprites.length
|
14
|
+
%x{
|
15
|
+
for (var i=0; i<n; i++) {
|
16
|
+
for (var j=i+1; j<n; j++) {
|
17
|
+
if (sprites[i]['$==='](sprites[j])) {
|
18
|
+
sprites[i]['$hit']();
|
19
|
+
sprites[j]['$hit']();
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
else
|
25
|
+
# offence-vs-defence mode
|
26
|
+
%x{
|
27
|
+
for (var i=0; i<offences.length; i++) {
|
28
|
+
for (var j=0; j<defences.length; j++) {
|
29
|
+
if (offences[i]['$==='](defences[j])) {
|
30
|
+
offences[i]['$shot'](defences[j]);
|
31
|
+
defences[j]['$hit'](offences[i]);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Default callback methods of `Sprite.check`
|
41
|
+
def shot(other); end
|
42
|
+
def hit(other); end
|
43
|
+
|
44
|
+
# Called from Sprites#initialize
|
45
|
+
def _init_collision_info(image)
|
46
|
+
@collision ||= nil
|
47
|
+
@collision_enable = true if @collision_enable.nil?
|
48
|
+
@collision_sync = true if @collision_sync.nil?
|
49
|
+
@_collision_area ||=
|
50
|
+
if image
|
51
|
+
CollisionArea::Rect.new(self, 0, 0, image.width, image.height)
|
52
|
+
else
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
# Whether collision is detected for this object (default: true)
|
57
|
+
attr_accessor :collision_enable
|
58
|
+
# Whether collision areas synchronize with .scale and .angle (default: true)
|
59
|
+
# Setting this to false may improve collision detection performance
|
60
|
+
attr_accessor :collision_sync
|
61
|
+
# Return an array represents its collision area
|
62
|
+
attr_reader :collision
|
63
|
+
# (internal) Return a CollisionArea object
|
64
|
+
attr_reader :_collision_area
|
65
|
+
|
66
|
+
# Set collision area of this sprite
|
67
|
+
def collision=(area_spec)
|
68
|
+
@_collision_area =
|
69
|
+
case area_spec.length
|
70
|
+
when 2 then CollisionArea::Point.new(self, *area_spec)
|
71
|
+
when 3 then CollisionArea::Circle.new(self, *area_spec)
|
72
|
+
when 4 then CollisionArea::Rect.new(self, *area_spec)
|
73
|
+
when 6 then CollisionArea::Triangle.new(self, *area_spec)
|
74
|
+
else
|
75
|
+
raise "Inlivad area data: #{x.inspect}"
|
76
|
+
end
|
77
|
+
@collision = area_spec
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return true when this sprite collides with other sprite(s)
|
81
|
+
def ===(sprite_or_sprites)
|
82
|
+
return check(sprite_or_sprites).any?
|
83
|
+
end
|
84
|
+
|
85
|
+
# Return list of sprites collides with this sprite
|
86
|
+
def check(sprite_or_sprites)
|
87
|
+
sprites = Array(sprite_or_sprites)
|
88
|
+
return sprites.select{|sprite| _collides?(sprite)}
|
89
|
+
end
|
90
|
+
|
91
|
+
# Return true when this sprite collides with `sprite`
|
92
|
+
def _collides?(sprite)
|
93
|
+
if @_collision_area.nil? || sprite._collision_area.nil?
|
94
|
+
raise "Sprite image not set"
|
95
|
+
end
|
96
|
+
return false if !self._collidable? || !sprite._collidable?
|
97
|
+
return @_collision_area.collides?(sprite._collision_area)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Return true when this sprite may collide
|
101
|
+
def _collidable?
|
102
|
+
return !@vanished && @collision_enable
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# vim: set ft=javascript:
|
2
|
+
%x{ (function(){
|
3
|
+
|
4
|
+
var intersect = function(x1, y1, x2, y2, x3, y3, x4, y4){
|
5
|
+
return ((x1 - x2) * (y3 - y1) + (y1 - y2) * (x1 - x3)) *
|
6
|
+
((x1 - x2) * (y4 - y1) + (y1 - y2) * (x1 - x4));
|
7
|
+
};
|
8
|
+
|
9
|
+
var check_line_line = function(x1, y1, x2, y2, x3, y3, x4, y4){
|
10
|
+
return !((((x1 - x2) * (y3 - y1) + (y1 - y2) * (x1 - x3)) *
|
11
|
+
((x1 - x2) * (y4 - y1) + (y1 - y2) * (x1 - x4)) > 0.0) ||
|
12
|
+
(((x3 - x4) * (y1 - y3) + (y3 - y4) * (x3 - x1)) *
|
13
|
+
((x3 - x4) * (y2 - y3) + (y3 - y4) * (x3 - x2)) > 0.0 ));
|
14
|
+
};
|
15
|
+
|
16
|
+
var check_circle_line = function(x, y, r, x1, y1, x2, y2) {
|
17
|
+
var vx = x2-x1, vy = y2-y1;
|
18
|
+
var cx = x-x1, cy = y-y1;
|
19
|
+
|
20
|
+
if (vx == 0 && vy == 0 )
|
21
|
+
return CCk.check_point_circle(x, y, r, x1, y1);
|
22
|
+
|
23
|
+
var n1 = vx * cx + vy * cy;
|
24
|
+
if (n1 < 0)
|
25
|
+
return cx*cx + cy*cy < r * r;
|
26
|
+
|
27
|
+
var n2 = vx * vx + vy * vy;
|
28
|
+
if (n1 > n2) {
|
29
|
+
var len = (x2 - x)*(x2 - x) + (y2 - y)*(y2 - y);
|
30
|
+
return len < r * r;
|
31
|
+
}
|
32
|
+
else
|
33
|
+
{
|
34
|
+
var n3 = cx * cx + cy * cy;
|
35
|
+
return n3-(n1/n2)*n1 < r * r;
|
36
|
+
}
|
37
|
+
};
|
38
|
+
|
39
|
+
var CCk = {
|
40
|
+
check_point_circle: function(px, py, cx, cy, cr) {
|
41
|
+
return (cr*cr) >= ((cx-px) * (cx-px) + (cy-py) * (cy-py));
|
42
|
+
},
|
43
|
+
|
44
|
+
check_point_straight_rect: function(x, y, x1, y1, x2, y2) {
|
45
|
+
return ((x) >= (x1) &&
|
46
|
+
(y) >= (y1) &&
|
47
|
+
(x) < (x2) &&
|
48
|
+
(y) < (y2));
|
49
|
+
},
|
50
|
+
|
51
|
+
check_point_triangle: function(x, y, x1, y1, x2, y2, x3, y3){
|
52
|
+
if ((x1 - x3) * (y1 - y2) == (x1 - x2) * (y1 - y3))
|
53
|
+
return false;
|
54
|
+
|
55
|
+
var cx = (x1 + x2 + x3) / 3,
|
56
|
+
cy = (y1 + y2 + y3) / 3;
|
57
|
+
|
58
|
+
if (intersect( x1, y1, x2, y2, x, y, cx, cy ) < 0.0 ||
|
59
|
+
intersect( x2, y2, x3, y3, x, y, cx, cy ) < 0.0 ||
|
60
|
+
intersect( x3, y3, x1, y1, x, y, cx, cy ) < 0.0 ) {
|
61
|
+
return false;
|
62
|
+
}
|
63
|
+
return true;
|
64
|
+
},
|
65
|
+
|
66
|
+
check_circle_circle: function(ox, oy, or, dx, dy, dr) {
|
67
|
+
return ((or+dr) * (or+dr) >= (ox-dx) * (ox-dx) + (oy-dy) * (oy-dy));
|
68
|
+
},
|
69
|
+
|
70
|
+
check_ellipse_ellipse: function(E1, E2) {
|
71
|
+
var DefAng = E1.fAngle-E2.fAngle;
|
72
|
+
var Cos = Math.cos( DefAng );
|
73
|
+
var Sin = Math.sin( DefAng );
|
74
|
+
var nx = E2.fRad_X * Cos;
|
75
|
+
var ny = -E2.fRad_X * Sin;
|
76
|
+
var px = E2.fRad_Y * Sin;
|
77
|
+
var py = E2.fRad_Y * Cos;
|
78
|
+
var ox = Math.cos( E1.fAngle )*(E2.fCx-E1.fCx) + Math.sin(E1.fAngle)*(E2.fCy-E1.fCy);
|
79
|
+
var oy = -Math.sin( E1.fAngle )*(E2.fCx-E1.fCx) + Math.cos(E1.fAngle)*(E2.fCy-E1.fCy);
|
80
|
+
|
81
|
+
var rx_pow2 = 1/(E1.fRad_X*E1.fRad_X);
|
82
|
+
var ry_pow2 = 1/(E1.fRad_Y*E1.fRad_Y);
|
83
|
+
var A = rx_pow2*nx*nx + ry_pow2*ny*ny;
|
84
|
+
var B = rx_pow2*px*px + ry_pow2*py*py;
|
85
|
+
var D = 2*rx_pow2*nx*px + 2*ry_pow2*ny*py;
|
86
|
+
var E = 2*rx_pow2*nx*ox + 2*ry_pow2*ny*oy;
|
87
|
+
var F = 2*rx_pow2*px*ox + 2*ry_pow2*py*oy;
|
88
|
+
var G = (ox/E1.fRad_X)*(ox/E1.fRad_X) + (oy/E1.fRad_Y)*(oy/E1.fRad_Y) - 1;
|
89
|
+
|
90
|
+
var tmp1 = 1/(D*D-4*A*B);
|
91
|
+
var h = (F*D-2*E*B)*tmp1;
|
92
|
+
var k = (E*D-2*A*F)*tmp1;
|
93
|
+
var Th = (B-A)==0 ? 0 : Math.atan( D/(B-A) ) * 0.5;
|
94
|
+
|
95
|
+
var CosTh = Math.cos(Th);
|
96
|
+
var SinTh = Math.sin(Th);
|
97
|
+
var A_tt = A*CosTh*CosTh + B*SinTh*SinTh - D*CosTh*SinTh;
|
98
|
+
var B_tt = A*SinTh*SinTh + B*CosTh*CosTh + D*CosTh*SinTh;
|
99
|
+
var KK = A*h*h + B*k*k + D*h*k - E*h - F*k + G > 0 ? 0 : A*h*h + B*k*k + D*h*k - E*h - F*k + G;
|
100
|
+
var Rx_tt = 1+Math.sqrt(-KK/A_tt);
|
101
|
+
var Ry_tt = 1+Math.sqrt(-KK/B_tt);
|
102
|
+
var x_tt = CosTh*h-SinTh*k;
|
103
|
+
var y_tt = SinTh*h+CosTh*k;
|
104
|
+
var JudgeValue = x_tt*x_tt/(Rx_tt*Rx_tt) + y_tt*y_tt/(Ry_tt*Ry_tt);
|
105
|
+
|
106
|
+
return (JudgeValue <= 1);
|
107
|
+
},
|
108
|
+
|
109
|
+
check_circle_tilted_rect: function(cx, cy, cr, x1, y1, x2, y2, x3, y3, x4, y4){
|
110
|
+
return CCk.check_point_triangle(cx, cy, x1, y1, x2, y2, x3, y3) ||
|
111
|
+
CCk.check_point_triangle(cx, cy, x1, y1, x3, y3, x4, y4) ||
|
112
|
+
check_circle_line(cx, cy, cr, x1, y1, x2, y2) ||
|
113
|
+
check_circle_line(cx, cy, cr, x2, y2, x3, y3) ||
|
114
|
+
check_circle_line(cx, cy, cr, x3, y3, x4, y4) ||
|
115
|
+
check_circle_line(cx, cy, cr, x4, y4, x1, y1);
|
116
|
+
},
|
117
|
+
|
118
|
+
check_circle_triangle: function(cx, cy, cr, x1, y1, x2, y2, x3, y3) {
|
119
|
+
return CCk.check_point_triangle(cx, cy, x1, y1, x2, y2, x3, y3) ||
|
120
|
+
check_circle_line(cx, cy, cr, x1, y1, x2, y2) ||
|
121
|
+
check_circle_line(cx, cy, cr, x2, y2, x3, y3) ||
|
122
|
+
check_circle_line(cx, cy, cr, x3, y3, x1, y1);
|
123
|
+
},
|
124
|
+
|
125
|
+
check_rect_rect: function(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {
|
126
|
+
return ax1 < bx2 &&
|
127
|
+
ay1 < by2 &&
|
128
|
+
bx1 < ax2 &&
|
129
|
+
by1 < ay2;
|
130
|
+
},
|
131
|
+
|
132
|
+
// Rect(may be tilted) vs Triangle
|
133
|
+
check_tilted_rect_triangle: function(ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4,
|
134
|
+
dx1, dy1, dx2, dy2, dx3, dy3) {
|
135
|
+
return check_line_line(ox1, oy1, ox2, oy2, dx1, dy1, dx2, dy2) ||
|
136
|
+
check_line_line(ox1, oy1, ox2, oy2, dx2, dy2, dx3, dy3) ||
|
137
|
+
check_line_line(ox1, oy1, ox2, oy2, dx3, dy3, dx1, dy1) ||
|
138
|
+
check_line_line(ox2, oy2, ox3, oy3, dx1, dy1, dx2, dy2) ||
|
139
|
+
check_line_line(ox2, oy2, ox3, oy3, dx2, dy2, dx3, dy3) ||
|
140
|
+
check_line_line(ox2, oy2, ox3, oy3, dx3, dy3, dx1, dy1) ||
|
141
|
+
check_line_line(ox3, oy3, ox4, oy4, dx1, dy1, dx2, dy2) ||
|
142
|
+
check_line_line(ox3, oy3, ox4, oy4, dx2, dy2, dx3, dy3) ||
|
143
|
+
check_line_line(ox3, oy3, ox4, oy4, dx3, dy3, dx1, dy1) ||
|
144
|
+
check_line_line(ox4, oy4, ox1, oy1, dx1, dy1, dx2, dy2) ||
|
145
|
+
check_line_line(ox4, oy4, ox1, oy1, dx2, dy2, dx3, dy3) ||
|
146
|
+
check_line_line(ox4, oy4, ox1, oy1, dx3, dy3, dx1, dy1) ||
|
147
|
+
CCk.check_point_triangle(dx1, dy1, ox1, oy1, ox2, oy2, ox3, oy3) ||
|
148
|
+
CCk.check_point_triangle(dx1, dy1, ox1, oy1, ox3, oy3, ox4, oy4) ||
|
149
|
+
CCk.check_point_triangle(ox1, oy1, dx1, dy1, dx2, dy2, dx3, dy3);
|
150
|
+
},
|
151
|
+
|
152
|
+
// Triangle vs Triangle
|
153
|
+
check_triangle_triangle: function(ox1, oy1, ox2, oy2, ox3, oy3,
|
154
|
+
dx1, dy1, dx2, dy2, dx3, dy3) {
|
155
|
+
return check_line_line(ox1, oy1, ox2, oy2, dx2, dy2, dx3, dy3) ||
|
156
|
+
check_line_line(ox1, oy1, ox2, oy2, dx3, dy3, dx1, dy1) ||
|
157
|
+
check_line_line(ox2, oy2, ox3, oy3, dx1, dy1, dx2, dy2) ||
|
158
|
+
check_line_line(ox2, oy2, ox3, oy3, dx3, dy3, dx1, dy1) ||
|
159
|
+
check_line_line(ox3, oy3, ox1, oy1, dx1, dy1, dx2, dy2) ||
|
160
|
+
check_line_line(ox3, oy3, ox1, oy1, dx2, dy2, dx3, dy3) ||
|
161
|
+
CCk.check_point_triangle(ox1, oy1, dx1, dy1, dx2, dy2, dx3, dy3) ||
|
162
|
+
CCk.check_point_triangle(dx1, dy1, ox1, oy1, ox2, oy2, ox3, oy3);
|
163
|
+
}
|
164
|
+
};
|
165
|
+
|
166
|
+
Opal.DXOpal.CollisionChecker = CCk;
|
167
|
+
Opal.DXOpal.CCk = CCk; // Alias
|
168
|
+
|
169
|
+
})(); }
|