New polygon collision object examples and Body scale fixes.

This commit is contained in:
photonstorm
2014-01-31 10:34:18 +00:00
parent 45b6d5a741
commit 27fc447928
28 changed files with 2080 additions and 1295 deletions
+7 -6
View File
@@ -370,6 +370,12 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.cropEnabled = false;
/**
* @property {boolean} debug - Handy flag to use with Game.enableStep
* @default
*/
this.debug = false;
this.updateCache();
this.updateBounds();
@@ -600,12 +606,6 @@ Phaser.Sprite.prototype.updateBounds = function() {
this.renderable = this._cache.cameraVisible;
}
// Update our physics bounds
if (this.body)
{
this.body.updateScale(this._cache.scaleX, this._cache.scaleY);
}
};
/**
@@ -926,6 +926,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
this.x = x;
this.y = y;
this.world.setTo(x, y);
this.position.x = this.x;
this.position.y = this.y;
this.alive = true;
+29 -8
View File
@@ -173,10 +173,11 @@ Phaser.Physics.Arcade.POLYGON = 2;
Phaser.Physics.Arcade.prototype = {
/**
* Checks the given Physics.Body against the Physics Bounds, if any are set and separates them, setting the blocked flags on the Body as it does so.
* Checks the given Physics.Body against the Physics Bounds, if any are set, and separates them, setting the blocked flags on the Body as it does so.
*
* @method Phaser.Physics.Arcade#checkBounds
* @param {Phaser.Physics.Arcade.Body} The Body object to be checked.
* @return {boolean} True if the body hit the bounds, otherwise false.
*/
checkBounds: function (body) {
@@ -189,6 +190,7 @@ Phaser.Physics.Arcade.prototype = {
var test = SAT.testPolygonPolygon;
var part = body.polygon;
var rebounded = false;
if (body.type === Phaser.Physics.Arcade.CIRCLE)
{
@@ -200,13 +202,17 @@ Phaser.Physics.Arcade.prototype = {
{
body.blocked.left = true;
part.pos.add(this._response.overlapV);
console.log('World checkBounds Left', this._response.overlapV);
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
rebounded = true;
}
else if (this.worldRight && test(this.worldPolys[1], part, this._response))
{
body.blocked.right = true;
part.pos.add(this._response.overlapV);
console.log('World checkBounds Right', this._response.overlapV);
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
rebounded = true;
}
this._response.clear();
@@ -215,13 +221,24 @@ Phaser.Physics.Arcade.prototype = {
{
body.blocked.up = true;
part.pos.add(this._response.overlapV);
console.log('World checkBounds Up', this._response.overlapV);
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
rebounded = true;
}
else if (this.worldBottom && test(this.worldPolys[3], part, this._response))
{
body.blocked.down = true;
part.pos.add(this._response.overlapV);
console.log('World checkBounds Down', this._response.overlapV);
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
rebounded = true;
}
return rebounded;
if (body.sprite.debug)
{
console.log('checkBounds finished', body.blocked);
}
},
@@ -382,8 +399,8 @@ Phaser.Physics.Arcade.prototype = {
if (body.sprite.debug)
{
// console.log('updateMotion: acx', body.acceleration.x, 'acy', body.acceleration.y, 'gravx', this._gravityX, 'gravy', this._gravityY, 'elapsed', this.game.time.physicsElapsed);
console.log('updateMotion: rotation', body.rotation, 'vd', this._velocityDelta, 'drag', this._drag, 'acceleration', body.angularAcceleration);
console.log('updateMotion: acx', body.acceleration.x, 'acy', body.acceleration.y, 'gravx', this._gravityX, 'gravy', this._gravityY, 'elapsed', this.game.time.physicsElapsed);
// console.log('updateMotion: rotation', body.rotation, 'vd', this._velocityDelta, 'drag', this._drag, 'acceleration', body.angularAcceleration);
}
this._p.setTo((body.acceleration.x + this._gravityX) * this.game.time.physicsElapsed, (body.acceleration.y + this._gravityY) * this.game.time.physicsElapsed);
@@ -948,7 +965,7 @@ Phaser.Physics.Arcade.prototype = {
// console.log('*** separateTile', tile);
// console.log('intersection', this._intersection);
tile.tile.debug = true;
// tile.tile.debug = true;
// They overlap. Any custom callbacks?
if (tile.tile.callback || tile.layer.callbacks[tile.tile.index])
@@ -1079,6 +1096,7 @@ Phaser.Physics.Arcade.prototype = {
body.left -= body.overlapX;
body.right -= body.overlapX;
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
body.blocked.left = true;
body.touching.left = true;
body.touching.none = false;
@@ -1089,6 +1107,7 @@ Phaser.Physics.Arcade.prototype = {
body.left -= body.overlapX;
body.right -= body.overlapX;
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
body.blocked.right = true;
body.touching.right = true;
body.touching.none = false;
@@ -1099,6 +1118,7 @@ Phaser.Physics.Arcade.prototype = {
body.y -= body.overlapY;
body.top -= body.overlapY;
body.bottom -= body.overlapY;
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
body.blocked.up = true;
body.touching.up = true;
@@ -1110,6 +1130,7 @@ Phaser.Physics.Arcade.prototype = {
body.y -= body.overlapY;
body.top -= body.overlapY;
body.bottom -= body.overlapY;
body.blocked.x = Math.floor(body.x);
body.blocked.y = Math.floor(body.y);
body.blocked.down = true;
body.touching.down = true;
+91 -54
View File
@@ -390,50 +390,82 @@ Phaser.Physics.Arcade.Body.prototype = {
},
/**
* Sets this Body to use a convex polygon for all collision. The points are specified in a counter-clockwise direction and must create a convex polygon.
* It will be centered on the parent Sprite.
* Sets this Body to use a convex polygon for collision.
* The points are specified in a counter-clockwise direction and must create a convex polygon.
* Use Body.translate and/or Body.offset to re-position the polygon from the Sprite origin.
*
* @method Phaser.Physics.Arcade#setPolygon
* @param {array<SAT.Vector>} points - An array of vectors representing the points in the polygon, in counter-clockwise order.
* @param {number} [translateX=0] - The x amount the rectangle will be translated by from the Sprites center.
* @param {number} [translateY=0] - The y amount the rectangle will be translated by from the Sprites center.
* @param {array<SAT.Vector>|Array<Number>|SAT.Vector...|Number...} points - This can be an array of Vectors that form the polygon,
* a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
* all the points of the polygon e.g. `setPolygon(new SAT.Vector(), new SAT.Vector(), ...)`, or the
* arguments passed can be flat x,y values e.g. `setPolygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers.
*/
setPolygon: function (points, translateX, translateY) {
if (typeof translateX === 'undefined') { translateX = 0; }
if (typeof translateY === 'undefined') { translateY = 0; }
setPolygon: function (points) {
this.type = Phaser.Physics.Arcade.POLYGON;
this.shape = null;
if (!(points instanceof Array))
{
points = Array.prototype.slice.call(arguments);
}
if (typeof points[0] === 'number')
{
var p = [];
for (var i = 0, len = points.length; i < len; i += 2)
{
p.push(new SAT.Vector(points[i], points[i + 1]));
}
points = p;
}
this.polygon = new SAT.Polygon(new SAT.Vector(this.sprite.center.x, this.sprite.center.y), points);
this.polygon.translate(translateX, translateY);
this.offset.setTo(0, 0);
},
/**
* Used for translating rectangle and polygon bodies from the Sprite parent. Doesn't apply to Circles.
* See also the Body.offset property.
*
* @method Phaser.Physics.Arcade#translate
* @param {number} x - The x amount the polygon or rectangle will be translated by from the Sprite.
* @param {number} y - The y amount the polygon or rectangle will be translated by from the Sprite.
*/
translate: function (x, y) {
if (this.polygon)
{
this.polygon.translate(x, y);
}
},
/**
* Internal method.
*
* @method Phaser.Physics.Arcade#updateScale
* @private
*/
updateScale: function (scaleX, scaleY) {
updateScale: function () {
if (scaleX != this._sx || scaleY != this._sy)
if (this.polygon)
{
if (this.polygon)
{
this.polygon.scale(scaleX / this._sx, scaleY / this._sy);
}
else
{
this.shape.r *= Math.max(scaleX, scaleY);
}
this._sx = scaleX;
this._sy = scaleY;
this.polygon.scale(this.sprite.scale.x / this._sx, this.sprite.scale.y / this._sy);
}
else
{
this.shape.r *= Math.max(this.sprite.scale.x, this.sprite.scale.y);
}
this._sx = this.sprite.scale.x;
this._sy = this.sprite.scale.y;
console.log('updateScale', this.sprite.scale.x, this.sprite.scale.y);
},
@@ -449,19 +481,21 @@ Phaser.Physics.Arcade.Body.prototype = {
this.preY = this.y;
this.preRotation = this.sprite.angle;
// this.x = this.sprite.world.x + this.offset.x;
// this.y = this.sprite.world.y + this.offset.y;
this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x;
this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y;
this.rotation = this.preRotation;
if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy)
{
this.updateScale();
}
if (this.sprite.debug)
{
// console.log('Body preUpdate x:', this.x, 'y:', this.y, 'left:', this.left, 'right:', this.right, 'WAS', this.preX, this.preY);
// console.log('Body preUpdate blocked:', this.blocked, this.blockFlags);
// console.log('Body preUpdate velocity:', this.velocity.x, this.velocity.y);
console.log('Body preUpdate rotation:', this.rotation, this.preRotation);
console.log('Body preUpdate x:', this.x, 'y:', this.y, 'left:', this.left, 'right:', this.right, 'WAS', this.preX, this.preY);
console.log('Body preUpdate blocked:', this.blocked, this.blockFlags);
console.log('Body preUpdate velocity:', this.velocity.x, this.velocity.y);
// console.log('Body preUpdate rotation:', this.rotation, this.preRotation);
}
this.checkBlocked();
@@ -487,7 +521,10 @@ if (this.sprite.debug)
}
}
this.game.physics.checkBounds(this);
if (this.game.physics.checkBounds(this))
{
this.reboundCheck(true, true, true);
}
this.applyFriction();
@@ -514,16 +551,16 @@ if (this.sprite.debug)
checkBlocked: function () {
if (this.blocked.left || this.blocked.right && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
if ((this.blocked.left || this.blocked.right) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
{
// console.log('resetBlocked unlocked left + right');
// console.log('resetBlocked unlocked left + right', Math.floor(this.x), this.blocked.x);
this.blocked.left = false;
this.blocked.right = false;
}
if (this.blocked.up || this.blocked.down && (this.x !== this.blocked.x || this.y !== this.blocked.y))
if ((this.blocked.up || this.blocked.down) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
{
// console.log('resetBlocked unlocked up + down');
// console.log('resetBlocked unlocked up + down', Math.floor(this.y), this.blocked.y, 'x', Math.floor(this.x), this.blocked.x);
this.blocked.up = false;
this.blocked.down = false;
}
@@ -608,8 +645,8 @@ if (this.sprite.debug)
if (this.sprite.debug)
{
// console.log('reboundCheck start', this.velocity.x, this.velocity.y);
// console.log('reBound blocked state', this.blocked);
console.log('reboundCheck start', this.velocity.x, this.velocity.y);
console.log('reBound blocked state', this.blocked);
}
if (x)
@@ -621,7 +658,7 @@ if (this.sprite.debug)
if (this.sprite.debug)
{
// console.log('X rebound applied');
console.log('X rebound applied');
}
}
@@ -635,14 +672,14 @@ if (this.sprite.debug)
if (this.sprite.debug)
{
// console.log('reboundCheck X zeroed');
console.log('reboundCheck X zeroed');
}
}
}
if (this.sprite.debug)
{
// console.log('reboundCheck X', this.velocity.x, 'gravity', gx);
console.log('reboundCheck X', this.velocity.x, 'gravity', gx);
}
}
@@ -655,7 +692,7 @@ if (this.sprite.debug)
if (this.sprite.debug)
{
// console.log('Y rebound applied');
console.log('Y rebound applied');
}
}
@@ -669,14 +706,14 @@ if (this.sprite.debug)
if (this.sprite.debug)
{
// console.log('reboundCheck Y zeroed');
console.log('reboundCheck Y zeroed');
}
}
}
if (this.sprite.debug)
{
// console.log('reboundCheck Y', this.velocity.y, 'gravity', gy);
console.log('reboundCheck Y', this.velocity.y, 'gravity', gy);
}
}
@@ -887,7 +924,7 @@ if (this.sprite.debug)
*/
overlap: function (body, response) {
if (this.type === Phaser.Physics.Arcade.RECT && body.type === Phaser.Physics.Arcade.RECT)
if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
{
return SAT.testPolygonPolygon(this.polygon, body.polygon, response);
}
@@ -895,11 +932,11 @@ if (this.sprite.debug)
{
return SAT.testCircleCircle(this.shape, body.shape, response);
}
else if (this.type === Phaser.Physics.Arcade.RECT && body.type === Phaser.Physics.Arcade.CIRCLE)
else if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && body.type === Phaser.Physics.Arcade.CIRCLE)
{
return SAT.testPolygonCircle(this.polygon, body.shape, response);
}
else if (this.type === Phaser.Physics.Arcade.CIRCLE && body.type === Phaser.Physics.Arcade.RECT)
else if (this.type === Phaser.Physics.Arcade.CIRCLE && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
{
return SAT.testCirclePolygon(this.shape, body.polygon, response);
}
@@ -1279,21 +1316,18 @@ if (this.sprite.debug)
if (this.deltaX() !== 0 || this.deltaY() !== 0)
{
// this.sprite.worldTransform[2] = this.sprite.x = (this.x - this.offset.x);
// this.sprite.worldTransform[5] = this.sprite.y = (this.y - this.offset.y);
this.sprite.worldTransform[2] = this.sprite.x = (this.x + (this.sprite.anchor.x * this.sprite.width) - this.offset.x);
this.sprite.worldTransform[5] = this.sprite.y = (this.y + (this.sprite.anchor.y * this.sprite.height) - this.offset.y);
// this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
// this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
}
if (this.allowRotation && this.deltaZ() !== 0)
{
// this.sprite.rotation = this.rotation;
this.sprite.angle += this.deltaZ();
// this.sprite.angle = this.angle;
}
if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy)
{
this.updateScale();
}
}
@@ -1322,6 +1356,9 @@ if (this.sprite.debug)
this.friction = 0.1;
this.checkCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false };
this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x;
this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y;
this.updateBounds();
},
+1
View File
@@ -868,6 +868,7 @@ Phaser.Utils.Debug.prototype = {
for (var i = 1; i < points.length; i++)
{
this.context.fillStyle = 'rgb(255,' + (i * 40) + ',0)';
this.context.fillRect(x + points[i].x - 2, y + points[i].y - 2, 5, 5);
}