mirror of
https://github.com/wassname/phaser.git
synced 2026-08-12 12:20:38 +08:00
Refactoring ready for 1.0 release.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<ProjectGuid>{1106D1E1-DCE3-4CAF-8096-6C85F765D519}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<OutputPath>bin</OutputPath>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="verlet\AngleConstraint.js">
|
||||
<DependentUpon>AngleConstraint.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="verlet\Composite.js">
|
||||
<DependentUpon>Composite.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="verlet\DistanceConstraint.js">
|
||||
<DependentUpon>DistanceConstraint.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="verlet\Particle.js">
|
||||
<DependentUpon>Particle.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="verlet\PinConstraint.js">
|
||||
<DependentUpon>PinConstraint.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="verlet\VerletManager.js">
|
||||
<DependentUpon>VerletManager.ts</DependentUpon>
|
||||
</Content>
|
||||
<XamlAppDef Include="verlet\VerletManager.ts" />
|
||||
<XamlAppDef Include="verlet\PinConstraint.ts" />
|
||||
<XamlAppDef Include="verlet\Particle.ts" />
|
||||
<XamlAppDef Include="verlet\DistanceConstraint.ts" />
|
||||
<XamlAppDef Include="verlet\Composite.ts" />
|
||||
<XamlAppDef Include="verlet\AngleConstraint.ts" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RootNamespace>Plugins</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>0</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:61985/</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<TypeScriptTarget>ES3</TypeScriptTarget>
|
||||
<TypeScriptIncludeComments>true</TypeScriptIncludeComments>
|
||||
<TypeScriptSourceMap>true</TypeScriptSourceMap>
|
||||
<TypeScriptModuleKind>AMD</TypeScriptModuleKind>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<TypeScriptTarget>ES3</TypeScriptTarget>
|
||||
<TypeScriptIncludeComments>false</TypeScriptIncludeComments>
|
||||
<TypeScriptSourceMap>false</TypeScriptSourceMap>
|
||||
<TypeScriptModuleKind>AMD</TypeScriptModuleKind>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\TypeScript\Microsoft.TypeScript.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"app.js","sources":["app.ts"],"names":["Greeter","Greeter.constructor","Greeter.start","","Greeter.stop","onload"],"mappings":"AAAA;IAKIA,SALEA,OAAOA,CAKGA,OAAoBA;QAC5BC,IAAIA,CAACA,OAAOA,GAAGA,OAAOA;QACtBA,IAAIA,CAACA,OAAOA,CAACA,SAASA,IAAIA,eAAeA;QACzCA,IAAIA,CAACA,IAAIA,GAAGA,QAAQA,CAACA,aAAaA,CAACA,MAAMA,CAACA;QAC1CA,IAAIA,CAACA,OAAOA,CAACA,WAAWA,CAACA,IAAIA,CAACA,IAAIA,CAACA;QACnCA,IAAIA,CAACA,IAAIA,CAACA,SAASA,GAAGA,IAAIA,IAAIA,EAAEA,CAACA,WAAWA,EAAEA;IAClDA,CAACA;IAEDD,0BAAAA;QAAAE,iBAECA;QADGA,IAAIA,CAACA,UAAUA,GAAGA,WAAWA,CAACA;YAAMC,OAAAA,KAAIA,CAACA,IAAIA,CAACA,SAASA,GAAGA,IAAIA,IAAIA,EAAEA,CAACA,WAAWA,EAAEA,CAAAA;QAA9CA,CAA8CA,EAAED,GAAGA,CAACA;IAC5FA,CAACA;IAEDF,yBAAAA;QACII,YAAYA,CAACA,IAAIA,CAACA,UAAUA,CAACA;IACjCA,CAACA;IAELJ;AAACA,CAAAA,IAAA;AAED,MAAM,CAAC,MAAM,GAAG;IACZK,IAAIA,EAAEA,GAAGA,QAAQA,CAACA,cAAcA,CAACA,SAASA,CAACA,CAACA;IAC5CA,IAAIA,OAAOA,GAAGA,IAAIA,OAAOA,CAACA,EAAEA,CAACA,CAACA;IAC9BA,OAAOA,CAACA,KAAKA,EAAEA;AACnBA,CAACA"}
|
||||
@@ -0,0 +1,59 @@
|
||||
var Phaser;
|
||||
(function (Phaser) {
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
/**
|
||||
* Phaser - AngleConstraint
|
||||
*
|
||||
* constrains 3 particles to an angle
|
||||
*/
|
||||
(function (Verlet) {
|
||||
var AngleConstraint = (function () {
|
||||
/**
|
||||
* Creates a new AngleConstraint object.
|
||||
* @class AngleConstraint
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {AngleConstraint} This object
|
||||
**/
|
||||
function AngleConstraint(a, b, c, stiffness) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.angle = this.b.pos.angle2(this.a.pos, this.c.pos);
|
||||
this.stiffness = stiffness;
|
||||
}
|
||||
AngleConstraint.prototype.relax = function (stepCoef) {
|
||||
var angle = this.b.pos.angle2(this.a.pos, this.c.pos);
|
||||
var diff = angle - this.angle;
|
||||
if(diff <= -Math.PI) {
|
||||
diff += 2 * Math.PI;
|
||||
} else if(diff >= Math.PI) {
|
||||
diff -= 2 * Math.PI;
|
||||
}
|
||||
diff *= stepCoef * this.stiffness;
|
||||
this.a.pos = this.a.pos.rotate(this.b.pos, diff);
|
||||
this.c.pos = this.c.pos.rotate(this.b.pos, -diff);
|
||||
this.b.pos = this.b.pos.rotate(this.a.pos, diff);
|
||||
this.b.pos = this.b.pos.rotate(this.c.pos, -diff);
|
||||
};
|
||||
AngleConstraint.prototype.render = function (ctx) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.a.pos.x, this.a.pos.y);
|
||||
ctx.lineTo(this.b.pos.x, this.b.pos.y);
|
||||
ctx.lineTo(this.c.pos.x, this.c.pos.y);
|
||||
var tmp = ctx.lineWidth;
|
||||
ctx.lineWidth = 5;
|
||||
ctx.strokeStyle = "rgba(255,255,0,0.2)";
|
||||
ctx.stroke();
|
||||
ctx.lineWidth = tmp;
|
||||
};
|
||||
return AngleConstraint;
|
||||
})();
|
||||
Verlet.AngleConstraint = AngleConstraint;
|
||||
})(Phaser.Verlet || (Phaser.Verlet = {}));
|
||||
var Verlet = Phaser.Verlet;
|
||||
})(Phaser || (Phaser = {}));
|
||||
//@ sourceMappingURL=AngleConstraint.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AngleConstraint.js","sources":["AngleConstraint.ts"],"names":["Phaser","Phaser.Verlet","Phaser.Verlet.AngleConstraint","Phaser.Verlet.AngleConstraint.constructor","Phaser.Verlet.AngleConstraint.relax","Phaser.Verlet.AngleConstraint.render"],"mappings":"AAUA,IAAO,MAAM;AA+DZ,CA/DD,UAAO,MAAM;IAVbA,mCAAmCA;IACnCA,oCAAoCA;IACpCA,2CAA2CA;IAE3CA;;;;MAIEA;KAEKA,UAAOA,MAAMA;QAEhBC;YAUIC;;;;;;;eADGA;YACHA,SAVSA,eAAeA,CAUZA,CAAyBA,EAAEA,CAAyBA,EAAEA,CAAyBA,EAAEA,SAAiBA;gBAE1GC,IAAIA,CAACA,CAACA,GAAGA,CAACA;gBACVA,IAAIA,CAACA,CAACA,GAAGA,CAACA;gBACVA,IAAIA,CAACA,CAACA,GAAGA,CAACA;gBACVA,IAAIA,CAACA,KAAKA,GAAGA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,EAAEA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA;gBACtDA,IAAIA,CAACA,SAASA,GAAGA,SAASA;YAE9BA,CAACA;YAQDD,kCAAAA,UAAaA,QAAgBA;gBAEzBE,IAAIA,KAAKA,GAAGA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,EAAEA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,CAACA;gBACtDA,IAAIA,IAAIA,GAAGA,KAAKA,GAAGA,IAAIA,CAACA,KAAKA,CAACA;gBAE9BA,GAAIA,IAAIA,IAAIA,CAACA,IAAIA,CAACA,EAAEA,CAACA;oBACjBA,IAAIA,IAAIA,CAACA,GAAGA,IAAIA,CAACA,EAAEA;iBAACA,MACnBA,GAAIA,IAAIA,IAAIA,IAAIA,CAACA,EAAEA,CAACA;oBACrBA,IAAIA,IAAIA,CAACA,GAAGA,IAAIA,CAACA,EAAEA;iBAACA;gBAExBA,IAAIA,IAAIA,QAAQA,GAAGA,IAAIA,CAACA,SAASA;gBAEjCA,IAAIA,CAACA,CAACA,CAACA,GAAGA,GAAGA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,EAAEA,IAAIA,CAACA;gBAChDA,IAAIA,CAACA,CAACA,CAACA,GAAGA,GAAGA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,EAAEA,CAACA,IAAIA,CAACA;gBACjDA,IAAIA,CAACA,CAACA,CAACA,GAAGA,GAAGA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,EAAEA,IAAIA,CAACA;gBAChDA,IAAIA,CAACA,CAACA,CAACA,GAAGA,GAAGA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,EAAEA,CAACA,IAAIA,CAACA;YAErDA,CAACA;YAEDF,mCAAAA,UAAcA,GAAGA;gBAEbG,GAAGA,CAACA,SAASA,EAAEA;gBACfA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,CAACA,EAAEA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,CAACA,CAACA;gBACtCA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,CAACA,EAAEA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,CAACA,CAACA;gBACtCA,GAAGA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,CAACA,EAAEA,IAAIA,CAACA,CAACA,CAACA,GAAGA,CAACA,CAACA,CAACA;gBACtCA,IAAIA,GAAGA,GAAGA,GAAGA,CAACA,SAASA,CAACA;gBACxBA,GAAGA,CAACA,SAASA,GAAGA,CAACA;gBACjBA,GAAGA,CAACA,WAAWA,GAAGA,qBAAqBA;gBACvCA,GAAGA,CAACA,MAAMA,EAAEA;gBACZA,GAAGA,CAACA,SAASA,GAAGA,GAAGA;YAEvBA,CAACA;YAELH;AAACA,QAADA,CAACA,IAAAD;QA3DDA,yCA2DCA,QAAAA;IAELA,CAACA,yCAAAD;IA/DMA;AA+DNA,CAAAA,2BAAA"}
|
||||
@@ -0,0 +1,74 @@
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - AngleConstraint
|
||||
*
|
||||
* constrains 3 particles to an angle
|
||||
*/
|
||||
|
||||
module Phaser.Verlet {
|
||||
|
||||
export class AngleConstraint {
|
||||
|
||||
/**
|
||||
* Creates a new AngleConstraint object.
|
||||
* @class AngleConstraint
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {AngleConstraint} This object
|
||||
**/
|
||||
constructor(a: Phaser.Verlet.Particle, b: Phaser.Verlet.Particle, c: Phaser.Verlet.Particle, stiffness: number) {
|
||||
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.angle = this.b.pos.angle2(this.a.pos, this.c.pos);
|
||||
this.stiffness = stiffness;
|
||||
|
||||
}
|
||||
|
||||
public a: Phaser.Verlet.Particle;
|
||||
public b: Phaser.Verlet.Particle;
|
||||
public c: Phaser.Verlet.Particle;
|
||||
public angle: number;
|
||||
public stiffness: number;
|
||||
|
||||
public relax(stepCoef: number) {
|
||||
|
||||
var angle = this.b.pos.angle2(this.a.pos, this.c.pos);
|
||||
var diff = angle - this.angle;
|
||||
|
||||
if (diff <= -Math.PI)
|
||||
diff += 2 * Math.PI;
|
||||
else if (diff >= Math.PI)
|
||||
diff -= 2 * Math.PI;
|
||||
|
||||
diff *= stepCoef * this.stiffness;
|
||||
|
||||
this.a.pos = this.a.pos.rotate(this.b.pos, diff);
|
||||
this.c.pos = this.c.pos.rotate(this.b.pos, -diff);
|
||||
this.b.pos = this.b.pos.rotate(this.a.pos, diff);
|
||||
this.b.pos = this.b.pos.rotate(this.c.pos, -diff);
|
||||
|
||||
}
|
||||
|
||||
public render(ctx) {
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.a.pos.x, this.a.pos.y);
|
||||
ctx.lineTo(this.b.pos.x, this.b.pos.y);
|
||||
ctx.lineTo(this.c.pos.x, this.c.pos.y);
|
||||
var tmp = ctx.lineWidth;
|
||||
ctx.lineWidth = 5;
|
||||
ctx.strokeStyle = "rgba(255,255,0,0.2)";
|
||||
ctx.stroke();
|
||||
ctx.lineWidth = tmp;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
var Phaser;
|
||||
(function (Phaser) {
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="PinConstraint.ts" />
|
||||
/**
|
||||
* Phaser - Verlet - Composite
|
||||
*
|
||||
*
|
||||
*/
|
||||
(function (Verlet) {
|
||||
var Composite = (function () {
|
||||
/**
|
||||
* Creates a new Composite object.
|
||||
* @class Composite
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {Composite} This object
|
||||
**/
|
||||
function Composite(game) {
|
||||
/**
|
||||
* Texture of the particles to be rendered.
|
||||
*/
|
||||
this._texture = null;
|
||||
// local rendering related temp vars to help avoid gc spikes
|
||||
this._sx = 0;
|
||||
this._sy = 0;
|
||||
this._sw = 0;
|
||||
this._sh = 0;
|
||||
this._dx = 0;
|
||||
this._dy = 0;
|
||||
this._dw = 0;
|
||||
this._dh = 0;
|
||||
this._hw = 0;
|
||||
this._hh = 0;
|
||||
this.drawParticles = null;
|
||||
this.drawConstraints = null;
|
||||
this.hideConstraints = true;
|
||||
this.constraintLineColor = 'rgba(200,200,200,1)';
|
||||
this._game = game;
|
||||
this.sprites = [];
|
||||
this.particles = [];
|
||||
this.constraints = [];
|
||||
this.frameBounds = new Phaser.Quad();
|
||||
}
|
||||
Composite.prototype.createDistanceConstraint = // Create Constraints
|
||||
function (a, b, stiffness, distance) {
|
||||
if (typeof distance === "undefined") { distance = null; }
|
||||
this.constraints.push(new Phaser.Verlet.DistanceConstraint(a, b, stiffness, distance));
|
||||
return this.constraints[this.constraints.length - 1];
|
||||
};
|
||||
Composite.prototype.createAngleConstraint = function (a, b, c, stiffness) {
|
||||
this.constraints.push(new Phaser.Verlet.AngleConstraint(a, b, c, stiffness));
|
||||
return this.constraints[this.constraints.length - 1];
|
||||
};
|
||||
Composite.prototype.createPinConstraint = function (a, pos) {
|
||||
this.constraints.push(new Phaser.Verlet.PinConstraint(a, pos));
|
||||
return this.constraints[this.constraints.length - 1];
|
||||
};
|
||||
Composite.prototype.loadGraphic = /**
|
||||
* Load a graphic for this Composite. The graphic cannot be a SpriteSheet yet.
|
||||
* @param key {string} Key of the graphic you want to load for this sprite.
|
||||
* @return {Composite} This object
|
||||
*/
|
||||
function (key) {
|
||||
if(this._game.cache.getImage(key) !== null) {
|
||||
if(this._game.cache.isSpriteSheet(key) == false) {
|
||||
this._texture = this._game.cache.getImage(key);
|
||||
this.frameBounds.width = this._texture.width;
|
||||
this.frameBounds.height = this._texture.height;
|
||||
this._hw = Math.floor(this.frameBounds.width / 2);
|
||||
this._hh = Math.floor(this.frameBounds.width / 2);
|
||||
this.drawParticles = this.render;
|
||||
this.drawConstraints = this.renderConstraints;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
Composite.prototype.renderConstraints = function (context) {
|
||||
if(this.hideConstraints == true || this.constraints.length == 0) {
|
||||
return;
|
||||
}
|
||||
var i;
|
||||
context.beginPath();
|
||||
for(i in this.constraints) {
|
||||
if(this.constraints[i].b) {
|
||||
context.moveTo(this.constraints[i].a.pos.x, this.constraints[i].a.pos.y);
|
||||
context.lineTo(this.constraints[i].b.pos.x, this.constraints[i].b.pos.y);
|
||||
}
|
||||
}
|
||||
context.strokeStyle = this.constraintLineColor;
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
};
|
||||
Composite.prototype.render = function (context) {
|
||||
this._sx = 0;
|
||||
this._sy = 0;
|
||||
this._sw = this.frameBounds.width;
|
||||
this._sh = this.frameBounds.height;
|
||||
this._dw = this.frameBounds.width;
|
||||
this._dh = this.frameBounds.height;
|
||||
this._sx = Math.round(this._sx);
|
||||
this._sy = Math.round(this._sy);
|
||||
this._sw = Math.round(this._sw);
|
||||
this._sh = Math.round(this._sh);
|
||||
this._dw = Math.round(this._dw);
|
||||
this._dh = Math.round(this._dh);
|
||||
var i;
|
||||
for(i in this.particles) {
|
||||
//this._dx = cameraOffsetX + (this.frameBounds.topLeft.x - camera.worldView.x);
|
||||
//this._dy = cameraOffsetY + (this.frameBounds.topLeft.y - camera.worldView.y);
|
||||
this._dx = this.particles[i].pos.x - this._hw;
|
||||
this._dy = this.particles[i].pos.y - this._hh;
|
||||
this._dx = Math.round(this._dx);
|
||||
this._dy = Math.round(this._dy);
|
||||
context.drawImage(this._texture, // Source Image
|
||||
this._sx, // Source X (location within the source image)
|
||||
this._sy, // Source Y
|
||||
this._sw, // Source Width
|
||||
this._sh, // Source Height
|
||||
this._dx, // Destination X (where on the canvas it'll be drawn)
|
||||
this._dy, // Destination Y
|
||||
this._dw, // Destination Width (always same as Source Width unless scaled)
|
||||
this._dh);
|
||||
// Destination Height (always same as Source Height unless scaled)
|
||||
}
|
||||
};
|
||||
Composite.prototype.pin = function (index, pos) {
|
||||
if (typeof pos === "undefined") { pos = null; }
|
||||
if(pos == null) {
|
||||
pos = this.particles[index].pos;
|
||||
}
|
||||
var pc = new Phaser.Verlet.PinConstraint(this.particles[index], pos);
|
||||
this.constraints.push(pc);
|
||||
return pc;
|
||||
};
|
||||
return Composite;
|
||||
})();
|
||||
Verlet.Composite = Composite;
|
||||
})(Phaser.Verlet || (Phaser.Verlet = {}));
|
||||
var Verlet = Phaser.Verlet;
|
||||
})(Phaser || (Phaser = {}));
|
||||
@@ -0,0 +1,203 @@
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="PinConstraint.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - Verlet - Composite
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
module Phaser.Verlet {
|
||||
|
||||
export class Composite {
|
||||
|
||||
/**
|
||||
* Creates a new Composite object.
|
||||
* @class Composite
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {Composite} This object
|
||||
**/
|
||||
constructor(game: Game) {
|
||||
|
||||
this._game = game;
|
||||
|
||||
this.sprites = [];
|
||||
this.particles = [];
|
||||
this.constraints = [];
|
||||
|
||||
this.frameBounds = new Phaser.Quad();
|
||||
|
||||
}
|
||||
|
||||
private _game: Game;
|
||||
|
||||
/**
|
||||
* Texture of the particles to be rendered.
|
||||
*/
|
||||
private _texture = null;
|
||||
|
||||
/**
|
||||
* Rendering bounds for the texture
|
||||
* @type {Quad}
|
||||
*/
|
||||
private frameBounds: Quad;
|
||||
|
||||
// local rendering related temp vars to help avoid gc spikes
|
||||
private _sx: number = 0;
|
||||
private _sy: number = 0;
|
||||
private _sw: number = 0;
|
||||
private _sh: number = 0;
|
||||
private _dx: number = 0;
|
||||
private _dy: number = 0;
|
||||
private _dw: number = 0;
|
||||
private _dh: number = 0;
|
||||
private _hw: number = 0;
|
||||
private _hh: number = 0;
|
||||
|
||||
public sprites: Phaser.Sprite[];
|
||||
public particles: Phaser.Verlet.Particle[];
|
||||
public constraints;
|
||||
|
||||
public drawParticles = null;
|
||||
public drawConstraints = null;
|
||||
|
||||
// Create Constraints
|
||||
|
||||
public createDistanceConstraint(a: Phaser.Verlet.Particle, b: Phaser.Verlet.Particle, stiffness: number, distance?: number = null): Phaser.Verlet.DistanceConstraint {
|
||||
|
||||
this.constraints.push(new Phaser.Verlet.DistanceConstraint(a, b, stiffness, distance));
|
||||
return this.constraints[this.constraints.length - 1];
|
||||
|
||||
}
|
||||
|
||||
public createAngleConstraint(a: Phaser.Verlet.Particle, b: Phaser.Verlet.Particle, c: Phaser.Verlet.Particle, stiffness: number): Phaser.Verlet.AngleConstraint {
|
||||
|
||||
this.constraints.push(new Phaser.Verlet.AngleConstraint(a, b, c, stiffness));
|
||||
return this.constraints[this.constraints.length - 1];
|
||||
|
||||
}
|
||||
|
||||
public createPinConstraint(a: Phaser.Verlet.Particle, pos: Vector2): Phaser.Verlet.PinConstraint {
|
||||
|
||||
this.constraints.push(new Phaser.Verlet.PinConstraint(a, pos));
|
||||
return this.constraints[this.constraints.length - 1];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a graphic for this Composite. The graphic cannot be a SpriteSheet yet.
|
||||
* @param key {string} Key of the graphic you want to load for this sprite.
|
||||
* @return {Composite} This object
|
||||
*/
|
||||
public loadGraphic(key: string): Composite {
|
||||
|
||||
if (this._game.cache.getImage(key) !== null)
|
||||
{
|
||||
if (this._game.cache.isSpriteSheet(key) == false)
|
||||
{
|
||||
this._texture = this._game.cache.getImage(key);
|
||||
this.frameBounds.width = this._texture.width;
|
||||
this.frameBounds.height = this._texture.height;
|
||||
this._hw = Math.floor(this.frameBounds.width / 2);
|
||||
this._hh = Math.floor(this.frameBounds.width / 2);
|
||||
this.drawParticles = this.render;
|
||||
this.drawConstraints = this.renderConstraints;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public hideConstraints: bool = true;
|
||||
public constraintLineColor: string = 'rgba(200,200,200,1)';
|
||||
|
||||
private renderConstraints(context) {
|
||||
|
||||
if (this.hideConstraints == true || this.constraints.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var i;
|
||||
|
||||
context.beginPath();
|
||||
|
||||
for (i in this.constraints)
|
||||
{
|
||||
if (this.constraints[i].b)
|
||||
{
|
||||
context.moveTo(this.constraints[i].a.pos.x, this.constraints[i].a.pos.y);
|
||||
context.lineTo(this.constraints[i].b.pos.x, this.constraints[i].b.pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
context.strokeStyle = this.constraintLineColor;
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
|
||||
}
|
||||
|
||||
private render(context) {
|
||||
|
||||
this._sx = 0;
|
||||
this._sy = 0;
|
||||
this._sw = this.frameBounds.width;
|
||||
this._sh = this.frameBounds.height;
|
||||
this._dw = this.frameBounds.width;
|
||||
this._dh = this.frameBounds.height;
|
||||
|
||||
this._sx = Math.round(this._sx);
|
||||
this._sy = Math.round(this._sy);
|
||||
this._sw = Math.round(this._sw);
|
||||
this._sh = Math.round(this._sh);
|
||||
this._dw = Math.round(this._dw);
|
||||
this._dh = Math.round(this._dh);
|
||||
|
||||
var i;
|
||||
|
||||
for (i in this.particles)
|
||||
{
|
||||
//this._dx = cameraOffsetX + (this.frameBounds.topLeft.x - camera.worldView.x);
|
||||
//this._dy = cameraOffsetY + (this.frameBounds.topLeft.y - camera.worldView.y);
|
||||
this._dx = this.particles[i].pos.x - this._hw;
|
||||
this._dy = this.particles[i].pos.y - this._hh;
|
||||
this._dx = Math.round(this._dx);
|
||||
this._dy = Math.round(this._dy);
|
||||
|
||||
context.drawImage(
|
||||
this._texture, // Source Image
|
||||
this._sx, // Source X (location within the source image)
|
||||
this._sy, // Source Y
|
||||
this._sw, // Source Width
|
||||
this._sh, // Source Height
|
||||
this._dx, // Destination X (where on the canvas it'll be drawn)
|
||||
this._dy, // Destination Y
|
||||
this._dw, // Destination Width (always same as Source Width unless scaled)
|
||||
this._dh // Destination Height (always same as Source Height unless scaled)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public pin(index, pos?=null) {
|
||||
|
||||
if (pos == null)
|
||||
{
|
||||
pos = this.particles[index].pos;
|
||||
}
|
||||
|
||||
var pc = new Phaser.Verlet.PinConstraint(this.particles[index], pos);
|
||||
this.constraints.push(pc);
|
||||
return pc;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
var Phaser;
|
||||
(function (Phaser) {
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
/**
|
||||
* Phaser - DistanceConstraint
|
||||
*
|
||||
* Constrains to initial distance
|
||||
*/
|
||||
(function (Verlet) {
|
||||
var DistanceConstraint = (function () {
|
||||
/**
|
||||
* Creates a new DistanceConstraint object.
|
||||
* @class DistanceConstraint
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {DistanceConstraint} This object
|
||||
**/
|
||||
function DistanceConstraint(a, b, stiffness, distance) {
|
||||
if (typeof distance === "undefined") { distance = null; }
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
if(distance === null) {
|
||||
this.distance = a.pos.sub(b.pos).length();
|
||||
} else {
|
||||
this.distance = distance;
|
||||
}
|
||||
this.stiffness = stiffness;
|
||||
}
|
||||
DistanceConstraint.prototype.relax = function (stepCoef) {
|
||||
var normal = this.a.pos.sub(this.b.pos);
|
||||
var m = normal.length2();
|
||||
normal.mutableScale(((this.distance * this.distance - m) / m) * this.stiffness * stepCoef);
|
||||
this.a.pos.mutableAdd(normal);
|
||||
this.b.pos.mutableSub(normal);
|
||||
};
|
||||
DistanceConstraint.prototype.render = function (ctx) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.a.pos.x, this.a.pos.y);
|
||||
ctx.lineTo(this.b.pos.x, this.b.pos.y);
|
||||
ctx.strokeStyle = "#d8dde2";
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
};
|
||||
return DistanceConstraint;
|
||||
})();
|
||||
Verlet.DistanceConstraint = DistanceConstraint;
|
||||
})(Phaser.Verlet || (Phaser.Verlet = {}));
|
||||
var Verlet = Phaser.Verlet;
|
||||
})(Phaser || (Phaser = {}));
|
||||
@@ -0,0 +1,70 @@
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - DistanceConstraint
|
||||
*
|
||||
* Constrains to initial distance
|
||||
*/
|
||||
|
||||
module Phaser.Verlet {
|
||||
|
||||
export class DistanceConstraint {
|
||||
|
||||
/**
|
||||
* Creates a new DistanceConstraint object.
|
||||
* @class DistanceConstraint
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {DistanceConstraint} This object
|
||||
**/
|
||||
constructor(a: Phaser.Verlet.Particle, b: Phaser.Verlet.Particle, stiffness: number, distance?:number = null) {
|
||||
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
|
||||
if (distance === null)
|
||||
{
|
||||
this.distance = a.pos.sub(b.pos).length();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
this.stiffness = stiffness;
|
||||
|
||||
}
|
||||
|
||||
public a: Phaser.Verlet.Particle;
|
||||
public b: Phaser.Verlet.Particle;
|
||||
public distance: number;
|
||||
public stiffness: number;
|
||||
|
||||
public relax(stepCoef: number) {
|
||||
|
||||
var normal = this.a.pos.sub(this.b.pos);
|
||||
|
||||
var m = normal.length2();
|
||||
|
||||
normal.mutableScale(((this.distance * this.distance - m) / m) * this.stiffness * stepCoef);
|
||||
|
||||
this.a.pos.mutableAdd(normal);
|
||||
this.b.pos.mutableSub(normal);
|
||||
|
||||
}
|
||||
|
||||
public render(ctx) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.a.pos.x, this.a.pos.y);
|
||||
ctx.lineTo(this.b.pos.x, this.b.pos.y);
|
||||
ctx.strokeStyle = "#d8dde2";
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
var Phaser;
|
||||
(function (Phaser) {
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
/**
|
||||
* Phaser - Verlet - Particle
|
||||
*
|
||||
*
|
||||
*/
|
||||
(function (Verlet) {
|
||||
var Particle = (function () {
|
||||
/**
|
||||
* Creates a new Particle object.
|
||||
* @class Particle
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {Particle} This object
|
||||
**/
|
||||
function Particle(pos) {
|
||||
this.pos = (new Vector2()).mutableSet(pos);
|
||||
this.lastPos = (new Vector2()).mutableSet(pos);
|
||||
}
|
||||
Particle.prototype.render = function (ctx) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.pos.x, this.pos.y, 2, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "#2dad8f";
|
||||
ctx.fill();
|
||||
};
|
||||
return Particle;
|
||||
})();
|
||||
Verlet.Particle = Particle;
|
||||
})(Phaser.Verlet || (Phaser.Verlet = {}));
|
||||
var Verlet = Phaser.Verlet;
|
||||
})(Phaser || (Phaser = {}));
|
||||
//@ sourceMappingURL=Particle.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Particle.js","sources":["Particle.ts"],"names":["Phaser","Phaser.Verlet","Phaser.Verlet.Particle","Phaser.Verlet.Particle.constructor","Phaser.Verlet.Particle.render"],"mappings":"AASA,IAAO,MAAM;AAkCZ,CAlCD,UAAO,MAAM;IATbA,mCAAmCA;IACnCA,2CAA2CA;IAE3CA;;;;MAIEA;KAEKA,UAAOA,MAAMA;QAEhBC;YAUIC;;;;;;;eADGA;YACHA,SAVSA,QAAQA,CAULA,GAAYA;gBAEpBC,IAAIA,CAACA,GAAGA,GAAGA,CAACA,IAAIA,OAAOA,EAAEA,EAAEA,UAAUA,CAACA,GAAGA,CAACA;gBAC1CA,IAAIA,CAACA,OAAOA,GAAGA,CAACA,IAAIA,OAAOA,EAAEA,EAAEA,UAAUA,CAACA,GAAGA,CAACA;YAGlDA,CAACA;YAKDD,4BAAAA,UAAcA,GAAGA;gBAEhBE,GAAGA,CAACA,SAASA,EAAEA;gBACfA,GAAGA,CAACA,GAAGA,CAACA,IAAIA,CAACA,GAAGA,CAACA,CAACA,EAAEA,IAAIA,CAACA,GAAGA,CAACA,CAACA,EAAEA,CAACA,EAAEA,CAACA,EAAEA,CAACA,GAACA,IAAIA,CAACA,EAAEA,CAACA;gBAChDA,GAAGA,CAACA,SAASA,GAAGA,SAASA;gBACzBA,GAAGA,CAACA,IAAIA,EAAEA;YAEXA,CAACA;YAELF;AAACA,QAADA,CAACA,IAAAD;QA9BDA,2BA8BCA,QAAAA;IAELA,CAACA,yCAAAD;IAlCMA;AAkCNA,CAAAA,2BAAA"}
|
||||
@@ -0,0 +1,44 @@
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - Verlet - Particle
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
module Phaser.Verlet {
|
||||
|
||||
export class Particle {
|
||||
|
||||
/**
|
||||
* Creates a new Particle object.
|
||||
* @class Particle
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {Particle} This object
|
||||
**/
|
||||
constructor(pos: Vector2) {
|
||||
|
||||
this.pos = (new Vector2()).mutableSet(pos);
|
||||
this.lastPos = (new Vector2()).mutableSet(pos);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public pos: Vector2;
|
||||
public lastPos: Vector2;
|
||||
|
||||
public render(ctx) {
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.pos.x, this.pos.y, 2, 0, 2*Math.PI);
|
||||
ctx.fillStyle = "#2dad8f";
|
||||
ctx.fill();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
var Phaser;
|
||||
(function (Phaser) {
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
/**
|
||||
* Phaser - PinConstraint
|
||||
*
|
||||
* Constrains to static / fixed point
|
||||
*/
|
||||
(function (Verlet) {
|
||||
var PinConstraint = (function () {
|
||||
/**
|
||||
* Creates a new PinConstraint object.
|
||||
* @class PinConstraint
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {PinConstraint} This object
|
||||
**/
|
||||
function PinConstraint(a, pos) {
|
||||
this.a = a;
|
||||
this.pos = (new Phaser.Vector2()).mutableSet(pos);
|
||||
}
|
||||
PinConstraint.prototype.relax = function () {
|
||||
this.a.pos.mutableSet(this.pos);
|
||||
};
|
||||
PinConstraint.prototype.render = function (ctx) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.pos.x, this.pos.y, 6, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "rgba(0,153,255,0.1)";
|
||||
ctx.fill();
|
||||
};
|
||||
return PinConstraint;
|
||||
})();
|
||||
Verlet.PinConstraint = PinConstraint;
|
||||
})(Phaser.Verlet || (Phaser.Verlet = {}));
|
||||
var Verlet = Phaser.Verlet;
|
||||
})(Phaser || (Phaser = {}));
|
||||
@@ -0,0 +1,48 @@
|
||||
/// <reference path="../Game.ts" />
|
||||
/// <reference path="Particle.ts" />
|
||||
/// <reference path="../geom/Vector2.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - PinConstraint
|
||||
*
|
||||
* Constrains to static / fixed point
|
||||
*/
|
||||
|
||||
module Phaser.Verlet {
|
||||
|
||||
export class PinConstraint {
|
||||
|
||||
/**
|
||||
* Creates a new PinConstraint object.
|
||||
* @class PinConstraint
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {PinConstraint} This object
|
||||
**/
|
||||
constructor(a: Phaser.Verlet.Particle, pos: Vector2) {
|
||||
|
||||
this.a = a;
|
||||
this.pos = (new Vector2()).mutableSet(pos);
|
||||
|
||||
}
|
||||
|
||||
public a: Phaser.Verlet.Particle;
|
||||
public pos: Vector2;
|
||||
|
||||
public relax() {
|
||||
this.a.pos.mutableSet(this.pos);
|
||||
}
|
||||
|
||||
public render(ctx) {
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.pos.x, this.pos.y, 6, 0, 2*Math.PI);
|
||||
ctx.fillStyle = "rgba(0,153,255,0.1)";
|
||||
ctx.fill();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
var Phaser;
|
||||
(function (Phaser) {
|
||||
/// <reference path="Game.ts" />
|
||||
/// <reference path="geom/Vector2.ts" />
|
||||
/// <reference path="verlet/Composite.ts" />
|
||||
/// <reference path="verlet/Particle.ts" />
|
||||
/// <reference path="verlet/DistanceConstraint.ts" />
|
||||
/// <reference path="verlet/PinConstraint.ts" />
|
||||
/// <reference path="verlet/AngleConstraint.ts" />
|
||||
/**
|
||||
* Phaser - Verlet
|
||||
*
|
||||
* Based on verlet-js by Sub Protocol released under MIT
|
||||
*/
|
||||
(function (Verlet) {
|
||||
var VerletManager = (function () {
|
||||
/**
|
||||
* Creates a new Vector2 object.
|
||||
* @class Vector2
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {Vector2} This object
|
||||
**/
|
||||
function VerletManager(game, width, height) {
|
||||
this._v = new Phaser.Vector2();
|
||||
this.composites = [];
|
||||
this.step = 16;
|
||||
this.selectionRadius = 20;
|
||||
this.draggedEntity = null;
|
||||
this.highlightColor = '#4f545c';
|
||||
this.hideNearestEntityCircle = false;
|
||||
this._game = game;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.gravity = new Phaser.Vector2(0, 0.2);
|
||||
this.friction = 0.99;
|
||||
this.groundFriction = 0.8;
|
||||
this.canvas = game.stage.canvas;
|
||||
this.context = game.stage.context;
|
||||
this._game.input.onDown.add(this.mouseDownHandler, this);
|
||||
this._game.input.onUp.add(this.mouseUpHandler, this);
|
||||
}
|
||||
VerletManager.prototype.intersectionTime = /**
|
||||
* Computes time of intersection of a particle with a wall
|
||||
*
|
||||
* @param {Vec2} line walls root position
|
||||
* @param {Vec2} p particle position
|
||||
* @param {Vec2} dir walls direction
|
||||
* @param {Vec2} v particles velocity
|
||||
*/
|
||||
function (wall, p, dir, v) {
|
||||
if(dir.x != 0) {
|
||||
var denominator = v.y - dir.y * v.x / dir.x;
|
||||
if(denominator == 0) {
|
||||
return undefined;
|
||||
}// Movement is parallel to wall
|
||||
|
||||
var numerator = wall.y + dir.y * (p.x - wall.x) / dir.x - p.y;
|
||||
return numerator / denominator;
|
||||
} else {
|
||||
if(v.x == 0) {
|
||||
return undefined;
|
||||
}// parallel again
|
||||
|
||||
var denominator = v.x;
|
||||
var numerator = wall.x - p.x;
|
||||
return numerator / denominator;
|
||||
}
|
||||
};
|
||||
VerletManager.prototype.intersectionPoint = function (wall, p, dir, v) {
|
||||
var t = this.intersectionTime(wall, p, dir, v);
|
||||
return new Phaser.Vector2(p.x + v.x * t, p.y + v.y * t);
|
||||
};
|
||||
VerletManager.prototype.bounds = function (particle) {
|
||||
this._v.mutableSet(particle.pos);
|
||||
this._v.mutableSub(particle.lastPos);
|
||||
if(particle.pos.y > this.height - 1) {
|
||||
particle.pos.mutableSet(this.intersectionPoint(new Phaser.Vector2(0, this.height - 1), particle.lastPos, new Phaser.Vector2(1, 0), this._v));
|
||||
}
|
||||
if(particle.pos.x < 0) {
|
||||
particle.pos.mutableSet(this.intersectionPoint(new Phaser.Vector2(0, 0), particle.pos, new Phaser.Vector2(0, 1), this._v));
|
||||
}
|
||||
if(particle.pos.x > this.width - 1) {
|
||||
particle.pos.mutableSet(this.intersectionPoint(new Phaser.Vector2(this.width - 1, 0), particle.pos, new Phaser.Vector2(0, 1), this._v));
|
||||
}
|
||||
};
|
||||
VerletManager.prototype.createPoint = function (pos) {
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
composite.particles.push(new Phaser.Verlet.Particle(pos));
|
||||
this.composites.push(composite);
|
||||
return composite;
|
||||
};
|
||||
VerletManager.prototype.createLineSegments = function (vertices, stiffness) {
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
var i;
|
||||
for(i in vertices) {
|
||||
composite.particles.push(new Phaser.Verlet.Particle(vertices[i]));
|
||||
if(i > 0) {
|
||||
composite.constraints.push(new Phaser.Verlet.DistanceConstraint(composite.particles[i], composite.particles[i - 1], stiffness));
|
||||
}
|
||||
}
|
||||
this.composites.push(composite);
|
||||
return composite;
|
||||
};
|
||||
VerletManager.prototype.createCloth = function (origin, width, height, segments, pinMod, stiffness) {
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
var xStride = width / segments;
|
||||
var yStride = height / segments;
|
||||
var x;
|
||||
var y;
|
||||
for(y = 0; y < segments; ++y) {
|
||||
for(x = 0; x < segments; ++x) {
|
||||
var px = origin.x + x * xStride - width / 2 + xStride / 2;
|
||||
var py = origin.y + y * yStride - height / 2 + yStride / 2;
|
||||
composite.particles.push(new Phaser.Verlet.Particle(new Phaser.Vector2(px, py)));
|
||||
if(x > 0) {
|
||||
composite.constraints.push(new Phaser.Verlet.DistanceConstraint(composite.particles[y * segments + x], composite.particles[y * segments + x - 1], stiffness));
|
||||
}
|
||||
if(y > 0) {
|
||||
composite.constraints.push(new Phaser.Verlet.DistanceConstraint(composite.particles[y * segments + x], composite.particles[(y - 1) * segments + x], stiffness));
|
||||
}
|
||||
}
|
||||
}
|
||||
for(x = 0; x < segments; ++x) {
|
||||
if(x % pinMod == 0) {
|
||||
composite.pin(x);
|
||||
}
|
||||
}
|
||||
this.composites.push(composite);
|
||||
return composite;
|
||||
};
|
||||
VerletManager.prototype.createTire = function (origin, radius, segments, spokeStiffness, treadStiffness) {
|
||||
var stride = (2 * Math.PI) / segments;
|
||||
var i;
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
// particles
|
||||
for(i = 0; i < segments; ++i) {
|
||||
var theta = i * stride;
|
||||
composite.particles.push(new Verlet.Particle(new Phaser.Vector2(origin.x + Math.cos(theta) * radius, origin.y + Math.sin(theta) * radius)));
|
||||
}
|
||||
var center = new Verlet.Particle(origin);
|
||||
composite.particles.push(center);
|
||||
// constraints
|
||||
for(i = 0; i < segments; ++i) {
|
||||
composite.constraints.push(new Verlet.DistanceConstraint(composite.particles[i], composite.particles[(i + 1) % segments], treadStiffness));
|
||||
composite.constraints.push(new Verlet.DistanceConstraint(composite.particles[i], center, spokeStiffness));
|
||||
composite.constraints.push(new Verlet.DistanceConstraint(composite.particles[i], composite.particles[(i + 5) % segments], treadStiffness));
|
||||
}
|
||||
this.composites.push(composite);
|
||||
return composite;
|
||||
};
|
||||
VerletManager.prototype.update = function () {
|
||||
if(this.composites.length == 0) {
|
||||
return;
|
||||
}
|
||||
var i, j, c;
|
||||
for(c in this.composites) {
|
||||
for(i in this.composites[c].particles) {
|
||||
var particles = this.composites[c].particles;
|
||||
// calculate velocity
|
||||
var velocity = particles[i].pos.sub(particles[i].lastPos).scale(this.friction);
|
||||
// ground friction
|
||||
if(particles[i].pos.y >= this.height - 1 && velocity.length2() > 0.000001) {
|
||||
var m = velocity.length();
|
||||
velocity.x /= m;
|
||||
velocity.y /= m;
|
||||
velocity.mutableScale(m * this.groundFriction);
|
||||
}
|
||||
// save last good state
|
||||
particles[i].lastPos.mutableSet(particles[i].pos);
|
||||
// gravity
|
||||
particles[i].pos.mutableAdd(this.gravity);
|
||||
// inertia
|
||||
particles[i].pos.mutableAdd(velocity);
|
||||
}
|
||||
}
|
||||
// handle dragging of entities
|
||||
if(this.draggedEntity) {
|
||||
this.draggedEntity.pos.mutableSet(this._game.input.position);
|
||||
}
|
||||
// relax
|
||||
var stepCoef = 1 / this.step;
|
||||
for(c in this.composites) {
|
||||
var constraints = this.composites[c].constraints;
|
||||
for(i = 0; i < this.step; ++i) {
|
||||
for(j in constraints) {
|
||||
constraints[j].relax(stepCoef);
|
||||
}
|
||||
}
|
||||
}
|
||||
// bounds checking
|
||||
for(c in this.composites) {
|
||||
var particles = this.composites[c].particles;
|
||||
for(i in particles) {
|
||||
this.bounds(particles[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
VerletManager.prototype.mouseDownHandler = function () {
|
||||
var nearest = this.nearestEntity();
|
||||
if(nearest) {
|
||||
this.draggedEntity = nearest;
|
||||
}
|
||||
};
|
||||
VerletManager.prototype.mouseUpHandler = function () {
|
||||
this.draggedEntity = null;
|
||||
};
|
||||
VerletManager.prototype.nearestEntity = function () {
|
||||
var c, i;
|
||||
var d2Nearest = 0;
|
||||
var entity = null;
|
||||
var constraintsNearest = null;
|
||||
// find nearest point
|
||||
for(c in this.composites) {
|
||||
var particles = this.composites[c].particles;
|
||||
for(i in particles) {
|
||||
var d2 = particles[i].pos.distance2(this._game.input.position);
|
||||
if(d2 <= this.selectionRadius * this.selectionRadius && (entity == null || d2 < d2Nearest)) {
|
||||
entity = particles[i];
|
||||
constraintsNearest = this.composites[c].constraints;
|
||||
d2Nearest = d2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// search for pinned constraints for this entity
|
||||
for(i in constraintsNearest) {
|
||||
if(constraintsNearest[i] instanceof Verlet.PinConstraint && constraintsNearest[i].a == entity) {
|
||||
entity = constraintsNearest[i];
|
||||
}
|
||||
}
|
||||
return entity;
|
||||
};
|
||||
VerletManager.prototype.render = function () {
|
||||
var i, c;
|
||||
for(c in this.composites) {
|
||||
// draw constraints
|
||||
if(this.composites[c].drawConstraints) {
|
||||
this.composites[c].drawConstraints(this.context, this.composites[c]);
|
||||
} else {
|
||||
var constraints = this.composites[c].constraints;
|
||||
for(i in constraints) {
|
||||
constraints[i].render(this.context);
|
||||
}
|
||||
}
|
||||
// draw particles
|
||||
if(this.composites[c].drawParticles) {
|
||||
this.composites[c].drawParticles(this.context, this.composites[c]);
|
||||
} else {
|
||||
var particles = this.composites[c].particles;
|
||||
for(i in particles) {
|
||||
particles[i].render(this.context);
|
||||
}
|
||||
}
|
||||
}
|
||||
// highlight nearest / dragged entity
|
||||
var nearest = this.draggedEntity || this.nearestEntity();
|
||||
if(nearest && this.hideNearestEntityCircle == false) {
|
||||
this.context.beginPath();
|
||||
this.context.arc(nearest.pos.x, nearest.pos.y, 8, 0, 2 * Math.PI);
|
||||
this.context.strokeStyle = this.highlightColor;
|
||||
this.context.stroke();
|
||||
this.context.closePath();
|
||||
}
|
||||
};
|
||||
return VerletManager;
|
||||
})();
|
||||
Verlet.VerletManager = VerletManager;
|
||||
})(Phaser.Verlet || (Phaser.Verlet = {}));
|
||||
var Verlet = Phaser.Verlet;
|
||||
})(Phaser || (Phaser = {}));
|
||||
@@ -0,0 +1,411 @@
|
||||
/// <reference path="Game.ts" />
|
||||
/// <reference path="geom/Vector2.ts" />
|
||||
/// <reference path="verlet/Composite.ts" />
|
||||
/// <reference path="verlet/Particle.ts" />
|
||||
/// <reference path="verlet/DistanceConstraint.ts" />
|
||||
/// <reference path="verlet/PinConstraint.ts" />
|
||||
/// <reference path="verlet/AngleConstraint.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - Verlet
|
||||
*
|
||||
* Based on verlet-js by Sub Protocol released under MIT
|
||||
*/
|
||||
|
||||
module Phaser.Verlet {
|
||||
|
||||
export class VerletManager {
|
||||
|
||||
/**
|
||||
* Creates a new Vector2 object.
|
||||
* @class Vector2
|
||||
* @constructor
|
||||
* @param {Number} x The x coordinate of vector2
|
||||
* @param {Number} y The y coordinate of vector2
|
||||
* @return {Vector2} This object
|
||||
**/
|
||||
constructor(game: Game, width: number, height: number) {
|
||||
|
||||
this._game = game;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.gravity = new Vector2(0, 0.2);
|
||||
this.friction = 0.99;
|
||||
this.groundFriction = 0.8;
|
||||
|
||||
this.canvas = game.stage.canvas;
|
||||
this.context = game.stage.context;
|
||||
|
||||
this._game.input.onDown.add(this.mouseDownHandler, this);
|
||||
this._game.input.onUp.add(this.mouseUpHandler, this);
|
||||
|
||||
}
|
||||
|
||||
private _game: Game;
|
||||
private _v = new Phaser.Vector2;
|
||||
|
||||
public composites = [];
|
||||
|
||||
public width: number;
|
||||
public height: number;
|
||||
public step: number = 16;
|
||||
public gravity: Vector2;
|
||||
public friction: number;
|
||||
public groundFriction: number;
|
||||
public selectionRadius: number = 20;
|
||||
public draggedEntity = null;
|
||||
public highlightColor = '#4f545c';
|
||||
|
||||
/**
|
||||
* A reference to the canvas this renders to
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
public canvas: HTMLCanvasElement;
|
||||
|
||||
/**
|
||||
* A reference to the context this renders to
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
public context: CanvasRenderingContext2D;
|
||||
|
||||
/**
|
||||
* Computes time of intersection of a particle with a wall
|
||||
*
|
||||
* @param {Vec2} line walls root position
|
||||
* @param {Vec2} p particle position
|
||||
* @param {Vec2} dir walls direction
|
||||
* @param {Vec2} v particles velocity
|
||||
*/
|
||||
public intersectionTime(wall, p, dir, v) {
|
||||
|
||||
if (dir.x != 0)
|
||||
{
|
||||
var denominator = v.y - dir.y * v.x / dir.x;
|
||||
if (denominator == 0) return undefined; // Movement is parallel to wall
|
||||
var numerator = wall.y + dir.y * (p.x - wall.x) / dir.x - p.y;
|
||||
return numerator / denominator;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v.x == 0) return undefined; // parallel again
|
||||
var denominator = v.x;
|
||||
var numerator = wall.x - p.x;
|
||||
return numerator / denominator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public intersectionPoint(wall, p, dir, v) {
|
||||
var t = this.intersectionTime(wall, p, dir, v);
|
||||
return new Phaser.Vector2(p.x + v.x * t, p.y + v.y * t);
|
||||
}
|
||||
|
||||
public bounds(particle: Phaser.Verlet.Particle) {
|
||||
|
||||
this._v.mutableSet(particle.pos);
|
||||
this._v.mutableSub(particle.lastPos);
|
||||
|
||||
if (particle.pos.y > this.height - 1)
|
||||
{
|
||||
particle.pos.mutableSet(this.intersectionPoint(new Phaser.Vector2(0, this.height - 1), particle.lastPos, new Phaser.Vector2(1, 0), this._v));
|
||||
}
|
||||
|
||||
if (particle.pos.x < 0)
|
||||
{
|
||||
particle.pos.mutableSet(this.intersectionPoint(new Phaser.Vector2(0, 0), particle.pos, new Phaser.Vector2(0, 1), this._v));
|
||||
}
|
||||
|
||||
if (particle.pos.x > this.width - 1)
|
||||
{
|
||||
particle.pos.mutableSet(this.intersectionPoint(new Phaser.Vector2(this.width - 1, 0), particle.pos, new Phaser.Vector2(0, 1), this._v));
|
||||
}
|
||||
}
|
||||
|
||||
public createPoint(pos: Vector2) {
|
||||
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
|
||||
composite.particles.push(new Phaser.Verlet.Particle(pos));
|
||||
|
||||
this.composites.push(composite);
|
||||
|
||||
return composite;
|
||||
|
||||
}
|
||||
|
||||
public createLineSegments(vertices, stiffness) {
|
||||
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
var i;
|
||||
|
||||
for (i in vertices)
|
||||
{
|
||||
composite.particles.push(new Phaser.Verlet.Particle(vertices[i]));
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
composite.constraints.push(new Phaser.Verlet.DistanceConstraint(composite.particles[i], composite.particles[i - 1], stiffness));
|
||||
}
|
||||
}
|
||||
|
||||
this.composites.push(composite);
|
||||
|
||||
return composite;
|
||||
|
||||
}
|
||||
|
||||
public createCloth(origin, width, height, segments, pinMod, stiffness) {
|
||||
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
|
||||
var xStride = width / segments;
|
||||
var yStride = height / segments;
|
||||
|
||||
var x;
|
||||
var y;
|
||||
|
||||
for (y = 0; y < segments; ++y)
|
||||
{
|
||||
for (x = 0; x < segments; ++x)
|
||||
{
|
||||
var px = origin.x + x * xStride - width / 2 + xStride / 2;
|
||||
var py = origin.y + y * yStride - height / 2 + yStride / 2;
|
||||
|
||||
composite.particles.push(new Phaser.Verlet.Particle(new Vector2(px, py)));
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
composite.constraints.push(new Phaser.Verlet.DistanceConstraint(composite.particles[y * segments + x], composite.particles[y * segments + x - 1], stiffness));
|
||||
}
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
composite.constraints.push(new Phaser.Verlet.DistanceConstraint(composite.particles[y * segments + x], composite.particles[(y - 1) * segments + x], stiffness));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < segments; ++x)
|
||||
{
|
||||
if (x % pinMod == 0)
|
||||
{
|
||||
composite.pin(x);
|
||||
}
|
||||
}
|
||||
|
||||
this.composites.push(composite);
|
||||
|
||||
return composite;
|
||||
|
||||
}
|
||||
|
||||
public createTire(origin, radius, segments, spokeStiffness, treadStiffness) {
|
||||
|
||||
var stride = (2 * Math.PI) / segments;
|
||||
var i;
|
||||
|
||||
var composite = new Phaser.Verlet.Composite(this._game);
|
||||
|
||||
// particles
|
||||
for (i = 0; i < segments; ++i)
|
||||
{
|
||||
var theta = i * stride;
|
||||
composite.particles.push(new Particle(new Vector2(origin.x + Math.cos(theta) * radius, origin.y + Math.sin(theta) * radius)));
|
||||
}
|
||||
|
||||
var center = new Particle(origin);
|
||||
composite.particles.push(center);
|
||||
|
||||
// constraints
|
||||
for (i = 0; i < segments; ++i)
|
||||
{
|
||||
composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[(i + 1) % segments], treadStiffness));
|
||||
composite.constraints.push(new DistanceConstraint(composite.particles[i], center, spokeStiffness))
|
||||
composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[(i + 5) % segments], treadStiffness));
|
||||
}
|
||||
|
||||
this.composites.push(composite);
|
||||
|
||||
return composite;
|
||||
}
|
||||
|
||||
public update() {
|
||||
|
||||
if (this.composites.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var i, j, c;
|
||||
|
||||
for (c in this.composites)
|
||||
{
|
||||
for (i in this.composites[c].particles)
|
||||
{
|
||||
var particles = this.composites[c].particles;
|
||||
|
||||
// calculate velocity
|
||||
var velocity = particles[i].pos.sub(particles[i].lastPos).scale(this.friction);
|
||||
|
||||
// ground friction
|
||||
if (particles[i].pos.y >= this.height - 1 && velocity.length2() > 0.000001)
|
||||
{
|
||||
var m = velocity.length();
|
||||
velocity.x /= m;
|
||||
velocity.y /= m;
|
||||
velocity.mutableScale(m * this.groundFriction);
|
||||
}
|
||||
|
||||
// save last good state
|
||||
particles[i].lastPos.mutableSet(particles[i].pos);
|
||||
|
||||
// gravity
|
||||
particles[i].pos.mutableAdd(this.gravity);
|
||||
|
||||
// inertia
|
||||
particles[i].pos.mutableAdd(velocity);
|
||||
}
|
||||
}
|
||||
|
||||
// handle dragging of entities
|
||||
if (this.draggedEntity)
|
||||
{
|
||||
this.draggedEntity.pos.mutableSet(this._game.input.position);
|
||||
}
|
||||
|
||||
// relax
|
||||
var stepCoef = 1 / this.step;
|
||||
|
||||
for (c in this.composites)
|
||||
{
|
||||
var constraints = this.composites[c].constraints;
|
||||
|
||||
for (i = 0; i < this.step; ++i)
|
||||
{
|
||||
for (j in constraints)
|
||||
{
|
||||
constraints[j].relax(stepCoef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bounds checking
|
||||
for (c in this.composites)
|
||||
{
|
||||
var particles = this.composites[c].particles;
|
||||
|
||||
for (i in particles)
|
||||
{
|
||||
this.bounds(particles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private mouseDownHandler() {
|
||||
|
||||
var nearest = this.nearestEntity();
|
||||
|
||||
if (nearest)
|
||||
{
|
||||
this.draggedEntity = nearest;
|
||||
}
|
||||
}
|
||||
|
||||
private mouseUpHandler() {
|
||||
this.draggedEntity = null;
|
||||
}
|
||||
|
||||
public nearestEntity() {
|
||||
|
||||
var c, i;
|
||||
var d2Nearest = 0;
|
||||
var entity = null;
|
||||
var constraintsNearest = null;
|
||||
|
||||
// find nearest point
|
||||
for (c in this.composites)
|
||||
{
|
||||
var particles = this.composites[c].particles;
|
||||
|
||||
for (i in particles)
|
||||
{
|
||||
var d2 = particles[i].pos.distance2(this._game.input.position);
|
||||
|
||||
if (d2 <= this.selectionRadius * this.selectionRadius && (entity == null || d2 < d2Nearest))
|
||||
{
|
||||
entity = particles[i];
|
||||
constraintsNearest = this.composites[c].constraints;
|
||||
d2Nearest = d2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search for pinned constraints for this entity
|
||||
for (i in constraintsNearest)
|
||||
{
|
||||
if (constraintsNearest[i] instanceof PinConstraint && constraintsNearest[i].a == entity)
|
||||
{
|
||||
entity = constraintsNearest[i];
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
|
||||
}
|
||||
|
||||
public hideNearestEntityCircle: bool = false;
|
||||
|
||||
public render() {
|
||||
|
||||
var i, c;
|
||||
|
||||
for (c in this.composites)
|
||||
{
|
||||
// draw constraints
|
||||
if (this.composites[c].drawConstraints)
|
||||
{
|
||||
this.composites[c].drawConstraints(this.context, this.composites[c]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var constraints = this.composites[c].constraints;
|
||||
|
||||
for (i in constraints)
|
||||
{
|
||||
constraints[i].render(this.context);
|
||||
}
|
||||
}
|
||||
|
||||
// draw particles
|
||||
if (this.composites[c].drawParticles)
|
||||
{
|
||||
this.composites[c].drawParticles(this.context, this.composites[c]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var particles = this.composites[c].particles;
|
||||
|
||||
for (i in particles)
|
||||
{
|
||||
particles[i].render(this.context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// highlight nearest / dragged entity
|
||||
var nearest = this.draggedEntity || this.nearestEntity();
|
||||
|
||||
if (nearest && this.hideNearestEntityCircle == false)
|
||||
{
|
||||
this.context.beginPath();
|
||||
this.context.arc(nearest.pos.x, nearest.pos.y, 8, 0, 2 * Math.PI);
|
||||
this.context.strokeStyle = this.highlightColor;
|
||||
this.context.stroke();
|
||||
this.context.closePath();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user