-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcollision.js
96 lines (93 loc) · 2.94 KB
/
collision.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
define(['vector'],function(Vector) {
return function(game) {
game.objects.lists.collide = game.objects.createIndexList('collide');
game.objects.lists.collidable = game.objects.createIndexList('collidable');
game.on('postupdate',function() {
game.emit('precollision');
handleCollision();
game.emit('postcollision');
});
function handleCollision() {
var t = new Vector(0,0);
var t2 = new Vector(0,0);
var collisionlines = [];
game.objects.lists.collidable.each(function(o) {
collisionlines = collisionlines.concat(o.collisionlines);
});
game.objects.lists.collide.each(function(o) {
if (!o.velocity){return;}
o.surfaces = [];
for(var iteration=0;iteration<5;iteration++) {
var collisions = [];
function handleCollisionLineSegments(lineSegments) {
for(var i=0;i<lineSegments.length;i++) {
var lineSegment = lineSegments[i];
if (lineSegment.normal.dotV(o.velocity) > 0) {
continue;
}
t.setV(lineSegment.normal);
t.normalRight();
var l = lineSegment.start.distanceToV(lineSegment.end);
t2.setV(o.position);
t2.substractV(lineSegment.start);
var offY = lineSegment.normal.dotV(t2)-o.collisionRadius;
var offX = t.dotV(t2);
if (offY < -o.collisionRadius*2) {
continue;
} else if (offY < 0) {
var d;
if (offX > 0 && offX < l) {
offY*=-1;
collisions.push({
lineSegment: lineSegment,
offset:offY
});
} else if (offX < 0 && offX > -o.collisionRadius) {
d = o.position.distanceToV(lineSegment.start);
if (d < o.collisionRadius) {
t.setV(o.position);
t.substractV(lineSegment.start);
t.normalize();
collisions.push({
lineSegment: lineSegment,
offset:o.collisionRadius-d
});
}
} else if (offX > l && offX < l+o.collisionRadius) {
d = o.position.distanceToV(lineSegment.end);
if (d < o.collisionRadius) {
t.setV(o.position);
t.substractV(lineSegment.end);
t.normalize();
collisions.push({
lineSegment: lineSegment,
offset:o.collisionRadius-d
});
}
}
} else {
continue;
}
}
}
handleCollisionLineSegments(collisionlines);
if (collisions.length > 0) {
collisions.sort(function(a,b) {
return b.offset-a.offset;
});
var c = collisions[0];
//offset-=1;
o.position.add(c.lineSegment.normal.x*c.offset,c.lineSegment.normal.y*c.offset);
var vc = o.velocity.dotV(c.lineSegment.normal);
o.velocity.substract(c.lineSegment.normal.x*vc, c.lineSegment.normal.y*vc);
o.surfaces.push(c);
o.collide(c);
} else {
o.surface = null;
break;
}
}
});
}
};
});