修复circleToBox检测偏差问题
This commit is contained in:
@@ -2733,6 +2733,8 @@ var es;
|
|||||||
};
|
};
|
||||||
SpriteRenderer.prototype.render = function (camera) {
|
SpriteRenderer.prototype.render = function (camera) {
|
||||||
this.sync(camera);
|
this.sync(camera);
|
||||||
|
this.displayObject.x = this.entity.position.x - this.origin.x + this.localOffset.x - camera.position.x + camera.origin.x;
|
||||||
|
this.displayObject.y = this.entity.position.y - this.origin.y + this.localOffset.y - camera.position.y + camera.origin.y;
|
||||||
};
|
};
|
||||||
return SpriteRenderer;
|
return SpriteRenderer;
|
||||||
}(es.RenderableComponent));
|
}(es.RenderableComponent));
|
||||||
@@ -2995,7 +2997,7 @@ var es;
|
|||||||
continue;
|
continue;
|
||||||
var _internalcollisionResult = new es.CollisionResult();
|
var _internalcollisionResult = new es.CollisionResult();
|
||||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
||||||
motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
motion = motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
||||||
if (_internalcollisionResult.collider != null) {
|
if (_internalcollisionResult.collider != null) {
|
||||||
collisionResult = _internalcollisionResult;
|
collisionResult = _internalcollisionResult;
|
||||||
}
|
}
|
||||||
@@ -3139,18 +3141,17 @@ var es;
|
|||||||
}
|
}
|
||||||
var renderable = this.entity.getComponent(es.RenderableComponent);
|
var renderable = this.entity.getComponent(es.RenderableComponent);
|
||||||
if (renderable) {
|
if (renderable) {
|
||||||
var bounds = renderable.bounds;
|
var renderableBounds = renderable.bounds;
|
||||||
var width = bounds.width / this.entity.scale.x;
|
var width = renderableBounds.width / this.entity.scale.x;
|
||||||
var height = bounds.height / this.entity.scale.y;
|
var height = renderableBounds.height / this.entity.scale.y;
|
||||||
if (this instanceof es.CircleCollider) {
|
if (this instanceof es.CircleCollider) {
|
||||||
var circleCollider = this;
|
this.radius = Math.max(width, height) * 0.5;
|
||||||
circleCollider.radius = Math.max(width, height) * 0.5;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
this.localOffset = es.Vector2.subtract(bounds.center, this.entity.transform.position);
|
this.localOffset = es.Vector2.subtract(renderableBounds.center, this.entity.transform.position);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
|
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
|
||||||
@@ -3202,7 +3203,7 @@ var es;
|
|||||||
};
|
};
|
||||||
Collider.prototype.collidesWith = function (collider, motion, result) {
|
Collider.prototype.collidesWith = function (collider, motion, result) {
|
||||||
var oldPosition = this.entity.position;
|
var oldPosition = this.entity.position;
|
||||||
this.entity.position.add(motion);
|
this.entity.position = this.entity.position.add(motion);
|
||||||
var didCollide = this.shape.collidesWithShape(collider.shape, result);
|
var didCollide = this.shape.collidesWithShape(collider.shape, result);
|
||||||
if (didCollide)
|
if (didCollide)
|
||||||
result.collider = collider;
|
result.collider = collider;
|
||||||
@@ -6090,7 +6091,7 @@ var es;
|
|||||||
edgeNormal = new es.Vector2(-line.y, line.x);
|
edgeNormal = new es.Vector2(-line.y, line.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
es.Vector2Ext.normalize(edgeNormal);
|
edgeNormal = es.Vector2Ext.normalize(edgeNormal);
|
||||||
return closestPoint;
|
return closestPoint;
|
||||||
};
|
};
|
||||||
Polygon.prototype.recalculateBounds = function (collider) {
|
Polygon.prototype.recalculateBounds = function (collider) {
|
||||||
@@ -6122,7 +6123,7 @@ var es;
|
|||||||
}
|
}
|
||||||
this.position = es.Vector2.add(collider.entity.transform.position, this.center);
|
this.position = es.Vector2.add(collider.entity.transform.position, this.center);
|
||||||
this.bounds = es.Rectangle.rectEncompassingPoints(this.points);
|
this.bounds = es.Rectangle.rectEncompassingPoints(this.points);
|
||||||
this.bounds.location = es.Vector2.add(this.bounds.location, this.position);
|
this.bounds.location = this.bounds.location.add(this.position);
|
||||||
};
|
};
|
||||||
Polygon.prototype.overlaps = function (other) {
|
Polygon.prototype.overlaps = function (other) {
|
||||||
var result = new es.CollisionResult();
|
var result = new es.CollisionResult();
|
||||||
@@ -6394,7 +6395,7 @@ var es;
|
|||||||
var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
||||||
if (box.containsPoint(circle.position)) {
|
if (box.containsPoint(circle.position)) {
|
||||||
result.point = closestPointOnBounds;
|
result.point = closestPointOnBounds;
|
||||||
var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.subtract(result.normal, new es.Vector2(circle.radius)));
|
var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius)));
|
||||||
result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace);
|
result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -6406,7 +6407,7 @@ var es;
|
|||||||
result.normal = es.Vector2.subtract(circle.position, closestPointOnBounds);
|
result.normal = es.Vector2.subtract(circle.position, closestPointOnBounds);
|
||||||
var depth = result.normal.length() - circle.radius;
|
var depth = result.normal.length() - circle.radius;
|
||||||
result.point = closestPointOnBounds;
|
result.point = closestPointOnBounds;
|
||||||
es.Vector2Ext.normalize(result.normal);
|
result.normal = es.Vector2Ext.normalize(result.normal);
|
||||||
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(depth), result.normal);
|
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(depth), result.normal);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+13
-12
@@ -2733,6 +2733,8 @@ var es;
|
|||||||
};
|
};
|
||||||
SpriteRenderer.prototype.render = function (camera) {
|
SpriteRenderer.prototype.render = function (camera) {
|
||||||
this.sync(camera);
|
this.sync(camera);
|
||||||
|
this.displayObject.x = this.entity.position.x - this.origin.x + this.localOffset.x - camera.position.x + camera.origin.x;
|
||||||
|
this.displayObject.y = this.entity.position.y - this.origin.y + this.localOffset.y - camera.position.y + camera.origin.y;
|
||||||
};
|
};
|
||||||
return SpriteRenderer;
|
return SpriteRenderer;
|
||||||
}(es.RenderableComponent));
|
}(es.RenderableComponent));
|
||||||
@@ -2995,7 +2997,7 @@ var es;
|
|||||||
continue;
|
continue;
|
||||||
var _internalcollisionResult = new es.CollisionResult();
|
var _internalcollisionResult = new es.CollisionResult();
|
||||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
||||||
motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
motion = motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
||||||
if (_internalcollisionResult.collider != null) {
|
if (_internalcollisionResult.collider != null) {
|
||||||
collisionResult = _internalcollisionResult;
|
collisionResult = _internalcollisionResult;
|
||||||
}
|
}
|
||||||
@@ -3139,18 +3141,17 @@ var es;
|
|||||||
}
|
}
|
||||||
var renderable = this.entity.getComponent(es.RenderableComponent);
|
var renderable = this.entity.getComponent(es.RenderableComponent);
|
||||||
if (renderable) {
|
if (renderable) {
|
||||||
var bounds = renderable.bounds;
|
var renderableBounds = renderable.bounds;
|
||||||
var width = bounds.width / this.entity.scale.x;
|
var width = renderableBounds.width / this.entity.scale.x;
|
||||||
var height = bounds.height / this.entity.scale.y;
|
var height = renderableBounds.height / this.entity.scale.y;
|
||||||
if (this instanceof es.CircleCollider) {
|
if (this instanceof es.CircleCollider) {
|
||||||
var circleCollider = this;
|
this.radius = Math.max(width, height) * 0.5;
|
||||||
circleCollider.radius = Math.max(width, height) * 0.5;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
this.localOffset = es.Vector2.subtract(bounds.center, this.entity.transform.position);
|
this.localOffset = es.Vector2.subtract(renderableBounds.center, this.entity.transform.position);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
|
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
|
||||||
@@ -3202,7 +3203,7 @@ var es;
|
|||||||
};
|
};
|
||||||
Collider.prototype.collidesWith = function (collider, motion, result) {
|
Collider.prototype.collidesWith = function (collider, motion, result) {
|
||||||
var oldPosition = this.entity.position;
|
var oldPosition = this.entity.position;
|
||||||
this.entity.position.add(motion);
|
this.entity.position = this.entity.position.add(motion);
|
||||||
var didCollide = this.shape.collidesWithShape(collider.shape, result);
|
var didCollide = this.shape.collidesWithShape(collider.shape, result);
|
||||||
if (didCollide)
|
if (didCollide)
|
||||||
result.collider = collider;
|
result.collider = collider;
|
||||||
@@ -6090,7 +6091,7 @@ var es;
|
|||||||
edgeNormal = new es.Vector2(-line.y, line.x);
|
edgeNormal = new es.Vector2(-line.y, line.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
es.Vector2Ext.normalize(edgeNormal);
|
edgeNormal = es.Vector2Ext.normalize(edgeNormal);
|
||||||
return closestPoint;
|
return closestPoint;
|
||||||
};
|
};
|
||||||
Polygon.prototype.recalculateBounds = function (collider) {
|
Polygon.prototype.recalculateBounds = function (collider) {
|
||||||
@@ -6122,7 +6123,7 @@ var es;
|
|||||||
}
|
}
|
||||||
this.position = es.Vector2.add(collider.entity.transform.position, this.center);
|
this.position = es.Vector2.add(collider.entity.transform.position, this.center);
|
||||||
this.bounds = es.Rectangle.rectEncompassingPoints(this.points);
|
this.bounds = es.Rectangle.rectEncompassingPoints(this.points);
|
||||||
this.bounds.location = es.Vector2.add(this.bounds.location, this.position);
|
this.bounds.location = this.bounds.location.add(this.position);
|
||||||
};
|
};
|
||||||
Polygon.prototype.overlaps = function (other) {
|
Polygon.prototype.overlaps = function (other) {
|
||||||
var result = new es.CollisionResult();
|
var result = new es.CollisionResult();
|
||||||
@@ -6394,7 +6395,7 @@ var es;
|
|||||||
var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
||||||
if (box.containsPoint(circle.position)) {
|
if (box.containsPoint(circle.position)) {
|
||||||
result.point = closestPointOnBounds;
|
result.point = closestPointOnBounds;
|
||||||
var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.subtract(result.normal, new es.Vector2(circle.radius)));
|
var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius)));
|
||||||
result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace);
|
result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -6406,7 +6407,7 @@ var es;
|
|||||||
result.normal = es.Vector2.subtract(circle.position, closestPointOnBounds);
|
result.normal = es.Vector2.subtract(circle.position, closestPointOnBounds);
|
||||||
var depth = result.normal.length() - circle.radius;
|
var depth = result.normal.length() - circle.radius;
|
||||||
result.point = closestPointOnBounds;
|
result.point = closestPointOnBounds;
|
||||||
es.Vector2Ext.normalize(result.normal);
|
result.normal = es.Vector2Ext.normalize(result.normal);
|
||||||
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(depth), result.normal);
|
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(depth), result.normal);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -124,22 +124,21 @@ module es {
|
|||||||
|
|
||||||
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent);
|
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent);
|
||||||
if (renderable) {
|
if (renderable) {
|
||||||
let bounds = renderable.bounds;
|
let renderableBounds = renderable.bounds;
|
||||||
|
|
||||||
// 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染
|
// 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染
|
||||||
let width = bounds.width / this.entity.scale.x;
|
let width = renderableBounds.width / this.entity.scale.x;
|
||||||
let height = bounds.height / this.entity.scale.y;
|
let height = renderableBounds.height / this.entity.scale.y;
|
||||||
// 圆碰撞器需要特别注意原点
|
// 圆碰撞器需要特别注意原点
|
||||||
if (this instanceof CircleCollider) {
|
if (this instanceof CircleCollider) {
|
||||||
let circleCollider = this as CircleCollider;
|
this.radius = Math.max(width, height) * 0.5;
|
||||||
circleCollider.radius = Math.max(width, height) * 0.5;
|
|
||||||
} else {
|
} else {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取渲染的中心,将其转移到本地坐标,并使用它作为碰撞器的localOffset
|
// 获取渲染的中心,将其转移到本地坐标,并使用它作为碰撞器的localOffset
|
||||||
this.localOffset = Vector2.subtract(bounds.center, this.entity.transform.position);
|
this.localOffset = Vector2.subtract(renderableBounds.center, this.entity.transform.position);
|
||||||
} else {
|
} else {
|
||||||
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
|
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
|
||||||
}
|
}
|
||||||
@@ -218,7 +217,7 @@ module es {
|
|||||||
public collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean {
|
public collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean {
|
||||||
// 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠
|
// 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠
|
||||||
let oldPosition = this.entity.position;
|
let oldPosition = this.entity.position;
|
||||||
this.entity.position.add(motion);
|
this.entity.position = this.entity.position.add(motion);
|
||||||
|
|
||||||
let didCollide = this.shape.collidesWithShape(collider.shape, result);
|
let didCollide = this.shape.collidesWithShape(collider.shape, result);
|
||||||
if (didCollide)
|
if (didCollide)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ module es {
|
|||||||
let _internalcollisionResult: CollisionResult = new CollisionResult();
|
let _internalcollisionResult: CollisionResult = new CollisionResult();
|
||||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)){
|
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)){
|
||||||
// 如果碰撞 则退回之前的移动量
|
// 如果碰撞 则退回之前的移动量
|
||||||
motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
motion = motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
||||||
|
|
||||||
// 如果我们碰到多个对象,为了简单起见,只取第一个。
|
// 如果我们碰到多个对象,为了简单起见,只取第一个。
|
||||||
if (_internalcollisionResult.collider != null){
|
if (_internalcollisionResult.collider != null){
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ module es {
|
|||||||
|
|
||||||
public render(camera: Camera) {
|
public render(camera: Camera) {
|
||||||
this.sync(camera);
|
this.sync(camera);
|
||||||
|
|
||||||
|
this.displayObject.x = this.entity.position.x - this.origin.x + this.localOffset.x - camera.position.x + camera.origin.x;
|
||||||
|
this.displayObject.y = this.entity.position.y - this.origin.y + this.localOffset.y - camera.position.y + camera.origin.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ module es {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2Ext.normalize(edgeNormal);
|
edgeNormal = Vector2Ext.normalize(edgeNormal);
|
||||||
|
|
||||||
return closestPoint;
|
return closestPoint;
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ module es {
|
|||||||
|
|
||||||
this.position = Vector2.add(collider.entity.transform.position, this.center);
|
this.position = Vector2.add(collider.entity.transform.position, this.center);
|
||||||
this.bounds = Rectangle.rectEncompassingPoints(this.points);
|
this.bounds = Rectangle.rectEncompassingPoints(this.points);
|
||||||
this.bounds.location = Vector2.add(this.bounds.location, this.position);
|
this.bounds.location = this.bounds.location.add(this.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public overlaps(other: Shape){
|
public overlaps(other: Shape){
|
||||||
|
|||||||
@@ -154,16 +154,19 @@ module es {
|
|||||||
public static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean {
|
public static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean {
|
||||||
let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
||||||
|
|
||||||
|
// 处理那些中心在盒子里的圆,因为比较好操作,
|
||||||
if (box.containsPoint(circle.position)) {
|
if (box.containsPoint(circle.position)) {
|
||||||
result.point = closestPointOnBounds;
|
result.point = closestPointOnBounds;
|
||||||
|
|
||||||
let safePlace = Vector2.add(closestPointOnBounds, Vector2.subtract(result.normal, new Vector2(circle.radius)));
|
// 计算mtv。找到安全的,没有碰撞的位置,然后从那里得到mtv
|
||||||
|
let safePlace = Vector2.add(closestPointOnBounds, Vector2.multiply(result.normal, new Vector2(circle.radius)));
|
||||||
result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace);
|
result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position);
|
let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position);
|
||||||
|
// 看盒子上的点与圆的距离是否小于半径
|
||||||
if (sqrDistance == 0) {
|
if (sqrDistance == 0) {
|
||||||
result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius));
|
result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius));
|
||||||
} else if (sqrDistance <= circle.radius * circle.radius) {
|
} else if (sqrDistance <= circle.radius * circle.radius) {
|
||||||
@@ -171,7 +174,7 @@ module es {
|
|||||||
let depth = result.normal.length() - circle.radius;
|
let depth = result.normal.length() - circle.radius;
|
||||||
|
|
||||||
result.point = closestPointOnBounds;
|
result.point = closestPointOnBounds;
|
||||||
Vector2Ext.normalize(result.normal);
|
result.normal = Vector2Ext.normalize(result.normal);
|
||||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(depth), result.normal);
|
result.minimumTranslationVector = Vector2.multiply(new Vector2(depth), result.normal);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user