Merged updateMotion with new PhysicsManager

This commit is contained in:
Richard Davey
2013-05-30 01:09:27 +01:00
parent c1eafe865a
commit 0fad46e04b
7 changed files with 635 additions and 461 deletions
+167 -95
View File
@@ -5554,7 +5554,7 @@ var Phaser;
this._game = game;
this.gravity = new Phaser.Vec2(0, 0.2);
this.drag = new Phaser.Vec2(1, 1);
this.bounce = new Phaser.Vec2(0.3, 0.9);
this.bounce = new Phaser.Vec2(0.3, 0.7);
this.friction = new Phaser.Vec2(0.05, 0.05);
this.bounds = new Phaser.Rectangle(0, 0, width, height);
this._objects = [];
@@ -5601,61 +5601,147 @@ var Phaser;
this.halfHeight = Math.round(height / 2);
this.position = new Phaser.Vec2(x + this.halfWidth, y + this.halfHeight);
this.oldPosition = new Phaser.Vec2(x + this.halfWidth, y + this.halfHeight);
this.newVelocity = new Phaser.Vec2(0, 0);
}
AABB.prototype.update = function () {
if(this.sprite.physics.moves) {
this.integrate();
this.oldPosition.x = this.position.x;
this.oldPosition.y = this.position.y;
this.updateMotion();
//this.integrate();
this.collideWorld();
}
};
AABB.prototype.integrate = function () {
var ox = this.oldPosition.x;
var oy = this.oldPosition.y;
this.oldPosition.x = this.position.x;
this.oldPosition.y = this.position.y;
//this.position.x += (this.world.drag.x * this.position.x + this.halfWidth) - (this.world.drag.x * ox) + this.world.gravity.x;
//this.position.y += (this.world.drag.y * this.position.y + this.halfHeight) - (this.world.drag.y * oy) + this.world.gravity.y;
this.position.x += (this.world.drag.x * this.position.x) - (this.world.drag.x * ox) + this.world.gravity.x;
this.position.y += (this.world.drag.y * this.position.y) - (this.world.drag.y * oy) + this.world.gravity.y;
AABB.prototype.updateMotion = function () {
/*
var delta: number;
var velocityDelta: number;
velocityDelta = (this._game.motion.computeVelocity(this.angularVelocity, this.angularAcceleration, this.angularDrag, this.maxAngular) - this.angularVelocity) / 2;
this.angularVelocity += velocityDelta;
this._angle += this.angularVelocity * this._game.time.elapsed;
this.angularVelocity += velocityDelta;
*/
var delta;
var velocityDelta = (this.computeVelocity(this.sprite.physics.velocity.x, this.sprite.physics.acceleration.x, this.sprite.physics.drag.x) - this.sprite.physics.velocity.x) / 2;
this.sprite.physics.velocity.x += velocityDelta;
delta = this.sprite.physics.velocity.x * this.game.time.elapsed;
this.sprite.physics.velocity.x += velocityDelta;
this.position.x += delta;
var velocityDelta = (this.computeVelocity(this.sprite.physics.velocity.y, this.sprite.physics.acceleration.y, this.sprite.physics.drag.y) - this.sprite.physics.velocity.y) / 2;
this.sprite.physics.velocity.y += velocityDelta;
delta = this.sprite.physics.velocity.y * this.game.time.elapsed;
this.sprite.physics.velocity.y += velocityDelta;
this.position.y += delta;
};
AABB.prototype.computeVelocity = /**
* A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
*
* @param {number} Velocity Any component of velocity (e.g. 20).
* @param {number} Acceleration Rate at which the velocity is changing.
* @param {number} Drag Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
* @param {number} Max An absolute value cap for the velocity.
*
* @return {number} The altered Velocity value.
*/
function (velocity, acceleration, drag, max) {
if (typeof acceleration === "undefined") { acceleration = 0; }
if (typeof drag === "undefined") { drag = 0; }
if (typeof max === "undefined") { max = 10000; }
if(acceleration !== 0) {
velocity += acceleration * this.game.time.elapsed;
} else if(drag !== 0) {
this._drag = drag * this.game.time.elapsed;
if(velocity - this._drag > 0) {
velocity = velocity - this._drag;
} else if(velocity + this._drag < 0) {
velocity += this._drag;
} else {
velocity = 0;
}
}
if((velocity != 0) && (max != 10000)) {
if(velocity > max) {
velocity = max;
} else if(velocity < -max) {
velocity = -max;
}
}
return velocity;
};
AABB.prototype.integrate = function () {
//this.position.x += (this.sprite.physics.drag.x * this.position.x) - (this.sprite.physics.drag.x * this._ox) + (this.world.gravity.x * this.sprite.physics.gravityFactor.x);
//this.position.y += (this.sprite.physics.drag.y * this.position.y) - (this.sprite.physics.drag.y * this._oy) + (this.world.gravity.y * this.sprite.physics.gravityFactor.y);
};
AABB.prototype.collideWorld = function () {
// Collide on the x-axis
var dx = this.world.bounds.x - (this.position.x - this.halfWidth);
if(0 < dx) {
this.processWorld(dx, 0, 1, 0, null);
// Hit Left
this.oH = 1;
this.position.x += dx;
if(this.sprite.physics.bounce.x > 0) {
this.sprite.physics.velocity.x *= -(this.sprite.physics.bounce.x);
} else {
this.sprite.physics.velocity.x = 0;
}
} else {
dx = (this.position.x + this.halfWidth) - this.world.bounds.right;
if(0 < dx) {
this.processWorld(-dx, 0, -1, 0, null);
// Hit Right
this.oH = -1;
this.position.x -= dx;
if(this.sprite.physics.bounce.x > 0) {
this.sprite.physics.velocity.x *= -(this.sprite.physics.bounce.x);
} else {
this.sprite.physics.velocity.x = 0;
}
}
}
// Collide on the y-axis
var dy = this.world.bounds.y - (this.position.y - this.halfHeight);
if(0 < dy) {
this.processWorld(0, dy, 0, 1, null);
// Hit Top
this.oV = 1;
this.position.y += dy;
if(this.sprite.physics.bounce.y > 0) {
this.sprite.physics.velocity.y *= -(this.sprite.physics.bounce.y);
} else {
this.sprite.physics.velocity.y = 0;
}
} else {
dy = (this.position.y + this.halfHeight) - this.world.bounds.bottom;
if(0 < dy) {
this.processWorld(0, -dy, 0, -1, null);
// Hit Bottom
this.oV = -1;
this.position.y -= dy;
if(this.sprite.physics.bounce.y > 0) {
this.sprite.physics.velocity.y *= -(this.sprite.physics.bounce.y);
} else {
this.sprite.physics.velocity.y = 0;
}
}
}
};
AABB.prototype.processWorld = function (px, py, dx, dy, tile) {
// Velocity
var vx = this.position.x - this.oldPosition.x;
var vy = this.position.y - this.oldPosition.y;
var dp = (vx * dx + vy * dy);
//this.sprite.physics.velocity.x = this.position.x - this.oldPosition.x;
//this.sprite.physics.velocity.y = this.position.y - this.oldPosition.y;
// Optimise!!!
var dp = (this.sprite.physics.velocity.x * dx + this.sprite.physics.velocity.y * dy);
var nx = dp * dx;
var ny = dp * dy;
var tx = vx - nx;
var ty = vy - ny;
var b, bx, by, f, fx, fy;
var tx = this.sprite.physics.velocity.x - nx;
var ty = this.sprite.physics.velocity.y - ny;
var bx, by, fx, fy;
if(dp < 0) {
fx = tx * this.world.friction.x;
fy = ty * this.world.friction.y;
bx = (nx * (1 + this.world.bounce.x));
by = (ny * (1 + this.world.bounce.y));
} else {
fx = tx * this.sprite.physics.friction.x;
fy = ty * this.sprite.physics.friction.y;
bx = (nx * (1 + this.sprite.physics.bounce.x));
by = (ny * (1 + this.sprite.physics.bounce.y));
//this.sprite.physics.velocity.x = bx;
//this.sprite.physics.velocity.y = by;
} else {
bx = by = fx = fy = 0;
}
this.position.x += px;
@@ -5672,6 +5758,36 @@ var Phaser;
// center point
context.fillStyle = 'rgb(0,255,0)';
context.fillRect(this.position.x, this.position.y, 2, 2);
if(this.oH == 1) {
context.beginPath();
context.strokeStyle = 'rgb(255,0,0)';
context.moveTo(this.position.x - this.halfWidth, this.position.y - this.halfHeight);
context.lineTo(this.position.x - this.halfWidth, this.position.y + this.halfHeight);
context.stroke();
context.closePath();
} else if(this.oH == -1) {
context.beginPath();
context.strokeStyle = 'rgb(255,0,0)';
context.moveTo(this.position.x + this.halfWidth, this.position.y - this.halfHeight);
context.lineTo(this.position.x + this.halfWidth, this.position.y + this.halfHeight);
context.stroke();
context.closePath();
}
if(this.oV == 1) {
context.beginPath();
context.strokeStyle = 'rgb(255,0,0)';
context.moveTo(this.position.x - this.halfWidth, this.position.y - this.halfHeight);
context.lineTo(this.position.x + this.halfWidth, this.position.y - this.halfHeight);
context.stroke();
context.closePath();
} else if(this.oV == -1) {
context.beginPath();
context.strokeStyle = 'rgb(255,0,0)';
context.moveTo(this.position.x - this.halfWidth, this.position.y + this.halfHeight);
context.lineTo(this.position.x + this.halfWidth, this.position.y + this.halfHeight);
context.stroke();
context.closePath();
}
};
return AABB;
})();
@@ -11548,90 +11664,46 @@ var Phaser;
var Physics = (function () {
function Physics(parent) {
/**
* Set this to false if you want to skip the automatic motion/movement stuff
* (see updateMotion()).
* Set this to false if you want to skip the automatic movement stuff
* @type {boolean}
*/
this.moves = true;
this._game = parent.game;
this._sprite = parent;
this.gravityFactor = new Phaser.Vec2(1, 1);
this.drag = new Phaser.Vec2(0, 0);
this.bounce = new Phaser.Vec2(0, 0);
this.friction = new Phaser.Vec2(0.05, 0.05);
this.velocity = new Phaser.Vec2(0, 0);
this.acceleration = new Phaser.Vec2(0, 0);
//this.AABB = new Phaser.Physics.AABB(this._game, this._sprite, this._sprite.x, this._sprite.y, this._sprite.width, this._sprite.height);
this.AABB = this._game.world.physics.add(new Phaser.Physics.AABB(this._game, this._sprite, this._sprite.x, this._sprite.y, this._sprite.width, this._sprite.height));
}
Physics.prototype.update = /**
* Handy for checking if this object is touching a particular surface.
* For slightly better performance you can just &amp; the value directly into <code>touching</code>.
* However, this method is good for readability and accessibility.
*
* @param Direction {number} Any of the collision flags (e.g. LEFT, FLOOR, etc).
*
* @return {boolean} Whether the object is touching an object in (any of) the specified direction(s) this frame.
*/
//public isTouching(direction: number): bool {
// return (this.touching & direction) > Collision.NONE;
//}
/**
* Handy function for checking if this object just landed on a particular surface.
*
* @param Direction {number} Any of the collision flags (e.g. LEFT, FLOOR, etc).
*
* @returns {boolean} Whether the object just landed on any specicied surfaces.
*/
//public justTouched(direction: number): bool {
// return ((this.touching & direction) > Collision.NONE) && ((this.wasTouching & direction) <= Collision.NONE);
//}
/**
* Internal function for updating the position and speed of this object.
*/
function () {
if(this.moves) {
this._sprite.x = this.AABB.position.x - this.AABB.halfWidth;
this._sprite.y = this.AABB.position.y - this.AABB.halfHeight;
}
/*
var delta: number;
var velocityDelta: number;
velocityDelta = (this._game.motion.computeVelocity(this.angularVelocity, this.angularAcceleration, this.angularDrag, this.maxAngular) - this.angularVelocity) / 2;
this.angularVelocity += velocityDelta;
this._angle += this.angularVelocity * this._game.time.elapsed;
this.angularVelocity += velocityDelta;
velocityDelta = (this._game.motion.computeVelocity(this.velocity.x, this.acceleration.x, this.drag.x, this.maxVelocity.x) - this.velocity.x) / 2;
this.velocity.x += velocityDelta;
delta = this.velocity.x * this._game.time.elapsed;
this.velocity.x += velocityDelta;
this.frameBounds.x += delta;
velocityDelta = (this._game.motion.computeVelocity(this.velocity.y, this.acceleration.y, this.drag.y, this.maxVelocity.y) - this.velocity.y) / 2;
this.velocity.y += velocityDelta;
delta = this.velocity.y * this._game.time.elapsed;
this.velocity.y += velocityDelta;
this.frameBounds.y += delta;
*/
};
Object.defineProperty(Physics.prototype, "solid", {
set: /**
* Whether the object collides or not. For more control over what directions
* the object will collide from, use collision constants (like LEFT, FLOOR, etc)
* to set the value of allowCollisions directly.
*/
//public get solid(): bool {
// return (this.allowCollisions & Collision.ANY) > Collision.NONE;
//}
function (value) {
//if (value)
//{
// this.allowCollisions = Collision.ANY;
//}
//else
//{
// this.allowCollisions = Collision.NONE;
//}
},
enumerable: true,
configurable: true
});
//this._sprite.x = this.AABB.position.x;
//this._sprite.y = this.AABB.position.y;
}
};
Physics.prototype.renderDebugInfo = /**
* Render debug infos. (including name, bounds info, position and some other properties)
* @param x {number} X position of the debug info to be rendered.
* @param y {number} Y position of the debug info to be rendered.
* @param [color] {number} color of the debug info to be rendered. (format is css color string)
*/
function (x, y, color) {
if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
this._sprite.texture.context.fillStyle = color;
this._sprite.texture.context.fillText('Sprite: (' + this._sprite.frameBounds.width + ' x ' + this._sprite.frameBounds.height + ')', x, y);
this._sprite.texture.context.fillText('x: ' + this._sprite.frameBounds.x.toFixed(1) + ' y: ' + this._sprite.frameBounds.y.toFixed(1) + ' rotation: ' + this._sprite.rotation.toFixed(1), x, y + 14);
this._sprite.texture.context.fillText('vx: ' + this.velocity.x.toFixed(1) + ' vy: ' + this.velocity.y.toFixed(1), x, y + 28);
this._sprite.texture.context.fillText('ax: ' + this.acceleration.x.toFixed(1) + ' ay: ' + this.acceleration.y.toFixed(1), x, y + 42);
};
return Physics;
})();
Components.Physics = Physics;
+24 -6
View File
@@ -1,17 +1,35 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
function init() {
// Using Phasers asset loader we load up a PNG from the assets folder
game.loader.addImageFile('bunny', 'assets/sprites/atari800xl.png');
game.loader.addImageFile('atari', 'assets/sprites/atari800xl.png');
game.loader.load();
}
var atari;
function create() {
atari = game.add.sprite(200, 200, 'bunny');
//game.add.physicsAABB(200, 200, 233, 99);
atari = game.add.sprite(200, 200, 'atari');
atari.texture.alpha = 0.5;
atari.physics.bounce.setTo(0.5, 0.5);
atari.physics.drag.setTo(10, 10);
//atari.physics.gravityFactor.x = 0;
//atari.physics.gravityFactor.y = 0;
}
function update() {
//atari.y += 0.2;
}
atari.physics.acceleration.x = 0;
atari.physics.acceleration.y = 0;
if(game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) {
atari.physics.acceleration.x = -150;
} else if(game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) {
atari.physics.acceleration.x = 150;
}
if(game.input.keyboard.isDown(Phaser.Keyboard.UP)) {
atari.physics.acceleration.y = -150;
} else if(game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
atari.physics.acceleration.y = 150;
}
}
function render() {
atari.physics.renderDebugInfo(16, 16);
}
})();
+36 -1
View File
@@ -2,7 +2,7 @@
(function () {
var game = new Phaser.Game(this, 'game', 800, 600, init, create, update);
var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
function init() {
@@ -17,10 +17,45 @@
function create() {
atari = game.add.sprite(200, 200, 'atari');
atari.texture.alpha = 0.5;
atari.physics.bounce.setTo(0.5, 0.5);
atari.physics.drag.setTo(10, 10);
//atari.physics.gravityFactor.x = 0;
//atari.physics.gravityFactor.y = 0;
}
function update() {
atari.physics.acceleration.x = 0;
atari.physics.acceleration.y = 0;
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
atari.physics.acceleration.x = -150;
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
atari.physics.acceleration.x = 150;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
{
atari.physics.acceleration.y = -150;
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
atari.physics.acceleration.y = 150;
}
}
function render() {
atari.physics.renderDebugInfo(16, 16);
}
})();