Starting merge of the Advanced Physics classes and splitting off Flixel physics into ArcadePhysics.

This commit is contained in:
Richard Davey
2013-06-13 17:15:16 +01:00
parent 7dac2b6506
commit 038cb213e8
23 changed files with 6273 additions and 42 deletions
+36 -1
View File
@@ -56,7 +56,10 @@
<TypeScriptOutFile>../build/phaser.js</TypeScriptOutFile>
<TypeScriptGeneratesDeclarations>true</TypeScriptGeneratesDeclarations>
</PropertyGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="physics\advanced\joints\" />
<Folder Include="physics\arcade\" />
</ItemGroup>
<ItemGroup>
<Content Include="components\animation\AnimationManager.js">
<DependentUpon>AnimationManager.ts</DependentUpon>
@@ -161,12 +164,44 @@
</Content>
<TypeScriptCompile Include="Motion.ts" />
<TypeScriptCompile Include="math\Vec2.ts" />
<TypeScriptCompile Include="math\Transform.ts" />
<Content Include="math\Transform.js">
<DependentUpon>Transform.ts</DependentUpon>
</Content>
<Content Include="math\Vec2.js">
<DependentUpon>Vec2.ts</DependentUpon>
</Content>
<Content Include="Motion.js">
<DependentUpon>Motion.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="physics\ArcadePhysics.ts" />
<TypeScriptCompile Include="physics\advanced\Body.ts" />
<Content Include="physics\advanced\Body.js">
<DependentUpon>Body.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="physics\advanced\Joint.ts" />
<TypeScriptCompile Include="physics\advanced\Bounds.ts" />
<Content Include="physics\advanced\Bounds.js">
<DependentUpon>Bounds.ts</DependentUpon>
</Content>
<Content Include="physics\advanced\Joint.js">
<DependentUpon>Joint.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="physics\advanced\Manager.ts" />
<Content Include="physics\advanced\Manager.js">
<DependentUpon>Manager.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="physics\advanced\Shape.ts" />
<Content Include="physics\advanced\Shape.js">
<DependentUpon>Shape.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="physics\advanced\ShapeCircle.ts" />
<Content Include="physics\advanced\ShapeCircle.js">
<DependentUpon>ShapeCircle.ts</DependentUpon>
</Content>
<Content Include="physics\ArcadePhysics.js">
<DependentUpon>ArcadePhysics.ts</DependentUpon>
</Content>
<Content Include="physics\Body.js">
<DependentUpon>Body.ts</DependentUpon>
</Content>
+3 -3
View File
@@ -25,9 +25,9 @@ module Phaser {
static GEOM_POLYGON: number = 4;
static BODY_DISABLED: number = 0;
static BODY_DYNAMIC: number = 1;
static BODY_STATIC: number = 2;
static BODY_KINEMATIC: number = 3;
static BODY_STATIC: number = 1;
static BODY_KINETIC: number = 2;
static BODY_DYNAMIC: number = 3;
/**
* Flag used to allow GameObjects to collide on their left side
+1 -1
View File
@@ -75,7 +75,7 @@ module Phaser {
}
/**
* Called one by Game during the boot process.
* Called once by Game during the boot process.
*/
public boot() {
+11 -8
View File
@@ -623,7 +623,6 @@ module Phaser {
this.sort();
// What's the z index of the top most child?
var tempZ: number = child.z;
var childIndex: number = this._zCounter;
this._i = 0;
@@ -632,17 +631,21 @@ module Phaser {
{
this._member = this.members[this._i++];
if (this._i > childIndex)
if (this._member)
{
this._member.z--;
}
else if (this._member.z == child.z)
{
childIndex = this._i;
this._member.z = this._zCounter;
if (this._i > childIndex)
{
this._member.z--;
}
else if (this._member.z == child.z)
{
childIndex = this._i;
this._member.z = this._zCounter;
}
}
}
// Maybe redundant?
this.sort();
return true;
+95
View File
@@ -0,0 +1,95 @@
/// <reference path="../Game.ts" />
/// <reference path="Vec2Utils.ts" />
/**
* Phaser - 2D Transform
*
* A 2D Transform
*/
module Phaser {
export class Transform {
/**
* Creates a new 2D Transform object.
* @class Transform
* @constructor
* @return {Transform} This object
**/
constructor(pos: Phaser.Vec2, angle: number) {
this.t = Phaser.Vec2Utils.clone(pos);
this.c = Math.cos(angle);
this.s = Math.sin(angle);
this._tempVec = new Phaser.Vec2;
}
private _tempVec: Phaser.Vec2;
public t: Phaser.Vec2;
public c: number;
public s: number;
public setTo(pos:Phaser.Vec2, angle:number) {
this.t.copyFrom(pos);
this.c = Math.cos(angle);
this.s = Math.sin(angle);
return this;
}
public setRotation(angle:number) {
this.c = Math.cos(angle);
this.s = Math.sin(angle);
return this;
}
public setPosition(p:Phaser.Vec2) {
this.t.copyFrom(p);
return this;
}
public identity() {
this.t.setTo(0, 0);
this.c = 1;
this.s = 0;
return this;
}
public rotate(v:Phaser.Vec2):Phaser.Vec2 {
return this._tempVec.setTo(v.x * this.c - v.y * this.s, v.x * this.s + v.y * this.c);
}
public unrotate(v:Phaser.Vec2):Phaser.Vec2 {
return this._tempVec.setTo(v.x * this.c + v.y * this.s, -v.x * this.s + v.y * this.c);
}
public transform(v:Phaser.Vec2):Phaser.Vec2 {
return this._tempVec.setTo(v.x * this.c - v.y * this.s + this.t.x, v.x * this.s + v.y * this.c + this.t.y);
}
public untransform(v:Phaser.Vec2):Phaser.Vec2 {
var px = v.x - this.t.x;
var py = v.y - this.t.y;
// expensive - check for alternatives
return this._tempVec.setTo(px * this.c + py * this.s, -px * this.s + py * this.c);
}
}
}
+15
View File
@@ -217,6 +217,21 @@ module Phaser {
}
/**
* Adds the given vector to this vector then multiplies by the given scalar.
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {number} scalar
* @return {Vec2} This for chaining.
*/
public multiplyAddByScalar(a: Vec2, scalar: number): Vec2 {
this.x += a.x * scalar;
this.y += a.y * scalar;
return this;
}
/**
* Divide this vector by the given scalar.
*
+25 -1
View File
@@ -73,13 +73,37 @@ module Phaser {
}
/**
* Rotate a 2D vector by 90 degrees.
* Adds two 2D vectors together and multiplies the result by the given scalar.
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {Vec2} b Reference to a source Vec2 object.
* @param {number} s Scaling value.
* @param {Vec2} out The output Vec2 that is the result of the operation.
* @return {Vec2} A Vec2 that is the sum of the two vectors added and multiplied.
*/
static multiplyAdd(a: Vec2, b: Vec2, s: number, out?: Vec2 = new Vec2): Vec2 {
return out.setTo(a.x + b.x * s, a.y + b.y * s);
}
/**
* Return a perpendicular vector (90 degrees rotation)
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {Vec2} out The output Vec2 that is the result of the operation.
* @return {Vec2} A Vec2 that is the scaled vector.
*/
static perp(a: Vec2, out?: Vec2 = new Vec2): Vec2 {
return out.setTo(-a.y, a.x);
}
/**
* Return a perpendicular vector (-90 degrees rotation)
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {Vec2} out The output Vec2 that is the result of the operation.
* @return {Vec2} A Vec2 that is the scaled vector.
*/
static rperp(a: Vec2, out?: Vec2 = new Vec2): Vec2 {
return out.setTo(a.y, -a.x);
}
File diff suppressed because it is too large Load Diff
+535
View File
@@ -0,0 +1,535 @@
/// <reference path="../../math/Vec2.ts" />
/// <reference path="../../geom/Point.ts" />
/// <reference path="../../math/Vec2Utils.ts" />
/// <reference path="../../math/Transform.ts" />
/// <reference path="Manager.ts" />
/// <reference path="Joint.ts" />
/// <reference path="Bounds.ts" />
/**
* Phaser - Advanced Physics - Body
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
export class Body {
constructor(sprite: Phaser.Sprite, type: number) {
this.sprite = sprite;
this.game = sprite.game;
this.id = Phaser.Physics.Advanced.Manager.bodyCounter++;
this.name = 'body' + this.id;
this.type = type;
this.position = new Phaser.Vec2(sprite.x, sprite.y);
this.angle = sprite.rotation;
this.transform = new Phaser.Transform(this.position, this.angle);
this.centroid = new Phaser.Vec2;
this.velocity = new Phaser.Vec2;
this.force = new Phaser.Vec2;
this.angularVelocity = 0;
this.torque = 0;
this.linearDamping = 0;
this.angularDamping = 0;
this.sleepTime = 0;
this.awaked = false;
this.shapes = [];
this.joints = [];
this.jointHash = {};
this.bounds = new Bounds;
this.fixedRotation = false;
this.categoryBits = 0x0001;
this.maskBits = 0xFFFF;
this.stepCount = 0;
}
/**
* Reference to Phaser.Game
*/
public game: Game;
/**
* Reference to the parent Sprite
*/
public sprite: Phaser.Sprite;
/**
* The Body ID
*/
public id: number;
/**
* The Body name
*/
public name: string;
/**
* The type of Body (disabled, dynamic, static or kinematic)
* Disabled = skips all physics operations / tests (default)
* Dynamic = gives and receives impacts
* Static = gives but doesn't receive impacts, cannot be moved by physics
* Kinematic = gives impacts, but never receives, can be moved by physics
* @type {number}
*/
public type: number;
public angle: number;
// Local to world transform
public transform: Phaser.Transform;
// Local center of mass
public centroid: Phaser.Vec2;
// World position of centroid
public position: Phaser.Vec2;
// Velocity
public velocity: Phaser.Vec2;
// Force
public force: Phaser.Vec2;
// Angular velocity
public angularVelocity: number;
// Torque
public torque: number;
// Linear damping
public linearDamping: number;
// Angular damping
public angularDamping: number;
// Sleep time
public sleepTime: number;
// Awaked
public awaked: bool;
// Shapes
public shapes = [];
// Joints
public joints = [];
public jointHash = {};
// Bounds of all shapes
public bounds;
public fixedRotation = false;
public categoryBits = 0x0001;
public maskBits = 0xFFFF;
public stepCount = 0;
// duplicate = Util function
// serialize = Util function
public get isDisabled(): bool {
return this.type == Phaser.Types.BODY_DISABLED ? true : false;
}
public get isStatic(): bool {
return this.type == Phaser.Types.BODY_STATIC ? true : false;
}
public get isKinetic(): bool {
return this.type == Phaser.Types.BODY_KINETIC ? true : false;
}
public get isDynamic(): bool {
return this.type == Phaser.Types.BODY_DYNAMIC ? true : false;
}
public setType(type: number) {
if (type == this.type)
{
return;
}
this.force.setTo(0, 0);
this.velocity.setTo(0, 0);
this.torque = 0;
this.angularVelocity = 0;
this.type = type;
this.awake(true);
}
public addShape(shape) {
// Check not already part of this body
shape.body = this;
this.shapes.push(shape);
}
public removeShape(shape) {
var index = this.shapes.indexOf(shape);
if (index != -1)
{
this.shapes.splice(index, 1);
shape.body = undefined;
}
}
public mass: number;
public massInverted: number;
public inertia: number;
public inertiaInverted: number;
private setMass(mass) {
this.mass = mass;
this.massInverted = mass > 0 ? 1 / mass : 0;
}
private setInertia(inertia) {
this.inertia = inertia;
this.inertiaInverted = inertia > 0 ? 1 / inertia : 0;
}
public setTransform(pos, angle) {
this.transform.setTo(pos, angle)
this.position = this.transform.transform(this.centroid);
this.angle = angle;
}
public syncTransform() {
this.transform.setRotation(this.angle);
// this.transform.setPosition(vec2.sub(this.position, this.transform.rotate(this.centroid)));
Phaser.Vec2Utils.subtract(this.position, this.transform.rotate(this.centroid), this.transform.t);
}
public getWorldPoint(p:Phaser.Vec2) {
// This is returning a new vector - check it's actually used in that way
return this.transform.transform(p)
}
public getWorldVector(v) {
return this.transform.rotate(v)
}
public getLocalPoint(p) {
return this.transform.untransform(p)
}
public getLocalVector(v) {
return this.transform.unrotate(v)
}
public setFixedRotation(flag) {
this.fixedRotation = flag;
this.resetMassData();
}
public resetMassData() {
this.centroid.setTo(0, 0);
this.mass = 0;
this.massInverted = 0;
this.inertia = 0;
this.inertiaInverted = 0;
if (this.isDynamic == false)
{
this.position.copyFrom(this.transform.transform(this.centroid));
return;
}
var totalMassCentroid = new Phaser.Vec2(0, 0);
var totalMass = 0;
var totalInertia = 0;
for (var i = 0; i < this.shapes.length; i++)
{
var shape = this.shapes[i];
var centroid = shape.centroid();
var mass = shape.area() * shape.density;
var inertia = shape.inertia(mass);
totalMassCentroid.multiplyAddByScalar(centroid, mass);
totalMass += mass;
totalInertia += inertia;
}
//this.centroid.copy(vec2.scale(totalMassCentroid, 1 / totalMass));
Phaser.Vec2Utils.scale(totalMassCentroid, 1 / totalMass, this.centroid);
this.setMass(totalMass);
if (!this.fixedRotation)
{
//this.setInertia(totalInertia - totalMass * vec2.dot(this.centroid, this.centroid));
this.setInertia(totalInertia - totalMass * Phaser.Vec2Utils.dot(this.centroid, this.centroid));
}
//console.log("mass = " + this.m + " inertia = " + this.i);
// Move center of mass
var oldPosition: Phaser.Vec2 = Phaser.Vec2Utils.clone(this.position);
this.position = this.transform.transform(this.centroid);
// Update center of mass velocity
//this.velocity.mad(vec2.perp(vec2.sub(this.position, old_p)), this.angularVelocity);
oldPosition.subtract(this.position);
this.velocity.multiplyAddByScalar(Phaser.Vec2Utils.perp(oldPosition, oldPosition), this.angularVelocity);
}
public resetJointAnchors() {
for (var i = 0; i < this.joints.length; i++)
{
var joint = this.joints[i];
if (!joint)
{
continue;
}
var anchor1 = joint.getWorldAnchor1();
var anchor2 = joint.getWorldAnchor2();
joint.setWorldAnchor1(anchor1);
joint.setWorldAnchor2(anchor2);
}
}
public cacheData() {
this.bounds.clear();
for (var i = 0; i < this.shapes.length; i++)
{
var shape = this.shapes[i];
shape.cacheData(this.transform);
this.bounds.addBounds(shape.bounds);
}
}
private _tempVec2: Phaser.Vec2;
public updateVelocity(gravity, dt, damping) {
// this.velocity = vec2.mad(this.velocity, vec2.mad(gravity, this.force, this.massInverted), dt);
Phaser.Vec2Utils.multiplyAdd(gravity, this.force, this.massInverted, this._tempVec2);
Phaser.Vec2Utils.multiplyAdd(this.velocity, this._tempVec2, dt, this.velocity);
this.angularVelocity = this.angularVelocity + this.torque * this.inertiaInverted * dt;
// Apply damping.
// ODE: dv/dt + c * v = 0
// Solution: v(t) = v0 * exp(-c * t)
// Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt)
// v2 = exp(-c * dt) * v1
// Taylor expansion:
// v2 = (1.0f - c * dt) * v1
this.velocity.scale(this.game.math.clamp(1 - dt * (damping + this.linearDamping), 0, 1));
this.angularVelocity *= this.game.math.clamp(1 - dt * (damping + this.angularDamping), 0, 1);
this.force.setTo(0, 0);
this.torque = 0;
}
public updatePosition(dt) {
//this.position.addself(vec2.scale(this.velocity, dt));
this.position.add(Phaser.Vec2Utils.scale(this.velocity, dt, this._tempVec2));
this.angle += this.angularVelocity * dt;
}
public resetForce() {
this.force.setTo(0, 0);
this.torque = 0;
}
public applyForce(force, p) {
if (this.isDynamic == false)
{
return;
}
if (this.isAwake == false)
{
this.awake(true);
}
this.force.add(force);
// this.f.addself(force);
// this.torque += vec2.cross(vec2.sub(p, this.p), force);
Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
this.torque += Phaser.Vec2Utils.cross(this._tempVec2, force);
}
public applyForceToCenter(force) {
if (this.isDynamic == false)
{
return;
}
if (this.isAwake == false)
{
this.awake(true);
}
this.force.add(force);
}
public applyTorque(torque) {
if (this.isDynamic == false)
{
return;
}
if (this.isAwake == false)
{
this.awake(true);
}
this.torque += torque;
}
public applyLinearImpulse(impulse, p) {
if (this.isDynamic == false)
{
return;
}
if (this.isAwake == false)
{
this.awake(true);
}
this.velocity.multiplyAddByScalar(impulse, this.massInverted);
// this.angularVelocity += vec2.cross(vec2.sub(p, this.position), impulse) * this.inertiaInverted;
Phaser.Vec2Utils.subtract(p, this.position, this._tempVec2);
this.angularVelocity += Phaser.Vec2Utils.cross(this._tempVec2, impulse) * this.inertiaInverted;
}
public applyAngularImpulse(impulse) {
if (this.isDynamic == false)
{
return;
}
if (this.isAwake == false)
{
this.awake(true);
}
this.angularVelocity += impulse * this.inertiaInverted;
}
public kineticEnergy() {
var vsq = this.velocity.dot(this.velocity);
var wsq = this.angularVelocity * this.angularVelocity;
return 0.5 * (this.mass * vsq + this.inertia * wsq);
}
public get isAwake(): bool {
return this.awaked;
}
public awake(flag) {
this.awaked = flag;
if (flag)
{
this.sleepTime = 0;
}
else
{
this.velocity.setTo(0, 0);
this.angularVelocity = 0;
this.force.setTo(0, 0);
this.torque = 0;
}
}
public isCollidable(other) {
if (this == other)
{
return false;
}
if (this.isDynamic == false && other.isDynamic == false)
{
return false;
}
if (!(this.maskBits & other.categoryBits) || !(other.maskBits & this.categoryBits))
{
return false;
}
for (var i = 0; i < this.joints.length; i++)
{
var joint = this.joints[i];
if (!joint)
{
continue;
}
if (!joint.collideConnected && other.jointHash[joint.id] != undefined)
{
return false;
}
}
return true;
}
}
}
+154
View File
@@ -0,0 +1,154 @@
/// <reference path="../../Game.ts" />
/// <reference path="../../math/Vec2.ts" />
/// <reference path="../../math/Vec2Utils.ts" />
/**
* Phaser - 2D AABB
*
* A 2D AABB object
*/
module Phaser.Physics.Advanced {
export class Bounds {
/**
* Creates a new 2D AABB object.
* @class Bounds
* @constructor
* @return {Bounds} This object
**/
constructor(mins?: Phaser.Vec2 = null, maxs?: Phaser.Vec2 = null) {
if (mins)
{
this.mins = Phaser.Vec2Utils.clone(mins);
}
else
{
this.mins = new Phaser.Vec2(999999, 999999);
}
if (maxs)
{
this.maxs = Phaser.Vec2Utils.clone(maxs);
}
else
{
this.maxs = new Phaser.Vec2(999999, 999999);
}
}
public mins: Phaser.Vec2;
public maxs: Phaser.Vec2;
public toString() {
return ["mins:", this.mins.toString(), "maxs:", this.maxs.toString()].join(" ");
}
public setTo(mins, maxs) {
this.mins.setTo(mins.x, mins.y);
this.maxs.setTo(maxs.x, maxs.y);
}
public copy(b:Bounds) {
this.mins.copyFrom(b.mins);
this.maxs.copyFrom(b.maxs);
return this;
}
public clear() {
this.mins.setTo(999999, 999999);
this.maxs.setTo(-999999, -999999);
return this;
}
public isEmpty(): bool {
return (this.mins.x > this.maxs.x || this.mins.y > this.maxs.y);
}
/*
public getCenter() {
return vec2.scale(vec2.add(this.mins, this.maxs), 0.5);
}
public getExtent() {
return vec2.scale(vec2.sub(this.maxs, this.mins), 0.5);
}
*/
public getPerimeter() {
return (this.maxs.x - this.mins.x + this.maxs.y - this.mins.y) * 2;
}
public addPoint(p) {
if (this.mins.x > p.x) this.mins.x = p.x;
if (this.maxs.x < p.x) this.maxs.x = p.x;
if (this.mins.y > p.y) this.mins.y = p.y;
if (this.maxs.y < p.y) this.maxs.y = p.y;
return this;
}
public addBounds(b) {
if (this.mins.x > b.mins.x) this.mins.x = b.mins.x;
if (this.maxs.x < b.maxs.x) this.maxs.x = b.maxs.x;
if (this.mins.y > b.mins.y) this.mins.y = b.mins.y;
if (this.maxs.y < b.maxs.y) this.maxs.y = b.maxs.y;
return this;
}
public addBounds2(mins, maxs) {
if (this.mins.x > mins.x) this.mins.x = mins.x;
if (this.maxs.x < maxs.x) this.maxs.x = maxs.x;
if (this.mins.y > mins.y) this.mins.y = mins.y;
if (this.maxs.y < maxs.y) this.maxs.y = maxs.y;
return this;
}
public addExtents(center, extent_x, extent_y) {
if (this.mins.x > center.x - extent_x) this.mins.x = center.x - extent_x;
if (this.maxs.x < center.x + extent_x) this.maxs.x = center.x + extent_x;
if (this.mins.y > center.y - extent_y) this.mins.y = center.y - extent_y;
if (this.maxs.y < center.y + extent_y) this.maxs.y = center.y + extent_y;
return this;
}
public expand(ax, ay) {
this.mins.x -= ax;
this.mins.y -= ay;
this.maxs.x += ax;
this.maxs.y += ay;
return this;
}
public containPoint(p) {
if (p.x < this.mins.x || p.x > this.maxs.x || p.y < this.mins.y || p.y > this.maxs.y)
{
return false;
}
return true;
}
public intersectsBounds(b) {
if (this.mins.x > b.maxs.x || this.maxs.x < b.mins.x || this.mins.y > b.maxs.y || this.maxs.y < b.mins.y)
{
return false;
}
return true;
}
public static expand(b, ax, ay) {
var b = new Bounds(b.mins, b.maxs);
b.expand(ax, ay);
return b;
}
}
}
+64
View File
@@ -0,0 +1,64 @@
/// <reference path="../../math/Vec2.ts" />
/// <reference path="../../geom/Point.ts" />
/// <reference path="../../math/Vec2Utils.ts" />
/// <reference path="Manager.ts" />
/// <reference path="Body.ts" />
/**
* Phaser - Advanced Physics - Joint
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
export class Joint {
constructor(type: number, body1:Phaser.Physics.Advanced.Body, body2:Phaser.Physics.Advanced.Body, collideConnected) {
this.id = Phaser.Physics.Advanced.Manager.jointCounter++;
this.type = type;
this.body1 = body1;
this.body2 = body2;
this.collideConnected = collideConnected;
this.maxForce = 9999999999;
this.breakable = false;
}
public id: number;
public type: number;
public body1: Phaser.Physics.Advanced.Body;
public body2: Phaser.Physics.Advanced.Body;
public collideConnected; // bool?
public maxForce: number;
public breakable: bool;
public anchor1: Phaser.Vec2;
public anchor2: Phaser.Vec2;
public getWorldAnchor1() {
return this.body1.getWorldPoint(this.anchor1);
}
public getWorldAnchor2() {
return this.body2.getWorldPoint(this.anchor2);
}
public setWorldAnchor1(anchor1) {
this.anchor1 = this.body1.getLocalPoint(anchor1);
}
public setWorldAnchor2(anchor2) {
this.anchor2 = this.body2.getLocalPoint(anchor2);
}
}
}
+73
View File
@@ -0,0 +1,73 @@
/// <reference path="../../Game.ts" />
/// <reference path="Body.ts" />
/// <reference path="Joint.ts" />
/**
* Phaser - Advanced Physics Manager
*
* Your game only has one PhysicsManager instance and it's responsible for looking after, creating and colliding
* all of the physics objects in the world.
*/
module Phaser.Physics.Advanced {
export class Manager {
constructor(game: Game) {
this.game = game;
}
/**
* Local reference to Game.
*/
public game: Game;
public static SHAPE_TYPE_CIRCLE: number = 0;
public static SHAPE_TYPE_SEGMENT: number = 1;
public static SHAPE_TYPE_POLY: number = 2;
public static SHAPE_NUM_TYPES: number = 3;
public static JOINT_TYPE_ANGLE: number = 0;
public static JOINT_TYPE_REVOLUTE: number = 1;
public static JOINT_TYPE_WELD: number = 2;
public static JOINT_TYPE_WHEEL: number = 3;
public static JOINT_TYPE_PRISMATIC: number = 4;
public static JOINT_TYPE_DISTANCE: number = 5;
public static JOINT_TYPE_ROPE: number = 6;
public static JOINT_TYPE_MOUSE: number = 7;
public static JOINT_LINEAR_SLOP: number = 0.0008;
public static JOINT_ANGULAR_SLOP: number = 2 * Phaser.GameMath.DEG_TO_RAD;
public static JOINT_MAX_LINEAR_CORRECTION: number = 0.5;
public static JOINT_MAX_ANGULAR_CORRECTION: number = 8 * Phaser.GameMath.DEG_TO_RAD;
public static JOINT_LIMIT_STATE_INACTIVE: number = 0;
public static JOINT_LIMIT_STATE_AT_LOWER: number = 1;
public static JOINT_LIMIT_STATE_AT_UPPER: number = 2;
public static JOINT_LIMIT_STATE_EQUAL_LIMITS: number = 3;
public static bodyCounter: number = 0;
public static jointCounter: number = 0;
public static shapeCounter: number = 0;
public static pixelsToMeters(value: number): number {
return value * 0.02;
}
public static metersToPixels(value: number): number {
return value * 50;
}
public static p2m(value: number): number {
return value * 0.02;
}
public static m2p(value: number): number {
return value * 50;
}
}
}
+47
View File
@@ -0,0 +1,47 @@
/// <reference path="../../math/Vec2.ts" />
/// <reference path="../../geom/Point.ts" />
/// <reference path="../../math/Vec2Utils.ts" />
/// <reference path="Manager.ts" />
/// <reference path="Body.ts" />
/**
* Phaser - Advanced Physics - Shape
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
export class Shape {
constructor(type: number) {
this.id = Phaser.Physics.Advanced.Manager.shapeCounter++;
this.type = type;
this.elasticity = 0.0;
this.friction = 1.0;
this.density = 1;
//this.bounds = new Bounds;
}
public id: number;
public type: number;
// Coefficient of restitution (elasticity)
public elasticity: number;
// Frictional coefficient
public friction: number;
// Mass density
public density: number;
// Axis-aligned bounding box
public bounds;
}
}
+29
View File
@@ -0,0 +1,29 @@
/// <reference path="../../math/Vec2.ts" />
/// <reference path="../../geom/Point.ts" />
/// <reference path="../../math/Vec2Utils.ts" />
/// <reference path="Manager.ts" />
/// <reference path="Body.ts" />
/// <reference path="Shape.ts" />
/**
* Phaser - Advanced Physics - Shape
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
export class ShapeCircle extends Phaser.Physics.Advanced.Shape {
constructor() {
super(Manager.SHAPE_TYPE_CIRCLE);
}
}
}
+2
View File
@@ -45,6 +45,8 @@ TODO:
* Sprite collision events
* See which functions in the input component can move elsewhere (utils)
* Move all of the renderDebugInfo methods to the DebugUtils class
* Check bounds/edge points when sprite is only 1x1 sized :)
V1.0.0
+8
View File
@@ -186,6 +186,14 @@
<Content Include="physics\aabb vs aabb 1.js">
<DependentUpon>aabb vs aabb 1.ts</DependentUpon>
</Content>
<TypeScriptCompile Include="physics\obb vs obb.ts" />
<TypeScriptCompile Include="physics\body1.ts" />
<Content Include="physics\body1.js">
<DependentUpon>body1.ts</DependentUpon>
</Content>
<Content Include="physics\obb vs obb.js">
<DependentUpon>obb vs obb.ts</DependentUpon>
</Content>
<Content Include="scrollzones\ballscroller.js">
<DependentUpon>ballscroller.ts</DependentUpon>
</Content>
+1767 -12
View File
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../Phaser/physics/advanced/Manager.ts" />
(function () {
var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
function init() {
game.load.image('atari', 'assets/sprites/atari800xl.png');
game.load.image('card', 'assets/sprites/mana_card.png');
game.load.start();
}
var atari;
var card;
function create() {
atari = game.add.sprite(200, 310, 'atari');
//card = game.add.sprite(500, 300, 'card');
var body = new Phaser.Physics.Advanced.Body(atari, Phaser.Types.BODY_DYNAMIC);
var body2 = new Phaser.Physics.Advanced.Body(atari, Phaser.Types.BODY_DYNAMIC);
console.log(body);
console.log(body2);
}
function update() {
}
function render() {
}
})();
+38
View File
@@ -0,0 +1,38 @@
/// <reference path="../../Phaser/Game.ts" />
/// <reference path="../../Phaser/physics/advanced/Manager.ts" />
(function () {
var game = new Phaser.Game(this, 'game', 800, 600, init, create, update, render);
function init() {
game.load.image('atari', 'assets/sprites/atari800xl.png');
game.load.image('card', 'assets/sprites/mana_card.png');
game.load.start();
}
var atari: Phaser.Sprite;
var card: Phaser.Sprite;
function create() {
atari = game.add.sprite(200, 310, 'atari');
//card = game.add.sprite(500, 300, 'card');
var body = new Phaser.Physics.Advanced.Body(atari, Phaser.Types.BODY_DYNAMIC);
//body.
console.log(body);
}
function update() {
}
function render() {
}
})();
+33
View File
@@ -0,0 +1,33 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
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.load.image('atari', 'assets/sprites/atari800xl.png');
game.load.image('card', 'assets/sprites/mana_card.png');
game.load.start();
}
var atari;
var card;
function create() {
atari = game.add.sprite(200, 310, 'atari');
card = game.add.sprite(500, 300, 'card');
atari.input.start(0);
atari.input.enableDrag();
card.input.start(0);
card.events.onInputDown.add(rotateIt, this);
}
function rotateIt() {
card.rotation += 10;
}
function update() {
}
function render() {
game.stage.context.save();
game.stage.context.strokeStyle = 'rgb(255,255,0)';
game.stage.context.strokeRect(atari.cameraView.x, atari.cameraView.y, atari.cameraView.width, atari.cameraView.height);
game.stage.context.strokeStyle = 'rgb(255,0,255)';
game.stage.context.strokeRect(card.cameraView.x, card.cameraView.y, card.cameraView.width, card.cameraView.height);
game.stage.context.restore();
}
})();
+54
View File
@@ -0,0 +1,54 @@
/// <reference path="../../Phaser/Game.ts" />
(function () {
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.load.image('atari', 'assets/sprites/atari800xl.png');
game.load.image('card', 'assets/sprites/mana_card.png');
game.load.start();
}
var atari: Phaser.Sprite;
var card: Phaser.Sprite;
function create() {
atari = game.add.sprite(200, 310, 'atari');
card = game.add.sprite(500, 300, 'card');
atari.input.start(0);
atari.input.enableDrag();
card.input.start(0);
card.events.onInputDown.add(rotateIt, this);
}
function rotateIt() {
card.rotation += 10;
}
function update() {
}
function render() {
game.stage.context.save();
game.stage.context.strokeStyle = 'rgb(255,255,0)';
game.stage.context.strokeRect(atari.cameraView.x, atari.cameraView.y, atari.cameraView.width, atari.cameraView.height);
game.stage.context.strokeStyle = 'rgb(255,0,255)';
game.stage.context.strokeRect(card.cameraView.x, card.cameraView.y, card.cameraView.width, card.cameraView.height);
game.stage.context.restore();
}
})();
+393 -4
View File
@@ -615,6 +615,14 @@ module Phaser {
*/
public multiplyByScalar(scalar: number): Vec2;
/**
* Adds the given vector to this vector then multiplies by the given scalar.
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {number} scalar
* @return {Vec2} This for chaining.
*/
public multiplyAddByScalar(a: Vec2, scalar: number): Vec2;
/**
* Divide this vector by the given scalar.
*
* @param {number} scalar
@@ -822,9 +830,9 @@ module Phaser {
static GEOM_LINE: number;
static GEOM_POLYGON: number;
static BODY_DISABLED: number;
static BODY_DYNAMIC: number;
static BODY_STATIC: number;
static BODY_KINEMATIC: number;
static BODY_KINETIC: number;
static BODY_DYNAMIC: number;
/**
* Flag used to allow GameObjects to collide on their left side
* @type {number}
@@ -2378,7 +2386,17 @@ module Phaser {
*/
static scale(a: Vec2, s: number, out?: Vec2): Vec2;
/**
* Rotate a 2D vector by 90 degrees.
* Adds two 2D vectors together and multiplies the result by the given scalar.
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {Vec2} b Reference to a source Vec2 object.
* @param {number} s Scaling value.
* @param {Vec2} out The output Vec2 that is the result of the operation.
* @return {Vec2} A Vec2 that is the sum of the two vectors added and multiplied.
*/
static multiplyAdd(a: Vec2, b: Vec2, s: number, out?: Vec2): Vec2;
/**
* Return a perpendicular vector (90 degrees rotation)
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {Vec2} out The output Vec2 that is the result of the operation.
@@ -2386,6 +2404,14 @@ module Phaser {
*/
static perp(a: Vec2, out?: Vec2): Vec2;
/**
* Return a perpendicular vector (-90 degrees rotation)
*
* @param {Vec2} a Reference to a source Vec2 object.
* @param {Vec2} out The output Vec2 that is the result of the operation.
* @return {Vec2} A Vec2 that is the scaled vector.
*/
static rperp(a: Vec2, out?: Vec2): Vec2;
/**
* Checks if two 2D vectors are equal.
*
* @param {Vec2} a Reference to a source Vec2 object.
@@ -3832,8 +3858,22 @@ module Phaser {
* @return {object} The text data you want.
*/
public getText(key: string);
/**
* Returns an array containing all of the keys of Images in the Cache.
* @return {Array} The string based keys in the Cache.
*/
public getImageKeys(): any[];
/**
* Returns an array containing all of the keys of Sounds in the Cache.
* @return {Array} The string based keys in the Cache.
*/
public getSoundKeys(): any[];
/**
* Returns an array containing all of the keys of Text Files in the Cache.
* @return {Array} The string based keys in the Cache.
*/
public getTextKeys(): any[];
/**
* Clean up cache memory.
*/
public destroy(): void;
@@ -7215,7 +7255,7 @@ module Phaser {
private _groupCounter;
public getNextGroupID(): number;
/**
* Called one by Game during the boot process.
* Called once by Game during the boot process.
*/
public boot(): void;
/**
@@ -9349,6 +9389,355 @@ module Phaser {
}
}
/**
* Phaser - 2D Transform
*
* A 2D Transform
*/
module Phaser {
class Transform {
/**
* Creates a new 2D Transform object.
* @class Transform
* @constructor
* @return {Transform} This object
**/
constructor(pos: Vec2, angle: number);
private _tempVec;
public t: Vec2;
public c: number;
public s: number;
public setTo(pos: Vec2, angle: number): Transform;
public setRotation(angle: number): Transform;
public setPosition(p: Vec2): Transform;
public identity(): Transform;
public rotate(v: Vec2): Vec2;
public unrotate(v: Vec2): Vec2;
public transform(v: Vec2): Vec2;
public untransform(v: Vec2): Vec2;
}
}
/**
* Phaser - PhysicsManager
*
* Your game only has one PhysicsManager instance and it's responsible for looking after, creating and colliding
* all of the physics objects in the world.
*/
module Phaser.Physics {
class ArcadePhysics {
constructor(game: Game, width: number, height: number);
/**
* Local private reference to Game.
*/
public game: Game;
/**
* Physics object pool
*/
public members: Group;
private _drag;
private _delta;
private _velocityDelta;
private _length;
private _distance;
private _tangent;
private _separatedX;
private _separatedY;
private _overlap;
private _maxOverlap;
private _obj1Velocity;
private _obj2Velocity;
private _obj1NewVelocity;
private _obj2NewVelocity;
private _average;
private _quadTree;
private _quadTreeResult;
public bounds: Rectangle;
public gravity: Vec2;
public drag: Vec2;
public bounce: Vec2;
public angularDrag: number;
/**
* The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
* @type {number}
*/
static OVERLAP_BIAS: number;
/**
* The overlap bias is used when calculating hull overlap before separation - change it if you have especially small or large GameObjects
* @type {number}
*/
static TILE_OVERLAP: bool;
/**
* @type {number}
*/
public worldDivisions: number;
public updateMotion(body: Body): void;
/**
* 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.
*/
public computeVelocity(velocity: number, gravity?: number, acceleration?: number, drag?: number, max?: number): number;
/**
* The core Collision separation method.
* @param body1 The first Physics.Body to separate
* @param body2 The second Physics.Body to separate
* @returns {boolean} Returns true if the bodies were separated, otherwise false.
*/
public separate(body1: Body, body2: Body): bool;
public checkHullIntersection(body1: Body, body2: Body): bool;
/**
* Separates the two objects on their x axis
* @param object1 The first GameObject to separate
* @param object2 The second GameObject to separate
* @returns {boolean} Whether the objects in fact touched and were separated along the X axis.
*/
public separateBodyX(body1: Body, body2: Body): bool;
/**
* Separates the two objects on their y axis
* @param object1 The first GameObject to separate
* @param object2 The second GameObject to separate
* @returns {boolean} Whether the objects in fact touched and were separated along the Y axis.
*/
public separateBodyY(body1: Body, body2: Body): bool;
/**
* Checks for overlaps between two objects using the world QuadTree. Can be Sprite vs. Sprite, Sprite vs. Group or Group vs. Group.
* Note: Does not take the objects scrollFactor into account. All overlaps are check in world space.
* @param object1 The first Sprite or Group to check. If null the world.group is used.
* @param object2 The second Sprite or Group to check.
* @param notifyCallback A callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you passed them to Collision.overlap.
* @param processCallback A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then notifyCallback will only be called if processCallback returns true.
* @param context The context in which the callbacks will be called
* @returns {boolean} true if the objects overlap, otherwise false.
*/
public overlap(object1?, object2?, notifyCallback?, processCallback?, context?): bool;
/**
* Collision resolution specifically for GameObjects vs. Tiles.
* @param object The GameObject to separate
* @param tile The Tile to separate
* @returns {boolean} Whether the objects in fact touched and were separated
*/
public separateTile(object: Sprite, x: number, y: number, width: number, height: number, mass: number, collideLeft: bool, collideRight: bool, collideUp: bool, collideDown: bool, separateX: bool, separateY: bool): bool;
}
}
/**
* Phaser - Advanced Physics - Joint
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
class Joint {
constructor(type: number, body1: Body, body2: Body, collideConnected);
public id: number;
public type: number;
public body1: Body;
public body2: Body;
public collideConnected;
public maxForce: number;
public breakable: bool;
public anchor1: Vec2;
public anchor2: Vec2;
public getWorldAnchor1(): Vec2;
public getWorldAnchor2(): Vec2;
public setWorldAnchor1(anchor1): void;
public setWorldAnchor2(anchor2): void;
}
}
/**
* Phaser - Advanced Physics Manager
*
* Your game only has one PhysicsManager instance and it's responsible for looking after, creating and colliding
* all of the physics objects in the world.
*/
module Phaser.Physics.Advanced {
class Manager {
constructor(game: Game);
/**
* Local reference to Game.
*/
public game: Game;
static SHAPE_TYPE_CIRCLE: number;
static SHAPE_TYPE_SEGMENT: number;
static SHAPE_TYPE_POLY: number;
static SHAPE_NUM_TYPES: number;
static JOINT_TYPE_ANGLE: number;
static JOINT_TYPE_REVOLUTE: number;
static JOINT_TYPE_WELD: number;
static JOINT_TYPE_WHEEL: number;
static JOINT_TYPE_PRISMATIC: number;
static JOINT_TYPE_DISTANCE: number;
static JOINT_TYPE_ROPE: number;
static JOINT_TYPE_MOUSE: number;
static JOINT_LINEAR_SLOP: number;
static JOINT_ANGULAR_SLOP: number;
static JOINT_MAX_LINEAR_CORRECTION: number;
static JOINT_MAX_ANGULAR_CORRECTION: number;
static JOINT_LIMIT_STATE_INACTIVE: number;
static JOINT_LIMIT_STATE_AT_LOWER: number;
static JOINT_LIMIT_STATE_AT_UPPER: number;
static JOINT_LIMIT_STATE_EQUAL_LIMITS: number;
static bodyCounter: number;
static jointCounter: number;
static shapeCounter: number;
static pixelsToMeters(value: number): number;
static metersToPixels(value: number): number;
static p2m(value: number): number;
static m2p(value: number): number;
}
}
/**
* Phaser - 2D AABB
*
* A 2D AABB object
*/
module Phaser.Physics.Advanced {
class Bounds {
/**
* Creates a new 2D AABB object.
* @class Bounds
* @constructor
* @return {Bounds} This object
**/
constructor(mins?: Vec2, maxs?: Vec2);
public mins: Vec2;
public maxs: Vec2;
public toString(): string;
public setTo(mins, maxs): void;
public copy(b: Bounds): Bounds;
public clear(): Bounds;
public isEmpty(): bool;
public getPerimeter(): number;
public addPoint(p): Bounds;
public addBounds(b): Bounds;
public addBounds2(mins, maxs): Bounds;
public addExtents(center, extent_x, extent_y): Bounds;
public expand(ax, ay): Bounds;
public containPoint(p): bool;
public intersectsBounds(b): bool;
static expand(b, ax, ay);
}
}
/**
* Phaser - Advanced Physics - Body
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
class Body {
constructor(sprite: Sprite, type: number);
/**
* Reference to Phaser.Game
*/
public game: Game;
/**
* Reference to the parent Sprite
*/
public sprite: Sprite;
/**
* The Body ID
*/
public id: number;
/**
* The Body name
*/
public name: string;
/**
* The type of Body (disabled, dynamic, static or kinematic)
* Disabled = skips all physics operations / tests (default)
* Dynamic = gives and receives impacts
* Static = gives but doesn't receive impacts, cannot be moved by physics
* Kinematic = gives impacts, but never receives, can be moved by physics
* @type {number}
*/
public type: number;
public angle: number;
public transform: Transform;
public centroid: Vec2;
public position: Vec2;
public velocity: Vec2;
public force: Vec2;
public angularVelocity: number;
public torque: number;
public linearDamping: number;
public angularDamping: number;
public sleepTime: number;
public awaked: bool;
public shapes: any[];
public joints: any[];
public jointHash: {};
public bounds;
public fixedRotation: bool;
public categoryBits: number;
public maskBits: number;
public stepCount: number;
public isDisabled : bool;
public isStatic : bool;
public isKinetic : bool;
public isDynamic : bool;
public setType(type: number): void;
public addShape(shape): void;
public removeShape(shape): void;
public mass: number;
public massInverted: number;
public inertia: number;
public inertiaInverted: number;
private setMass(mass);
private setInertia(inertia);
public setTransform(pos, angle): void;
public syncTransform(): void;
public getWorldPoint(p: Vec2): Vec2;
public getWorldVector(v): Vec2;
public getLocalPoint(p): Vec2;
public getLocalVector(v): Vec2;
public setFixedRotation(flag): void;
public resetMassData(): void;
public resetJointAnchors(): void;
public cacheData(): void;
private _tempVec2;
public updateVelocity(gravity, dt, damping): void;
public updatePosition(dt): void;
public resetForce(): void;
public applyForce(force, p): void;
public applyForceToCenter(force): void;
public applyTorque(torque): void;
public applyLinearImpulse(impulse, p): void;
public applyAngularImpulse(impulse): void;
public kineticEnergy(): number;
public isAwake : bool;
public awake(flag): void;
public isCollidable(other): bool;
}
}
/**
* Phaser - Advanced Physics - Shape
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
class Shape {
constructor(type: number);
public id: number;
public type: number;
public elasticity: number;
public friction: number;
public density: number;
public bounds;
}
}
/**
* Phaser - Advanced Physics - Shape
*
* Based on the work Ju Hyung Lee started in JS PhyRus.
*/
module Phaser.Physics.Advanced {
class ShapeCircle extends Shape {
constructor();
}
}
/**
* Phaser - PixelUtils
*
* A collection of methods useful for manipulating pixels.
+1745 -12
View File
File diff suppressed because it is too large Load Diff