mirror of
https://github.com/photonstorm/phaser
synced 2024-11-22 12:43:26 +00:00
Merge branch 'master' of https://github.com/photonstorm/phaser
This commit is contained in:
commit
3546140b51
72 changed files with 93052 additions and 90179 deletions
|
@ -70,6 +70,9 @@ Development of this feature was kindly sponsored by Club Penguin Rewritten (http
|
||||||
* `Math.LinearXY` is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
|
* `Math.LinearXY` is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
|
||||||
* `Curves.Path.getCurveAt` is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
|
* `Curves.Path.getCurveAt` is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
|
||||||
* You can now use any `Shape` Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
|
* You can now use any `Shape` Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
|
||||||
|
* `Mesh.setTint` is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
|
||||||
|
* `Mesh.tint` is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
|
||||||
|
* `Mesh.clearTint` is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
|
||||||
|
|
||||||
### Geom Updates
|
### Geom Updates
|
||||||
|
|
||||||
|
@ -117,6 +120,9 @@ The following are API-breaking, in that a new optional parameter has been insert
|
||||||
* `TileMap.createStaticLayer` has now been removed as it was deprecated in 3.50.
|
* `TileMap.createStaticLayer` has now been removed as it was deprecated in 3.50.
|
||||||
* `Animations.AnimationManager.createFromAseprite` has a new optional 3rd parameter `target`. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
|
* `Animations.AnimationManager.createFromAseprite` has a new optional 3rd parameter `target`. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
|
||||||
* `Animations.AnimationState.createFromAseprite` is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
|
* `Animations.AnimationState.createFromAseprite` is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
|
||||||
|
* The `path` package used by the TS Defs generator has been moved to `devDependencies` (thanks @antkhnvsk)
|
||||||
|
* The `GetValue` function has a new optional parameter `altSource` which allows you to provide an alternative object to source the value from.
|
||||||
|
* The `Renderer.Snapshot.WebGL` function has had its first parameter changed from an `HTMLCanvasElement` to a `WebGLRenderingContext`. This is now passed in from the `snapshot` methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
@ -165,9 +171,24 @@ The following are API-breaking, in that a new optional parameter has been insert
|
||||||
* `InputPlugin.disable` will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match `enable`. Fix #5828 (thank @natureofcode @thewaver)
|
* `InputPlugin.disable` will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match `enable`. Fix #5828 (thank @natureofcode @thewaver)
|
||||||
* The `GetBounds` component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
|
* The `GetBounds` component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
|
||||||
* `SceneManager.moveAbove` and `moveBelow` now take into account the modified indexes after the move (thanks @EmilSV)
|
* `SceneManager.moveAbove` and `moveBelow` now take into account the modified indexes after the move (thanks @EmilSV)
|
||||||
|
* When forcing a game to use `setTimeout` and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
|
||||||
|
* Including a `render` object within the Game Config will no longer erase any top-level config render settings. The `render` object will now take priority over the game config, but both will be used (thanks @vzhou842)
|
||||||
|
* Calling `Tween.stop(0)` would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
|
||||||
|
* The `Utils.Array.SafeRange` function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
|
||||||
|
* The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
|
||||||
|
* The `Container.pointToContainer` method would ignore the provided `output` parameter, but now uses it (thanks @vforsh)
|
||||||
|
* The `Polygon` Game Object would ignore its `closePath` property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
|
||||||
|
* IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
|
||||||
|
* IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
|
||||||
|
* `RenderTexture.batchTextureFrame` will now skip the `drawImage` call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
|
||||||
|
* `BlitterCanvasRenderer` will now skip the `drawImage` call in canvas if the frame width or height are zero.
|
||||||
|
* `ParticleManagerCanvasRenderer` will now skip the `drawImage` call in canvas if the frame width or height are zero.
|
||||||
|
* `CanvasSnapshot` will now skip the `drawImage` call in canvas if the frame width or height are zero.
|
||||||
|
* `TextureManager.getBase64` will now skip the `drawImage` call in canvas if the frame width or height are zero.
|
||||||
|
* `TilemapLayerCanvasRenderer` will now skip the `drawImage` call in canvas if the frame width or height are zero.
|
||||||
|
|
||||||
### Examples, Documentation and TypeScript
|
### Examples, Documentation and TypeScript
|
||||||
|
|
||||||
My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:
|
My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:
|
||||||
|
|
||||||
@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe
|
@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake
|
||||||
|
|
651
package-lock.json
generated
651
package-lock.json
generated
File diff suppressed because it is too large
Load diff
17
package.json
17
package.json
|
@ -64,27 +64,28 @@
|
||||||
"web audio"
|
"web audio"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/offscreencanvas": "^2019.6.4",
|
||||||
"@types/source-map": "^0.5.7",
|
"@types/source-map": "^0.5.7",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"dts-dom": "^3.6.0",
|
"dts-dom": "^3.6.0",
|
||||||
"eslint": "^8.4.1",
|
"eslint": "^8.8.0",
|
||||||
"eslint-plugin-es5": "^1.5.0",
|
"eslint-plugin-es5": "^1.5.0",
|
||||||
"exports-loader": "^3.1.0",
|
"exports-loader": "^3.1.0",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"imports-loader": "^3.1.1",
|
"imports-loader": "^3.1.1",
|
||||||
"jsdoc": "^3.6.7",
|
"jsdoc": "^3.6.10",
|
||||||
"node-sloc": "^0.2.1",
|
"node-sloc": "^0.2.1",
|
||||||
|
"path": "^0.12.7",
|
||||||
"remove-files-webpack-plugin": "^1.5.0",
|
"remove-files-webpack-plugin": "^1.5.0",
|
||||||
"source-map": "^0.7.3",
|
"source-map": "^0.7.3",
|
||||||
"terser-webpack-plugin": "^5.2.5",
|
"terser-webpack-plugin": "^5.3.1",
|
||||||
"typescript": "^4.5.4",
|
"typescript": "^4.5.5",
|
||||||
"vivid-cli": "^1.1.2",
|
"vivid-cli": "^1.1.2",
|
||||||
"webpack": "^5.65.0",
|
"webpack": "^5.68.0",
|
||||||
"webpack-cli": "^4.9.1",
|
"webpack-cli": "^4.9.2",
|
||||||
"webpack-shell-plugin": "^0.5.0"
|
"webpack-shell-plugin": "^0.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eventemitter3": "^4.0.7",
|
"eventemitter3": "^4.0.7"
|
||||||
"path": "^0.12.7"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
1. Checkout the Esoteric Spine Runtimes repo to the `spine-runtimes` folder: https://github.com/EsotericSoftware/spine-runtimes/ and make sure this is in the `plugins/spine` folder, not the `plugins/spine/src` folder.
|
1. Checkout the Esoteric Spine Runtimes repo to the `spine-runtimes` folder: https://github.com/EsotericSoftware/spine-runtimes/ and make sure this is in the `plugins/spine` folder, not the `plugins/spine/src` folder.
|
||||||
2. Run `npm i` inside the `spine-runtimes` folder.
|
2. Run `npm i` inside the `spine-runtimes` folder.
|
||||||
3. Add the `source-map` module: `npm i --save-dev source-map`.
|
3. Add the `offscreencanvas` module: `npm i --save-dev @types/offscreencanvas`.
|
||||||
4. Run `npm run plugin.spine.runtimes` to build the new runtimes to the `plugins/spine/src/runtimes` folder.
|
4. Add the `source-map` module: `npm i --save-dev source-map`.
|
||||||
|
5. Run `npm run plugin.spine.runtimes` to build the new runtimes to the `plugins/spine/src/runtimes` folder.
|
||||||
|
|
||||||
You can now build a new version of the Spine Plugin:
|
You can now build a new version of the Spine Plugin:
|
||||||
|
|
||||||
5. `npm run plugin.spine.dist`.
|
6. `npm run plugin.spine.dist`.
|
||||||
|
|
||||||
|
|
59183
plugins/spine/dist/SpineCanvasPlugin.js
vendored
59183
plugins/spine/dist/SpineCanvasPlugin.js
vendored
File diff suppressed because it is too large
Load diff
2
plugins/spine/dist/SpineCanvasPlugin.min.js
vendored
2
plugins/spine/dist/SpineCanvasPlugin.min.js
vendored
File diff suppressed because one or more lines are too long
60256
plugins/spine/dist/SpinePlugin.js
vendored
60256
plugins/spine/dist/SpinePlugin.js
vendored
File diff suppressed because it is too large
Load diff
2
plugins/spine/dist/SpinePlugin.min.js
vendored
2
plugins/spine/dist/SpinePlugin.min.js
vendored
File diff suppressed because one or more lines are too long
59757
plugins/spine/dist/SpineWebGLPlugin.js
vendored
59757
plugins/spine/dist/SpineWebGLPlugin.js
vendored
File diff suppressed because it is too large
Load diff
2
plugins/spine/dist/SpineWebGLPlugin.min.js
vendored
2
plugins/spine/dist/SpineWebGLPlugin.min.js
vendored
File diff suppressed because one or more lines are too long
3
plugins/spine/src/runtimes/spine-both.d.ts
vendored
3
plugins/spine/src/runtimes/spine-both.d.ts
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
/// <reference types="offscreencanvas" />
|
||||||
declare module spine {
|
declare module spine {
|
||||||
class Animation {
|
class Animation {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -1402,7 +1403,7 @@ declare module spine.webgl {
|
||||||
static DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL: boolean;
|
static DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL: boolean;
|
||||||
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement | ImageBitmap, useMipMaps?: boolean);
|
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement | ImageBitmap, useMipMaps?: boolean);
|
||||||
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
|
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
|
||||||
static validateMagFilter(magFilter: TextureFilter): TextureFilter.Nearest | TextureFilter.Linear | TextureFilter.Linear;
|
static validateMagFilter(magFilter: TextureFilter): TextureFilter.Nearest | TextureFilter.Linear;
|
||||||
setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
|
setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
|
||||||
update(useMipMaps: boolean): void;
|
update(useMipMaps: boolean): void;
|
||||||
restore(): void;
|
restore(): void;
|
||||||
|
|
|
@ -6,6 +6,8 @@ var __extends = (this && this.__extends) || (function () {
|
||||||
return extendStatics(d, b);
|
return extendStatics(d, b);
|
||||||
};
|
};
|
||||||
return function (d, b) {
|
return function (d, b) {
|
||||||
|
if (typeof b !== "function" && b !== null)
|
||||||
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||||
extendStatics(d, b);
|
extendStatics(d, b);
|
||||||
function __() { this.constructor = d; }
|
function __() { this.constructor = d; }
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
@ -2239,9 +2241,9 @@ var spine;
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load binary " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load binary " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -2259,9 +2261,9 @@ var spine;
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load text " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -2284,11 +2286,11 @@ var spine;
|
||||||
success(path, img);
|
success(path, img);
|
||||||
};
|
};
|
||||||
img.onerror = function (ev) {
|
img.onerror = function (ev) {
|
||||||
_this.errors[path] = "Couldn't load image " + path;
|
_this.errors[path] = "Couldn't load image ".concat(path);
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load image " + path);
|
error(path, "Couldn't load image ".concat(path));
|
||||||
};
|
};
|
||||||
if (this.rawDataUris[path])
|
if (this.rawDataUris[path])
|
||||||
path = this.rawDataUris[path];
|
path = this.rawDataUris[path];
|
||||||
|
@ -2315,9 +2317,9 @@ var spine;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
var ex = e;
|
var ex = e;
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
return;
|
return;
|
||||||
|
@ -2340,17 +2342,17 @@ var spine;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
var ex = e;
|
var ex = e;
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
_this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
|
@ -2359,9 +2361,9 @@ var spine;
|
||||||
pageLoadError = true;
|
pageLoadError = true;
|
||||||
pagesLoaded.count++;
|
pagesLoaded.count++;
|
||||||
if (pagesLoaded.count == atlasPages.length) {
|
if (pagesLoaded.count == atlasPages.length) {
|
||||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
_this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
|
@ -2372,9 +2374,9 @@ var spine;
|
||||||
_loop_1(atlasPage);
|
_loop_1(atlasPage);
|
||||||
}
|
}
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -3540,7 +3542,7 @@ var spine;
|
||||||
_this.rawAssets[path] = request.responseText;
|
_this.rawAssets[path] = request.responseText;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3560,7 +3562,7 @@ var spine;
|
||||||
_this.rawAssets[path] = JSON.parse(request.responseText);
|
_this.rawAssets[path] = JSON.parse(request.responseText);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3597,7 +3599,7 @@ var spine;
|
||||||
_this.rawAssets[path] = img_1;
|
_this.rawAssets[path] = img_1;
|
||||||
};
|
};
|
||||||
img_1.onerror = function (ev) {
|
img_1.onerror = function (ev) {
|
||||||
_this.errors[path] = "Couldn't load image " + path;
|
_this.errors[path] = "Couldn't load image ".concat(path);
|
||||||
};
|
};
|
||||||
img_1.src = path;
|
img_1.src = path;
|
||||||
}
|
}
|
||||||
|
@ -6251,7 +6253,7 @@ var spine;
|
||||||
return spine.BlendMode.Multiply;
|
return spine.BlendMode.Multiply;
|
||||||
if (str == "screen")
|
if (str == "screen")
|
||||||
return spine.BlendMode.Screen;
|
return spine.BlendMode.Screen;
|
||||||
throw new Error("Unknown blend mode: " + str);
|
throw new Error("Unknown blend mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.positionModeFromString = function (str) {
|
SkeletonJson.positionModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6259,7 +6261,7 @@ var spine;
|
||||||
return spine.PositionMode.Fixed;
|
return spine.PositionMode.Fixed;
|
||||||
if (str == "percent")
|
if (str == "percent")
|
||||||
return spine.PositionMode.Percent;
|
return spine.PositionMode.Percent;
|
||||||
throw new Error("Unknown position mode: " + str);
|
throw new Error("Unknown position mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.spacingModeFromString = function (str) {
|
SkeletonJson.spacingModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6269,7 +6271,7 @@ var spine;
|
||||||
return spine.SpacingMode.Fixed;
|
return spine.SpacingMode.Fixed;
|
||||||
if (str == "percent")
|
if (str == "percent")
|
||||||
return spine.SpacingMode.Percent;
|
return spine.SpacingMode.Percent;
|
||||||
throw new Error("Unknown position mode: " + str);
|
throw new Error("Unknown position mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.rotateModeFromString = function (str) {
|
SkeletonJson.rotateModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6279,7 +6281,7 @@ var spine;
|
||||||
return spine.RotateMode.Chain;
|
return spine.RotateMode.Chain;
|
||||||
if (str == "chainscale")
|
if (str == "chainscale")
|
||||||
return spine.RotateMode.ChainScale;
|
return spine.RotateMode.ChainScale;
|
||||||
throw new Error("Unknown rotate mode: " + str);
|
throw new Error("Unknown rotate mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.transformModeFromString = function (str) {
|
SkeletonJson.transformModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6293,7 +6295,7 @@ var spine;
|
||||||
return spine.TransformMode.NoScale;
|
return spine.TransformMode.NoScale;
|
||||||
if (str == "noscaleorreflection")
|
if (str == "noscaleorreflection")
|
||||||
return spine.TransformMode.NoScaleOrReflection;
|
return spine.TransformMode.NoScaleOrReflection;
|
||||||
throw new Error("Unknown transform mode: " + str);
|
throw new Error("Unknown transform mode: ".concat(str));
|
||||||
};
|
};
|
||||||
return SkeletonJson;
|
return SkeletonJson;
|
||||||
}());
|
}());
|
||||||
|
@ -6558,7 +6560,7 @@ var spine;
|
||||||
case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
|
case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
|
||||||
case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
|
case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
|
||||||
case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
|
case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
|
||||||
default: throw new Error("Unknown texture filter " + text);
|
default: throw new Error("Unknown texture filter ".concat(text));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Texture.wrapFromString = function (text) {
|
Texture.wrapFromString = function (text) {
|
||||||
|
@ -6566,7 +6568,7 @@ var spine;
|
||||||
case "mirroredtepeat": return TextureWrap.MirroredRepeat;
|
case "mirroredtepeat": return TextureWrap.MirroredRepeat;
|
||||||
case "clamptoedge": return TextureWrap.ClampToEdge;
|
case "clamptoedge": return TextureWrap.ClampToEdge;
|
||||||
case "repeat": return TextureWrap.Repeat;
|
case "repeat": return TextureWrap.Repeat;
|
||||||
default: throw new Error("Unknown texture wrap " + text);
|
default: throw new Error("Unknown texture wrap ".concat(text));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Texture;
|
return Texture;
|
||||||
|
@ -9796,14 +9798,14 @@ var spine;
|
||||||
var gl = this.context.gl;
|
var gl = this.context.gl;
|
||||||
var location = gl.getUniformLocation(this.program, uniform);
|
var location = gl.getUniformLocation(this.program, uniform);
|
||||||
if (!location && !gl.isContextLost())
|
if (!location && !gl.isContextLost())
|
||||||
throw new Error("Couldn't find location for uniform " + uniform);
|
throw new Error("Couldn't find location for uniform ".concat(uniform));
|
||||||
return location;
|
return location;
|
||||||
};
|
};
|
||||||
Shader.prototype.getAttributeLocation = function (attribute) {
|
Shader.prototype.getAttributeLocation = function (attribute) {
|
||||||
var gl = this.context.gl;
|
var gl = this.context.gl;
|
||||||
var location = gl.getAttribLocation(this.program, attribute);
|
var location = gl.getAttribLocation(this.program, attribute);
|
||||||
if (location == -1 && !gl.isContextLost())
|
if (location == -1 && !gl.isContextLost())
|
||||||
throw new Error("Couldn't find location for attribute " + attribute);
|
throw new Error("Couldn't find location for attribute ".concat(attribute));
|
||||||
return location;
|
return location;
|
||||||
};
|
};
|
||||||
Shader.prototype.dispose = function () {
|
Shader.prototype.dispose = function () {
|
||||||
|
@ -9823,17 +9825,17 @@ var spine;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Shader.newColoredTextured = function (context) {
|
Shader.newColoredTextured = function (context) {
|
||||||
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tattribute vec2 ").concat(Shader.TEXCOORDS, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = ").concat(Shader.COLOR, ";\n\t\t\t\t\tv_texCoords = ").concat(Shader.TEXCOORDS, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
|
||||||
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
|
||||||
return new Shader(context, vs, fs);
|
return new Shader(context, vs, fs);
|
||||||
};
|
};
|
||||||
Shader.newTwoColoredTextured = function (context) {
|
Shader.newTwoColoredTextured = function (context) {
|
||||||
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR2 + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = " + Shader.COLOR + ";\n\t\t\t\t\tv_dark = " + Shader.COLOR2 + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR2, ";\n\t\t\t\tattribute vec2 ").concat(Shader.TEXCOORDS, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = ").concat(Shader.COLOR, ";\n\t\t\t\t\tv_dark = ").concat(Shader.COLOR2, ";\n\t\t\t\t\tv_texCoords = ").concat(Shader.TEXCOORDS, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
|
||||||
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tgl_FragColor.a = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tgl_FragColor.a = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
|
||||||
return new Shader(context, vs, fs);
|
return new Shader(context, vs, fs);
|
||||||
};
|
};
|
||||||
Shader.newColored = function (context) {
|
Shader.newColored = function (context) {
|
||||||
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = ").concat(Shader.COLOR, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
|
||||||
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
|
||||||
return new Shader(context, vs, fs);
|
return new Shader(context, vs, fs);
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,8 @@ var __extends = (this && this.__extends) || (function () {
|
||||||
return extendStatics(d, b);
|
return extendStatics(d, b);
|
||||||
};
|
};
|
||||||
return function (d, b) {
|
return function (d, b) {
|
||||||
|
if (typeof b !== "function" && b !== null)
|
||||||
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||||
extendStatics(d, b);
|
extendStatics(d, b);
|
||||||
function __() { this.constructor = d; }
|
function __() { this.constructor = d; }
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
@ -2239,9 +2241,9 @@ var spine;
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load binary " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load binary " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -2259,9 +2261,9 @@ var spine;
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load text " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -2284,11 +2286,11 @@ var spine;
|
||||||
success(path, img);
|
success(path, img);
|
||||||
};
|
};
|
||||||
img.onerror = function (ev) {
|
img.onerror = function (ev) {
|
||||||
_this.errors[path] = "Couldn't load image " + path;
|
_this.errors[path] = "Couldn't load image ".concat(path);
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load image " + path);
|
error(path, "Couldn't load image ".concat(path));
|
||||||
};
|
};
|
||||||
if (this.rawDataUris[path])
|
if (this.rawDataUris[path])
|
||||||
path = this.rawDataUris[path];
|
path = this.rawDataUris[path];
|
||||||
|
@ -2315,9 +2317,9 @@ var spine;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
var ex = e;
|
var ex = e;
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
return;
|
return;
|
||||||
|
@ -2340,17 +2342,17 @@ var spine;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
var ex = e;
|
var ex = e;
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
_this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
|
@ -2359,9 +2361,9 @@ var spine;
|
||||||
pageLoadError = true;
|
pageLoadError = true;
|
||||||
pagesLoaded.count++;
|
pagesLoaded.count++;
|
||||||
if (pagesLoaded.count == atlasPages.length) {
|
if (pagesLoaded.count == atlasPages.length) {
|
||||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
_this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
|
@ -2372,9 +2374,9 @@ var spine;
|
||||||
_loop_1(atlasPage);
|
_loop_1(atlasPage);
|
||||||
}
|
}
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -3540,7 +3542,7 @@ var spine;
|
||||||
_this.rawAssets[path] = request.responseText;
|
_this.rawAssets[path] = request.responseText;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3560,7 +3562,7 @@ var spine;
|
||||||
_this.rawAssets[path] = JSON.parse(request.responseText);
|
_this.rawAssets[path] = JSON.parse(request.responseText);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3597,7 +3599,7 @@ var spine;
|
||||||
_this.rawAssets[path] = img_1;
|
_this.rawAssets[path] = img_1;
|
||||||
};
|
};
|
||||||
img_1.onerror = function (ev) {
|
img_1.onerror = function (ev) {
|
||||||
_this.errors[path] = "Couldn't load image " + path;
|
_this.errors[path] = "Couldn't load image ".concat(path);
|
||||||
};
|
};
|
||||||
img_1.src = path;
|
img_1.src = path;
|
||||||
}
|
}
|
||||||
|
@ -6251,7 +6253,7 @@ var spine;
|
||||||
return spine.BlendMode.Multiply;
|
return spine.BlendMode.Multiply;
|
||||||
if (str == "screen")
|
if (str == "screen")
|
||||||
return spine.BlendMode.Screen;
|
return spine.BlendMode.Screen;
|
||||||
throw new Error("Unknown blend mode: " + str);
|
throw new Error("Unknown blend mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.positionModeFromString = function (str) {
|
SkeletonJson.positionModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6259,7 +6261,7 @@ var spine;
|
||||||
return spine.PositionMode.Fixed;
|
return spine.PositionMode.Fixed;
|
||||||
if (str == "percent")
|
if (str == "percent")
|
||||||
return spine.PositionMode.Percent;
|
return spine.PositionMode.Percent;
|
||||||
throw new Error("Unknown position mode: " + str);
|
throw new Error("Unknown position mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.spacingModeFromString = function (str) {
|
SkeletonJson.spacingModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6269,7 +6271,7 @@ var spine;
|
||||||
return spine.SpacingMode.Fixed;
|
return spine.SpacingMode.Fixed;
|
||||||
if (str == "percent")
|
if (str == "percent")
|
||||||
return spine.SpacingMode.Percent;
|
return spine.SpacingMode.Percent;
|
||||||
throw new Error("Unknown position mode: " + str);
|
throw new Error("Unknown position mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.rotateModeFromString = function (str) {
|
SkeletonJson.rotateModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6279,7 +6281,7 @@ var spine;
|
||||||
return spine.RotateMode.Chain;
|
return spine.RotateMode.Chain;
|
||||||
if (str == "chainscale")
|
if (str == "chainscale")
|
||||||
return spine.RotateMode.ChainScale;
|
return spine.RotateMode.ChainScale;
|
||||||
throw new Error("Unknown rotate mode: " + str);
|
throw new Error("Unknown rotate mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.transformModeFromString = function (str) {
|
SkeletonJson.transformModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6293,7 +6295,7 @@ var spine;
|
||||||
return spine.TransformMode.NoScale;
|
return spine.TransformMode.NoScale;
|
||||||
if (str == "noscaleorreflection")
|
if (str == "noscaleorreflection")
|
||||||
return spine.TransformMode.NoScaleOrReflection;
|
return spine.TransformMode.NoScaleOrReflection;
|
||||||
throw new Error("Unknown transform mode: " + str);
|
throw new Error("Unknown transform mode: ".concat(str));
|
||||||
};
|
};
|
||||||
return SkeletonJson;
|
return SkeletonJson;
|
||||||
}());
|
}());
|
||||||
|
@ -6558,7 +6560,7 @@ var spine;
|
||||||
case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
|
case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
|
||||||
case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
|
case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
|
||||||
case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
|
case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
|
||||||
default: throw new Error("Unknown texture filter " + text);
|
default: throw new Error("Unknown texture filter ".concat(text));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Texture.wrapFromString = function (text) {
|
Texture.wrapFromString = function (text) {
|
||||||
|
@ -6566,7 +6568,7 @@ var spine;
|
||||||
case "mirroredtepeat": return TextureWrap.MirroredRepeat;
|
case "mirroredtepeat": return TextureWrap.MirroredRepeat;
|
||||||
case "clamptoedge": return TextureWrap.ClampToEdge;
|
case "clamptoedge": return TextureWrap.ClampToEdge;
|
||||||
case "repeat": return TextureWrap.Repeat;
|
case "repeat": return TextureWrap.Repeat;
|
||||||
default: throw new Error("Unknown texture wrap " + text);
|
default: throw new Error("Unknown texture wrap ".concat(text));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Texture;
|
return Texture;
|
||||||
|
|
File diff suppressed because one or more lines are too long
3
plugins/spine/src/runtimes/spine-webgl.d.ts
vendored
3
plugins/spine/src/runtimes/spine-webgl.d.ts
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
/// <reference types="offscreencanvas" />
|
||||||
declare module spine {
|
declare module spine {
|
||||||
class Animation {
|
class Animation {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -1371,7 +1372,7 @@ declare module spine.webgl {
|
||||||
static DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL: boolean;
|
static DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL: boolean;
|
||||||
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement | ImageBitmap, useMipMaps?: boolean);
|
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement | ImageBitmap, useMipMaps?: boolean);
|
||||||
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
|
setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
|
||||||
static validateMagFilter(magFilter: TextureFilter): TextureFilter.Nearest | TextureFilter.Linear | TextureFilter.Linear;
|
static validateMagFilter(magFilter: TextureFilter): TextureFilter.Nearest | TextureFilter.Linear;
|
||||||
setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
|
setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
|
||||||
update(useMipMaps: boolean): void;
|
update(useMipMaps: boolean): void;
|
||||||
restore(): void;
|
restore(): void;
|
||||||
|
|
|
@ -6,6 +6,8 @@ var __extends = (this && this.__extends) || (function () {
|
||||||
return extendStatics(d, b);
|
return extendStatics(d, b);
|
||||||
};
|
};
|
||||||
return function (d, b) {
|
return function (d, b) {
|
||||||
|
if (typeof b !== "function" && b !== null)
|
||||||
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||||
extendStatics(d, b);
|
extendStatics(d, b);
|
||||||
function __() { this.constructor = d; }
|
function __() { this.constructor = d; }
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
@ -2239,9 +2241,9 @@ var spine;
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load binary " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load binary " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load binary ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -2259,9 +2261,9 @@ var spine;
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load text " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load text ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -2284,11 +2286,11 @@ var spine;
|
||||||
success(path, img);
|
success(path, img);
|
||||||
};
|
};
|
||||||
img.onerror = function (ev) {
|
img.onerror = function (ev) {
|
||||||
_this.errors[path] = "Couldn't load image " + path;
|
_this.errors[path] = "Couldn't load image ".concat(path);
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load image " + path);
|
error(path, "Couldn't load image ".concat(path));
|
||||||
};
|
};
|
||||||
if (this.rawDataUris[path])
|
if (this.rawDataUris[path])
|
||||||
path = this.rawDataUris[path];
|
path = this.rawDataUris[path];
|
||||||
|
@ -2315,9 +2317,9 @@ var spine;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
var ex = e;
|
var ex = e;
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
return;
|
return;
|
||||||
|
@ -2340,17 +2342,17 @@ var spine;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
var ex = e;
|
var ex = e;
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": " + ex.message;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": " + ex.message);
|
error(path, "Couldn't load texture atlas ".concat(path, ": ").concat(ex.message));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
_this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
|
@ -2359,9 +2361,9 @@ var spine;
|
||||||
pageLoadError = true;
|
pageLoadError = true;
|
||||||
pagesLoaded.count++;
|
pagesLoaded.count++;
|
||||||
if (pagesLoaded.count == atlasPages.length) {
|
if (pagesLoaded.count == atlasPages.length) {
|
||||||
_this.errors[path] = "Couldn't load texture atlas page " + imagePath + "} of atlas " + path;
|
_this.errors[path] = "Couldn't load texture atlas page ".concat(imagePath, "} of atlas ").concat(path);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas page " + imagePath + " of atlas " + path);
|
error(path, "Couldn't load texture atlas page ".concat(imagePath, " of atlas ").concat(path));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
}
|
}
|
||||||
|
@ -2372,9 +2374,9 @@ var spine;
|
||||||
_loop_1(atlasPage);
|
_loop_1(atlasPage);
|
||||||
}
|
}
|
||||||
}, function (state, responseText) {
|
}, function (state, responseText) {
|
||||||
_this.errors[path] = "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText;
|
_this.errors[path] = "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText);
|
||||||
if (error)
|
if (error)
|
||||||
error(path, "Couldn't load texture atlas " + path + ": status " + status + ", " + responseText);
|
error(path, "Couldn't load texture atlas ".concat(path, ": status ").concat(status, ", ").concat(responseText));
|
||||||
_this.toLoad--;
|
_this.toLoad--;
|
||||||
_this.loaded++;
|
_this.loaded++;
|
||||||
});
|
});
|
||||||
|
@ -3540,7 +3542,7 @@ var spine;
|
||||||
_this.rawAssets[path] = request.responseText;
|
_this.rawAssets[path] = request.responseText;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3560,7 +3562,7 @@ var spine;
|
||||||
_this.rawAssets[path] = JSON.parse(request.responseText);
|
_this.rawAssets[path] = JSON.parse(request.responseText);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_this.errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
|
_this.errors[path] = "Couldn't load text ".concat(path, ": status ").concat(request.status, ", ").concat(request.responseText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3597,7 +3599,7 @@ var spine;
|
||||||
_this.rawAssets[path] = img_1;
|
_this.rawAssets[path] = img_1;
|
||||||
};
|
};
|
||||||
img_1.onerror = function (ev) {
|
img_1.onerror = function (ev) {
|
||||||
_this.errors[path] = "Couldn't load image " + path;
|
_this.errors[path] = "Couldn't load image ".concat(path);
|
||||||
};
|
};
|
||||||
img_1.src = path;
|
img_1.src = path;
|
||||||
}
|
}
|
||||||
|
@ -6251,7 +6253,7 @@ var spine;
|
||||||
return spine.BlendMode.Multiply;
|
return spine.BlendMode.Multiply;
|
||||||
if (str == "screen")
|
if (str == "screen")
|
||||||
return spine.BlendMode.Screen;
|
return spine.BlendMode.Screen;
|
||||||
throw new Error("Unknown blend mode: " + str);
|
throw new Error("Unknown blend mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.positionModeFromString = function (str) {
|
SkeletonJson.positionModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6259,7 +6261,7 @@ var spine;
|
||||||
return spine.PositionMode.Fixed;
|
return spine.PositionMode.Fixed;
|
||||||
if (str == "percent")
|
if (str == "percent")
|
||||||
return spine.PositionMode.Percent;
|
return spine.PositionMode.Percent;
|
||||||
throw new Error("Unknown position mode: " + str);
|
throw new Error("Unknown position mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.spacingModeFromString = function (str) {
|
SkeletonJson.spacingModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6269,7 +6271,7 @@ var spine;
|
||||||
return spine.SpacingMode.Fixed;
|
return spine.SpacingMode.Fixed;
|
||||||
if (str == "percent")
|
if (str == "percent")
|
||||||
return spine.SpacingMode.Percent;
|
return spine.SpacingMode.Percent;
|
||||||
throw new Error("Unknown position mode: " + str);
|
throw new Error("Unknown position mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.rotateModeFromString = function (str) {
|
SkeletonJson.rotateModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6279,7 +6281,7 @@ var spine;
|
||||||
return spine.RotateMode.Chain;
|
return spine.RotateMode.Chain;
|
||||||
if (str == "chainscale")
|
if (str == "chainscale")
|
||||||
return spine.RotateMode.ChainScale;
|
return spine.RotateMode.ChainScale;
|
||||||
throw new Error("Unknown rotate mode: " + str);
|
throw new Error("Unknown rotate mode: ".concat(str));
|
||||||
};
|
};
|
||||||
SkeletonJson.transformModeFromString = function (str) {
|
SkeletonJson.transformModeFromString = function (str) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
|
@ -6293,7 +6295,7 @@ var spine;
|
||||||
return spine.TransformMode.NoScale;
|
return spine.TransformMode.NoScale;
|
||||||
if (str == "noscaleorreflection")
|
if (str == "noscaleorreflection")
|
||||||
return spine.TransformMode.NoScaleOrReflection;
|
return spine.TransformMode.NoScaleOrReflection;
|
||||||
throw new Error("Unknown transform mode: " + str);
|
throw new Error("Unknown transform mode: ".concat(str));
|
||||||
};
|
};
|
||||||
return SkeletonJson;
|
return SkeletonJson;
|
||||||
}());
|
}());
|
||||||
|
@ -6558,7 +6560,7 @@ var spine;
|
||||||
case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
|
case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
|
||||||
case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
|
case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
|
||||||
case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
|
case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
|
||||||
default: throw new Error("Unknown texture filter " + text);
|
default: throw new Error("Unknown texture filter ".concat(text));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Texture.wrapFromString = function (text) {
|
Texture.wrapFromString = function (text) {
|
||||||
|
@ -6566,7 +6568,7 @@ var spine;
|
||||||
case "mirroredtepeat": return TextureWrap.MirroredRepeat;
|
case "mirroredtepeat": return TextureWrap.MirroredRepeat;
|
||||||
case "clamptoedge": return TextureWrap.ClampToEdge;
|
case "clamptoedge": return TextureWrap.ClampToEdge;
|
||||||
case "repeat": return TextureWrap.Repeat;
|
case "repeat": return TextureWrap.Repeat;
|
||||||
default: throw new Error("Unknown texture wrap " + text);
|
default: throw new Error("Unknown texture wrap ".concat(text));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Texture;
|
return Texture;
|
||||||
|
@ -9528,14 +9530,14 @@ var spine;
|
||||||
var gl = this.context.gl;
|
var gl = this.context.gl;
|
||||||
var location = gl.getUniformLocation(this.program, uniform);
|
var location = gl.getUniformLocation(this.program, uniform);
|
||||||
if (!location && !gl.isContextLost())
|
if (!location && !gl.isContextLost())
|
||||||
throw new Error("Couldn't find location for uniform " + uniform);
|
throw new Error("Couldn't find location for uniform ".concat(uniform));
|
||||||
return location;
|
return location;
|
||||||
};
|
};
|
||||||
Shader.prototype.getAttributeLocation = function (attribute) {
|
Shader.prototype.getAttributeLocation = function (attribute) {
|
||||||
var gl = this.context.gl;
|
var gl = this.context.gl;
|
||||||
var location = gl.getAttribLocation(this.program, attribute);
|
var location = gl.getAttribLocation(this.program, attribute);
|
||||||
if (location == -1 && !gl.isContextLost())
|
if (location == -1 && !gl.isContextLost())
|
||||||
throw new Error("Couldn't find location for attribute " + attribute);
|
throw new Error("Couldn't find location for attribute ".concat(attribute));
|
||||||
return location;
|
return location;
|
||||||
};
|
};
|
||||||
Shader.prototype.dispose = function () {
|
Shader.prototype.dispose = function () {
|
||||||
|
@ -9555,17 +9557,17 @@ var spine;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Shader.newColoredTextured = function (context) {
|
Shader.newColoredTextured = function (context) {
|
||||||
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tattribute vec2 ").concat(Shader.TEXCOORDS, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = ").concat(Shader.COLOR, ";\n\t\t\t\t\tv_texCoords = ").concat(Shader.TEXCOORDS, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
|
||||||
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n\t\t\t\t}\n\t\t\t";
|
||||||
return new Shader(context, vs, fs);
|
return new Shader(context, vs, fs);
|
||||||
};
|
};
|
||||||
Shader.newTwoColoredTextured = function (context) {
|
Shader.newTwoColoredTextured = function (context) {
|
||||||
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR2 + ";\n\t\t\t\tattribute vec2 " + Shader.TEXCOORDS + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = " + Shader.COLOR + ";\n\t\t\t\t\tv_dark = " + Shader.COLOR2 + ";\n\t\t\t\t\tv_texCoords = " + Shader.TEXCOORDS + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR2, ";\n\t\t\t\tattribute vec2 ").concat(Shader.TEXCOORDS, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_light;\n\t\t\t\tvarying vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_light = ").concat(Shader.COLOR, ";\n\t\t\t\t\tv_dark = ").concat(Shader.COLOR2, ";\n\t\t\t\t\tv_texCoords = ").concat(Shader.TEXCOORDS, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
|
||||||
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tgl_FragColor.a = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_light;\n\t\t\t\tvarying LOWP vec4 v_dark;\n\t\t\t\tvarying vec2 v_texCoords;\n\t\t\t\tuniform sampler2D u_texture;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tvec4 texColor = texture2D(u_texture, v_texCoords);\n\t\t\t\t\tgl_FragColor.a = texColor.a * v_light.a;\n\t\t\t\t\tgl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n\t\t\t\t}\n\t\t\t";
|
||||||
return new Shader(context, vs, fs);
|
return new Shader(context, vs, fs);
|
||||||
};
|
};
|
||||||
Shader.newColored = function (context) {
|
Shader.newColored = function (context) {
|
||||||
var vs = "\n\t\t\t\tattribute vec4 " + Shader.POSITION + ";\n\t\t\t\tattribute vec4 " + Shader.COLOR + ";\n\t\t\t\tuniform mat4 " + Shader.MVP_MATRIX + ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = " + Shader.COLOR + ";\n\t\t\t\t\tgl_Position = " + Shader.MVP_MATRIX + " * " + Shader.POSITION + ";\n\t\t\t\t}\n\t\t\t";
|
var vs = "\n\t\t\t\tattribute vec4 ".concat(Shader.POSITION, ";\n\t\t\t\tattribute vec4 ").concat(Shader.COLOR, ";\n\t\t\t\tuniform mat4 ").concat(Shader.MVP_MATRIX, ";\n\t\t\t\tvarying vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tv_color = ").concat(Shader.COLOR, ";\n\t\t\t\t\tgl_Position = ").concat(Shader.MVP_MATRIX, " * ").concat(Shader.POSITION, ";\n\t\t\t\t}\n\t\t\t");
|
||||||
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
|
var fs = "\n\t\t\t\t#ifdef GL_ES\n\t\t\t\t\t#define LOWP lowp\n\t\t\t\t\tprecision mediump float;\n\t\t\t\t#else\n\t\t\t\t\t#define LOWP\n\t\t\t\t#endif\n\t\t\t\tvarying LOWP vec4 v_color;\n\n\t\t\t\tvoid main () {\n\t\t\t\t\tgl_FragColor = v_color;\n\t\t\t\t}\n\t\t\t";
|
||||||
return new Shader(context, vs, fs);
|
return new Shader(context, vs, fs);
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||||
|
|
||||||
|
@ -53,18 +53,19 @@ module.exports = {
|
||||||
|
|
||||||
optimization: {
|
optimization: {
|
||||||
minimizer: [
|
minimizer: [
|
||||||
new UglifyJSPlugin({
|
new TerserPlugin({
|
||||||
include: /\.min\.js$/,
|
include: /\.min\.js$/,
|
||||||
parallel: true,
|
parallel: true,
|
||||||
sourceMap: false,
|
extractComments: false,
|
||||||
uglifyOptions: {
|
terserOptions: {
|
||||||
|
format: {
|
||||||
|
comments: false
|
||||||
|
},
|
||||||
compress: true,
|
compress: true,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
ecma: 5,
|
ecma: 5,
|
||||||
output: {comments: false},
|
|
||||||
warnings: false
|
warnings: false
|
||||||
},
|
}
|
||||||
warningsFilter: () => false
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||||
|
|
||||||
|
@ -53,18 +53,19 @@ module.exports = {
|
||||||
|
|
||||||
optimization: {
|
optimization: {
|
||||||
minimizer: [
|
minimizer: [
|
||||||
new UglifyJSPlugin({
|
new TerserPlugin({
|
||||||
include: /\.min\.js$/,
|
include: /\.min\.js$/,
|
||||||
parallel: true,
|
parallel: true,
|
||||||
sourceMap: false,
|
extractComments: false,
|
||||||
uglifyOptions: {
|
terserOptions: {
|
||||||
|
format: {
|
||||||
|
comments: false
|
||||||
|
},
|
||||||
compress: true,
|
compress: true,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
ecma: 5,
|
ecma: 5,
|
||||||
output: {comments: false},
|
|
||||||
warnings: false
|
warnings: false
|
||||||
},
|
}
|
||||||
warningsFilter: () => false
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||||
|
|
||||||
|
@ -53,18 +53,19 @@ module.exports = {
|
||||||
|
|
||||||
optimization: {
|
optimization: {
|
||||||
minimizer: [
|
minimizer: [
|
||||||
new UglifyJSPlugin({
|
new TerserPlugin({
|
||||||
include: /\.min\.js$/,
|
include: /\.min\.js$/,
|
||||||
parallel: true,
|
parallel: true,
|
||||||
sourceMap: false,
|
extractComments: false,
|
||||||
uglifyOptions: {
|
terserOptions: {
|
||||||
|
format: {
|
||||||
|
comments: false
|
||||||
|
},
|
||||||
compress: true,
|
compress: true,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
ecma: 5,
|
ecma: 5,
|
||||||
output: {comments: false},
|
|
||||||
warnings: false
|
warnings: false
|
||||||
},
|
}
|
||||||
warningsFilter: () => false
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -603,6 +603,7 @@ var AnimationManager = new Class({
|
||||||
* Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}.
|
* Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}.
|
||||||
*
|
*
|
||||||
* It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases.
|
* It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases.
|
||||||
|
*
|
||||||
* If you're working with a sprite sheet, see the `generateFrameNumbers` method instead.
|
* If you're working with a sprite sheet, see the `generateFrameNumbers` method instead.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
|
@ -697,7 +698,6 @@ var AnimationManager = new Class({
|
||||||
* If you're working with a texture atlas, see the `generateFrameNames` method instead.
|
* If you're working with a texture atlas, see the `generateFrameNames` method instead.
|
||||||
*
|
*
|
||||||
* It's a helper method, designed to make it easier for you to extract frames from sprite sheets.
|
* It's a helper method, designed to make it easier for you to extract frames from sprite sheets.
|
||||||
* If you're working with a texture atlas, see the `generateFrameNames` method instead.
|
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
|
|
|
@ -472,7 +472,7 @@ var AnimationState = new Class({
|
||||||
* @method Phaser.Animations.AnimationState#chain
|
* @method Phaser.Animations.AnimationState#chain
|
||||||
* @since 3.16.0
|
* @since 3.16.0
|
||||||
*
|
*
|
||||||
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them.
|
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} [key] - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them.
|
||||||
*
|
*
|
||||||
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
|
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -46,97 +46,79 @@ var Config = new Class({
|
||||||
|
|
||||||
var defaultBannerTextColor = '#ffffff';
|
var defaultBannerTextColor = '#ffffff';
|
||||||
|
|
||||||
|
// Scale Manager - Anything set in here over-rides anything set in the core game config
|
||||||
|
|
||||||
|
var scaleConfig = GetValue(config, 'scale', null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {(number|string)} Phaser.Core.Config#width - The width of the underlying canvas, in pixels.
|
* @const {(number|string)} Phaser.Core.Config#width - The width of the underlying canvas, in pixels.
|
||||||
*/
|
*/
|
||||||
this.width = GetValue(config, 'width', 1024);
|
this.width = GetValue(scaleConfig, 'width', 1024, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {(number|string)} Phaser.Core.Config#height - The height of the underlying canvas, in pixels.
|
* @const {(number|string)} Phaser.Core.Config#height - The height of the underlying canvas, in pixels.
|
||||||
*/
|
*/
|
||||||
this.height = GetValue(config, 'height', 768);
|
this.height = GetValue(scaleConfig, 'height', 768, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {(Phaser.Scale.ZoomType|number)} Phaser.Core.Config#zoom - The zoom factor, as used by the Scale Manager.
|
* @const {(Phaser.Scale.ZoomType|number)} Phaser.Core.Config#zoom - The zoom factor, as used by the Scale Manager.
|
||||||
*/
|
*/
|
||||||
this.zoom = GetValue(config, 'zoom', 1);
|
this.zoom = GetValue(scaleConfig, 'zoom', 1, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {?*} Phaser.Core.Config#parent - A parent DOM element into which the canvas created by the renderer will be injected.
|
* @const {?*} Phaser.Core.Config#parent - A parent DOM element into which the canvas created by the renderer will be injected.
|
||||||
*/
|
*/
|
||||||
this.parent = GetValue(config, 'parent', undefined);
|
this.parent = GetValue(scaleConfig, 'parent', undefined, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {Phaser.Scale.ScaleModeType} Phaser.Core.Config#scaleMode - The scale mode as used by the Scale Manager. The default is zero, which is no scaling.
|
* @const {Phaser.Scale.ScaleModeType} Phaser.Core.Config#scaleMode - The scale mode as used by the Scale Manager. The default is zero, which is no scaling.
|
||||||
*/
|
*/
|
||||||
this.scaleMode = GetValue(config, 'scaleMode', 0);
|
this.scaleMode = GetValue(scaleConfig, 'scaleMode', 0, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#expandParent - Is the Scale Manager allowed to adjust the CSS height property of the parent to be 100%?
|
* @const {boolean} Phaser.Core.Config#expandParent - Is the Scale Manager allowed to adjust the CSS height property of the parent to be 100%?
|
||||||
*/
|
*/
|
||||||
this.expandParent = GetValue(config, 'expandParent', true);
|
this.expandParent = GetValue(scaleConfig, 'expandParent', true, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#autoRound - Automatically round the display and style sizes of the canvas. This can help with performance in lower-powered devices.
|
* @const {boolean} Phaser.Core.Config#autoRound - Automatically round the display and style sizes of the canvas. This can help with performance in lower-powered devices.
|
||||||
*/
|
*/
|
||||||
this.autoRound = GetValue(config, 'autoRound', false);
|
this.autoRound = GetValue(scaleConfig, 'autoRound', false, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {Phaser.Scale.CenterType} Phaser.Core.Config#autoCenter - Automatically center the canvas within the parent?
|
* @const {Phaser.Scale.CenterType} Phaser.Core.Config#autoCenter - Automatically center the canvas within the parent?
|
||||||
*/
|
*/
|
||||||
this.autoCenter = GetValue(config, 'autoCenter', 0);
|
this.autoCenter = GetValue(scaleConfig, 'autoCenter', 0, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#resizeInterval - How many ms should elapse before checking if the browser size has changed?
|
* @const {number} Phaser.Core.Config#resizeInterval - How many ms should elapse before checking if the browser size has changed?
|
||||||
*/
|
*/
|
||||||
this.resizeInterval = GetValue(config, 'resizeInterval', 500);
|
this.resizeInterval = GetValue(scaleConfig, 'resizeInterval', 500, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {?(HTMLElement|string)} Phaser.Core.Config#fullscreenTarget - The DOM element that will be sent into full screen mode, or its `id`. If undefined Phaser will create its own div and insert the canvas into it when entering fullscreen mode.
|
* @const {?(HTMLElement|string)} Phaser.Core.Config#fullscreenTarget - The DOM element that will be sent into full screen mode, or its `id`. If undefined Phaser will create its own div and insert the canvas into it when entering fullscreen mode.
|
||||||
*/
|
*/
|
||||||
this.fullscreenTarget = GetValue(config, 'fullscreenTarget', null);
|
this.fullscreenTarget = GetValue(scaleConfig, 'fullscreenTarget', null, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#minWidth - The minimum width, in pixels, the canvas will scale down to. A value of zero means no minimum.
|
* @const {number} Phaser.Core.Config#minWidth - The minimum width, in pixels, the canvas will scale down to. A value of zero means no minimum.
|
||||||
*/
|
*/
|
||||||
this.minWidth = GetValue(config, 'minWidth', 0);
|
this.minWidth = GetValue(scaleConfig, 'minWidth', 0, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#maxWidth - The maximum width, in pixels, the canvas will scale up to. A value of zero means no maximum.
|
* @const {number} Phaser.Core.Config#maxWidth - The maximum width, in pixels, the canvas will scale up to. A value of zero means no maximum.
|
||||||
*/
|
*/
|
||||||
this.maxWidth = GetValue(config, 'maxWidth', 0);
|
this.maxWidth = GetValue(scaleConfig, 'maxWidth', 0, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#minHeight - The minimum height, in pixels, the canvas will scale down to. A value of zero means no minimum.
|
* @const {number} Phaser.Core.Config#minHeight - The minimum height, in pixels, the canvas will scale down to. A value of zero means no minimum.
|
||||||
*/
|
*/
|
||||||
this.minHeight = GetValue(config, 'minHeight', 0);
|
this.minHeight = GetValue(scaleConfig, 'minHeight', 0, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#maxHeight - The maximum height, in pixels, the canvas will scale up to. A value of zero means no maximum.
|
* @const {number} Phaser.Core.Config#maxHeight - The maximum height, in pixels, the canvas will scale up to. A value of zero means no maximum.
|
||||||
*/
|
*/
|
||||||
this.maxHeight = GetValue(config, 'maxHeight', 0);
|
this.maxHeight = GetValue(scaleConfig, 'maxHeight', 0, config);
|
||||||
|
|
||||||
// Scale Manager - Anything set in here over-rides anything set above
|
|
||||||
|
|
||||||
var scaleConfig = GetValue(config, 'scale', null);
|
|
||||||
|
|
||||||
if (scaleConfig)
|
|
||||||
{
|
|
||||||
this.width = GetValue(scaleConfig, 'width', this.width);
|
|
||||||
this.height = GetValue(scaleConfig, 'height', this.height);
|
|
||||||
this.zoom = GetValue(scaleConfig, 'zoom', this.zoom);
|
|
||||||
this.parent = GetValue(scaleConfig, 'parent', this.parent);
|
|
||||||
this.scaleMode = GetValue(scaleConfig, 'mode', this.scaleMode);
|
|
||||||
this.expandParent = GetValue(scaleConfig, 'expandParent', this.expandParent);
|
|
||||||
this.autoRound = GetValue(scaleConfig, 'autoRound', this.autoRound);
|
|
||||||
this.autoCenter = GetValue(scaleConfig, 'autoCenter', this.autoCenter);
|
|
||||||
this.resizeInterval = GetValue(scaleConfig, 'resizeInterval', this.resizeInterval);
|
|
||||||
this.fullscreenTarget = GetValue(scaleConfig, 'fullscreenTarget', this.fullscreenTarget);
|
|
||||||
this.minWidth = GetValue(scaleConfig, 'min.width', this.minWidth);
|
|
||||||
this.maxWidth = GetValue(scaleConfig, 'max.width', this.maxWidth);
|
|
||||||
this.minHeight = GetValue(scaleConfig, 'min.height', this.minHeight);
|
|
||||||
this.maxHeight = GetValue(scaleConfig, 'max.height', this.maxHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#renderType - Force Phaser to use a specific renderer. Can be `CONST.CANVAS`, `CONST.WEBGL`, `CONST.HEADLESS` or `CONST.AUTO` (default)
|
* @const {number} Phaser.Core.Config#renderType - Force Phaser to use a specific renderer. Can be `CONST.CANVAS`, `CONST.WEBGL`, `CONST.HEADLESS` or `CONST.AUTO` (default)
|
||||||
|
@ -336,45 +318,44 @@ var Config = new Class({
|
||||||
*/
|
*/
|
||||||
this.fps = GetValue(config, 'fps', null);
|
this.fps = GetValue(config, 'fps', null);
|
||||||
|
|
||||||
// Renderer Settings
|
// Render Settings - Anything set in here over-rides anything set in the core game config
|
||||||
// These can either be in a `render` object within the Config, or specified on their own
|
|
||||||
|
|
||||||
var renderConfig = GetValue(config, 'render', config);
|
var renderConfig = GetValue(config, 'render', null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {Phaser.Types.Core.PipelineConfig} Phaser.Core.Config#pipeline - An object mapping WebGL names to WebGLPipeline classes. These should be class constructors, not instances.
|
* @const {Phaser.Types.Core.PipelineConfig} Phaser.Core.Config#pipeline - An object mapping WebGL names to WebGLPipeline classes. These should be class constructors, not instances.
|
||||||
*/
|
*/
|
||||||
this.pipeline = GetValue(renderConfig, 'pipeline', null);
|
this.pipeline = GetValue(renderConfig, 'pipeline', null, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#antialias - When set to `true`, WebGL uses linear interpolation to draw scaled or rotated textures, giving a smooth appearance. When set to `false`, WebGL uses nearest-neighbor interpolation, giving a crisper appearance. `false` also disables antialiasing of the game canvas itself, if the browser supports it, when the game canvas is scaled.
|
* @const {boolean} Phaser.Core.Config#antialias - When set to `true`, WebGL uses linear interpolation to draw scaled or rotated textures, giving a smooth appearance. When set to `false`, WebGL uses nearest-neighbor interpolation, giving a crisper appearance. `false` also disables antialiasing of the game canvas itself, if the browser supports it, when the game canvas is scaled.
|
||||||
*/
|
*/
|
||||||
this.antialias = GetValue(renderConfig, 'antialias', true);
|
this.antialias = GetValue(renderConfig, 'antialias', true, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#antialiasGL - Sets the `antialias` property when the WebGL context is created. Setting this value does not impact any subsequent textures that are created, or the canvas style attributes.
|
* @const {boolean} Phaser.Core.Config#antialiasGL - Sets the `antialias` property when the WebGL context is created. Setting this value does not impact any subsequent textures that are created, or the canvas style attributes.
|
||||||
*/
|
*/
|
||||||
this.antialiasGL = GetValue(renderConfig, 'antialiasGL', true);
|
this.antialiasGL = GetValue(renderConfig, 'antialiasGL', true, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {string} Phaser.Core.Config#mipmapFilter - Sets the `mipmapFilter` property when the WebGL renderer is created.
|
* @const {string} Phaser.Core.Config#mipmapFilter - Sets the `mipmapFilter` property when the WebGL renderer is created.
|
||||||
*/
|
*/
|
||||||
this.mipmapFilter = GetValue(renderConfig, 'mipmapFilter', 'LINEAR');
|
this.mipmapFilter = GetValue(renderConfig, 'mipmapFilter', 'LINEAR', config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#desynchronized - When set to `true` it will create a desynchronized context for both 2D and WebGL. See https://developers.google.com/web/updates/2019/05/desynchronized for details.
|
* @const {boolean} Phaser.Core.Config#desynchronized - When set to `true` it will create a desynchronized context for both 2D and WebGL. See https://developers.google.com/web/updates/2019/05/desynchronized for details.
|
||||||
*/
|
*/
|
||||||
this.desynchronized = GetValue(renderConfig, 'desynchronized', false);
|
this.desynchronized = GetValue(renderConfig, 'desynchronized', false, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#roundPixels - Draw texture-based Game Objects at only whole-integer positions. Game Objects without textures, like Graphics, ignore this property.
|
* @const {boolean} Phaser.Core.Config#roundPixels - Draw texture-based Game Objects at only whole-integer positions. Game Objects without textures, like Graphics, ignore this property.
|
||||||
*/
|
*/
|
||||||
this.roundPixels = GetValue(renderConfig, 'roundPixels', false);
|
this.roundPixels = GetValue(renderConfig, 'roundPixels', false, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#pixelArt - Prevent pixel art from becoming blurred when scaled. It will remain crisp (tells the WebGL renderer to automatically create textures using a linear filter mode).
|
* @const {boolean} Phaser.Core.Config#pixelArt - Prevent pixel art from becoming blurred when scaled. It will remain crisp (tells the WebGL renderer to automatically create textures using a linear filter mode).
|
||||||
*/
|
*/
|
||||||
this.pixelArt = GetValue(renderConfig, 'pixelArt', this.zoom !== 1);
|
this.pixelArt = GetValue(renderConfig, 'pixelArt', this.zoom !== 1, config);
|
||||||
|
|
||||||
if (this.pixelArt)
|
if (this.pixelArt)
|
||||||
{
|
{
|
||||||
|
@ -386,47 +367,47 @@ var Config = new Class({
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#transparent - Whether the game canvas will have a transparent background.
|
* @const {boolean} Phaser.Core.Config#transparent - Whether the game canvas will have a transparent background.
|
||||||
*/
|
*/
|
||||||
this.transparent = GetValue(renderConfig, 'transparent', false);
|
this.transparent = GetValue(renderConfig, 'transparent', false, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#clearBeforeRender - Whether the game canvas will be cleared between each rendering frame. You can disable this if you have a full-screen background image or game object.
|
* @const {boolean} Phaser.Core.Config#clearBeforeRender - Whether the game canvas will be cleared between each rendering frame. You can disable this if you have a full-screen background image or game object.
|
||||||
*/
|
*/
|
||||||
this.clearBeforeRender = GetValue(renderConfig, 'clearBeforeRender', true);
|
this.clearBeforeRender = GetValue(renderConfig, 'clearBeforeRender', true, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#preserveDrawingBuffer - If the value is true the WebGL buffers will not be cleared and will preserve their values until cleared or overwritten by the author.
|
* @const {boolean} Phaser.Core.Config#preserveDrawingBuffer - If the value is true the WebGL buffers will not be cleared and will preserve their values until cleared or overwritten by the author.
|
||||||
*/
|
*/
|
||||||
this.preserveDrawingBuffer = GetValue(renderConfig, 'preserveDrawingBuffer', false);
|
this.preserveDrawingBuffer = GetValue(renderConfig, 'preserveDrawingBuffer', false, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#premultipliedAlpha - In WebGL mode, sets the drawing buffer to contain colors with pre-multiplied alpha.
|
* @const {boolean} Phaser.Core.Config#premultipliedAlpha - In WebGL mode, sets the drawing buffer to contain colors with pre-multiplied alpha.
|
||||||
*/
|
*/
|
||||||
this.premultipliedAlpha = GetValue(renderConfig, 'premultipliedAlpha', true);
|
this.premultipliedAlpha = GetValue(renderConfig, 'premultipliedAlpha', true, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {boolean} Phaser.Core.Config#failIfMajorPerformanceCaveat - Let the browser abort creating a WebGL context if it judges performance would be unacceptable.
|
* @const {boolean} Phaser.Core.Config#failIfMajorPerformanceCaveat - Let the browser abort creating a WebGL context if it judges performance would be unacceptable.
|
||||||
*/
|
*/
|
||||||
this.failIfMajorPerformanceCaveat = GetValue(renderConfig, 'failIfMajorPerformanceCaveat', false);
|
this.failIfMajorPerformanceCaveat = GetValue(renderConfig, 'failIfMajorPerformanceCaveat', false, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {string} Phaser.Core.Config#powerPreference - "high-performance", "low-power" or "default". A hint to the browser on how much device power the game might use.
|
* @const {string} Phaser.Core.Config#powerPreference - "high-performance", "low-power" or "default". A hint to the browser on how much device power the game might use.
|
||||||
*/
|
*/
|
||||||
this.powerPreference = GetValue(renderConfig, 'powerPreference', 'default');
|
this.powerPreference = GetValue(renderConfig, 'powerPreference', 'default', config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#batchSize - The default WebGL Batch size. Represents the number of _quads_ that can be added to a single batch.
|
* @const {number} Phaser.Core.Config#batchSize - The default WebGL Batch size. Represents the number of _quads_ that can be added to a single batch.
|
||||||
*/
|
*/
|
||||||
this.batchSize = GetValue(renderConfig, 'batchSize', 4096);
|
this.batchSize = GetValue(renderConfig, 'batchSize', 4096, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#maxTextures - When in WebGL mode, this sets the maximum number of GPU Textures to use. The default, -1, will use all available units. The WebGL1 spec says all browsers should provide a minimum of 8.
|
* @const {number} Phaser.Core.Config#maxTextures - When in WebGL mode, this sets the maximum number of GPU Textures to use. The default, -1, will use all available units. The WebGL1 spec says all browsers should provide a minimum of 8.
|
||||||
*/
|
*/
|
||||||
this.maxTextures = GetValue(renderConfig, 'maxTextures', -1);
|
this.maxTextures = GetValue(renderConfig, 'maxTextures', -1, config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const {number} Phaser.Core.Config#maxLights - The maximum number of lights allowed to be visible within range of a single Camera in the LightManager.
|
* @const {number} Phaser.Core.Config#maxLights - The maximum number of lights allowed to be visible within range of a single Camera in the LightManager.
|
||||||
*/
|
*/
|
||||||
this.maxLights = GetValue(renderConfig, 'maxLights', 10);
|
this.maxLights = GetValue(renderConfig, 'maxLights', 10, config);
|
||||||
|
|
||||||
var bgc = GetValue(config, 'backgroundColor', 0);
|
var bgc = GetValue(config, 'backgroundColor', 0);
|
||||||
|
|
||||||
|
|
|
@ -651,7 +651,7 @@ var TimeStep = new Class({
|
||||||
this.startTime += -this.lastTime + (this.lastTime + window.performance.now());
|
this.startTime += -this.lastTime + (this.lastTime + window.performance.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.raf.start(this.step.bind(this), this.useRAF);
|
this.raf.start(this.step.bind(this), this.forceSetTimeOut, this._target);
|
||||||
|
|
||||||
this.running = true;
|
this.running = true;
|
||||||
|
|
||||||
|
|
|
@ -85,17 +85,20 @@ var BlitterCanvasRenderer = function (renderer, src, camera, parentMatrix)
|
||||||
dy = Math.round(dy);
|
dy = Math.round(dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.drawImage(
|
if (cd.width > 0 && cd.height > 0)
|
||||||
frame.source.image,
|
{
|
||||||
cd.x,
|
ctx.drawImage(
|
||||||
cd.y,
|
frame.source.image,
|
||||||
cd.width,
|
cd.x,
|
||||||
cd.height,
|
cd.y,
|
||||||
dx + bob.x + cameraScrollX,
|
cd.width,
|
||||||
dy + bob.y + cameraScrollY,
|
cd.height,
|
||||||
cd.width,
|
dx + bob.x + cameraScrollX,
|
||||||
cd.height
|
dy + bob.y + cameraScrollY,
|
||||||
);
|
cd.width,
|
||||||
|
cd.height
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -111,11 +114,14 @@ var BlitterCanvasRenderer = function (renderer, src, camera, parentMatrix)
|
||||||
dy -= cd.height;
|
dy -= cd.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.save();
|
if (cd.width > 0 && cd.height > 0)
|
||||||
ctx.translate(bob.x + cameraScrollX, bob.y + cameraScrollY);
|
{
|
||||||
ctx.scale(fx, fy);
|
ctx.save();
|
||||||
ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, dx, dy, cd.width, cd.height);
|
ctx.translate(bob.x + cameraScrollX, bob.y + cameraScrollY);
|
||||||
ctx.restore();
|
ctx.scale(fx, fy);
|
||||||
|
ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, dx, dy, cd.width, cd.height);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -498,7 +498,8 @@ var Container = new Class({
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output = new Vector2(source.x, source.y);
|
output.x = source.x;
|
||||||
|
output.y = source.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempMatrix = this.tempTransformMatrix;
|
var tempMatrix = this.tempTransformMatrix;
|
||||||
|
|
|
@ -1064,8 +1064,74 @@ var Mesh = new Class({
|
||||||
|
|
||||||
this.debugCallback = null;
|
this.debugCallback = null;
|
||||||
this.debugGraphic = null;
|
this.debugGraphic = null;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all tint values associated with this Game Object.
|
||||||
|
*
|
||||||
|
* Immediately sets the color values back to 0xffffff on all vertices,
|
||||||
|
* which results in no visible change to the texture.
|
||||||
|
*
|
||||||
|
* @method Phaser.GameObjects.Mesh#clearTint
|
||||||
|
* @webglOnly
|
||||||
|
* @since 3.60.0
|
||||||
|
*
|
||||||
|
* @return {this} This Game Object instance.
|
||||||
|
*/
|
||||||
|
clearTint: function ()
|
||||||
|
{
|
||||||
|
return this.setTint();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an additive tint on all vertices of this Mesh Game Object.
|
||||||
|
*
|
||||||
|
* The tint works by taking the pixel color values from the Game Objects texture, and then
|
||||||
|
* multiplying it by the color value of the tint.
|
||||||
|
*
|
||||||
|
* To modify the tint color once set, either call this method again with new values or use the
|
||||||
|
* `tint` property to set all colors at once.
|
||||||
|
*
|
||||||
|
* To remove a tint call `clearTint`.
|
||||||
|
*
|
||||||
|
* @method Phaser.GameObjects.Mesh#setTint
|
||||||
|
* @webglOnly
|
||||||
|
* @since 3.60.0
|
||||||
|
*
|
||||||
|
* @param {number} [tint=0xffffff] - The tint being applied to all vertices of this Mesh Game Object.
|
||||||
|
*
|
||||||
|
* @return {this} This Game Object instance.
|
||||||
|
*/
|
||||||
|
setTint: function (tint)
|
||||||
|
{
|
||||||
|
if (tint === undefined) { tint = 0xffffff; }
|
||||||
|
|
||||||
|
var vertices = this.vertices;
|
||||||
|
|
||||||
|
for (var i = 0; i < vertices.length; i++)
|
||||||
|
{
|
||||||
|
vertices[i].color = tint;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tint value being applied to the whole of the Game Object.
|
||||||
|
* This property is a setter-only.
|
||||||
|
*
|
||||||
|
* @method Phaser.GameObjects.Mesh#tint
|
||||||
|
* @type {number}
|
||||||
|
* @webglOnly
|
||||||
|
* @since 3.60.0
|
||||||
|
*/
|
||||||
|
tint: {
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this.setTint(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = Mesh;
|
module.exports = Mesh;
|
||||||
|
|
|
@ -103,26 +103,29 @@ var ParticleManagerCanvasRenderer = function (renderer, emitterManager, camera,
|
||||||
var frame = particle.frame;
|
var frame = particle.frame;
|
||||||
var cd = frame.canvasData;
|
var cd = frame.canvasData;
|
||||||
|
|
||||||
var x = -(frame.halfWidth);
|
if (cd.width > 0 && cd.height > 0)
|
||||||
var y = -(frame.halfHeight);
|
|
||||||
|
|
||||||
ctx.globalAlpha = alpha;
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
|
|
||||||
calcMatrix.setToContext(ctx);
|
|
||||||
|
|
||||||
if (roundPixels)
|
|
||||||
{
|
{
|
||||||
x = Math.round(x);
|
var x = -(frame.halfWidth);
|
||||||
y = Math.round(y);
|
var y = -(frame.halfHeight);
|
||||||
|
|
||||||
|
ctx.globalAlpha = alpha;
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
|
||||||
|
calcMatrix.setToContext(ctx);
|
||||||
|
|
||||||
|
if (roundPixels)
|
||||||
|
{
|
||||||
|
x = Math.round(x);
|
||||||
|
y = Math.round(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.imageSmoothingEnabled = !(!renderer.antialias || frame.source.scaleMode);
|
||||||
|
|
||||||
|
ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height);
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.imageSmoothingEnabled = !(!renderer.antialias || frame.source.scaleMode);
|
|
||||||
|
|
||||||
ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height);
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
|
|
|
@ -664,7 +664,10 @@ var RenderTexture = new Class({
|
||||||
* * A Texture Frame instance.
|
* * A Texture Frame instance.
|
||||||
* * A string. This is used to look-up a texture from the Texture Manager.
|
* * A string. This is used to look-up a texture from the Texture Manager.
|
||||||
*
|
*
|
||||||
* Note: You cannot draw a Render Texture to itself.
|
* Note 1: You cannot draw a Render Texture to itself.
|
||||||
|
*
|
||||||
|
* Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be
|
||||||
|
* used when drawn to this Render Texture.
|
||||||
*
|
*
|
||||||
* If passing in a Group or Container it will only draw children that return `true`
|
* If passing in a Group or Container it will only draw children that return `true`
|
||||||
* when their `willRender()` method is called. I.e. a Container with 10 children,
|
* when their `willRender()` method is called. I.e. a Container with 10 children,
|
||||||
|
@ -1279,7 +1282,10 @@ var RenderTexture = new Class({
|
||||||
|
|
||||||
matrix.setToContext(ctx);
|
matrix.setToContext(ctx);
|
||||||
|
|
||||||
ctx.drawImage(source, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height);
|
if (cd.width > 0 && cd.height > 0)
|
||||||
|
{
|
||||||
|
ctx.drawImage(source, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height);
|
||||||
|
}
|
||||||
|
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,10 @@ var PolygonCanvasRenderer = function (renderer, src, camera, parentMatrix)
|
||||||
ctx.lineTo(px2, py2);
|
ctx.lineTo(px2, py2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.closePath();
|
if (src.closePath)
|
||||||
|
{
|
||||||
|
ctx.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
if (src.isFilled)
|
if (src.isFilled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -346,7 +346,7 @@ var Sprite = new Class({
|
||||||
* @method Phaser.GameObjects.Sprite#chain
|
* @method Phaser.GameObjects.Sprite#chain
|
||||||
* @since 3.50.0
|
* @since 3.50.0
|
||||||
*
|
*
|
||||||
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them.
|
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} [key] - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them.
|
||||||
*
|
*
|
||||||
* @return {this} This Game Object.
|
* @return {this} This Game Object.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
* @property {number} [width=512] - The width of the Tile Sprite. If zero it will use the size of the texture frame.
|
* @property {number} [width=512] - The width of the Tile Sprite. If zero it will use the size of the texture frame.
|
||||||
* @property {number} [height=512] - The height of the Tile Sprite. If zero it will use the size of the texture frame.
|
* @property {number} [height=512] - The height of the Tile Sprite. If zero it will use the size of the texture frame.
|
||||||
* @property {string} [key=''] - The key of the Texture this Tile Sprite will use to render with, as stored in the Texture Manager.
|
* @property {string} [key=''] - The key of the Texture this Tile Sprite will use to render with, as stored in the Texture Manager.
|
||||||
* @property {string} [frame=''] - An optional frame from the Texture this Tile Sprite is rendering with.
|
* @property {(number|string|Phaser.Textures.Frame)} [frame=''] - An optional frame from the Texture this Tile Sprite is rendering with.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -158,13 +158,21 @@ var HTML5AudioFile = new Class({
|
||||||
var audio = new Audio();
|
var audio = new Audio();
|
||||||
var dataset = audio.dataset;
|
var dataset = audio.dataset;
|
||||||
|
|
||||||
|
if (dataset === undefined)
|
||||||
|
{
|
||||||
|
audio.dataset = dataset = {
|
||||||
|
name: '',
|
||||||
|
used: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
dataset.name = this.key + '-' + i.toString();
|
dataset.name = this.key + '-' + i.toString();
|
||||||
dataset.used = 'false';
|
dataset.used = 'false';
|
||||||
|
|
||||||
if (this.locked)
|
if (this.locked)
|
||||||
{
|
{
|
||||||
dataset.locked = 'true';
|
dataset.locked = 'true';
|
||||||
console.log('HTML5AudioFile:', dataset.name, 'locked');
|
// console.log('HTML5AudioFile:', dataset.name, 'locked');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -174,7 +182,7 @@ var HTML5AudioFile = new Class({
|
||||||
audio.oncanplaythrough = this.onProgress.bind(this);
|
audio.oncanplaythrough = this.onProgress.bind(this);
|
||||||
audio.onerror = this.onError.bind(this);
|
audio.onerror = this.onError.bind(this);
|
||||||
|
|
||||||
console.log('HTML5AudioFile:', dataset.name, 'unlocked');
|
// console.log('HTML5AudioFile:', dataset.name, 'unlocked');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.data.push(audio);
|
this.data.push(audio);
|
||||||
|
@ -189,7 +197,7 @@ var HTML5AudioFile = new Class({
|
||||||
if (!this.locked)
|
if (!this.locked)
|
||||||
{
|
{
|
||||||
audio.load();
|
audio.load();
|
||||||
console.log('HTML5AudioFile:', dataset.name, 'load called');
|
// console.log('HTML5AudioFile:', dataset.name, 'load called');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1346,14 +1346,12 @@ var World = new Class({
|
||||||
* @param {ArcadePhysicsCallback} [processCallback] - The process callback.
|
* @param {ArcadePhysicsCallback} [processCallback] - The process callback.
|
||||||
* @param {*} [callbackContext] - The context in which to invoke the callback.
|
* @param {*} [callbackContext] - The context in which to invoke the callback.
|
||||||
* @param {boolean} [overlapOnly] - If this a collide or overlap check?
|
* @param {boolean} [overlapOnly] - If this a collide or overlap check?
|
||||||
* @param {boolean} [intersects] - Assert that the bodies intersect and should not be tested before separation.
|
|
||||||
*
|
*
|
||||||
* @return {boolean} True if separation occurred, otherwise false.
|
* @return {boolean} True if separation occurred, otherwise false.
|
||||||
*/
|
*/
|
||||||
separate: function (body1, body2, processCallback, callbackContext, overlapOnly, intersects)
|
separate: function (body1, body2, processCallback, callbackContext, overlapOnly)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
!intersects &&
|
|
||||||
!body1.enable ||
|
!body1.enable ||
|
||||||
!body2.enable ||
|
!body2.enable ||
|
||||||
body1.checkCollision.none ||
|
body1.checkCollision.none ||
|
||||||
|
@ -2002,7 +2000,7 @@ var World = new Class({
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly, true))
|
if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly))
|
||||||
{
|
{
|
||||||
if (collideCallback)
|
if (collideCallback)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ var Body = require('./lib/body/Body');
|
||||||
var BodyBounds = require('./BodyBounds');
|
var BodyBounds = require('./BodyBounds');
|
||||||
var Bounds = require('./lib/geometry/Bounds');
|
var Bounds = require('./lib/geometry/Bounds');
|
||||||
var Class = require('../../utils/Class');
|
var Class = require('../../utils/Class');
|
||||||
|
var Collision = require('./lib/collision/Collision');
|
||||||
var Composite = require('./lib/body/Composite');
|
var Composite = require('./lib/body/Composite');
|
||||||
var Composites = require('./lib/factory/Composites');
|
var Composites = require('./lib/factory/Composites');
|
||||||
var Constraint = require('./lib/constraint/Constraint');
|
var Constraint = require('./lib/constraint/Constraint');
|
||||||
|
@ -41,10 +42,10 @@ var World = require('./World');
|
||||||
/**
|
/**
|
||||||
* @classdesc
|
* @classdesc
|
||||||
* The Phaser Matter plugin provides the ability to use the Matter JS Physics Engine within your Phaser games.
|
* The Phaser Matter plugin provides the ability to use the Matter JS Physics Engine within your Phaser games.
|
||||||
*
|
*
|
||||||
* Unlike Arcade Physics, the other physics system provided with Phaser, Matter JS is a full-body physics system.
|
* Unlike Arcade Physics, the other physics system provided with Phaser, Matter JS is a full-body physics system.
|
||||||
* It features:
|
* It features:
|
||||||
*
|
*
|
||||||
* * Rigid bodies
|
* * Rigid bodies
|
||||||
* * Compound bodies
|
* * Compound bodies
|
||||||
* * Composite bodies
|
* * Composite bodies
|
||||||
|
@ -62,10 +63,10 @@ var World = require('./World');
|
||||||
* * Views (translate, zoom)
|
* * Views (translate, zoom)
|
||||||
* * Collision queries (raycasting, region tests)
|
* * Collision queries (raycasting, region tests)
|
||||||
* * Time scaling (slow-mo, speed-up)
|
* * Time scaling (slow-mo, speed-up)
|
||||||
*
|
*
|
||||||
* Configuration of Matter is handled via the Matter World Config object, which can be passed in either the
|
* Configuration of Matter is handled via the Matter World Config object, which can be passed in either the
|
||||||
* Phaser Game Config, or Phaser Scene Config. Here is a basic example:
|
* Phaser Game Config, or Phaser Scene Config. Here is a basic example:
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* physics: {
|
* physics: {
|
||||||
* default: 'matter',
|
* default: 'matter',
|
||||||
|
@ -81,11 +82,11 @@ var World = require('./World');
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* This class acts as an interface between a Phaser Scene and a single instance of the Matter Engine.
|
* This class acts as an interface between a Phaser Scene and a single instance of the Matter Engine.
|
||||||
*
|
*
|
||||||
* Use it to access the most common Matter features and helper functions.
|
* Use it to access the most common Matter features and helper functions.
|
||||||
*
|
*
|
||||||
* You can find details, documentation and examples on the Matter JS website: https://brm.io/matter-js/
|
* You can find details, documentation and examples on the Matter JS website: https://brm.io/matter-js/
|
||||||
*
|
*
|
||||||
* @class MatterPhysics
|
* @class MatterPhysics
|
||||||
|
@ -141,7 +142,7 @@ var MatterPhysics = new Class({
|
||||||
/**
|
/**
|
||||||
* An instance of the Matter Factory. This class provides lots of functions for creating a
|
* An instance of the Matter Factory. This class provides lots of functions for creating a
|
||||||
* wide variety of physics objects and adds them automatically to the Matter World.
|
* wide variety of physics objects and adds them automatically to the Matter World.
|
||||||
*
|
*
|
||||||
* You can use this class to cut-down on the amount of code required in your game, however,
|
* You can use this class to cut-down on the amount of code required in your game, however,
|
||||||
* use of the Factory is entirely optional and should be seen as a development aid. It's
|
* use of the Factory is entirely optional and should be seen as a development aid. It's
|
||||||
* perfectly possible to create and add components to the Matter world without using it.
|
* perfectly possible to create and add components to the Matter world without using it.
|
||||||
|
@ -166,7 +167,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Body` module.
|
* A reference to the `Matter.Body` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Body` module contains methods for creating and manipulating body models.
|
* The `Matter.Body` module contains methods for creating and manipulating body models.
|
||||||
* A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`.
|
* A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`.
|
||||||
* Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the `Bodies` module.
|
* Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the `Bodies` module.
|
||||||
|
@ -179,7 +180,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Composite` module.
|
* A reference to the `Matter.Composite` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Composite` module contains methods for creating and manipulating composite bodies.
|
* The `Matter.Composite` module contains methods for creating and manipulating composite bodies.
|
||||||
* A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure.
|
* A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure.
|
||||||
* It is important to use the functions in this module to modify composites, rather than directly modifying their properties.
|
* It is important to use the functions in this module to modify composites, rather than directly modifying their properties.
|
||||||
|
@ -193,9 +194,22 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
// Collision:
|
// Collision:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to the `Matter.Collision` module.
|
||||||
|
*
|
||||||
|
* The `Matter.Collision` module contains methods for detecting collisions between a given pair of bodies.
|
||||||
|
*
|
||||||
|
* For efficient detection between a list of bodies, see `Matter.Detector` and `Matter.Query`.
|
||||||
|
*
|
||||||
|
* @name Phaser.Physics.Matter.MatterPhysics#collision
|
||||||
|
* @type {MatterJS.Collision}
|
||||||
|
* @since 3.60.0
|
||||||
|
*/
|
||||||
|
this.collision = Collision;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Detector` module.
|
* A reference to the `Matter.Detector` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Detector` module contains methods for detecting collisions given a set of pairs.
|
* The `Matter.Detector` module contains methods for detecting collisions given a set of pairs.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#detector
|
* @name Phaser.Physics.Matter.MatterPhysics#detector
|
||||||
|
@ -206,7 +220,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Grid` module.
|
* A reference to the `Matter.Grid` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
|
* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#grid
|
* @name Phaser.Physics.Matter.MatterPhysics#grid
|
||||||
|
@ -217,7 +231,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Pair` module.
|
* A reference to the `Matter.Pair` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Pair` module contains methods for creating and manipulating collision pairs.
|
* The `Matter.Pair` module contains methods for creating and manipulating collision pairs.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#pair
|
* @name Phaser.Physics.Matter.MatterPhysics#pair
|
||||||
|
@ -228,7 +242,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Pairs` module.
|
* A reference to the `Matter.Pairs` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets.
|
* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#pairs
|
* @name Phaser.Physics.Matter.MatterPhysics#pairs
|
||||||
|
@ -239,7 +253,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Query` module.
|
* A reference to the `Matter.Query` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Query` module contains methods for performing collision queries.
|
* The `Matter.Query` module contains methods for performing collision queries.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#query
|
* @name Phaser.Physics.Matter.MatterPhysics#query
|
||||||
|
@ -250,7 +264,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Resolver` module.
|
* A reference to the `Matter.Resolver` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Resolver` module contains methods for resolving collision pairs.
|
* The `Matter.Resolver` module contains methods for resolving collision pairs.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#resolver
|
* @name Phaser.Physics.Matter.MatterPhysics#resolver
|
||||||
|
@ -261,7 +275,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.SAT` module.
|
* A reference to the `Matter.SAT` module.
|
||||||
*
|
*
|
||||||
* The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
|
* The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#sat
|
* @name Phaser.Physics.Matter.MatterPhysics#sat
|
||||||
|
@ -274,7 +288,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Constraint` module.
|
* A reference to the `Matter.Constraint` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Constraint` module contains methods for creating and manipulating constraints.
|
* The `Matter.Constraint` module contains methods for creating and manipulating constraints.
|
||||||
* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
|
* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
|
||||||
* The stiffness of constraints can be modified to create springs or elastic.
|
* The stiffness of constraints can be modified to create springs or elastic.
|
||||||
|
@ -289,7 +303,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Bodies` module.
|
* A reference to the `Matter.Bodies` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Bodies` module contains factory methods for creating rigid bodies
|
* The `Matter.Bodies` module contains factory methods for creating rigid bodies
|
||||||
* with commonly used body configurations (such as rectangles, circles and other polygons).
|
* with commonly used body configurations (such as rectangles, circles and other polygons).
|
||||||
*
|
*
|
||||||
|
@ -301,7 +315,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Composites` module.
|
* A reference to the `Matter.Composites` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Composites` module contains factory methods for creating composite bodies
|
* The `Matter.Composites` module contains factory methods for creating composite bodies
|
||||||
* with commonly used configurations (such as stacks and chains).
|
* with commonly used configurations (such as stacks and chains).
|
||||||
*
|
*
|
||||||
|
@ -315,7 +329,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Axes` module.
|
* A reference to the `Matter.Axes` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Axes` module contains methods for creating and manipulating sets of axes.
|
* The `Matter.Axes` module contains methods for creating and manipulating sets of axes.
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#axes
|
* @name Phaser.Physics.Matter.MatterPhysics#axes
|
||||||
|
@ -326,7 +340,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Bounds` module.
|
* A reference to the `Matter.Bounds` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
|
* The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
|
||||||
*
|
*
|
||||||
* @name Phaser.Physics.Matter.MatterPhysics#bounds
|
* @name Phaser.Physics.Matter.MatterPhysics#bounds
|
||||||
|
@ -337,7 +351,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Svg` module.
|
* A reference to the `Matter.Svg` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Svg` module contains methods for converting SVG images into an array of vector points.
|
* The `Matter.Svg` module contains methods for converting SVG images into an array of vector points.
|
||||||
*
|
*
|
||||||
* To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg
|
* To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg
|
||||||
|
@ -350,7 +364,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Vector` module.
|
* A reference to the `Matter.Vector` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Vector` module contains methods for creating and manipulating vectors.
|
* The `Matter.Vector` module contains methods for creating and manipulating vectors.
|
||||||
* Vectors are the basis of all the geometry related operations in the engine.
|
* Vectors are the basis of all the geometry related operations in the engine.
|
||||||
* A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`.
|
* A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`.
|
||||||
|
@ -363,7 +377,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Vertices` module.
|
* A reference to the `Matter.Vertices` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
|
* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
|
||||||
* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
|
* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
|
||||||
* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
|
* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
|
||||||
|
@ -376,7 +390,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the `Matter.Vertices` module.
|
* A reference to the `Matter.Vertices` module.
|
||||||
*
|
*
|
||||||
* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
|
* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
|
||||||
* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
|
* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
|
||||||
* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
|
* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
|
||||||
|
@ -488,18 +502,18 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the Matter Attractors Plugin.
|
* Enables the Matter Attractors Plugin.
|
||||||
*
|
*
|
||||||
* The attractors plugin that makes it easy to apply continual forces on bodies.
|
* The attractors plugin that makes it easy to apply continual forces on bodies.
|
||||||
* It's possible to simulate effects such as wind, gravity and magnetism.
|
* It's possible to simulate effects such as wind, gravity and magnetism.
|
||||||
*
|
*
|
||||||
* https://github.com/liabru/matter-attractors
|
* https://github.com/liabru/matter-attractors
|
||||||
*
|
*
|
||||||
* This method is called automatically if `plugins.attractors` is set in the Matter World Config.
|
* This method is called automatically if `plugins.attractors` is set in the Matter World Config.
|
||||||
* However, you can also call it directly from within your game.
|
* However, you can also call it directly from within your game.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#enableAttractorPlugin
|
* @method Phaser.Physics.Matter.MatterPhysics#enableAttractorPlugin
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
*
|
||||||
* @return {this} This Matter Physics instance.
|
* @return {this} This Matter Physics instance.
|
||||||
*/
|
*/
|
||||||
enableAttractorPlugin: function ()
|
enableAttractorPlugin: function ()
|
||||||
|
@ -512,19 +526,19 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the Matter Wrap Plugin.
|
* Enables the Matter Wrap Plugin.
|
||||||
*
|
*
|
||||||
* The coordinate wrapping plugin that automatically wraps the position of bodies such that they always stay
|
* The coordinate wrapping plugin that automatically wraps the position of bodies such that they always stay
|
||||||
* within the given bounds. Upon crossing a boundary the body will appear on the opposite side of the bounds,
|
* within the given bounds. Upon crossing a boundary the body will appear on the opposite side of the bounds,
|
||||||
* while maintaining its velocity.
|
* while maintaining its velocity.
|
||||||
*
|
*
|
||||||
* https://github.com/liabru/matter-wrap
|
* https://github.com/liabru/matter-wrap
|
||||||
*
|
*
|
||||||
* This method is called automatically if `plugins.wrap` is set in the Matter World Config.
|
* This method is called automatically if `plugins.wrap` is set in the Matter World Config.
|
||||||
* However, you can also call it directly from within your game.
|
* However, you can also call it directly from within your game.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#enableWrapPlugin
|
* @method Phaser.Physics.Matter.MatterPhysics#enableWrapPlugin
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
*
|
||||||
* @return {this} This Matter Physics instance.
|
* @return {this} This Matter Physics instance.
|
||||||
*/
|
*/
|
||||||
enableWrapPlugin: function ()
|
enableWrapPlugin: function ()
|
||||||
|
@ -537,33 +551,33 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the Matter Collision Events Plugin.
|
* Enables the Matter Collision Events Plugin.
|
||||||
*
|
*
|
||||||
* Note that this plugin is enabled by default. So you should only ever need to call this
|
* Note that this plugin is enabled by default. So you should only ever need to call this
|
||||||
* method if you have specifically disabled the plugin in your Matter World Config.
|
* method if you have specifically disabled the plugin in your Matter World Config.
|
||||||
* You can disable it by setting `plugins.collisionevents: false` in your Matter World Config.
|
* You can disable it by setting `plugins.collisionevents: false` in your Matter World Config.
|
||||||
*
|
*
|
||||||
* This plugin triggers three new events on Matter.Body:
|
* This plugin triggers three new events on Matter.Body:
|
||||||
*
|
*
|
||||||
* 1. `onCollide`
|
* 1. `onCollide`
|
||||||
* 2. `onCollideEnd`
|
* 2. `onCollideEnd`
|
||||||
* 3. `onCollideActive`
|
* 3. `onCollideActive`
|
||||||
*
|
*
|
||||||
* These events correspond to the Matter.js events `collisionStart`, `collisionActive` and `collisionEnd`, respectively.
|
* These events correspond to the Matter.js events `collisionStart`, `collisionActive` and `collisionEnd`, respectively.
|
||||||
* You can listen to these events via Matter.Events or they will also be emitted from the Matter World.
|
* You can listen to these events via Matter.Events or they will also be emitted from the Matter World.
|
||||||
*
|
*
|
||||||
* This plugin also extends Matter.Body with three convenience functions:
|
* This plugin also extends Matter.Body with three convenience functions:
|
||||||
*
|
*
|
||||||
* `Matter.Body.setOnCollide(callback)`
|
* `Matter.Body.setOnCollide(callback)`
|
||||||
* `Matter.Body.setOnCollideEnd(callback)`
|
* `Matter.Body.setOnCollideEnd(callback)`
|
||||||
* `Matter.Body.setOnCollideActive(callback)`
|
* `Matter.Body.setOnCollideActive(callback)`
|
||||||
*
|
*
|
||||||
* You can register event callbacks by providing a function of type (pair: Matter.Pair) => void
|
* You can register event callbacks by providing a function of type (pair: Matter.Pair) => void
|
||||||
*
|
*
|
||||||
* https://github.com/dxu/matter-collision-events
|
* https://github.com/dxu/matter-collision-events
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#enableCollisionEventsPlugin
|
* @method Phaser.Physics.Matter.MatterPhysics#enableCollisionEventsPlugin
|
||||||
* @since 3.22.0
|
* @since 3.22.0
|
||||||
*
|
*
|
||||||
* @return {this} This Matter Physics instance.
|
* @return {this} This Matter Physics instance.
|
||||||
*/
|
*/
|
||||||
enableCollisionEventsPlugin: function ()
|
enableCollisionEventsPlugin: function ()
|
||||||
|
@ -576,7 +590,7 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pauses the Matter World instance and sets `enabled` to `false`.
|
* Pauses the Matter World instance and sets `enabled` to `false`.
|
||||||
*
|
*
|
||||||
* A paused world will not run any simulations for the duration it is paused.
|
* A paused world will not run any simulations for the duration it is paused.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#pause
|
* @method Phaser.Physics.Matter.MatterPhysics#pause
|
||||||
|
@ -639,12 +653,12 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manually advances the physics simulation by one iteration.
|
* Manually advances the physics simulation by one iteration.
|
||||||
*
|
*
|
||||||
* You can optionally pass in the `delta` and `correction` values to be used by Engine.update.
|
* You can optionally pass in the `delta` and `correction` values to be used by Engine.update.
|
||||||
* If undefined they use the Matter defaults of 60Hz and no correction.
|
* If undefined they use the Matter defaults of 60Hz and no correction.
|
||||||
*
|
*
|
||||||
* Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`.
|
* Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`.
|
||||||
*
|
*
|
||||||
* It also ignores any custom `getDelta` functions, as you should be passing the delta
|
* It also ignores any custom `getDelta` functions, as you should be passing the delta
|
||||||
* value in to this call.
|
* value in to this call.
|
||||||
*
|
*
|
||||||
|
@ -671,22 +685,22 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the vertices of the given body, or an array of bodies, contains the given point, or not.
|
* Checks if the vertices of the given body, or an array of bodies, contains the given point, or not.
|
||||||
*
|
*
|
||||||
* You can pass in either a single body, or an array of bodies to be checked. This method will
|
* You can pass in either a single body, or an array of bodies to be checked. This method will
|
||||||
* return `true` if _any_ of the bodies in the array contain the point. See the `intersectPoint` method if you need
|
* return `true` if _any_ of the bodies in the array contain the point. See the `intersectPoint` method if you need
|
||||||
* to get a list of intersecting bodies.
|
* to get a list of intersecting bodies.
|
||||||
*
|
*
|
||||||
* The point should be transformed into the Matter World coordinate system in advance. This happens by
|
* The point should be transformed into the Matter World coordinate system in advance. This happens by
|
||||||
* default with Input Pointers, but if you wish to use points from another system you may need to
|
* default with Input Pointers, but if you wish to use points from another system you may need to
|
||||||
* transform them before passing them.
|
* transform them before passing them.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#containsPoint
|
* @method Phaser.Physics.Matter.MatterPhysics#containsPoint
|
||||||
* @since 3.22.0
|
* @since 3.22.0
|
||||||
*
|
*
|
||||||
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} body - The body, or an array of bodies, to check against the point.
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} body - The body, or an array of bodies, to check against the point.
|
||||||
* @param {number} x - The horizontal coordinate of the point.
|
* @param {number} x - The horizontal coordinate of the point.
|
||||||
* @param {number} y - The vertical coordinate of the point.
|
* @param {number} y - The vertical coordinate of the point.
|
||||||
*
|
*
|
||||||
* @return {boolean} `true` if the point is within one of the bodies given, otherwise `false`.
|
* @return {boolean} `true` if the point is within one of the bodies given, otherwise `false`.
|
||||||
*/
|
*/
|
||||||
containsPoint: function (body, x, y)
|
containsPoint: function (body, x, y)
|
||||||
|
@ -702,20 +716,20 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the given coordinates to see if any vertices of the given bodies contain it.
|
* Checks the given coordinates to see if any vertices of the given bodies contain it.
|
||||||
*
|
*
|
||||||
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
|
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
|
||||||
*
|
*
|
||||||
* The coordinates should be transformed into the Matter World coordinate system in advance. This happens by
|
* The coordinates should be transformed into the Matter World coordinate system in advance. This happens by
|
||||||
* default with Input Pointers, but if you wish to use coordinates from another system you may need to
|
* default with Input Pointers, but if you wish to use coordinates from another system you may need to
|
||||||
* transform them before passing them.
|
* transform them before passing them.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#intersectPoint
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectPoint
|
||||||
* @since 3.22.0
|
* @since 3.22.0
|
||||||
*
|
*
|
||||||
* @param {number} x - The horizontal coordinate of the point.
|
* @param {number} x - The horizontal coordinate of the point.
|
||||||
* @param {number} y - The vertical coordinate of the point.
|
* @param {number} y - The vertical coordinate of the point.
|
||||||
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
||||||
*
|
*
|
||||||
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies which contain the given point.
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies which contain the given point.
|
||||||
*/
|
*/
|
||||||
intersectPoint: function (x, y, bodies)
|
intersectPoint: function (x, y, bodies)
|
||||||
|
@ -743,9 +757,9 @@ var MatterPhysics = new Class({
|
||||||
* Checks the given rectangular area to see if any vertices of the given bodies intersect with it.
|
* Checks the given rectangular area to see if any vertices of the given bodies intersect with it.
|
||||||
* Or, if the `outside` parameter is set to `true`, it checks to see which bodies do not
|
* Or, if the `outside` parameter is set to `true`, it checks to see which bodies do not
|
||||||
* intersect with it.
|
* intersect with it.
|
||||||
*
|
*
|
||||||
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
|
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#intersectRect
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectRect
|
||||||
* @since 3.22.0
|
* @since 3.22.0
|
||||||
*
|
*
|
||||||
|
@ -755,7 +769,7 @@ var MatterPhysics = new Class({
|
||||||
* @param {number} height - The height of the area.
|
* @param {number} height - The height of the area.
|
||||||
* @param {boolean} [outside=false] - If `false` it checks for vertices inside the area, if `true` it checks for vertices outside the area.
|
* @param {boolean} [outside=false] - If `false` it checks for vertices inside the area, if `true` it checks for vertices outside the area.
|
||||||
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
||||||
*
|
*
|
||||||
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies that intersect with the given area.
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies that intersect with the given area.
|
||||||
*/
|
*/
|
||||||
intersectRect: function (x, y, width, height, outside, bodies)
|
intersectRect: function (x, y, width, height, outside, bodies)
|
||||||
|
@ -786,11 +800,11 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the given ray segment to see if any vertices of the given bodies intersect with it.
|
* Checks the given ray segment to see if any vertices of the given bodies intersect with it.
|
||||||
*
|
*
|
||||||
* If no bodies are provided it will search all bodies in the Matter World.
|
* If no bodies are provided it will search all bodies in the Matter World.
|
||||||
*
|
*
|
||||||
* The width of the ray can be specified via the `rayWidth` parameter.
|
* The width of the ray can be specified via the `rayWidth` parameter.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#intersectRay
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectRay
|
||||||
* @since 3.22.0
|
* @since 3.22.0
|
||||||
*
|
*
|
||||||
|
@ -800,13 +814,13 @@ var MatterPhysics = new Class({
|
||||||
* @param {number} y2 - The vertical coordinate of the end of the ray segment.
|
* @param {number} y2 - The vertical coordinate of the end of the ray segment.
|
||||||
* @param {number} [rayWidth=1] - The width of the ray segment.
|
* @param {number} [rayWidth=1] - The width of the ray segment.
|
||||||
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
||||||
*
|
*
|
||||||
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with the ray segment.
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with the ray segment.
|
||||||
*/
|
*/
|
||||||
intersectRay: function (x1, y1, x2, y2, rayWidth, bodies)
|
intersectRay: function (x1, y1, x2, y2, rayWidth, bodies)
|
||||||
{
|
{
|
||||||
if (rayWidth === undefined) { rayWidth = 1; }
|
if (rayWidth === undefined) { rayWidth = 1; }
|
||||||
|
|
||||||
bodies = this.getMatterBodies(bodies);
|
bodies = this.getMatterBodies(bodies);
|
||||||
|
|
||||||
var result = [];
|
var result = [];
|
||||||
|
@ -822,15 +836,15 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the given Matter Body to see if it intersects with any of the given bodies.
|
* Checks the given Matter Body to see if it intersects with any of the given bodies.
|
||||||
*
|
*
|
||||||
* If no bodies are provided it will check against all bodies in the Matter World.
|
* If no bodies are provided it will check against all bodies in the Matter World.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#intersectBody
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectBody
|
||||||
* @since 3.22.0
|
* @since 3.22.0
|
||||||
*
|
*
|
||||||
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The target body.
|
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The target body.
|
||||||
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check the target body against. If not provided it will search all bodies in the world.
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check the target body against. If not provided it will search all bodies in the world.
|
||||||
*
|
*
|
||||||
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with target body.
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with target body.
|
||||||
*/
|
*/
|
||||||
intersectBody: function (body, bodies)
|
intersectBody: function (body, bodies)
|
||||||
|
@ -859,22 +873,22 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see if the target body, or an array of target bodies, intersects with any of the given bodies.
|
* Checks to see if the target body, or an array of target bodies, intersects with any of the given bodies.
|
||||||
*
|
*
|
||||||
* If intersection occurs this method will return `true` and, if provided, invoke the callbacks.
|
* If intersection occurs this method will return `true` and, if provided, invoke the callbacks.
|
||||||
*
|
*
|
||||||
* If no bodies are provided for the second parameter the target will check again all bodies in the Matter World.
|
* If no bodies are provided for the second parameter the target will check again all bodies in the Matter World.
|
||||||
*
|
*
|
||||||
* Note that bodies can only overlap if they are in non-colliding collision groups or categories.
|
* Note that bodies can only overlap if they are in non-colliding collision groups or categories.
|
||||||
*
|
*
|
||||||
* If you provide a `processCallback` then the two bodies that overlap are sent to it. This callback
|
* If you provide a `processCallback` then the two bodies that overlap are sent to it. This callback
|
||||||
* must return a boolean and is used to allow you to perform additional processing tests before a final
|
* must return a boolean and is used to allow you to perform additional processing tests before a final
|
||||||
* outcome is decided. If it returns `true` then the bodies are finally passed to the `overlapCallback`, if set.
|
* outcome is decided. If it returns `true` then the bodies are finally passed to the `overlapCallback`, if set.
|
||||||
*
|
*
|
||||||
* If you provide an `overlapCallback` then the matching pairs of overlapping bodies will be sent to it.
|
* If you provide an `overlapCallback` then the matching pairs of overlapping bodies will be sent to it.
|
||||||
*
|
*
|
||||||
* Both callbacks have the following signature: `function (bodyA, bodyB, collisionInfo)` where `bodyA` is always
|
* Both callbacks have the following signature: `function (bodyA, bodyB, collisionInfo)` where `bodyA` is always
|
||||||
* the target body. The `collisionInfo` object contains additional data, such as the angle and depth of penetration.
|
* the target body. The `collisionInfo` object contains additional data, such as the angle and depth of penetration.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#overlap
|
* @method Phaser.Physics.Matter.MatterPhysics#overlap
|
||||||
* @since 3.22.0
|
* @since 3.22.0
|
||||||
*
|
*
|
||||||
|
@ -883,7 +897,7 @@ var MatterPhysics = new Class({
|
||||||
* @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the bodies overlap.
|
* @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the bodies overlap.
|
||||||
* @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two bodies if they overlap. If this is set then `overlapCallback` will only be invoked if this callback returns `true`.
|
* @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two bodies if they overlap. If this is set then `overlapCallback` will only be invoked if this callback returns `true`.
|
||||||
* @param {*} [callbackContext] - The context, or scope, in which to run the callbacks.
|
* @param {*} [callbackContext] - The context, or scope, in which to run the callbacks.
|
||||||
*
|
*
|
||||||
* @return {boolean} `true` if the target body intersects with _any_ of the bodies given, otherwise `false`.
|
* @return {boolean} `true` if the target body intersects with _any_ of the bodies given, otherwise `false`.
|
||||||
*/
|
*/
|
||||||
overlap: function (target, bodies, overlapCallback, processCallback, callbackContext)
|
overlap: function (target, bodies, overlapCallback, processCallback, callbackContext)
|
||||||
|
@ -935,9 +949,9 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the collision filter category of all given Matter Bodies to the given value.
|
* Sets the collision filter category of all given Matter Bodies to the given value.
|
||||||
*
|
*
|
||||||
* This number must be a power of two between 2^0 (= 1) and 2^31.
|
* This number must be a power of two between 2^0 (= 1) and 2^31.
|
||||||
*
|
*
|
||||||
* Bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision
|
* Bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision
|
||||||
* categories are included in their collision masks (see {@link #setCollidesWith}).
|
* categories are included in their collision masks (see {@link #setCollidesWith}).
|
||||||
*
|
*
|
||||||
|
@ -963,10 +977,10 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the collision filter group of all given Matter Bodies to the given value.
|
* Sets the collision filter group of all given Matter Bodies to the given value.
|
||||||
*
|
*
|
||||||
* If the group value is zero, or if two Matter Bodies have different group values,
|
* If the group value is zero, or if two Matter Bodies have different group values,
|
||||||
* they will collide according to the usual collision filter rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}).
|
* they will collide according to the usual collision filter rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}).
|
||||||
*
|
*
|
||||||
* If two Matter Bodies have the same positive group value, they will always collide;
|
* If two Matter Bodies have the same positive group value, they will always collide;
|
||||||
* if they have the same negative group value they will never collide.
|
* if they have the same negative group value they will never collide.
|
||||||
*
|
*
|
||||||
|
@ -992,9 +1006,9 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the collision filter mask of all given Matter Bodies to the given value.
|
* Sets the collision filter mask of all given Matter Bodies to the given value.
|
||||||
*
|
*
|
||||||
* Two Matter Bodies with different collision groups will only collide if each one includes the others
|
* Two Matter Bodies with different collision groups will only collide if each one includes the others
|
||||||
* category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and
|
* category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and
|
||||||
* `(categoryB & maskA) !== 0` are both true.
|
* `(categoryB & maskA) !== 0` are both true.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#setCollidesWith
|
* @method Phaser.Physics.Matter.MatterPhysics#setCollidesWith
|
||||||
|
@ -1033,10 +1047,10 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes an array and returns a new array made from all of the Matter Bodies found in the original array.
|
* Takes an array and returns a new array made from all of the Matter Bodies found in the original array.
|
||||||
*
|
*
|
||||||
* For example, passing in Matter Game Objects, such as a bunch of Matter Sprites, to this method, would
|
* For example, passing in Matter Game Objects, such as a bunch of Matter Sprites, to this method, would
|
||||||
* return an array containing all of their native Matter Body objects.
|
* return an array containing all of their native Matter Body objects.
|
||||||
*
|
*
|
||||||
* If the `bodies` argument is falsey, it will return all bodies in the world.
|
* If the `bodies` argument is falsey, it will return all bodies in the world.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#getMatterBodies
|
* @method Phaser.Physics.Matter.MatterPhysics#getMatterBodies
|
||||||
|
@ -1212,7 +1226,7 @@ var MatterPhysics = new Class({
|
||||||
/**
|
/**
|
||||||
* Applies a force to a body, from the given world position, including resulting torque.
|
* Applies a force to a body, from the given world position, including resulting torque.
|
||||||
* If no angle is given, the current body angle is used.
|
* If no angle is given, the current body angle is used.
|
||||||
*
|
*
|
||||||
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
|
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromPosition
|
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromPosition
|
||||||
|
@ -1250,7 +1264,7 @@ var MatterPhysics = new Class({
|
||||||
/**
|
/**
|
||||||
* Apply a force to a body based on the given angle and speed.
|
* Apply a force to a body based on the given angle and speed.
|
||||||
* If no angle is given, the current body angle is used.
|
* If no angle is given, the current body angle is used.
|
||||||
*
|
*
|
||||||
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
|
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
|
||||||
*
|
*
|
||||||
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromAngle
|
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromAngle
|
||||||
|
@ -1318,22 +1332,22 @@ var MatterPhysics = new Class({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aligns a Body, or Matter Game Object, against the given coordinates.
|
* Aligns a Body, or Matter Game Object, against the given coordinates.
|
||||||
*
|
*
|
||||||
* The alignment takes place using the body bounds, which take into consideration things
|
* The alignment takes place using the body bounds, which take into consideration things
|
||||||
* like body scale and rotation.
|
* like body scale and rotation.
|
||||||
*
|
*
|
||||||
* Although a Body has a `position` property, it is based on the center of mass for the body,
|
* Although a Body has a `position` property, it is based on the center of mass for the body,
|
||||||
* not a dimension based center. This makes aligning bodies difficult, especially if they have
|
* not a dimension based center. This makes aligning bodies difficult, especially if they have
|
||||||
* rotated or scaled. This method will derive the correct position based on the body bounds and
|
* rotated or scaled. This method will derive the correct position based on the body bounds and
|
||||||
* its center of mass offset, in order to align the body with the given coordinate.
|
* its center of mass offset, in order to align the body with the given coordinate.
|
||||||
*
|
*
|
||||||
* For example, if you wanted to align a body so it sat in the bottom-center of the
|
* For example, if you wanted to align a body so it sat in the bottom-center of the
|
||||||
* Scene, and the world was 800 x 600 in size:
|
* Scene, and the world was 800 x 600 in size:
|
||||||
*
|
*
|
||||||
* ```javascript
|
* ```javascript
|
||||||
* this.matter.alignBody(body, 400, 600, Phaser.Display.Align.BOTTOM_CENTER);
|
* this.matter.alignBody(body, 400, 600, Phaser.Display.Align.BOTTOM_CENTER);
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* You pass in 400 for the x coordinate, because that is the center of the world, and 600 for
|
* You pass in 400 for the x coordinate, because that is the center of the world, and 600 for
|
||||||
* the y coordinate, as that is the base of the world.
|
* the y coordinate, as that is the base of the world.
|
||||||
*
|
*
|
||||||
|
@ -1363,7 +1377,7 @@ var MatterPhysics = new Class({
|
||||||
case ALIGN_CONST.TOP_CENTER:
|
case ALIGN_CONST.TOP_CENTER:
|
||||||
pos = this.bodyBounds.getTopCenter(body, x, y);
|
pos = this.bodyBounds.getTopCenter(body, x, y);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALIGN_CONST.TOP_RIGHT:
|
case ALIGN_CONST.TOP_RIGHT:
|
||||||
case ALIGN_CONST.RIGHT_TOP:
|
case ALIGN_CONST.RIGHT_TOP:
|
||||||
pos = this.bodyBounds.getTopRight(body, x, y);
|
pos = this.bodyBounds.getTopRight(body, x, y);
|
||||||
|
|
|
@ -37,7 +37,12 @@ var Body = require('./Body');
|
||||||
constraints: [],
|
constraints: [],
|
||||||
composites: [],
|
composites: [],
|
||||||
label: 'Composite',
|
label: 'Composite',
|
||||||
plugin: {}
|
plugin: {},
|
||||||
|
cache: {
|
||||||
|
allBodies: null,
|
||||||
|
allConstraints: null,
|
||||||
|
allComposites: null
|
||||||
|
}
|
||||||
}, options);
|
}, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,12 +62,18 @@ var Body = require('./Body');
|
||||||
|
|
||||||
composite.isModified = isModified;
|
composite.isModified = isModified;
|
||||||
|
|
||||||
|
if (isModified && composite.cache) {
|
||||||
|
composite.cache.allBodies = null;
|
||||||
|
composite.cache.allConstraints = null;
|
||||||
|
composite.cache.allComposites = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (updateParents && composite.parent) {
|
if (updateParents && composite.parent) {
|
||||||
Composite.setModified(composite.parent, isModified, updateParents, updateChildren);
|
Composite.setModified(composite.parent, isModified, updateParents, updateChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateChildren) {
|
if (updateChildren) {
|
||||||
for(var i = 0; i < composite.composites.length; i++) {
|
for (var i = 0; i < composite.composites.length; i++) {
|
||||||
var childComposite = composite.composites[i];
|
var childComposite = composite.composites[i];
|
||||||
Composite.setModified(childComposite, isModified, updateParents, updateChildren);
|
Composite.setModified(childComposite, isModified, updateParents, updateChildren);
|
||||||
}
|
}
|
||||||
|
@ -70,11 +81,11 @@ var Body = require('./Body');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic add function. Adds one or many body(s), constraint(s) or a composite(s) to the given composite.
|
* Generic single or multi-add function. Adds a single or an array of body(s), constraint(s) or composite(s) to the given composite.
|
||||||
* Triggers `beforeAdd` and `afterAdd` events on the `composite`.
|
* Triggers `beforeAdd` and `afterAdd` events on the `composite`.
|
||||||
* @method add
|
* @method add
|
||||||
* @param {composite} composite
|
* @param {composite} composite
|
||||||
* @param {} object
|
* @param {object|array} object A single or an array of body(s), constraint(s) or composite(s)
|
||||||
* @return {composite} The original composite with the objects added
|
* @return {composite} The original composite with the objects added
|
||||||
*/
|
*/
|
||||||
Composite.add = function(composite, object) {
|
Composite.add = function(composite, object) {
|
||||||
|
@ -120,7 +131,7 @@ var Body = require('./Body');
|
||||||
* Triggers `beforeRemove` and `afterRemove` events on the `composite`.
|
* Triggers `beforeRemove` and `afterRemove` events on the `composite`.
|
||||||
* @method remove
|
* @method remove
|
||||||
* @param {composite} composite
|
* @param {composite} composite
|
||||||
* @param {} object
|
* @param {object|array} object
|
||||||
* @param {boolean} [deep=false]
|
* @param {boolean} [deep=false]
|
||||||
* @return {composite} The original composite with the objects removed
|
* @return {composite} The original composite with the objects removed
|
||||||
*/
|
*/
|
||||||
|
@ -180,10 +191,9 @@ var Body = require('./Body');
|
||||||
* @return {composite} The original compositeA with the composite removed
|
* @return {composite} The original compositeA with the composite removed
|
||||||
*/
|
*/
|
||||||
Composite.removeComposite = function(compositeA, compositeB, deep) {
|
Composite.removeComposite = function(compositeA, compositeB, deep) {
|
||||||
var position = compositeA.composites.indexOf(compositeB);
|
var position = Common.indexOf(compositeA.composites, compositeB);
|
||||||
if (position !== -1) {
|
if (position !== -1) {
|
||||||
Composite.removeCompositeAt(compositeA, position);
|
Composite.removeCompositeAt(compositeA, position);
|
||||||
Composite.setModified(compositeA, true, true, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deep) {
|
if (deep) {
|
||||||
|
@ -233,10 +243,9 @@ var Body = require('./Body');
|
||||||
* @return {composite} The original composite with the body removed
|
* @return {composite} The original composite with the body removed
|
||||||
*/
|
*/
|
||||||
Composite.removeBody = function(composite, body, deep) {
|
Composite.removeBody = function(composite, body, deep) {
|
||||||
var position = composite.bodies.indexOf(body);
|
var position = Common.indexOf(composite.bodies, body);
|
||||||
if (position !== -1) {
|
if (position !== -1) {
|
||||||
Composite.removeBodyAt(composite, position);
|
Composite.removeBodyAt(composite, position);
|
||||||
Composite.setModified(composite, true, true, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deep) {
|
if (deep) {
|
||||||
|
@ -286,7 +295,7 @@ var Body = require('./Body');
|
||||||
* @return {composite} The original composite with the constraint removed
|
* @return {composite} The original composite with the constraint removed
|
||||||
*/
|
*/
|
||||||
Composite.removeConstraint = function(composite, constraint, deep) {
|
Composite.removeConstraint = function(composite, constraint, deep) {
|
||||||
var position = composite.constraints.indexOf(constraint);
|
var position = Common.indexOf(composite.constraints, constraint);
|
||||||
if (position !== -1) {
|
if (position !== -1) {
|
||||||
Composite.removeConstraintAt(composite, position);
|
Composite.removeConstraintAt(composite, position);
|
||||||
}
|
}
|
||||||
|
@ -337,6 +346,7 @@ var Body = require('./Body');
|
||||||
|
|
||||||
composite.constraints.length = 0;
|
composite.constraints.length = 0;
|
||||||
composite.composites.length = 0;
|
composite.composites.length = 0;
|
||||||
|
|
||||||
Composite.setModified(composite, true, true, false);
|
Composite.setModified(composite, true, true, false);
|
||||||
|
|
||||||
return composite;
|
return composite;
|
||||||
|
@ -349,11 +359,19 @@ var Body = require('./Body');
|
||||||
* @return {body[]} All the bodies
|
* @return {body[]} All the bodies
|
||||||
*/
|
*/
|
||||||
Composite.allBodies = function(composite) {
|
Composite.allBodies = function(composite) {
|
||||||
|
if (composite.cache && composite.cache.allBodies) {
|
||||||
|
return composite.cache.allBodies;
|
||||||
|
}
|
||||||
|
|
||||||
var bodies = [].concat(composite.bodies);
|
var bodies = [].concat(composite.bodies);
|
||||||
|
|
||||||
for (var i = 0; i < composite.composites.length; i++)
|
for (var i = 0; i < composite.composites.length; i++)
|
||||||
bodies = bodies.concat(Composite.allBodies(composite.composites[i]));
|
bodies = bodies.concat(Composite.allBodies(composite.composites[i]));
|
||||||
|
|
||||||
|
if (composite.cache) {
|
||||||
|
composite.cache.allBodies = bodies;
|
||||||
|
}
|
||||||
|
|
||||||
return bodies;
|
return bodies;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -364,11 +382,19 @@ var Body = require('./Body');
|
||||||
* @return {constraint[]} All the constraints
|
* @return {constraint[]} All the constraints
|
||||||
*/
|
*/
|
||||||
Composite.allConstraints = function(composite) {
|
Composite.allConstraints = function(composite) {
|
||||||
|
if (composite.cache && composite.cache.allConstraints) {
|
||||||
|
return composite.cache.allConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
var constraints = [].concat(composite.constraints);
|
var constraints = [].concat(composite.constraints);
|
||||||
|
|
||||||
for (var i = 0; i < composite.composites.length; i++)
|
for (var i = 0; i < composite.composites.length; i++)
|
||||||
constraints = constraints.concat(Composite.allConstraints(composite.composites[i]));
|
constraints = constraints.concat(Composite.allConstraints(composite.composites[i]));
|
||||||
|
|
||||||
|
if (composite.cache) {
|
||||||
|
composite.cache.allConstraints = constraints;
|
||||||
|
}
|
||||||
|
|
||||||
return constraints;
|
return constraints;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -379,11 +405,19 @@ var Body = require('./Body');
|
||||||
* @return {composite[]} All the composites
|
* @return {composite[]} All the composites
|
||||||
*/
|
*/
|
||||||
Composite.allComposites = function(composite) {
|
Composite.allComposites = function(composite) {
|
||||||
|
if (composite.cache && composite.cache.allComposites) {
|
||||||
|
return composite.cache.allComposites;
|
||||||
|
}
|
||||||
|
|
||||||
var composites = [].concat(composite.composites);
|
var composites = [].concat(composite.composites);
|
||||||
|
|
||||||
for (var i = 0; i < composite.composites.length; i++)
|
for (var i = 0; i < composite.composites.length; i++)
|
||||||
composites = composites.concat(Composite.allComposites(composite.composites[i]));
|
composites = composites.concat(Composite.allComposites(composite.composites[i]));
|
||||||
|
|
||||||
|
if (composite.cache) {
|
||||||
|
composite.cache.allComposites = composites;
|
||||||
|
}
|
||||||
|
|
||||||
return composites;
|
return composites;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -450,8 +484,6 @@ var Body = require('./Body');
|
||||||
objects[i].id = Common.nextId();
|
objects[i].id = Common.nextId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Composite.setModified(composite, true, true, false);
|
|
||||||
|
|
||||||
return composite;
|
return composite;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -470,8 +502,6 @@ var Body = require('./Body');
|
||||||
Body.translate(bodies[i], translation);
|
Body.translate(bodies[i], translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Composite.setModified(composite, true, true, false);
|
|
||||||
|
|
||||||
return composite;
|
return composite;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -501,8 +531,6 @@ var Body = require('./Body');
|
||||||
Body.rotate(body, rotation);
|
Body.rotate(body, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Composite.setModified(composite, true, true, false);
|
|
||||||
|
|
||||||
return composite;
|
return composite;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -531,8 +559,6 @@ var Body = require('./Body');
|
||||||
Body.scale(body, scaleX, scaleY);
|
Body.scale(body, scaleX, scaleY);
|
||||||
}
|
}
|
||||||
|
|
||||||
Composite.setModified(composite, true, true, false);
|
|
||||||
|
|
||||||
return composite;
|
return composite;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -685,4 +711,13 @@ var Body = require('./Body');
|
||||||
* @type {}
|
* @type {}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object used for storing cached results for performance reasons.
|
||||||
|
* This is used internally only and is automatically managed.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @property cache
|
||||||
|
* @type {}
|
||||||
|
*/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
/**
|
/**
|
||||||
* The `Matter.World` module contains methods for creating and manipulating the world composite.
|
* This module has now been replaced by `Matter.Composite`.
|
||||||
* A `Matter.World` is a `Matter.Composite` body, which is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`.
|
|
||||||
* A `Matter.World` has a few additional properties including `gravity` and `bounds`.
|
|
||||||
* It is important to use the functions in the `Matter.Composite` module to modify the world composite, rather than directly modifying its properties.
|
|
||||||
* There are also a few methods here that alias those in `Matter.Composite` for easier readability.
|
|
||||||
*
|
*
|
||||||
* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
|
* All usage should be migrated to the equivalent functions found on `Matter.Composite`.
|
||||||
|
* For example `World.add(world, body)` now becomes `Composite.add(world, body)`.
|
||||||
|
*
|
||||||
|
* The property `world.gravity` has been moved to `engine.gravity`.
|
||||||
|
*
|
||||||
|
* For back-compatibility purposes this module will remain as a direct alias to `Matter.Composite` in the short term during migration.
|
||||||
|
* Eventually this alias module will be marked as deprecated and then later removed in a future release.
|
||||||
*
|
*
|
||||||
* @class World
|
* @class World
|
||||||
* @extends Composite
|
* @extends Composite
|
||||||
|
@ -16,37 +18,19 @@ var World = {};
|
||||||
module.exports = World;
|
module.exports = World;
|
||||||
|
|
||||||
var Composite = require('./Composite');
|
var Composite = require('./Composite');
|
||||||
var Constraint = require('../constraint/Constraint');
|
|
||||||
var Common = require('../core/Common');
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new world composite. The options parameter is an object that specifies any properties you wish to override the defaults.
|
* See above, aliases for back compatibility only
|
||||||
* See the properties section below for detailed information on what you can pass via the `options` object.
|
|
||||||
* @method create
|
|
||||||
* @constructor
|
|
||||||
* @param {} options
|
|
||||||
* @return {world} A new world
|
|
||||||
*/
|
*/
|
||||||
World.create = function(options) {
|
World.create = Composite.create;
|
||||||
var composite = Composite.create();
|
World.add = Composite.add;
|
||||||
|
World.remove = Composite.remove;
|
||||||
var defaults = {
|
World.clear = Composite.clear;
|
||||||
label: 'World',
|
World.addComposite = Composite.addComposite;
|
||||||
gravity: {
|
World.addBody = Composite.addBody;
|
||||||
x: 0,
|
World.addConstraint = Composite.addConstraint;
|
||||||
y: 1,
|
|
||||||
scale: 0.001
|
|
||||||
},
|
|
||||||
bounds: {
|
|
||||||
min: { x: -Infinity, y: -Infinity },
|
|
||||||
max: { x: Infinity, y: Infinity }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return Common.extend(composite, defaults, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -95,7 +79,7 @@ var Common = require('../core/Common');
|
||||||
|
|
||||||
// World is a Composite body
|
// World is a Composite body
|
||||||
// see src/module/Outro.js for these aliases:
|
// see src/module/Outro.js for these aliases:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An alias for Composite.add
|
* An alias for Composite.add
|
||||||
* @method add
|
* @method add
|
||||||
|
@ -127,7 +111,7 @@ var Common = require('../core/Common');
|
||||||
* @param {composite} composite
|
* @param {composite} composite
|
||||||
* @return {world} The original world with the objects from composite added
|
* @return {world} The original world with the objects from composite added
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An alias for Composite.addBody
|
* An alias for Composite.addBody
|
||||||
* @method addBody
|
* @method addBody
|
||||||
|
|
408
src/physics/matter-js/lib/collision/Collision.js
Normal file
408
src/physics/matter-js/lib/collision/Collision.js
Normal file
|
@ -0,0 +1,408 @@
|
||||||
|
/**
|
||||||
|
* The `Matter.Collision` module contains methods for detecting collisions between a given pair of bodies.
|
||||||
|
*
|
||||||
|
* For efficient detection between a list of bodies, see `Matter.Detector` and `Matter.Query`.
|
||||||
|
*
|
||||||
|
* See `Matter.Engine` for collision events.
|
||||||
|
*
|
||||||
|
* @class Collision
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Collision = {};
|
||||||
|
|
||||||
|
module.exports = Collision;
|
||||||
|
|
||||||
|
var Vertices = require('../geometry/Vertices');
|
||||||
|
var Pair = require('./Pair');
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var _supports = [];
|
||||||
|
|
||||||
|
var _overlapAB = {
|
||||||
|
overlap: 0,
|
||||||
|
axis: null
|
||||||
|
};
|
||||||
|
|
||||||
|
var _overlapBA = {
|
||||||
|
overlap: 0,
|
||||||
|
axis: null
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new collision record.
|
||||||
|
* @method create
|
||||||
|
* @param {body} bodyA The first body part represented by the collision record
|
||||||
|
* @param {body} bodyB The second body part represented by the collision record
|
||||||
|
* @return {collision} A new collision record
|
||||||
|
*/
|
||||||
|
Collision.create = function(bodyA, bodyB) {
|
||||||
|
return {
|
||||||
|
pair: null,
|
||||||
|
collided: false,
|
||||||
|
bodyA: bodyA,
|
||||||
|
bodyB: bodyB,
|
||||||
|
parentA: bodyA.parent,
|
||||||
|
parentB: bodyB.parent,
|
||||||
|
depth: 0,
|
||||||
|
normal: { x: 0, y: 0 },
|
||||||
|
tangent: { x: 0, y: 0 },
|
||||||
|
penetration: { x: 0, y: 0 },
|
||||||
|
supports: []
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect collision between two bodies.
|
||||||
|
* @method collides
|
||||||
|
* @param {body} bodyA
|
||||||
|
* @param {body} bodyB
|
||||||
|
* @param {pairs} [pairs] Optionally reuse collision records from existing pairs.
|
||||||
|
* @return {collision|null} A collision record if detected, otherwise null
|
||||||
|
*/
|
||||||
|
Collision.collides = function(bodyA, bodyB, pairs) {
|
||||||
|
Collision._overlapAxes(_overlapAB, bodyA.vertices, bodyB.vertices, bodyA.axes);
|
||||||
|
|
||||||
|
if (_overlapAB.overlap <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collision._overlapAxes(_overlapBA, bodyB.vertices, bodyA.vertices, bodyB.axes);
|
||||||
|
|
||||||
|
if (_overlapBA.overlap <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reuse collision records for gc efficiency
|
||||||
|
var pair = pairs && pairs.table[Pair.id(bodyA, bodyB)],
|
||||||
|
collision;
|
||||||
|
|
||||||
|
if (!pair) {
|
||||||
|
collision = Collision.create(bodyA, bodyB);
|
||||||
|
collision.collided = true;
|
||||||
|
collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB;
|
||||||
|
collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA;
|
||||||
|
collision.parentA = collision.bodyA.parent;
|
||||||
|
collision.parentB = collision.bodyB.parent;
|
||||||
|
} else {
|
||||||
|
collision = pair.collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyA = collision.bodyA;
|
||||||
|
bodyB = collision.bodyB;
|
||||||
|
|
||||||
|
var minOverlap;
|
||||||
|
|
||||||
|
if (_overlapAB.overlap < _overlapBA.overlap) {
|
||||||
|
minOverlap = _overlapAB;
|
||||||
|
} else {
|
||||||
|
minOverlap = _overlapBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
var normal = collision.normal,
|
||||||
|
supports = collision.supports,
|
||||||
|
minAxis = minOverlap.axis,
|
||||||
|
minAxisX = minAxis.x,
|
||||||
|
minAxisY = minAxis.y;
|
||||||
|
|
||||||
|
// ensure normal is facing away from bodyA
|
||||||
|
if (minAxisX * (bodyB.position.x - bodyA.position.x) + minAxisY * (bodyB.position.y - bodyA.position.y) < 0) {
|
||||||
|
normal.x = minAxisX;
|
||||||
|
normal.y = minAxisY;
|
||||||
|
} else {
|
||||||
|
normal.x = -minAxisX;
|
||||||
|
normal.y = -minAxisY;
|
||||||
|
}
|
||||||
|
|
||||||
|
collision.tangent.x = -normal.y;
|
||||||
|
collision.tangent.y = normal.x;
|
||||||
|
|
||||||
|
collision.depth = minOverlap.overlap;
|
||||||
|
|
||||||
|
collision.penetration.x = normal.x * collision.depth;
|
||||||
|
collision.penetration.y = normal.y * collision.depth;
|
||||||
|
|
||||||
|
// find support points, there is always either exactly one or two
|
||||||
|
var supportsB = Collision._findSupports(bodyA, bodyB, normal, 1),
|
||||||
|
supportCount = 0;
|
||||||
|
|
||||||
|
// find the supports from bodyB that are inside bodyA
|
||||||
|
if (Vertices.contains(bodyA.vertices, supportsB[0])) {
|
||||||
|
supports[supportCount++] = supportsB[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Vertices.contains(bodyA.vertices, supportsB[1])) {
|
||||||
|
supports[supportCount++] = supportsB[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the supports from bodyA that are inside bodyB
|
||||||
|
if (supportCount < 2) {
|
||||||
|
var supportsA = Collision._findSupports(bodyB, bodyA, normal, -1);
|
||||||
|
|
||||||
|
if (Vertices.contains(bodyB.vertices, supportsA[0])) {
|
||||||
|
supports[supportCount++] = supportsA[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportCount < 2 && Vertices.contains(bodyB.vertices, supportsA[1])) {
|
||||||
|
supports[supportCount++] = supportsA[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// account for the edge case of overlapping but no vertex containment
|
||||||
|
if (supportCount === 0) {
|
||||||
|
supports[supportCount++] = supportsB[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// update supports array size
|
||||||
|
supports.length = supportCount;
|
||||||
|
|
||||||
|
return collision;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the overlap between two sets of vertices.
|
||||||
|
* @method _overlapAxes
|
||||||
|
* @private
|
||||||
|
* @param {object} result
|
||||||
|
* @param {vertices} verticesA
|
||||||
|
* @param {vertices} verticesB
|
||||||
|
* @param {axes} axes
|
||||||
|
*/
|
||||||
|
Collision._overlapAxes = function(result, verticesA, verticesB, axes) {
|
||||||
|
var verticesALength = verticesA.length,
|
||||||
|
verticesBLength = verticesB.length,
|
||||||
|
verticesAX = verticesA[0].x,
|
||||||
|
verticesAY = verticesA[0].y,
|
||||||
|
verticesBX = verticesB[0].x,
|
||||||
|
verticesBY = verticesB[0].y,
|
||||||
|
axesLength = axes.length,
|
||||||
|
overlapMin = Number.MAX_VALUE,
|
||||||
|
overlapAxisNumber = 0,
|
||||||
|
overlap,
|
||||||
|
overlapAB,
|
||||||
|
overlapBA,
|
||||||
|
dot,
|
||||||
|
i,
|
||||||
|
j;
|
||||||
|
|
||||||
|
for (i = 0; i < axesLength; i++) {
|
||||||
|
var axis = axes[i],
|
||||||
|
axisX = axis.x,
|
||||||
|
axisY = axis.y,
|
||||||
|
minA = verticesAX * axisX + verticesAY * axisY,
|
||||||
|
minB = verticesBX * axisX + verticesBY * axisY,
|
||||||
|
maxA = minA,
|
||||||
|
maxB = minB;
|
||||||
|
|
||||||
|
for (j = 1; j < verticesALength; j += 1) {
|
||||||
|
dot = verticesA[j].x * axisX + verticesA[j].y * axisY;
|
||||||
|
|
||||||
|
if (dot > maxA) {
|
||||||
|
maxA = dot;
|
||||||
|
} else if (dot < minA) {
|
||||||
|
minA = dot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 1; j < verticesBLength; j += 1) {
|
||||||
|
dot = verticesB[j].x * axisX + verticesB[j].y * axisY;
|
||||||
|
|
||||||
|
if (dot > maxB) {
|
||||||
|
maxB = dot;
|
||||||
|
} else if (dot < minB) {
|
||||||
|
minB = dot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overlapAB = maxA - minB;
|
||||||
|
overlapBA = maxB - minA;
|
||||||
|
overlap = overlapAB < overlapBA ? overlapAB : overlapBA;
|
||||||
|
|
||||||
|
if (overlap < overlapMin) {
|
||||||
|
overlapMin = overlap;
|
||||||
|
overlapAxisNumber = i;
|
||||||
|
|
||||||
|
if (overlap <= 0) {
|
||||||
|
// can not be intersecting
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.axis = axes[overlapAxisNumber];
|
||||||
|
result.overlap = overlapMin;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Projects vertices on an axis and returns an interval.
|
||||||
|
* @method _projectToAxis
|
||||||
|
* @private
|
||||||
|
* @param {} projection
|
||||||
|
* @param {} vertices
|
||||||
|
* @param {} axis
|
||||||
|
*/
|
||||||
|
Collision._projectToAxis = function(projection, vertices, axis) {
|
||||||
|
var min = vertices[0].x * axis.x + vertices[0].y * axis.y,
|
||||||
|
max = min;
|
||||||
|
|
||||||
|
for (var i = 1; i < vertices.length; i += 1) {
|
||||||
|
var dot = vertices[i].x * axis.x + vertices[i].y * axis.y;
|
||||||
|
|
||||||
|
if (dot > max) {
|
||||||
|
max = dot;
|
||||||
|
} else if (dot < min) {
|
||||||
|
min = dot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
projection.min = min;
|
||||||
|
projection.max = max;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds supporting vertices given two bodies along a given direction using hill-climbing.
|
||||||
|
* @method _findSupports
|
||||||
|
* @private
|
||||||
|
* @param {body} bodyA
|
||||||
|
* @param {body} bodyB
|
||||||
|
* @param {vector} normal
|
||||||
|
* @param {number} direction
|
||||||
|
* @return [vector]
|
||||||
|
*/
|
||||||
|
Collision._findSupports = function(bodyA, bodyB, normal, direction) {
|
||||||
|
var vertices = bodyB.vertices,
|
||||||
|
verticesLength = vertices.length,
|
||||||
|
bodyAPositionX = bodyA.position.x,
|
||||||
|
bodyAPositionY = bodyA.position.y,
|
||||||
|
normalX = normal.x * direction,
|
||||||
|
normalY = normal.y * direction,
|
||||||
|
nearestDistance = Number.MAX_VALUE,
|
||||||
|
vertexA,
|
||||||
|
vertexB,
|
||||||
|
vertexC,
|
||||||
|
distance,
|
||||||
|
j;
|
||||||
|
|
||||||
|
// find deepest vertex relative to the axis
|
||||||
|
for (j = 0; j < verticesLength; j += 1) {
|
||||||
|
vertexB = vertices[j];
|
||||||
|
distance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y);
|
||||||
|
|
||||||
|
// convex hill-climbing
|
||||||
|
if (distance < nearestDistance) {
|
||||||
|
nearestDistance = distance;
|
||||||
|
vertexA = vertexB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// measure next vertex
|
||||||
|
vertexC = vertices[(verticesLength + vertexA.index - 1) % verticesLength];
|
||||||
|
nearestDistance = normalX * (bodyAPositionX - vertexC.x) + normalY * (bodyAPositionY - vertexC.y);
|
||||||
|
|
||||||
|
// compare with previous vertex
|
||||||
|
vertexB = vertices[(vertexA.index + 1) % verticesLength];
|
||||||
|
if (normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y) < nearestDistance) {
|
||||||
|
_supports[0] = vertexA;
|
||||||
|
_supports[1] = vertexB;
|
||||||
|
|
||||||
|
return _supports;
|
||||||
|
}
|
||||||
|
|
||||||
|
_supports[0] = vertexA;
|
||||||
|
_supports[1] = vertexC;
|
||||||
|
|
||||||
|
return _supports;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Properties Documentation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reference to the pair using this collision record, if there is one.
|
||||||
|
*
|
||||||
|
* @property pair
|
||||||
|
* @type {pair|null}
|
||||||
|
* @default null
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag that indicates if the bodies were colliding when the collision was last updated.
|
||||||
|
*
|
||||||
|
* @property collided
|
||||||
|
* @type boolean
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first body part represented by the collision (see also `collision.parentA`).
|
||||||
|
*
|
||||||
|
* @property bodyA
|
||||||
|
* @type body
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The second body part represented by the collision (see also `collision.parentB`).
|
||||||
|
*
|
||||||
|
* @property bodyB
|
||||||
|
* @type body
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first body represented by the collision (i.e. `collision.bodyA.parent`).
|
||||||
|
*
|
||||||
|
* @property parentA
|
||||||
|
* @type body
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The second body represented by the collision (i.e. `collision.bodyB.parent`).
|
||||||
|
*
|
||||||
|
* @property parentB
|
||||||
|
* @type body
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Number` that represents the minimum separating distance between the bodies along the collision normal.
|
||||||
|
*
|
||||||
|
* @readOnly
|
||||||
|
* @property depth
|
||||||
|
* @type number
|
||||||
|
* @default 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A normalised `Vector` that represents the direction between the bodies that provides the minimum separating distance.
|
||||||
|
*
|
||||||
|
* @property normal
|
||||||
|
* @type vector
|
||||||
|
* @default { x: 0, y: 0 }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A normalised `Vector` that is the tangent direction to the collision normal.
|
||||||
|
*
|
||||||
|
* @property tangent
|
||||||
|
* @type vector
|
||||||
|
* @default { x: 0, y: 0 }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Vector` that represents the direction and depth of the collision.
|
||||||
|
*
|
||||||
|
* @property penetration
|
||||||
|
* @type vector
|
||||||
|
* @default { x: 0, y: 0 }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of body vertices that represent the support points in the collision.
|
||||||
|
* These are the deepest vertices (along the collision normal) of each body that are contained by the other body's vertices.
|
||||||
|
*
|
||||||
|
* @property supports
|
||||||
|
* @type vector[]
|
||||||
|
* @default []
|
||||||
|
*/
|
||||||
|
|
||||||
|
})();
|
27
src/physics/matter-js/lib/collision/Contact.js
Normal file
27
src/physics/matter-js/lib/collision/Contact.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* The `Matter.Contact` module contains methods for creating and manipulating collision contacts.
|
||||||
|
*
|
||||||
|
* @class Contact
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Contact = {};
|
||||||
|
|
||||||
|
module.exports = Contact;
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new contact.
|
||||||
|
* @method create
|
||||||
|
* @param {vertex} vertex
|
||||||
|
* @return {contact} A new contact
|
||||||
|
*/
|
||||||
|
Contact.create = function(vertex) {
|
||||||
|
return {
|
||||||
|
vertex: vertex,
|
||||||
|
normalImpulse: 0,
|
||||||
|
tangentImpulse: 0
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
|
@ -1,84 +1,132 @@
|
||||||
/**
|
/**
|
||||||
* The `Matter.Detector` module contains methods for detecting collisions given a set of pairs.
|
* The `Matter.Detector` module contains methods for efficiently detecting collisions between a list of bodies using a broadphase algorithm.
|
||||||
*
|
*
|
||||||
* @class Detector
|
* @class Detector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: speculative contacts
|
|
||||||
|
|
||||||
var Detector = {};
|
var Detector = {};
|
||||||
|
|
||||||
module.exports = Detector;
|
module.exports = Detector;
|
||||||
|
|
||||||
var SAT = require('./SAT');
|
var Common = require('../core/Common');
|
||||||
var Pair = require('./Pair');
|
var Collision = require('./Collision');
|
||||||
var Bounds = require('../geometry/Bounds');
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all collisions given a list of pairs.
|
* Creates a new collision detector.
|
||||||
* @method collisions
|
* @method create
|
||||||
* @param {pair[]} broadphasePairs
|
* @param {} options
|
||||||
* @param {engine} engine
|
* @return {detector} A new collision detector
|
||||||
* @return {array} collisions
|
|
||||||
*/
|
*/
|
||||||
Detector.collisions = function(broadphasePairs, engine) {
|
Detector.create = function(options) {
|
||||||
|
var defaults = {
|
||||||
|
bodies: [],
|
||||||
|
pairs: null
|
||||||
|
};
|
||||||
|
|
||||||
|
return Common.extend(defaults, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list of bodies in the detector.
|
||||||
|
* @method setBodies
|
||||||
|
* @param {detector} detector
|
||||||
|
* @param {body[]} bodies
|
||||||
|
*/
|
||||||
|
Detector.setBodies = function(detector, bodies) {
|
||||||
|
detector.bodies = bodies.slice(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the detector including its list of bodies.
|
||||||
|
* @method clear
|
||||||
|
* @param {detector} detector
|
||||||
|
*/
|
||||||
|
Detector.clear = function(detector) {
|
||||||
|
detector.bodies = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Efficiently finds all collisions among all the bodies in `detector.bodies` using a broadphase algorithm.
|
||||||
|
*
|
||||||
|
* _Note:_ The specific ordering of collisions returned is not guaranteed between releases and may change for performance reasons.
|
||||||
|
* If a specific ordering is required then apply a sort to the resulting array.
|
||||||
|
* @method collisions
|
||||||
|
* @param {detector} detector
|
||||||
|
* @return {collision[]} collisions
|
||||||
|
*/
|
||||||
|
Detector.collisions = function(detector) {
|
||||||
var collisions = [],
|
var collisions = [],
|
||||||
pairsTable = engine.pairs.table;
|
pairs = detector.pairs,
|
||||||
|
bodies = detector.bodies,
|
||||||
|
bodiesLength = bodies.length,
|
||||||
|
canCollide = Detector.canCollide,
|
||||||
|
collides = Collision.collides,
|
||||||
|
i,
|
||||||
|
j;
|
||||||
|
|
||||||
// @if DEBUG
|
bodies.sort(Detector._compareBoundsX);
|
||||||
var metrics = engine.metrics;
|
|
||||||
// @endif
|
|
||||||
|
|
||||||
for (var i = 0; i < broadphasePairs.length; i++) {
|
|
||||||
var bodyA = broadphasePairs[i][0],
|
|
||||||
bodyB = broadphasePairs[i][1];
|
|
||||||
|
|
||||||
if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping))
|
for (i = 0; i < bodiesLength; i++) {
|
||||||
continue;
|
var bodyA = bodies[i],
|
||||||
|
boundsA = bodyA.bounds,
|
||||||
if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter))
|
boundXMax = bodyA.bounds.max.x,
|
||||||
continue;
|
boundYMax = bodyA.bounds.max.y,
|
||||||
|
boundYMin = bodyA.bounds.min.y,
|
||||||
|
bodyAStatic = bodyA.isStatic || bodyA.isSleeping,
|
||||||
|
partsALength = bodyA.parts.length,
|
||||||
|
partsASingle = partsALength === 1;
|
||||||
|
|
||||||
// @if DEBUG
|
for (j = i + 1; j < bodiesLength; j++) {
|
||||||
metrics.midphaseTests += 1;
|
var bodyB = bodies[j],
|
||||||
// @endif
|
boundsB = bodyB.bounds;
|
||||||
|
|
||||||
// mid phase
|
if (boundsB.min.x > boundXMax) {
|
||||||
if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
|
break;
|
||||||
for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) {
|
}
|
||||||
var partA = bodyA.parts[j];
|
|
||||||
|
|
||||||
for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) {
|
if (boundYMax < boundsB.min.y || boundYMin > boundsB.max.y) {
|
||||||
var partB = bodyB.parts[k];
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
|
if (bodyAStatic && (bodyB.isStatic || bodyB.isSleeping)) {
|
||||||
// find a previous collision we could reuse
|
continue;
|
||||||
var pairId = Pair.id(partA, partB),
|
}
|
||||||
pair = pairsTable[pairId],
|
|
||||||
previousCollision;
|
|
||||||
|
|
||||||
if (pair && pair.isActive) {
|
if (!canCollide(bodyA.collisionFilter, bodyB.collisionFilter)) {
|
||||||
previousCollision = pair.collision;
|
continue;
|
||||||
} else {
|
}
|
||||||
previousCollision = null;
|
|
||||||
|
var partsBLength = bodyB.parts.length;
|
||||||
|
|
||||||
|
if (partsASingle && partsBLength === 1) {
|
||||||
|
var collision = collides(bodyA, bodyB, pairs);
|
||||||
|
|
||||||
|
if (collision) {
|
||||||
|
collisions.push(collision);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var partsAStart = partsALength > 1 ? 1 : 0,
|
||||||
|
partsBStart = partsBLength > 1 ? 1 : 0;
|
||||||
|
|
||||||
|
for (var k = partsAStart; k < partsALength; k++) {
|
||||||
|
var partA = bodyA.parts[k],
|
||||||
|
boundsA = partA.bounds;
|
||||||
|
|
||||||
|
for (var z = partsBStart; z < partsBLength; z++) {
|
||||||
|
var partB = bodyB.parts[z],
|
||||||
|
boundsB = partB.bounds;
|
||||||
|
|
||||||
|
if (boundsA.min.x > boundsB.max.x || boundsA.max.x < boundsB.min.x
|
||||||
|
|| boundsA.max.y < boundsB.min.y || boundsA.min.y > boundsB.max.y) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// narrow phase
|
var collision = collides(partA, partB, pairs);
|
||||||
var collision = SAT.collides(partA, partB, previousCollision);
|
|
||||||
|
|
||||||
// @if DEBUG
|
if (collision) {
|
||||||
metrics.narrowphaseTests += 1;
|
|
||||||
if (collision.reused)
|
|
||||||
metrics.narrowReuseCount += 1;
|
|
||||||
// @endif
|
|
||||||
|
|
||||||
if (collision.collided) {
|
|
||||||
collisions.push(collision);
|
collisions.push(collision);
|
||||||
// @if DEBUG
|
|
||||||
metrics.narrowDetections += 1;
|
|
||||||
// @endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,4 +152,39 @@ var Bounds = require('../geometry/Bounds');
|
||||||
return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0;
|
return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The comparison function used in the broadphase algorithm.
|
||||||
|
* Returns the signed delta of the bodies bounds on the x-axis.
|
||||||
|
* @private
|
||||||
|
* @method _sortCompare
|
||||||
|
* @param {body} bodyA
|
||||||
|
* @param {body} bodyB
|
||||||
|
* @return {number} The signed delta used for sorting
|
||||||
|
*/
|
||||||
|
Detector._compareBoundsX = function(bodyA, bodyB) {
|
||||||
|
return bodyA.bounds.min.x - bodyB.bounds.min.x;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Properties Documentation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The array of `Matter.Body` between which the detector finds collisions.
|
||||||
|
*
|
||||||
|
* _Note:_ The order of bodies in this array _is not fixed_ and will be continually managed by the detector.
|
||||||
|
* @property bodies
|
||||||
|
* @type body[]
|
||||||
|
* @default []
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional. A `Matter.Pairs` object from which previous collision objects may be reused. Intended for internal `Matter.Engine` usage.
|
||||||
|
* @property pairs
|
||||||
|
* @type {pairs|null}
|
||||||
|
* @default null
|
||||||
|
*/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
/**
|
/**
|
||||||
|
* This module has now been replaced by `Matter.Detector`.
|
||||||
|
*
|
||||||
|
* All usage should be migrated to `Matter.Detector` or another alternative.
|
||||||
|
* For back-compatibility purposes this module will remain for a short term and then later removed in a future release.
|
||||||
|
*
|
||||||
* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
|
* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
|
||||||
*
|
*
|
||||||
* @class Grid
|
* @class Grid
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Grid = {};
|
var Grid = {};
|
||||||
|
@ -9,21 +15,20 @@ var Grid = {};
|
||||||
module.exports = Grid;
|
module.exports = Grid;
|
||||||
|
|
||||||
var Pair = require('./Pair');
|
var Pair = require('./Pair');
|
||||||
var Detector = require('./Detector');
|
|
||||||
var Common = require('../core/Common');
|
var Common = require('../core/Common');
|
||||||
|
var deprecated = Common.deprecated;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new grid.
|
* Creates a new grid.
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @method create
|
* @method create
|
||||||
* @param {} options
|
* @param {} options
|
||||||
* @return {grid} A new grid
|
* @return {grid} A new grid
|
||||||
*/
|
*/
|
||||||
Grid.create = function(options) {
|
Grid.create = function(options) {
|
||||||
var defaults = {
|
var defaults = {
|
||||||
controller: Grid,
|
|
||||||
detector: Detector.collisions,
|
|
||||||
buckets: {},
|
buckets: {},
|
||||||
pairs: {},
|
pairs: {},
|
||||||
pairsList: [],
|
pairsList: [],
|
||||||
|
@ -52,6 +57,7 @@ var Common = require('../core/Common');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the grid.
|
* Updates the grid.
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @method update
|
* @method update
|
||||||
* @param {grid} grid
|
* @param {grid} grid
|
||||||
* @param {body[]} bodies
|
* @param {body[]} bodies
|
||||||
|
@ -66,20 +72,15 @@ var Common = require('../core/Common');
|
||||||
bucketId,
|
bucketId,
|
||||||
gridChanged = false;
|
gridChanged = false;
|
||||||
|
|
||||||
// @if DEBUG
|
|
||||||
var metrics = engine.metrics;
|
|
||||||
metrics.broadphaseTests = 0;
|
|
||||||
// @endif
|
|
||||||
|
|
||||||
for (i = 0; i < bodies.length; i++) {
|
for (i = 0; i < bodies.length; i++) {
|
||||||
var body = bodies[i];
|
var body = bodies[i];
|
||||||
|
|
||||||
if (body.isSleeping && !forceUpdate)
|
if (body.isSleeping && !forceUpdate)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// don't update out of world bodies
|
// temporary back compatibility bounds check
|
||||||
if (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x
|
if (world.bounds && (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x
|
||||||
|| body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)
|
|| body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var newRegion = Grid._getRegion(grid, body);
|
var newRegion = Grid._getRegion(grid, body);
|
||||||
|
@ -87,10 +88,6 @@ var Common = require('../core/Common');
|
||||||
// if the body has changed grid region
|
// if the body has changed grid region
|
||||||
if (!body.region || newRegion.id !== body.region.id || forceUpdate) {
|
if (!body.region || newRegion.id !== body.region.id || forceUpdate) {
|
||||||
|
|
||||||
// @if DEBUG
|
|
||||||
metrics.broadphaseTests += 1;
|
|
||||||
// @endif
|
|
||||||
|
|
||||||
if (!body.region || forceUpdate)
|
if (!body.region || forceUpdate)
|
||||||
body.region = newRegion;
|
body.region = newRegion;
|
||||||
|
|
||||||
|
@ -139,8 +136,11 @@ var Common = require('../core/Common');
|
||||||
grid.pairsList = Grid._createActivePairsList(grid);
|
grid.pairsList = Grid._createActivePairsList(grid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deprecated(Grid, 'update', 'Grid.update ➤ replaced by Matter.Detector');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the grid.
|
* Clears the grid.
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @method clear
|
* @method clear
|
||||||
* @param {grid} grid
|
* @param {grid} grid
|
||||||
*/
|
*/
|
||||||
|
@ -150,9 +150,12 @@ var Common = require('../core/Common');
|
||||||
grid.pairsList = [];
|
grid.pairsList = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deprecated(Grid, 'clear', 'Grid.clear ➤ replaced by Matter.Detector');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the union of two regions.
|
* Finds the union of two regions.
|
||||||
* @method _regionUnion
|
* @method _regionUnion
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} regionA
|
* @param {} regionA
|
||||||
* @param {} regionB
|
* @param {} regionB
|
||||||
|
@ -170,6 +173,7 @@ var Common = require('../core/Common');
|
||||||
/**
|
/**
|
||||||
* Gets the region a given body falls in for a given grid.
|
* Gets the region a given body falls in for a given grid.
|
||||||
* @method _getRegion
|
* @method _getRegion
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} grid
|
* @param {} grid
|
||||||
* @param {} body
|
* @param {} body
|
||||||
|
@ -188,6 +192,7 @@ var Common = require('../core/Common');
|
||||||
/**
|
/**
|
||||||
* Creates a region.
|
* Creates a region.
|
||||||
* @method _createRegion
|
* @method _createRegion
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} startCol
|
* @param {} startCol
|
||||||
* @param {} endCol
|
* @param {} endCol
|
||||||
|
@ -208,6 +213,7 @@ var Common = require('../core/Common');
|
||||||
/**
|
/**
|
||||||
* Gets the bucket id at the given position.
|
* Gets the bucket id at the given position.
|
||||||
* @method _getBucketId
|
* @method _getBucketId
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} column
|
* @param {} column
|
||||||
* @param {} row
|
* @param {} row
|
||||||
|
@ -220,6 +226,7 @@ var Common = require('../core/Common');
|
||||||
/**
|
/**
|
||||||
* Creates a bucket.
|
* Creates a bucket.
|
||||||
* @method _createBucket
|
* @method _createBucket
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} buckets
|
* @param {} buckets
|
||||||
* @param {} bucketId
|
* @param {} bucketId
|
||||||
|
@ -233,14 +240,20 @@ var Common = require('../core/Common');
|
||||||
/**
|
/**
|
||||||
* Adds a body to a bucket.
|
* Adds a body to a bucket.
|
||||||
* @method _bucketAddBody
|
* @method _bucketAddBody
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} grid
|
* @param {} grid
|
||||||
* @param {} bucket
|
* @param {} bucket
|
||||||
* @param {} body
|
* @param {} body
|
||||||
*/
|
*/
|
||||||
Grid._bucketAddBody = function(grid, bucket, body) {
|
Grid._bucketAddBody = function(grid, bucket, body) {
|
||||||
|
var gridPairs = grid.pairs,
|
||||||
|
pairId = Pair.id,
|
||||||
|
bucketLength = bucket.length,
|
||||||
|
i;
|
||||||
|
|
||||||
// add new pairs
|
// add new pairs
|
||||||
for (var i = 0; i < bucket.length; i++) {
|
for (i = 0; i < bucketLength; i++) {
|
||||||
var bodyB = bucket[i];
|
var bodyB = bucket[i];
|
||||||
|
|
||||||
if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic))
|
if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic))
|
||||||
|
@ -248,13 +261,13 @@ var Common = require('../core/Common');
|
||||||
|
|
||||||
// keep track of the number of buckets the pair exists in
|
// keep track of the number of buckets the pair exists in
|
||||||
// important for Grid.update to work
|
// important for Grid.update to work
|
||||||
var pairId = Pair.id(body, bodyB),
|
var id = pairId(body, bodyB),
|
||||||
pair = grid.pairs[pairId];
|
pair = gridPairs[id];
|
||||||
|
|
||||||
if (pair) {
|
if (pair) {
|
||||||
pair[2] += 1;
|
pair[2] += 1;
|
||||||
} else {
|
} else {
|
||||||
grid.pairs[pairId] = [body, bodyB, 1];
|
gridPairs[id] = [body, bodyB, 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,22 +278,27 @@ var Common = require('../core/Common');
|
||||||
/**
|
/**
|
||||||
* Removes a body from a bucket.
|
* Removes a body from a bucket.
|
||||||
* @method _bucketRemoveBody
|
* @method _bucketRemoveBody
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} grid
|
* @param {} grid
|
||||||
* @param {} bucket
|
* @param {} bucket
|
||||||
* @param {} body
|
* @param {} body
|
||||||
*/
|
*/
|
||||||
Grid._bucketRemoveBody = function(grid, bucket, body) {
|
Grid._bucketRemoveBody = function(grid, bucket, body) {
|
||||||
|
var gridPairs = grid.pairs,
|
||||||
|
pairId = Pair.id,
|
||||||
|
i;
|
||||||
|
|
||||||
// remove from bucket
|
// remove from bucket
|
||||||
bucket.splice(bucket.indexOf(body), 1);
|
bucket.splice(Common.indexOf(bucket, body), 1);
|
||||||
|
|
||||||
|
var bucketLength = bucket.length;
|
||||||
|
|
||||||
// update pair counts
|
// update pair counts
|
||||||
for (var i = 0; i < bucket.length; i++) {
|
for (i = 0; i < bucketLength; i++) {
|
||||||
// keep track of the number of buckets the pair exists in
|
// keep track of the number of buckets the pair exists in
|
||||||
// important for _createActivePairsList to work
|
// important for _createActivePairsList to work
|
||||||
var bodyB = bucket[i],
|
var pair = gridPairs[pairId(body, bucket[i])];
|
||||||
pairId = Pair.id(body, bodyB),
|
|
||||||
pair = grid.pairs[pairId];
|
|
||||||
|
|
||||||
if (pair)
|
if (pair)
|
||||||
pair[2] -= 1;
|
pair[2] -= 1;
|
||||||
|
@ -290,28 +308,29 @@ var Common = require('../core/Common');
|
||||||
/**
|
/**
|
||||||
* Generates a list of the active pairs in the grid.
|
* Generates a list of the active pairs in the grid.
|
||||||
* @method _createActivePairsList
|
* @method _createActivePairsList
|
||||||
|
* @deprecated replaced by Matter.Detector
|
||||||
* @private
|
* @private
|
||||||
* @param {} grid
|
* @param {} grid
|
||||||
* @return [] pairs
|
* @return [] pairs
|
||||||
*/
|
*/
|
||||||
Grid._createActivePairsList = function(grid) {
|
Grid._createActivePairsList = function(grid) {
|
||||||
var pairKeys,
|
var pair,
|
||||||
pair,
|
gridPairs = grid.pairs,
|
||||||
pairs = [];
|
pairKeys = Common.keys(gridPairs),
|
||||||
|
pairKeysLength = pairKeys.length,
|
||||||
// grid.pairs is used as a hashmap
|
pairs = [],
|
||||||
pairKeys = Common.keys(grid.pairs);
|
k;
|
||||||
|
|
||||||
// iterate over grid.pairs
|
// iterate over grid.pairs
|
||||||
for (var k = 0; k < pairKeys.length; k++) {
|
for (k = 0; k < pairKeysLength; k++) {
|
||||||
pair = grid.pairs[pairKeys[k]];
|
pair = gridPairs[pairKeys[k]];
|
||||||
|
|
||||||
// if pair exists in at least one bucket
|
// if pair exists in at least one bucket
|
||||||
// it is a pair that needs further collision testing so push it
|
// it is a pair that needs further collision testing so push it
|
||||||
if (pair[2] > 0) {
|
if (pair[2] > 0) {
|
||||||
pairs.push(pair);
|
pairs.push(pair);
|
||||||
} else {
|
} else {
|
||||||
delete grid.pairs[pairKeys[k]];
|
delete gridPairs[pairKeys[k]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ var Pair = {};
|
||||||
|
|
||||||
module.exports = Pair;
|
module.exports = Pair;
|
||||||
|
|
||||||
|
var Contact = require('./Contact');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,6 +27,8 @@ module.exports = Pair;
|
||||||
id: Pair.id(bodyA, bodyB),
|
id: Pair.id(bodyA, bodyB),
|
||||||
bodyA: bodyA,
|
bodyA: bodyA,
|
||||||
bodyB: bodyB,
|
bodyB: bodyB,
|
||||||
|
collision: collision,
|
||||||
|
contacts: [],
|
||||||
activeContacts: [],
|
activeContacts: [],
|
||||||
separation: 0,
|
separation: 0,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
@ -32,7 +36,6 @@ module.exports = Pair;
|
||||||
isSensor: bodyA.isSensor || bodyB.isSensor,
|
isSensor: bodyA.isSensor || bodyB.isSensor,
|
||||||
timeCreated: timestamp,
|
timeCreated: timestamp,
|
||||||
timeUpdated: timestamp,
|
timeUpdated: timestamp,
|
||||||
collision: null,
|
|
||||||
inverseMass: 0,
|
inverseMass: 0,
|
||||||
friction: 0,
|
friction: 0,
|
||||||
frictionStatic: 0,
|
frictionStatic: 0,
|
||||||
|
@ -53,35 +56,36 @@ module.exports = Pair;
|
||||||
* @param {number} timestamp
|
* @param {number} timestamp
|
||||||
*/
|
*/
|
||||||
Pair.update = function(pair, collision, timestamp) {
|
Pair.update = function(pair, collision, timestamp) {
|
||||||
|
var contacts = pair.contacts,
|
||||||
|
supports = collision.supports,
|
||||||
|
activeContacts = pair.activeContacts,
|
||||||
|
parentA = collision.parentA,
|
||||||
|
parentB = collision.parentB,
|
||||||
|
parentAVerticesLength = parentA.vertices.length;
|
||||||
|
|
||||||
|
pair.isActive = true;
|
||||||
|
pair.timeUpdated = timestamp;
|
||||||
pair.collision = collision;
|
pair.collision = collision;
|
||||||
|
pair.separation = collision.depth;
|
||||||
|
pair.inverseMass = parentA.inverseMass + parentB.inverseMass;
|
||||||
|
pair.friction = parentA.friction < parentB.friction ? parentA.friction : parentB.friction;
|
||||||
|
pair.frictionStatic = parentA.frictionStatic > parentB.frictionStatic ? parentA.frictionStatic : parentB.frictionStatic;
|
||||||
|
pair.restitution = parentA.restitution > parentB.restitution ? parentA.restitution : parentB.restitution;
|
||||||
|
pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop;
|
||||||
|
|
||||||
if (collision.collided) {
|
collision.pair = pair;
|
||||||
var supports = collision.supports,
|
activeContacts.length = 0;
|
||||||
activeContacts = pair.activeContacts,
|
|
||||||
parentA = collision.parentA,
|
for (var i = 0; i < supports.length; i++) {
|
||||||
parentB = collision.parentB;
|
var support = supports[i],
|
||||||
|
contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index,
|
||||||
|
contact = contacts[contactId];
|
||||||
|
|
||||||
pair.inverseMass = parentA.inverseMass + parentB.inverseMass;
|
if (contact) {
|
||||||
pair.friction = Math.min(parentA.friction, parentB.friction);
|
activeContacts.push(contact);
|
||||||
pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic);
|
} else {
|
||||||
pair.restitution = Math.max(parentA.restitution, parentB.restitution);
|
activeContacts.push(contacts[contactId] = Contact.create(support));
|
||||||
pair.slop = Math.max(parentA.slop, parentB.slop);
|
|
||||||
|
|
||||||
for (var i = 0; i < supports.length; i++) {
|
|
||||||
activeContacts[i] = supports[i].contact;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimise array size
|
|
||||||
var supportCount = supports.length;
|
|
||||||
if (supportCount < activeContacts.length) {
|
|
||||||
activeContacts.length = supportCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
pair.separation = collision.depth;
|
|
||||||
Pair.setActive(pair, true, timestamp);
|
|
||||||
} else {
|
|
||||||
if (pair.isActive === true)
|
|
||||||
Pair.setActive(pair, false, timestamp);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,6 @@ var Pair = require('./Pair');
|
||||||
var Common = require('../core/Common');
|
var Common = require('../core/Common');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
Pairs._pairMaxIdleLife = 1000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new pairs structure.
|
* Creates a new pairs structure.
|
||||||
|
@ -40,12 +38,14 @@ var Common = require('../core/Common');
|
||||||
*/
|
*/
|
||||||
Pairs.update = function(pairs, collisions, timestamp) {
|
Pairs.update = function(pairs, collisions, timestamp) {
|
||||||
var pairsList = pairs.list,
|
var pairsList = pairs.list,
|
||||||
|
pairsListLength = pairsList.length,
|
||||||
pairsTable = pairs.table,
|
pairsTable = pairs.table,
|
||||||
|
collisionsLength = collisions.length,
|
||||||
collisionStart = pairs.collisionStart,
|
collisionStart = pairs.collisionStart,
|
||||||
collisionEnd = pairs.collisionEnd,
|
collisionEnd = pairs.collisionEnd,
|
||||||
collisionActive = pairs.collisionActive,
|
collisionActive = pairs.collisionActive,
|
||||||
collision,
|
collision,
|
||||||
pairId,
|
pairIndex,
|
||||||
pair,
|
pair,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
|
@ -54,90 +54,61 @@ var Common = require('../core/Common');
|
||||||
collisionEnd.length = 0;
|
collisionEnd.length = 0;
|
||||||
collisionActive.length = 0;
|
collisionActive.length = 0;
|
||||||
|
|
||||||
for (i = 0; i < pairsList.length; i++) {
|
for (i = 0; i < pairsListLength; i++) {
|
||||||
pairsList[i].confirmedActive = false;
|
pairsList[i].confirmedActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < collisions.length; i++) {
|
for (i = 0; i < collisionsLength; i++) {
|
||||||
collision = collisions[i];
|
collision = collisions[i];
|
||||||
|
pair = collision.pair;
|
||||||
|
|
||||||
if (collision.collided) {
|
if (pair) {
|
||||||
pairId = Pair.id(collision.bodyA, collision.bodyB);
|
// pair already exists (but may or may not be active)
|
||||||
|
if (pair.isActive) {
|
||||||
pair = pairsTable[pairId];
|
// pair exists and is active
|
||||||
|
collisionActive.push(pair);
|
||||||
if (pair) {
|
|
||||||
// pair already exists (but may or may not be active)
|
|
||||||
if (pair.isActive) {
|
|
||||||
// pair exists and is active
|
|
||||||
collisionActive.push(pair);
|
|
||||||
} else {
|
|
||||||
// pair exists but was inactive, so a collision has just started again
|
|
||||||
collisionStart.push(pair);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the pair
|
|
||||||
Pair.update(pair, collision, timestamp);
|
|
||||||
pair.confirmedActive = true;
|
|
||||||
} else {
|
} else {
|
||||||
// pair did not exist, create a new pair
|
// pair exists but was inactive, so a collision has just started again
|
||||||
pair = Pair.create(collision, timestamp);
|
|
||||||
pairsTable[pairId] = pair;
|
|
||||||
|
|
||||||
// push the new pair
|
|
||||||
collisionStart.push(pair);
|
collisionStart.push(pair);
|
||||||
pairsList.push(pair);
|
}
|
||||||
|
|
||||||
|
// update the pair
|
||||||
|
Pair.update(pair, collision, timestamp);
|
||||||
|
pair.confirmedActive = true;
|
||||||
|
} else {
|
||||||
|
// pair did not exist, create a new pair
|
||||||
|
pair = Pair.create(collision, timestamp);
|
||||||
|
pairsTable[pair.id] = pair;
|
||||||
|
|
||||||
|
// push the new pair
|
||||||
|
collisionStart.push(pair);
|
||||||
|
pairsList.push(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find pairs that are no longer active
|
||||||
|
var removePairIndex = [];
|
||||||
|
pairsListLength = pairsList.length;
|
||||||
|
|
||||||
|
for (i = 0; i < pairsListLength; i++) {
|
||||||
|
pair = pairsList[i];
|
||||||
|
|
||||||
|
if (!pair.confirmedActive) {
|
||||||
|
Pair.setActive(pair, false, timestamp);
|
||||||
|
collisionEnd.push(pair);
|
||||||
|
|
||||||
|
if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) {
|
||||||
|
removePairIndex.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// deactivate previously active pairs that are now inactive
|
// remove inactive pairs
|
||||||
for (i = 0; i < pairsList.length; i++) {
|
for (i = 0; i < removePairIndex.length; i++) {
|
||||||
pair = pairsList[i];
|
pairIndex = removePairIndex[i] - i;
|
||||||
if (pair.isActive && !pair.confirmedActive) {
|
|
||||||
Pair.setActive(pair, false, timestamp);
|
|
||||||
collisionEnd.push(pair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds and removes pairs that have been inactive for a set amount of time.
|
|
||||||
* @method removeOld
|
|
||||||
* @param {object} pairs
|
|
||||||
* @param {number} timestamp
|
|
||||||
*/
|
|
||||||
Pairs.removeOld = function(pairs, timestamp) {
|
|
||||||
var pairsList = pairs.list,
|
|
||||||
pairsTable = pairs.table,
|
|
||||||
indexesToRemove = [],
|
|
||||||
pair,
|
|
||||||
collision,
|
|
||||||
pairIndex,
|
|
||||||
i;
|
|
||||||
|
|
||||||
for (i = 0; i < pairsList.length; i++) {
|
|
||||||
pair = pairsList[i];
|
|
||||||
collision = pair.collision;
|
|
||||||
|
|
||||||
// never remove sleeping pairs
|
|
||||||
if (collision.bodyA.isSleeping || collision.bodyB.isSleeping) {
|
|
||||||
pair.timeUpdated = timestamp;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if pair is inactive for too long, mark it to be removed
|
|
||||||
if (timestamp - pair.timeUpdated > Pairs._pairMaxIdleLife) {
|
|
||||||
indexesToRemove.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove marked pairs
|
|
||||||
for (i = 0; i < indexesToRemove.length; i++) {
|
|
||||||
pairIndex = indexesToRemove[i] - i;
|
|
||||||
pair = pairsList[pairIndex];
|
pair = pairsList[pairIndex];
|
||||||
delete pairsTable[pair.id];
|
|
||||||
pairsList.splice(pairIndex, 1);
|
pairsList.splice(pairIndex, 1);
|
||||||
|
delete pairsTable[pair.id];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ var Query = {};
|
||||||
module.exports = Query;
|
module.exports = Query;
|
||||||
|
|
||||||
var Vector = require('../geometry/Vector');
|
var Vector = require('../geometry/Vector');
|
||||||
var SAT = require('./SAT');
|
var Collision = require('./Collision');
|
||||||
var Bounds = require('../geometry/Bounds');
|
var Bounds = require('../geometry/Bounds');
|
||||||
var Bodies = require('../factory/Bodies');
|
var Bodies = require('../factory/Bodies');
|
||||||
var Vertices = require('../geometry/Vertices');
|
var Vertices = require('../geometry/Vertices');
|
||||||
|
@ -23,28 +23,34 @@ var Vertices = require('../geometry/Vertices');
|
||||||
* @method collides
|
* @method collides
|
||||||
* @param {body} body
|
* @param {body} body
|
||||||
* @param {body[]} bodies
|
* @param {body[]} bodies
|
||||||
* @return {object[]} Collisions
|
* @return {collision[]} Collisions
|
||||||
*/
|
*/
|
||||||
Query.collides = function(body, bodies) {
|
Query.collides = function(body, bodies) {
|
||||||
var collisions = [];
|
var collisions = [],
|
||||||
|
bodiesLength = bodies.length,
|
||||||
|
bounds = body.bounds,
|
||||||
|
collides = Collision.collides,
|
||||||
|
overlaps = Bounds.overlaps;
|
||||||
|
|
||||||
for (var i = 0; i < bodies.length; i++) {
|
for (var i = 0; i < bodiesLength; i++) {
|
||||||
var bodyA = bodies[i];
|
var bodyA = bodies[i],
|
||||||
|
partsALength = bodyA.parts.length,
|
||||||
|
partsAStart = partsALength === 1 ? 0 : 1;
|
||||||
|
|
||||||
// Phaser addition - skip same body checks
|
// Phaser addition - skip same body checks
|
||||||
if (body === bodyA)
|
if (body === bodyA)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Bounds.overlaps(bodyA.bounds, body.bounds)) {
|
if (overlaps(bodyA.bounds, bounds)) {
|
||||||
for (var j = bodyA.parts.length === 1 ? 0 : 1; j < bodyA.parts.length; j++) {
|
for (var j = partsAStart; j < partsALength; j++) {
|
||||||
var part = bodyA.parts[j];
|
var part = bodyA.parts[j];
|
||||||
|
|
||||||
if (Bounds.overlaps(part.bounds, body.bounds)) {
|
if (overlaps(part.bounds, bounds)) {
|
||||||
var collision = SAT.collides(part, body);
|
var collision = collides(part, body);
|
||||||
|
|
||||||
if (collision.collided) {
|
if (collision) {
|
||||||
collisions.push(collision);
|
collisions.push(collision);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +69,7 @@ var Vertices = require('../geometry/Vertices');
|
||||||
* @param {vector} startPoint
|
* @param {vector} startPoint
|
||||||
* @param {vector} endPoint
|
* @param {vector} endPoint
|
||||||
* @param {number} [rayWidth]
|
* @param {number} [rayWidth]
|
||||||
* @return {object[]} Collisions
|
* @return {collision[]} Collisions
|
||||||
*/
|
*/
|
||||||
Query.ray = function(bodies, startPoint, endPoint, rayWidth) {
|
Query.ray = function(bodies, startPoint, endPoint, rayWidth) {
|
||||||
rayWidth = rayWidth || 1e-100;
|
rayWidth = rayWidth || 1e-100;
|
||||||
|
@ -77,7 +83,7 @@ var Vertices = require('../geometry/Vertices');
|
||||||
|
|
||||||
for (var i = 0; i < collisions.length; i += 1) {
|
for (var i = 0; i < collisions.length; i += 1) {
|
||||||
var collision = collisions[i];
|
var collision = collisions[i];
|
||||||
collision.body = collision.bodyB = collision.bodyA;
|
collision.body = collision.bodyB = collision.bodyA;
|
||||||
}
|
}
|
||||||
|
|
||||||
return collisions;
|
return collisions;
|
||||||
|
@ -116,7 +122,7 @@ var Vertices = require('../geometry/Vertices');
|
||||||
|
|
||||||
for (var i = 0; i < bodies.length; i++) {
|
for (var i = 0; i < bodies.length; i++) {
|
||||||
var body = bodies[i];
|
var body = bodies[i];
|
||||||
|
|
||||||
if (Bounds.contains(body.bounds, point)) {
|
if (Bounds.contains(body.bounds, point)) {
|
||||||
for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) {
|
for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) {
|
||||||
var part = body.parts[j];
|
var part = body.parts[j];
|
||||||
|
|
|
@ -9,8 +9,6 @@ var Resolver = {};
|
||||||
module.exports = Resolver;
|
module.exports = Resolver;
|
||||||
|
|
||||||
var Vertices = require('../geometry/Vertices');
|
var Vertices = require('../geometry/Vertices');
|
||||||
var Vector = require('../geometry/Vector');
|
|
||||||
var Common = require('../core/Common');
|
|
||||||
var Bounds = require('../geometry/Bounds');
|
var Bounds = require('../geometry/Bounds');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
@ -29,10 +27,11 @@ var Bounds = require('../geometry/Bounds');
|
||||||
Resolver.preSolvePosition = function(pairs) {
|
Resolver.preSolvePosition = function(pairs) {
|
||||||
var i,
|
var i,
|
||||||
pair,
|
pair,
|
||||||
activeCount;
|
activeCount,
|
||||||
|
pairsLength = pairs.length;
|
||||||
|
|
||||||
// find total contacts on each body
|
// find total contacts on each body
|
||||||
for (i = 0; i < pairs.length; i++) {
|
for (i = 0; i < pairsLength; i++) {
|
||||||
pair = pairs[i];
|
pair = pairs[i];
|
||||||
|
|
||||||
if (!pair.isActive)
|
if (!pair.isActive)
|
||||||
|
@ -48,36 +47,22 @@ var Bounds = require('../geometry/Bounds');
|
||||||
* Find a solution for pair positions.
|
* Find a solution for pair positions.
|
||||||
* @method solvePosition
|
* @method solvePosition
|
||||||
* @param {pair[]} pairs
|
* @param {pair[]} pairs
|
||||||
* @param {body[]} bodies
|
|
||||||
* @param {number} timeScale
|
* @param {number} timeScale
|
||||||
*/
|
*/
|
||||||
Resolver.solvePosition = function(pairs, bodies, timeScale) {
|
Resolver.solvePosition = function(pairs, timeScale) {
|
||||||
var i,
|
var i,
|
||||||
normalX,
|
|
||||||
normalY,
|
|
||||||
pair,
|
pair,
|
||||||
collision,
|
collision,
|
||||||
bodyA,
|
bodyA,
|
||||||
bodyB,
|
bodyB,
|
||||||
normal,
|
normal,
|
||||||
separation,
|
|
||||||
penetration,
|
|
||||||
positionImpulseA,
|
|
||||||
positionImpulseB,
|
|
||||||
contactShare,
|
contactShare,
|
||||||
bodyBtoAX,
|
|
||||||
bodyBtoAY,
|
|
||||||
positionImpulse,
|
positionImpulse,
|
||||||
impulseCoefficient = timeScale * Resolver._positionDampen;
|
positionDampen = Resolver._positionDampen,
|
||||||
|
pairsLength = pairs.length;
|
||||||
for (i = 0; i < bodies.length; i++) {
|
|
||||||
var body = bodies[i];
|
|
||||||
body.previousPositionImpulse.x = body.positionImpulse.x;
|
|
||||||
body.previousPositionImpulse.y = body.positionImpulse.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find impulses required to resolve penetration
|
// find impulses required to resolve penetration
|
||||||
for (i = 0; i < pairs.length; i++) {
|
for (i = 0; i < pairsLength; i++) {
|
||||||
pair = pairs[i];
|
pair = pairs[i];
|
||||||
|
|
||||||
if (!pair.isActive || pair.isSensor)
|
if (!pair.isActive || pair.isSensor)
|
||||||
|
@ -88,35 +73,37 @@ var Bounds = require('../geometry/Bounds');
|
||||||
bodyB = collision.parentB;
|
bodyB = collision.parentB;
|
||||||
normal = collision.normal;
|
normal = collision.normal;
|
||||||
|
|
||||||
positionImpulseA = bodyA.previousPositionImpulse;
|
// get current separation between body edges involved in collision
|
||||||
positionImpulseB = bodyB.previousPositionImpulse;
|
pair.separation =
|
||||||
|
normal.x * (bodyB.positionImpulse.x + collision.penetration.x - bodyA.positionImpulse.x)
|
||||||
|
+ normal.y * (bodyB.positionImpulse.y + collision.penetration.y - bodyA.positionImpulse.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < pairsLength; i++) {
|
||||||
|
pair = pairs[i];
|
||||||
|
|
||||||
penetration = collision.penetration;
|
if (!pair.isActive || pair.isSensor)
|
||||||
|
continue;
|
||||||
bodyBtoAX = positionImpulseB.x - positionImpulseA.x + penetration.x;
|
|
||||||
bodyBtoAY = positionImpulseB.y - positionImpulseA.y + penetration.y;
|
collision = pair.collision;
|
||||||
|
bodyA = collision.parentA;
|
||||||
normalX = normal.x;
|
bodyB = collision.parentB;
|
||||||
normalY = normal.y;
|
normal = collision.normal;
|
||||||
|
positionImpulse = (pair.separation - pair.slop) * timeScale;
|
||||||
separation = normalX * bodyBtoAX + normalY * bodyBtoAY;
|
|
||||||
pair.separation = separation;
|
|
||||||
|
|
||||||
positionImpulse = (separation - pair.slop) * impulseCoefficient;
|
|
||||||
|
|
||||||
if (bodyA.isStatic || bodyB.isStatic)
|
if (bodyA.isStatic || bodyB.isStatic)
|
||||||
positionImpulse *= 2;
|
positionImpulse *= 2;
|
||||||
|
|
||||||
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
||||||
contactShare = positionImpulse / bodyA.totalContacts;
|
contactShare = positionDampen / bodyA.totalContacts;
|
||||||
bodyA.positionImpulse.x += normalX * contactShare;
|
bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
|
||||||
bodyA.positionImpulse.y += normalY * contactShare;
|
bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
||||||
contactShare = positionImpulse / bodyB.totalContacts;
|
contactShare = positionDampen / bodyB.totalContacts;
|
||||||
bodyB.positionImpulse.x -= normalX * contactShare;
|
bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
|
||||||
bodyB.positionImpulse.y -= normalY * contactShare;
|
bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -127,34 +114,43 @@ var Bounds = require('../geometry/Bounds');
|
||||||
* @param {body[]} bodies
|
* @param {body[]} bodies
|
||||||
*/
|
*/
|
||||||
Resolver.postSolvePosition = function(bodies) {
|
Resolver.postSolvePosition = function(bodies) {
|
||||||
for (var i = 0; i < bodies.length; i++) {
|
var positionWarming = Resolver._positionWarming,
|
||||||
var body = bodies[i];
|
bodiesLength = bodies.length,
|
||||||
|
verticesTranslate = Vertices.translate,
|
||||||
|
boundsUpdate = Bounds.update;
|
||||||
|
|
||||||
|
for (var i = 0; i < bodiesLength; i++) {
|
||||||
|
var body = bodies[i],
|
||||||
|
positionImpulse = body.positionImpulse,
|
||||||
|
positionImpulseX = positionImpulse.x,
|
||||||
|
positionImpulseY = positionImpulse.y,
|
||||||
|
velocity = body.velocity;
|
||||||
|
|
||||||
// reset contact count
|
// reset contact count
|
||||||
body.totalContacts = 0;
|
body.totalContacts = 0;
|
||||||
|
|
||||||
if (body.positionImpulse.x !== 0 || body.positionImpulse.y !== 0) {
|
if (positionImpulseX !== 0 || positionImpulseY !== 0) {
|
||||||
// update body geometry
|
// update body geometry
|
||||||
for (var j = 0; j < body.parts.length; j++) {
|
for (var j = 0; j < body.parts.length; j++) {
|
||||||
var part = body.parts[j];
|
var part = body.parts[j];
|
||||||
Vertices.translate(part.vertices, body.positionImpulse);
|
verticesTranslate(part.vertices, positionImpulse);
|
||||||
Bounds.update(part.bounds, part.vertices, body.velocity);
|
boundsUpdate(part.bounds, part.vertices, velocity);
|
||||||
part.position.x += body.positionImpulse.x;
|
part.position.x += positionImpulseX;
|
||||||
part.position.y += body.positionImpulse.y;
|
part.position.y += positionImpulseY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// move the body without changing velocity
|
// move the body without changing velocity
|
||||||
body.positionPrev.x += body.positionImpulse.x;
|
body.positionPrev.x += positionImpulseX;
|
||||||
body.positionPrev.y += body.positionImpulse.y;
|
body.positionPrev.y += positionImpulseY;
|
||||||
|
|
||||||
if (Vector.dot(body.positionImpulse, body.velocity) < 0) {
|
if (positionImpulseX * velocity.x + positionImpulseY * velocity.y < 0) {
|
||||||
// reset cached impulse if the body has velocity along it
|
// reset cached impulse if the body has velocity along it
|
||||||
body.positionImpulse.x = 0;
|
positionImpulse.x = 0;
|
||||||
body.positionImpulse.y = 0;
|
positionImpulse.y = 0;
|
||||||
} else {
|
} else {
|
||||||
// warm the next iteration
|
// warm the next iteration
|
||||||
body.positionImpulse.x *= Resolver._positionWarming;
|
positionImpulse.x *= positionWarming;
|
||||||
body.positionImpulse.y *= Resolver._positionWarming;
|
positionImpulse.y *= positionWarming;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,61 +162,53 @@ var Bounds = require('../geometry/Bounds');
|
||||||
* @param {pair[]} pairs
|
* @param {pair[]} pairs
|
||||||
*/
|
*/
|
||||||
Resolver.preSolveVelocity = function(pairs) {
|
Resolver.preSolveVelocity = function(pairs) {
|
||||||
var i,
|
var pairsLength = pairs.length,
|
||||||
j,
|
i,
|
||||||
pair,
|
j;
|
||||||
contacts,
|
|
||||||
collision,
|
|
||||||
bodyA,
|
|
||||||
bodyB,
|
|
||||||
normal,
|
|
||||||
tangent,
|
|
||||||
contact,
|
|
||||||
contactVertex,
|
|
||||||
normalImpulse,
|
|
||||||
tangentImpulse,
|
|
||||||
offset,
|
|
||||||
impulse = Vector._temp[0],
|
|
||||||
tempA = Vector._temp[1];
|
|
||||||
|
|
||||||
for (i = 0; i < pairs.length; i++) {
|
for (i = 0; i < pairsLength; i++) {
|
||||||
pair = pairs[i];
|
var pair = pairs[i];
|
||||||
|
|
||||||
if (!pair.isActive || pair.isSensor)
|
if (!pair.isActive || pair.isSensor)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
contacts = pair.activeContacts;
|
var contacts = pair.activeContacts,
|
||||||
collision = pair.collision;
|
contactsLength = contacts.length,
|
||||||
bodyA = collision.parentA;
|
collision = pair.collision,
|
||||||
bodyB = collision.parentB;
|
bodyA = collision.parentA,
|
||||||
normal = collision.normal;
|
bodyB = collision.parentB,
|
||||||
tangent = collision.tangent;
|
normal = collision.normal,
|
||||||
|
tangent = collision.tangent;
|
||||||
|
|
||||||
// resolve each contact
|
// resolve each contact
|
||||||
for (j = 0; j < contacts.length; j++) {
|
for (j = 0; j < contactsLength; j++) {
|
||||||
contact = contacts[j];
|
var contact = contacts[j],
|
||||||
contactVertex = contact.vertex;
|
contactVertex = contact.vertex,
|
||||||
normalImpulse = contact.normalImpulse;
|
normalImpulse = contact.normalImpulse,
|
||||||
tangentImpulse = contact.tangentImpulse;
|
tangentImpulse = contact.tangentImpulse;
|
||||||
|
|
||||||
if (normalImpulse !== 0 || tangentImpulse !== 0) {
|
if (normalImpulse !== 0 || tangentImpulse !== 0) {
|
||||||
// total impulse from contact
|
// total impulse from contact
|
||||||
impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
|
var impulseX = normal.x * normalImpulse + tangent.x * tangentImpulse,
|
||||||
impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
|
impulseY = normal.y * normalImpulse + tangent.y * tangentImpulse;
|
||||||
|
|
||||||
// apply impulse from contact
|
// apply impulse from contact
|
||||||
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
||||||
offset = Vector.sub(contactVertex, bodyA.position, tempA);
|
bodyA.positionPrev.x += impulseX * bodyA.inverseMass;
|
||||||
bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
|
bodyA.positionPrev.y += impulseY * bodyA.inverseMass;
|
||||||
bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
|
bodyA.anglePrev += bodyA.inverseInertia * (
|
||||||
bodyA.anglePrev += Vector.cross(offset, impulse) * bodyA.inverseInertia;
|
(contactVertex.x - bodyA.position.x) * impulseY
|
||||||
|
- (contactVertex.y - bodyA.position.y) * impulseX
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
||||||
offset = Vector.sub(contactVertex, bodyB.position, tempA);
|
bodyB.positionPrev.x -= impulseX * bodyB.inverseMass;
|
||||||
bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
|
bodyB.positionPrev.y -= impulseY * bodyB.inverseMass;
|
||||||
bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
|
bodyB.anglePrev -= bodyB.inverseInertia * (
|
||||||
bodyB.anglePrev -= Vector.cross(offset, impulse) * bodyB.inverseInertia;
|
(contactVertex.x - bodyB.position.x) * impulseY
|
||||||
|
- (contactVertex.y - bodyB.position.y) * impulseX
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,14 +223,17 @@ var Bounds = require('../geometry/Bounds');
|
||||||
*/
|
*/
|
||||||
Resolver.solveVelocity = function(pairs, timeScale) {
|
Resolver.solveVelocity = function(pairs, timeScale) {
|
||||||
var timeScaleSquared = timeScale * timeScale,
|
var timeScaleSquared = timeScale * timeScale,
|
||||||
impulse = Vector._temp[0],
|
restingThresh = Resolver._restingThresh * timeScaleSquared,
|
||||||
tempA = Vector._temp[1],
|
frictionNormalMultiplier = Resolver._frictionNormalMultiplier,
|
||||||
tempB = Vector._temp[2],
|
restingThreshTangent = Resolver._restingThreshTangent * timeScaleSquared,
|
||||||
tempC = Vector._temp[3],
|
NumberMaxValue = Number.MAX_VALUE,
|
||||||
tempD = Vector._temp[4],
|
pairsLength = pairs.length,
|
||||||
tempE = Vector._temp[5];
|
tangentImpulse,
|
||||||
|
maxFriction,
|
||||||
for (var i = 0; i < pairs.length; i++) {
|
i,
|
||||||
|
j;
|
||||||
|
|
||||||
|
for (i = 0; i < pairsLength; i++) {
|
||||||
var pair = pairs[i];
|
var pair = pairs[i];
|
||||||
|
|
||||||
if (!pair.isActive || pair.isSensor)
|
if (!pair.isActive || pair.isSensor)
|
||||||
|
@ -251,97 +242,119 @@ var Bounds = require('../geometry/Bounds');
|
||||||
var collision = pair.collision,
|
var collision = pair.collision,
|
||||||
bodyA = collision.parentA,
|
bodyA = collision.parentA,
|
||||||
bodyB = collision.parentB,
|
bodyB = collision.parentB,
|
||||||
normal = collision.normal,
|
bodyAVelocity = bodyA.velocity,
|
||||||
tangent = collision.tangent,
|
bodyBVelocity = bodyB.velocity,
|
||||||
|
normalX = collision.normal.x,
|
||||||
|
normalY = collision.normal.y,
|
||||||
|
tangentX = collision.tangent.x,
|
||||||
|
tangentY = collision.tangent.y,
|
||||||
contacts = pair.activeContacts,
|
contacts = pair.activeContacts,
|
||||||
contactShare = 1 / contacts.length;
|
contactsLength = contacts.length,
|
||||||
|
contactShare = 1 / contactsLength,
|
||||||
|
inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass,
|
||||||
|
friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier * timeScaleSquared;
|
||||||
|
|
||||||
// update body velocities
|
// update body velocities
|
||||||
bodyA.velocity.x = bodyA.position.x - bodyA.positionPrev.x;
|
bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x;
|
||||||
bodyA.velocity.y = bodyA.position.y - bodyA.positionPrev.y;
|
bodyAVelocity.y = bodyA.position.y - bodyA.positionPrev.y;
|
||||||
bodyB.velocity.x = bodyB.position.x - bodyB.positionPrev.x;
|
bodyBVelocity.x = bodyB.position.x - bodyB.positionPrev.x;
|
||||||
bodyB.velocity.y = bodyB.position.y - bodyB.positionPrev.y;
|
bodyBVelocity.y = bodyB.position.y - bodyB.positionPrev.y;
|
||||||
bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev;
|
bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev;
|
||||||
bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev;
|
bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev;
|
||||||
|
|
||||||
// resolve each contact
|
// resolve each contact
|
||||||
for (var j = 0; j < contacts.length; j++) {
|
for (j = 0; j < contactsLength; j++) {
|
||||||
var contact = contacts[j],
|
var contact = contacts[j],
|
||||||
contactVertex = contact.vertex,
|
contactVertex = contact.vertex;
|
||||||
offsetA = Vector.sub(contactVertex, bodyA.position, tempA),
|
|
||||||
offsetB = Vector.sub(contactVertex, bodyB.position, tempB),
|
|
||||||
velocityPointA = Vector.add(bodyA.velocity, Vector.mult(Vector.perp(offsetA), bodyA.angularVelocity), tempC),
|
|
||||||
velocityPointB = Vector.add(bodyB.velocity, Vector.mult(Vector.perp(offsetB), bodyB.angularVelocity), tempD),
|
|
||||||
relativeVelocity = Vector.sub(velocityPointA, velocityPointB, tempE),
|
|
||||||
normalVelocity = Vector.dot(normal, relativeVelocity);
|
|
||||||
|
|
||||||
var tangentVelocity = Vector.dot(tangent, relativeVelocity),
|
var offsetAX = contactVertex.x - bodyA.position.x,
|
||||||
tangentSpeed = Math.abs(tangentVelocity),
|
offsetAY = contactVertex.y - bodyA.position.y,
|
||||||
tangentVelocityDirection = Common.sign(tangentVelocity);
|
offsetBX = contactVertex.x - bodyB.position.x,
|
||||||
|
offsetBY = contactVertex.y - bodyB.position.y;
|
||||||
|
|
||||||
|
var velocityPointAX = bodyAVelocity.x - offsetAY * bodyA.angularVelocity,
|
||||||
|
velocityPointAY = bodyAVelocity.y + offsetAX * bodyA.angularVelocity,
|
||||||
|
velocityPointBX = bodyBVelocity.x - offsetBY * bodyB.angularVelocity,
|
||||||
|
velocityPointBY = bodyBVelocity.y + offsetBX * bodyB.angularVelocity;
|
||||||
|
|
||||||
// raw impulses
|
var relativeVelocityX = velocityPointAX - velocityPointBX,
|
||||||
var normalImpulse = (1 + pair.restitution) * normalVelocity,
|
relativeVelocityY = velocityPointAY - velocityPointBY;
|
||||||
normalForce = Common.clamp(pair.separation + normalVelocity, 0, 1) * Resolver._frictionNormalMultiplier;
|
|
||||||
|
var normalVelocity = normalX * relativeVelocityX + normalY * relativeVelocityY,
|
||||||
|
tangentVelocity = tangentX * relativeVelocityX + tangentY * relativeVelocityY;
|
||||||
|
|
||||||
// coulomb friction
|
// coulomb friction
|
||||||
var tangentImpulse = tangentVelocity,
|
var normalOverlap = pair.separation + normalVelocity;
|
||||||
maxFriction = Infinity;
|
var normalForce = Math.min(normalOverlap, 1);
|
||||||
|
normalForce = normalOverlap < 0 ? 0 : normalForce;
|
||||||
|
|
||||||
|
var frictionLimit = normalForce * friction;
|
||||||
|
|
||||||
if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScaleSquared) {
|
if (tangentVelocity > frictionLimit || -tangentVelocity > frictionLimit) {
|
||||||
maxFriction = tangentSpeed;
|
maxFriction = tangentVelocity > 0 ? tangentVelocity : -tangentVelocity;
|
||||||
tangentImpulse = Common.clamp(
|
tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScaleSquared;
|
||||||
pair.friction * tangentVelocityDirection * timeScaleSquared,
|
|
||||||
-maxFriction, maxFriction
|
if (tangentImpulse < -maxFriction) {
|
||||||
);
|
tangentImpulse = -maxFriction;
|
||||||
|
} else if (tangentImpulse > maxFriction) {
|
||||||
|
tangentImpulse = maxFriction;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tangentImpulse = tangentVelocity;
|
||||||
|
maxFriction = NumberMaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify impulses accounting for mass, inertia and offset
|
// account for mass, inertia and contact offset
|
||||||
var oAcN = Vector.cross(offsetA, normal),
|
var oAcN = offsetAX * normalY - offsetAY * normalX,
|
||||||
oBcN = Vector.cross(offsetB, normal),
|
oBcN = offsetBX * normalY - offsetBY * normalX,
|
||||||
share = contactShare / (bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN);
|
share = contactShare / (inverseMassTotal + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN);
|
||||||
|
|
||||||
normalImpulse *= share;
|
// raw impulses
|
||||||
|
var normalImpulse = (1 + pair.restitution) * normalVelocity * share;
|
||||||
tangentImpulse *= share;
|
tangentImpulse *= share;
|
||||||
|
|
||||||
// handle high velocity and resting collisions separately
|
// handle high velocity and resting collisions separately
|
||||||
if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScaleSquared) {
|
if (normalVelocity * normalVelocity > restingThresh && normalVelocity < 0) {
|
||||||
// high normal velocity so clear cached contact normal impulse
|
// high normal velocity so clear cached contact normal impulse
|
||||||
contact.normalImpulse = 0;
|
contact.normalImpulse = 0;
|
||||||
} else {
|
} else {
|
||||||
// solve resting collision constraints using Erin Catto's method (GDC08)
|
// solve resting collision constraints using Erin Catto's method (GDC08)
|
||||||
// impulse constraint tends to 0
|
// impulse constraint tends to 0
|
||||||
var contactNormalImpulse = contact.normalImpulse;
|
var contactNormalImpulse = contact.normalImpulse;
|
||||||
contact.normalImpulse = Math.min(contact.normalImpulse + normalImpulse, 0);
|
contact.normalImpulse += normalImpulse;
|
||||||
|
contact.normalImpulse = Math.min(contact.normalImpulse, 0);
|
||||||
normalImpulse = contact.normalImpulse - contactNormalImpulse;
|
normalImpulse = contact.normalImpulse - contactNormalImpulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle high velocity and resting collisions separately
|
// handle high velocity and resting collisions separately
|
||||||
if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScaleSquared) {
|
if (tangentVelocity * tangentVelocity > restingThreshTangent) {
|
||||||
// high tangent velocity so clear cached contact tangent impulse
|
// high tangent velocity so clear cached contact tangent impulse
|
||||||
contact.tangentImpulse = 0;
|
contact.tangentImpulse = 0;
|
||||||
} else {
|
} else {
|
||||||
// solve resting collision constraints using Erin Catto's method (GDC08)
|
// solve resting collision constraints using Erin Catto's method (GDC08)
|
||||||
// tangent impulse tends to -tangentSpeed or +tangentSpeed
|
// tangent impulse tends to -tangentSpeed or +tangentSpeed
|
||||||
var contactTangentImpulse = contact.tangentImpulse;
|
var contactTangentImpulse = contact.tangentImpulse;
|
||||||
contact.tangentImpulse = Common.clamp(contact.tangentImpulse + tangentImpulse, -maxFriction, maxFriction);
|
contact.tangentImpulse += tangentImpulse;
|
||||||
|
if (contact.tangentImpulse < -maxFriction) contact.tangentImpulse = -maxFriction;
|
||||||
|
if (contact.tangentImpulse > maxFriction) contact.tangentImpulse = maxFriction;
|
||||||
tangentImpulse = contact.tangentImpulse - contactTangentImpulse;
|
tangentImpulse = contact.tangentImpulse - contactTangentImpulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// total impulse from contact
|
// total impulse from contact
|
||||||
impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
|
var impulseX = normalX * normalImpulse + tangentX * tangentImpulse,
|
||||||
impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
|
impulseY = normalY * normalImpulse + tangentY * tangentImpulse;
|
||||||
|
|
||||||
// apply impulse from contact
|
// apply impulse from contact
|
||||||
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
if (!(bodyA.isStatic || bodyA.isSleeping)) {
|
||||||
bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
|
bodyA.positionPrev.x += impulseX * bodyA.inverseMass;
|
||||||
bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
|
bodyA.positionPrev.y += impulseY * bodyA.inverseMass;
|
||||||
bodyA.anglePrev += Vector.cross(offsetA, impulse) * bodyA.inverseInertia;
|
bodyA.anglePrev += (offsetAX * impulseY - offsetAY * impulseX) * bodyA.inverseInertia;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
if (!(bodyB.isStatic || bodyB.isSleeping)) {
|
||||||
bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
|
bodyB.positionPrev.x -= impulseX * bodyB.inverseMass;
|
||||||
bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
|
bodyB.positionPrev.y -= impulseY * bodyB.inverseMass;
|
||||||
bodyB.anglePrev -= Vector.cross(offsetB, impulse) * bodyB.inverseInertia;
|
bodyB.anglePrev -= (offsetBX * impulseY - offsetBY * impulseX) * bodyB.inverseInertia;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,270 +1,37 @@
|
||||||
/**
|
/**
|
||||||
|
* This module has now been replaced by `Matter.Collision`.
|
||||||
|
*
|
||||||
|
* All usage should be migrated to `Matter.Collision`.
|
||||||
|
* For back-compatibility purposes this module will remain for a short term and then later removed in a future release.
|
||||||
|
*
|
||||||
* The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
|
* The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
|
||||||
*
|
*
|
||||||
* @class SAT
|
* @class SAT
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: true circles and curves
|
|
||||||
|
|
||||||
var SAT = {};
|
var SAT = {};
|
||||||
|
|
||||||
module.exports = SAT;
|
module.exports = SAT;
|
||||||
|
|
||||||
var Vertices = require('../geometry/Vertices');
|
var Collision = require('./Collision');
|
||||||
var Vector = require('../geometry/Vector');
|
var Common = require('../core/Common');
|
||||||
|
var deprecated = Common.deprecated;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect collision between two bodies using the Separating Axis Theorem.
|
* Detect collision between two bodies using the Separating Axis Theorem.
|
||||||
|
* @deprecated replaced by Collision.collides
|
||||||
* @method collides
|
* @method collides
|
||||||
* @param {body} bodyA
|
* @param {body} bodyA
|
||||||
* @param {body} bodyB
|
* @param {body} bodyB
|
||||||
* @param {collision} previousCollision
|
|
||||||
* @return {collision} collision
|
* @return {collision} collision
|
||||||
*/
|
*/
|
||||||
SAT.collides = function(bodyA, bodyB, previousCollision) {
|
SAT.collides = function(bodyA, bodyB) {
|
||||||
var overlapAB,
|
return Collision.collides(bodyA, bodyB);
|
||||||
overlapBA,
|
|
||||||
minOverlap,
|
|
||||||
collision,
|
|
||||||
canReusePrevCol = false;
|
|
||||||
|
|
||||||
if (previousCollision) {
|
|
||||||
// estimate total motion
|
|
||||||
var parentA = bodyA.parent,
|
|
||||||
parentB = bodyB.parent,
|
|
||||||
motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed
|
|
||||||
+ parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed;
|
|
||||||
|
|
||||||
// we may be able to (partially) reuse collision result
|
|
||||||
// but only safe if collision was resting
|
|
||||||
canReusePrevCol = previousCollision && previousCollision.collided && motion < 0.2;
|
|
||||||
|
|
||||||
// reuse collision object
|
|
||||||
collision = previousCollision;
|
|
||||||
} else {
|
|
||||||
collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previousCollision && canReusePrevCol) {
|
|
||||||
// if we can reuse the collision result
|
|
||||||
// we only need to test the previously found axis
|
|
||||||
var axisBodyA = collision.axisBody,
|
|
||||||
axisBodyB = axisBodyA === bodyA ? bodyB : bodyA,
|
|
||||||
axes = [axisBodyA.axes[previousCollision.axisNumber]];
|
|
||||||
|
|
||||||
minOverlap = SAT._overlapAxes(axisBodyA.vertices, axisBodyB.vertices, axes);
|
|
||||||
collision.reused = true;
|
|
||||||
|
|
||||||
if (minOverlap.overlap <= 0) {
|
|
||||||
collision.collided = false;
|
|
||||||
return collision;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if we can't reuse a result, perform a full SAT test
|
|
||||||
|
|
||||||
overlapAB = SAT._overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);
|
|
||||||
|
|
||||||
if (overlapAB.overlap <= 0) {
|
|
||||||
collision.collided = false;
|
|
||||||
return collision;
|
|
||||||
}
|
|
||||||
|
|
||||||
overlapBA = SAT._overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);
|
|
||||||
|
|
||||||
if (overlapBA.overlap <= 0) {
|
|
||||||
collision.collided = false;
|
|
||||||
return collision;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overlapAB.overlap < overlapBA.overlap) {
|
|
||||||
minOverlap = overlapAB;
|
|
||||||
collision.axisBody = bodyA;
|
|
||||||
} else {
|
|
||||||
minOverlap = overlapBA;
|
|
||||||
collision.axisBody = bodyB;
|
|
||||||
}
|
|
||||||
|
|
||||||
// important for reuse later
|
|
||||||
collision.axisNumber = minOverlap.axisNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB;
|
|
||||||
collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA;
|
|
||||||
collision.collided = true;
|
|
||||||
collision.depth = minOverlap.overlap;
|
|
||||||
collision.parentA = collision.bodyA.parent;
|
|
||||||
collision.parentB = collision.bodyB.parent;
|
|
||||||
|
|
||||||
bodyA = collision.bodyA;
|
|
||||||
bodyB = collision.bodyB;
|
|
||||||
|
|
||||||
// ensure normal is facing away from bodyA
|
|
||||||
if (Vector.dot(minOverlap.axis, Vector.sub(bodyB.position, bodyA.position)) < 0) {
|
|
||||||
collision.normal = {
|
|
||||||
x: minOverlap.axis.x,
|
|
||||||
y: minOverlap.axis.y
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
collision.normal = {
|
|
||||||
x: -minOverlap.axis.x,
|
|
||||||
y: -minOverlap.axis.y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
collision.tangent = Vector.perp(collision.normal);
|
|
||||||
|
|
||||||
collision.penetration = collision.penetration || {};
|
|
||||||
collision.penetration.x = collision.normal.x * collision.depth;
|
|
||||||
collision.penetration.y = collision.normal.y * collision.depth;
|
|
||||||
|
|
||||||
// find support points, there is always either exactly one or two
|
|
||||||
var verticesB = SAT._findSupports(bodyA, bodyB, collision.normal),
|
|
||||||
supports = [];
|
|
||||||
|
|
||||||
// find the supports from bodyB that are inside bodyA
|
|
||||||
if (Vertices.contains(bodyA.vertices, verticesB[0]))
|
|
||||||
supports.push(verticesB[0]);
|
|
||||||
|
|
||||||
if (Vertices.contains(bodyA.vertices, verticesB[1]))
|
|
||||||
supports.push(verticesB[1]);
|
|
||||||
|
|
||||||
// find the supports from bodyA that are inside bodyB
|
|
||||||
if (supports.length < 2) {
|
|
||||||
var verticesA = SAT._findSupports(bodyB, bodyA, Vector.neg(collision.normal));
|
|
||||||
|
|
||||||
if (Vertices.contains(bodyB.vertices, verticesA[0]))
|
|
||||||
supports.push(verticesA[0]);
|
|
||||||
|
|
||||||
if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
|
|
||||||
supports.push(verticesA[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// account for the edge case of overlapping but no vertex containment
|
|
||||||
if (supports.length < 1)
|
|
||||||
supports = [verticesB[0]];
|
|
||||||
|
|
||||||
collision.supports = supports;
|
|
||||||
|
|
||||||
return collision;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
deprecated(SAT, 'collides', 'SAT.collides ➤ replaced by Collision.collides');
|
||||||
* Find the overlap between two sets of vertices.
|
|
||||||
* @method _overlapAxes
|
|
||||||
* @private
|
|
||||||
* @param {} verticesA
|
|
||||||
* @param {} verticesB
|
|
||||||
* @param {} axes
|
|
||||||
* @return result
|
|
||||||
*/
|
|
||||||
SAT._overlapAxes = function(verticesA, verticesB, axes) {
|
|
||||||
var projectionA = Vector._temp[0],
|
|
||||||
projectionB = Vector._temp[1],
|
|
||||||
result = { overlap: Number.MAX_VALUE },
|
|
||||||
overlap,
|
|
||||||
axis;
|
|
||||||
|
|
||||||
for (var i = 0; i < axes.length; i++) {
|
|
||||||
axis = axes[i];
|
|
||||||
|
|
||||||
SAT._projectToAxis(projectionA, verticesA, axis);
|
|
||||||
SAT._projectToAxis(projectionB, verticesB, axis);
|
|
||||||
|
|
||||||
overlap = Math.min(projectionA.max - projectionB.min, projectionB.max - projectionA.min);
|
|
||||||
|
|
||||||
if (overlap <= 0) {
|
|
||||||
result.overlap = overlap;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overlap < result.overlap) {
|
|
||||||
result.overlap = overlap;
|
|
||||||
result.axis = axis;
|
|
||||||
result.axisNumber = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Projects vertices on an axis and returns an interval.
|
|
||||||
* @method _projectToAxis
|
|
||||||
* @private
|
|
||||||
* @param {} projection
|
|
||||||
* @param {} vertices
|
|
||||||
* @param {} axis
|
|
||||||
*/
|
|
||||||
SAT._projectToAxis = function(projection, vertices, axis) {
|
|
||||||
var min = Vector.dot(vertices[0], axis),
|
|
||||||
max = min;
|
|
||||||
|
|
||||||
for (var i = 1; i < vertices.length; i += 1) {
|
|
||||||
var dot = Vector.dot(vertices[i], axis);
|
|
||||||
|
|
||||||
if (dot > max) {
|
|
||||||
max = dot;
|
|
||||||
} else if (dot < min) {
|
|
||||||
min = dot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
projection.min = min;
|
|
||||||
projection.max = max;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds supporting vertices given two bodies along a given direction using hill-climbing.
|
|
||||||
* @method _findSupports
|
|
||||||
* @private
|
|
||||||
* @param {} bodyA
|
|
||||||
* @param {} bodyB
|
|
||||||
* @param {} normal
|
|
||||||
* @return [vector]
|
|
||||||
*/
|
|
||||||
SAT._findSupports = function(bodyA, bodyB, normal) {
|
|
||||||
var nearestDistance = Number.MAX_VALUE,
|
|
||||||
vertexToBody = Vector._temp[0],
|
|
||||||
vertices = bodyB.vertices,
|
|
||||||
bodyAPosition = bodyA.position,
|
|
||||||
distance,
|
|
||||||
vertex,
|
|
||||||
vertexA,
|
|
||||||
vertexB;
|
|
||||||
|
|
||||||
// find closest vertex on bodyB
|
|
||||||
for (var i = 0; i < vertices.length; i++) {
|
|
||||||
vertex = vertices[i];
|
|
||||||
vertexToBody.x = vertex.x - bodyAPosition.x;
|
|
||||||
vertexToBody.y = vertex.y - bodyAPosition.y;
|
|
||||||
distance = -Vector.dot(normal, vertexToBody);
|
|
||||||
|
|
||||||
if (distance < nearestDistance) {
|
|
||||||
nearestDistance = distance;
|
|
||||||
vertexA = vertex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find next closest vertex using the two connected to it
|
|
||||||
var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
|
|
||||||
vertex = vertices[prevIndex];
|
|
||||||
vertexToBody.x = vertex.x - bodyAPosition.x;
|
|
||||||
vertexToBody.y = vertex.y - bodyAPosition.y;
|
|
||||||
nearestDistance = -Vector.dot(normal, vertexToBody);
|
|
||||||
vertexB = vertex;
|
|
||||||
|
|
||||||
var nextIndex = (vertexA.index + 1) % vertices.length;
|
|
||||||
vertex = vertices[nextIndex];
|
|
||||||
vertexToBody.x = vertex.x - bodyAPosition.x;
|
|
||||||
vertexToBody.y = vertex.y - bodyAPosition.y;
|
|
||||||
distance = -Vector.dot(normal, vertexToBody);
|
|
||||||
if (distance < nearestDistance) {
|
|
||||||
vertexB = vertex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [vertexA, vertexB];
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -312,8 +312,10 @@ var Common = require('../core/Common');
|
||||||
*/
|
*/
|
||||||
Constraint.pointAWorld = function(constraint) {
|
Constraint.pointAWorld = function(constraint) {
|
||||||
return {
|
return {
|
||||||
x: (constraint.bodyA ? constraint.bodyA.position.x : 0) + constraint.pointA.x,
|
x: (constraint.bodyA ? constraint.bodyA.position.x : 0)
|
||||||
y: (constraint.bodyA ? constraint.bodyA.position.y : 0) + constraint.pointA.y
|
+ (constraint.pointA ? constraint.pointA.x : 0),
|
||||||
|
y: (constraint.bodyA ? constraint.bodyA.position.y : 0)
|
||||||
|
+ (constraint.pointA ? constraint.pointA.y : 0)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -325,8 +327,10 @@ var Common = require('../core/Common');
|
||||||
*/
|
*/
|
||||||
Constraint.pointBWorld = function(constraint) {
|
Constraint.pointBWorld = function(constraint) {
|
||||||
return {
|
return {
|
||||||
x: (constraint.bodyB ? constraint.bodyB.position.x : 0) + constraint.pointB.x,
|
x: (constraint.bodyB ? constraint.bodyB.position.x : 0)
|
||||||
y: (constraint.bodyB ? constraint.bodyB.position.y : 0) + constraint.pointB.y
|
+ (constraint.pointB ? constraint.pointB.x : 0),
|
||||||
|
y: (constraint.bodyB ? constraint.bodyB.position.y : 0)
|
||||||
|
+ (constraint.pointB ? constraint.pointB.y : 0)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ module.exports = Common;
|
||||||
Common._nextId = 0;
|
Common._nextId = 0;
|
||||||
Common._seed = 0;
|
Common._seed = 0;
|
||||||
Common._nowStartTime = +(new Date());
|
Common._nowStartTime = +(new Date());
|
||||||
|
Common._warnedOnce = {};
|
||||||
|
Common._decomp = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends the object in the first argument using the object in the second argument.
|
* Extends the object in the first argument using the object in the second argument.
|
||||||
* @method extend
|
* @method extend
|
||||||
|
@ -221,7 +223,7 @@ module.exports = Common;
|
||||||
* @return {boolean} True if the object is a string, otherwise false
|
* @return {boolean} True if the object is a string, otherwise false
|
||||||
*/
|
*/
|
||||||
Common.isString = function(obj) {
|
Common.isString = function(obj) {
|
||||||
return Object.prototype.toString.call(obj) === '[object String]';
|
return toString.call(obj) === '[object String]';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -252,9 +254,9 @@ module.exports = Common;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current timestamp since the time origin (e.g. from page load).
|
* Returns the current timestamp since the time origin (e.g. from page load).
|
||||||
* The result will be high-resolution including decimal places if available.
|
* The result is in milliseconds and will use high-resolution timing if available.
|
||||||
* @method now
|
* @method now
|
||||||
* @return {number} the current timestamp
|
* @return {number} the current timestamp in milliseconds
|
||||||
*/
|
*/
|
||||||
Common.now = function() {
|
Common.now = function() {
|
||||||
if (typeof window !== 'undefined' && window.performance) {
|
if (typeof window !== 'undefined' && window.performance) {
|
||||||
|
@ -265,6 +267,10 @@ module.exports = Common;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Date.now) {
|
||||||
|
return Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
return (new Date()) - Common._nowStartTime;
|
return (new Date()) - Common._nowStartTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -358,6 +364,35 @@ module.exports = Common;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses `Common.warn` to log the given message one time only.
|
||||||
|
* @method warnOnce
|
||||||
|
* @param ...objs {} The objects to log.
|
||||||
|
*/
|
||||||
|
Common.warnOnce = function() {
|
||||||
|
var message = Array.prototype.slice.call(arguments).join(' ');
|
||||||
|
|
||||||
|
if (!Common._warnedOnce[message]) {
|
||||||
|
Common.warn(message);
|
||||||
|
Common._warnedOnce[message] = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a deprecated console warning when the function on the given object is called.
|
||||||
|
* The target function will be replaced with a new function that first shows the warning
|
||||||
|
* and then calls the original function.
|
||||||
|
* @method deprecated
|
||||||
|
* @param {object} obj The object or module
|
||||||
|
* @param {string} name The property name of the function on obj
|
||||||
|
* @param {string} warning The one-time message to show if the function is called
|
||||||
|
*/
|
||||||
|
Common.deprecated = function(obj, prop, warning) {
|
||||||
|
obj[prop] = Common.chain(function() {
|
||||||
|
Common.warnOnce('🔅 deprecated 🔅', warning);
|
||||||
|
}, obj[prop]);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next unique sequential ID.
|
* Returns the next unique sequential ID.
|
||||||
* @method nextId
|
* @method nextId
|
||||||
|
@ -535,4 +570,42 @@ module.exports = Common;
|
||||||
func
|
func
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module to enable
|
||||||
|
* concave vertex decomposition support when using `Bodies.fromVertices` e.g. `Common.setDecomp(require('poly-decomp'))`.
|
||||||
|
* @method setDecomp
|
||||||
|
* @param {} decomp The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module.
|
||||||
|
*/
|
||||||
|
Common.setDecomp = function(decomp) {
|
||||||
|
Common._decomp = decomp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module provided through `Common.setDecomp`,
|
||||||
|
* otherwise returns the global `decomp` if set.
|
||||||
|
* @method getDecomp
|
||||||
|
* @return {} The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module if provided.
|
||||||
|
*/
|
||||||
|
Common.getDecomp = function() {
|
||||||
|
// get user provided decomp if set
|
||||||
|
var decomp = Common._decomp;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// otherwise from window global
|
||||||
|
if (!decomp && typeof window !== 'undefined') {
|
||||||
|
decomp = window.decomp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise from node global
|
||||||
|
if (!decomp && typeof global !== 'undefined') {
|
||||||
|
decomp = global.decomp;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// decomp not available
|
||||||
|
decomp = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decomp;
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -12,12 +12,10 @@ var Engine = {};
|
||||||
|
|
||||||
module.exports = Engine;
|
module.exports = Engine;
|
||||||
|
|
||||||
var World = require('../body/World');
|
|
||||||
var Sleeping = require('./Sleeping');
|
var Sleeping = require('./Sleeping');
|
||||||
var Resolver = require('../collision/Resolver');
|
var Resolver = require('../collision/Resolver');
|
||||||
|
var Detector = require('../collision/Detector');
|
||||||
var Pairs = require('../collision/Pairs');
|
var Pairs = require('../collision/Pairs');
|
||||||
var Metrics = require('./Metrics');
|
|
||||||
var Grid = require('../collision/Grid');
|
|
||||||
var Events = require('./Events');
|
var Events = require('./Events');
|
||||||
var Composite = require('../body/Composite');
|
var Composite = require('../body/Composite');
|
||||||
var Constraint = require('../constraint/Constraint');
|
var Constraint = require('../constraint/Constraint');
|
||||||
|
@ -34,16 +32,9 @@ var Body = require('../body/Body');
|
||||||
* @param {object} [options]
|
* @param {object} [options]
|
||||||
* @return {engine} engine
|
* @return {engine} engine
|
||||||
*/
|
*/
|
||||||
Engine.create = function(element, options) {
|
Engine.create = function(options) {
|
||||||
// options may be passed as the first (and only) argument
|
|
||||||
options = Common.isElement(element) ? options : element;
|
|
||||||
element = Common.isElement(element) ? element : null;
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (element || options.render) {
|
|
||||||
Common.warn('Engine.create: engine.render is deprecated (see docs)');
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaults = {
|
var defaults = {
|
||||||
positionIterations: 6,
|
positionIterations: 6,
|
||||||
velocityIterations: 4,
|
velocityIterations: 4,
|
||||||
|
@ -51,26 +42,31 @@ var Body = require('../body/Body');
|
||||||
enableSleeping: false,
|
enableSleeping: false,
|
||||||
events: [],
|
events: [],
|
||||||
plugin: {},
|
plugin: {},
|
||||||
|
gravity: {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
scale: 0.001
|
||||||
|
},
|
||||||
timing: {
|
timing: {
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
timeScale: 1
|
timeScale: 1,
|
||||||
},
|
lastDelta: 0,
|
||||||
broadphase: {
|
lastElapsed: 0
|
||||||
controller: Grid
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var engine = Common.extend(defaults, options);
|
var engine = Common.extend(defaults, options);
|
||||||
|
|
||||||
engine.world = options.world || World.create(engine.world);
|
engine.world = options.world || Composite.create({ label: 'World' });
|
||||||
engine.pairs = Pairs.create();
|
engine.pairs = options.pairs || Pairs.create();
|
||||||
engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
|
engine.detector = options.detector || Detector.create();
|
||||||
engine.metrics = engine.metrics || { extended: false };
|
|
||||||
|
|
||||||
// @if DEBUG
|
|
||||||
engine.metrics = Metrics.create(engine.metrics);
|
|
||||||
// @endif
|
|
||||||
|
|
||||||
|
// for temporary back compatibility only
|
||||||
|
engine.grid = { buckets: [] };
|
||||||
|
engine.world.gravity = engine.gravity;
|
||||||
|
engine.broadphase = engine.grid;
|
||||||
|
engine.metrics = {};
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,17 +86,21 @@ var Body = require('../body/Body');
|
||||||
* @param {number} [correction=1]
|
* @param {number} [correction=1]
|
||||||
*/
|
*/
|
||||||
Engine.update = function(engine, delta, correction) {
|
Engine.update = function(engine, delta, correction) {
|
||||||
|
var startTime = Common.now();
|
||||||
|
|
||||||
delta = delta || 1000 / 60;
|
delta = delta || 1000 / 60;
|
||||||
correction = correction || 1;
|
correction = correction || 1;
|
||||||
|
|
||||||
var world = engine.world,
|
var world = engine.world,
|
||||||
|
detector = engine.detector,
|
||||||
|
pairs = engine.pairs,
|
||||||
timing = engine.timing,
|
timing = engine.timing,
|
||||||
broadphase = engine.broadphase,
|
timestamp = timing.timestamp,
|
||||||
broadphasePairs = [],
|
|
||||||
i;
|
i;
|
||||||
|
|
||||||
// increment timestamp
|
// increment timestamp
|
||||||
timing.timestamp += delta * timing.timeScale;
|
timing.timestamp += delta * timing.timeScale;
|
||||||
|
timing.lastDelta = delta * timing.timeScale;
|
||||||
|
|
||||||
// create an event object
|
// create an event object
|
||||||
var event = {
|
var event = {
|
||||||
|
@ -109,21 +109,26 @@ var Body = require('../body/Body');
|
||||||
|
|
||||||
Events.trigger(engine, 'beforeUpdate', event);
|
Events.trigger(engine, 'beforeUpdate', event);
|
||||||
|
|
||||||
// get lists of all bodies and constraints, no matter what composites they are in
|
// get all bodies and all constraints in the world
|
||||||
var allBodies = Composite.allBodies(world),
|
var allBodies = Composite.allBodies(world),
|
||||||
allConstraints = Composite.allConstraints(world);
|
allConstraints = Composite.allConstraints(world);
|
||||||
|
|
||||||
// @if DEBUG
|
// update the detector bodies if they have changed
|
||||||
// reset metrics logging
|
if (world.isModified) {
|
||||||
Metrics.reset(engine.metrics);
|
Detector.setBodies(detector, allBodies);
|
||||||
// @endif
|
}
|
||||||
|
|
||||||
// if sleeping enabled, call the sleeping controller
|
// reset all composite modified flags
|
||||||
|
if (world.isModified) {
|
||||||
|
Composite.setModified(world, false, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update sleeping if enabled
|
||||||
if (engine.enableSleeping)
|
if (engine.enableSleeping)
|
||||||
Sleeping.update(allBodies, timing.timeScale);
|
Sleeping.update(allBodies, timing.timeScale);
|
||||||
|
|
||||||
// applies gravity to all bodies
|
// apply gravity to all bodies
|
||||||
Engine._bodiesApplyGravity(allBodies, world.gravity);
|
Engine._bodiesApplyGravity(allBodies, engine.gravity);
|
||||||
|
|
||||||
// update all body position and rotation by integration
|
// update all body position and rotation by integration
|
||||||
Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds);
|
Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds);
|
||||||
|
@ -135,33 +140,12 @@ var Body = require('../body/Body');
|
||||||
}
|
}
|
||||||
Constraint.postSolveAll(allBodies);
|
Constraint.postSolveAll(allBodies);
|
||||||
|
|
||||||
// broadphase pass: find potential collision pairs
|
// find all collisions
|
||||||
if (broadphase.controller) {
|
detector.pairs = engine.pairs;
|
||||||
// if world is dirty, we must flush the whole grid
|
var collisions = Detector.collisions(detector);
|
||||||
if (world.isModified)
|
|
||||||
broadphase.controller.clear(broadphase);
|
|
||||||
|
|
||||||
// update the grid buckets based on current bodies
|
|
||||||
broadphase.controller.update(broadphase, allBodies, engine, world.isModified);
|
|
||||||
broadphasePairs = broadphase.pairsList;
|
|
||||||
} else {
|
|
||||||
// if no broadphase set, we just pass all bodies
|
|
||||||
broadphasePairs = allBodies;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear all composite modified flags
|
|
||||||
if (world.isModified) {
|
|
||||||
Composite.setModified(world, false, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// narrowphase pass: find actual collisions, then create or update collision pairs
|
|
||||||
var collisions = broadphase.detector(broadphasePairs, engine);
|
|
||||||
|
|
||||||
// update collision pairs
|
// update collision pairs
|
||||||
var pairs = engine.pairs,
|
|
||||||
timestamp = timing.timestamp;
|
|
||||||
Pairs.update(pairs, collisions, timestamp);
|
Pairs.update(pairs, collisions, timestamp);
|
||||||
Pairs.removeOld(pairs, timestamp);
|
|
||||||
|
|
||||||
// wake up bodies involved in collisions
|
// wake up bodies involved in collisions
|
||||||
if (engine.enableSleeping)
|
if (engine.enableSleeping)
|
||||||
|
@ -174,7 +158,7 @@ var Body = require('../body/Body');
|
||||||
// iteratively resolve position between collisions
|
// iteratively resolve position between collisions
|
||||||
Resolver.preSolvePosition(pairs.list);
|
Resolver.preSolvePosition(pairs.list);
|
||||||
for (i = 0; i < engine.positionIterations; i++) {
|
for (i = 0; i < engine.positionIterations; i++) {
|
||||||
Resolver.solvePosition(pairs.list, allBodies, timing.timeScale);
|
Resolver.solvePosition(pairs.list, timing.timeScale);
|
||||||
}
|
}
|
||||||
Resolver.postSolvePosition(allBodies);
|
Resolver.postSolvePosition(allBodies);
|
||||||
|
|
||||||
|
@ -198,16 +182,14 @@ var Body = require('../body/Body');
|
||||||
if (pairs.collisionEnd.length > 0)
|
if (pairs.collisionEnd.length > 0)
|
||||||
Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
|
Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
|
||||||
|
|
||||||
// @if DEBUG
|
|
||||||
// update metrics log
|
|
||||||
Metrics.update(engine.metrics, engine);
|
|
||||||
// @endif
|
|
||||||
|
|
||||||
// clear force buffers
|
// clear force buffers
|
||||||
Engine._bodiesClearForces(allBodies);
|
Engine._bodiesClearForces(allBodies);
|
||||||
|
|
||||||
Events.trigger(engine, 'afterUpdate', event);
|
Events.trigger(engine, 'afterUpdate', event);
|
||||||
|
|
||||||
|
// log the time elapsed computing this update
|
||||||
|
engine.timing.lastElapsed = Common.now() - startTime;
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -236,21 +218,13 @@ var Body = require('../body/Body');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the engine including the world, pairs and broadphase.
|
* Clears the engine pairs and detector.
|
||||||
* @method clear
|
* @method clear
|
||||||
* @param {engine} engine
|
* @param {engine} engine
|
||||||
*/
|
*/
|
||||||
Engine.clear = function(engine) {
|
Engine.clear = function(engine) {
|
||||||
var world = engine.world;
|
|
||||||
|
|
||||||
Pairs.clear(engine.pairs);
|
Pairs.clear(engine.pairs);
|
||||||
|
Detector.clear(engine.detector);
|
||||||
var broadphase = engine.broadphase;
|
|
||||||
if (broadphase.controller) {
|
|
||||||
var bodies = Composite.allBodies(world);
|
|
||||||
broadphase.controller.clear(broadphase);
|
|
||||||
broadphase.controller.update(broadphase, bodies, engine, true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -320,7 +294,8 @@ var Body = require('../body/Body');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An alias for `Runner.run`, see `Matter.Runner` for more information.
|
* A deprecated alias for `Runner.run`, use `Matter.Runner.run(engine)` instead and see `Matter.Runner` for more information.
|
||||||
|
* @deprecated use Matter.Runner.run(engine) instead
|
||||||
* @method run
|
* @method run
|
||||||
* @param {engine} engine
|
* @param {engine} engine
|
||||||
*/
|
*/
|
||||||
|
@ -329,53 +304,53 @@ var Body = require('../body/Body');
|
||||||
* Fired just before an update
|
* Fired just before an update
|
||||||
*
|
*
|
||||||
* @event beforeUpdate
|
* @event beforeUpdate
|
||||||
* @param {} event An event object
|
* @param {object} event An event object
|
||||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {engine} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {string} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired after engine update and all collision events
|
* Fired after engine update and all collision events
|
||||||
*
|
*
|
||||||
* @event afterUpdate
|
* @event afterUpdate
|
||||||
* @param {} event An event object
|
* @param {object} event An event object
|
||||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {engine} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {string} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any)
|
* Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any)
|
||||||
*
|
*
|
||||||
* @event collisionStart
|
* @event collisionStart
|
||||||
* @param {} event An event object
|
* @param {object} event An event object
|
||||||
* @param {} event.pairs List of affected pairs
|
* @param {pair[]} event.pairs List of affected pairs
|
||||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {engine} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {string} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any)
|
* Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any)
|
||||||
*
|
*
|
||||||
* @event collisionActive
|
* @event collisionActive
|
||||||
* @param {} event An event object
|
* @param {object} event An event object
|
||||||
* @param {} event.pairs List of affected pairs
|
* @param {pair[]} event.pairs List of affected pairs
|
||||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {engine} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {string} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any)
|
* Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any)
|
||||||
*
|
*
|
||||||
* @event collisionEnd
|
* @event collisionEnd
|
||||||
* @param {} event An event object
|
* @param {object} event An event object
|
||||||
* @param {} event.pairs List of affected pairs
|
* @param {pair[]} event.pairs List of affected pairs
|
||||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {engine} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {string} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -449,32 +424,56 @@ var Body = require('../body/Body');
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
|
* A `Number` that represents the total execution time elapsed during the last `Engine.update` in milliseconds.
|
||||||
* One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
|
* It is updated by timing from the start of the last `Engine.update` call until it ends.
|
||||||
*
|
*
|
||||||
* A minimal custom renderer object must define at least three functions: `create`, `clear` and `world` (see `Matter.Render`).
|
* This value will also include the total execution time of all event handlers directly or indirectly triggered by the engine update.
|
||||||
* It is also possible to instead pass the _module_ reference via `options.render.controller` and `Engine.create` will instantiate one for you.
|
|
||||||
*
|
*
|
||||||
* @property render
|
* @property timing.lastElapsed
|
||||||
* @type render
|
* @type number
|
||||||
* @deprecated see Demo.js for an example of creating a renderer
|
* @default 0
|
||||||
* @default a Matter.Render instance
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of a broadphase controller. The default value is a `Matter.Grid` instance created by `Engine.create`.
|
* A `Number` that represents the `delta` value used in the last engine update.
|
||||||
*
|
*
|
||||||
|
* @property timing.lastDelta
|
||||||
|
* @type number
|
||||||
|
* @default 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Matter.Detector` instance.
|
||||||
|
*
|
||||||
|
* @property detector
|
||||||
|
* @type detector
|
||||||
|
* @default a Matter.Detector instance
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Matter.Grid` instance.
|
||||||
|
*
|
||||||
|
* @deprecated replaced by `engine.detector`
|
||||||
|
* @property grid
|
||||||
|
* @type grid
|
||||||
|
* @default a Matter.Grid instance
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaced by and now alias for `engine.grid`.
|
||||||
|
*
|
||||||
|
* @deprecated replaced by `engine.detector`
|
||||||
* @property broadphase
|
* @property broadphase
|
||||||
* @type grid
|
* @type grid
|
||||||
* @default a Matter.Grid instance
|
* @default a Matter.Grid instance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `World` composite object that will contain all simulated bodies and constraints.
|
* The root `Matter.Composite` instance that will contain all bodies, constraints and other composites to be simulated by this engine.
|
||||||
*
|
*
|
||||||
* @property world
|
* @property world
|
||||||
* @type world
|
* @type composite
|
||||||
* @default a Matter.World instance
|
* @default a Matter.Composite instance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -484,4 +483,35 @@ var Body = require('../body/Body');
|
||||||
* @type {}
|
* @type {}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The gravity to apply on all bodies in `engine.world`.
|
||||||
|
*
|
||||||
|
* @property gravity
|
||||||
|
* @type object
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The gravity x component.
|
||||||
|
*
|
||||||
|
* @property gravity.x
|
||||||
|
* @type object
|
||||||
|
* @default 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The gravity y component.
|
||||||
|
*
|
||||||
|
* @property gravity.y
|
||||||
|
* @type object
|
||||||
|
* @default 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The gravity scale factor.
|
||||||
|
*
|
||||||
|
* @property gravity.scale
|
||||||
|
* @type object
|
||||||
|
* @default 0.001
|
||||||
|
*/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -27,7 +27,7 @@ var Common = require('./Common');
|
||||||
* @readOnly
|
* @readOnly
|
||||||
* @type {String}
|
* @type {String}
|
||||||
*/
|
*/
|
||||||
Matter.version = '0.14.2';
|
Matter.version = '0.18.0';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`.
|
* A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`.
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
// @if DEBUG
|
|
||||||
/**
|
|
||||||
* _Internal Class_, not generally used outside of the engine's internals.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Metrics = {};
|
|
||||||
|
|
||||||
module.exports = Metrics;
|
|
||||||
|
|
||||||
var Composite = require('../body/Composite');
|
|
||||||
var Common = require('./Common');
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new metrics.
|
|
||||||
* @method create
|
|
||||||
* @private
|
|
||||||
* @return {metrics} A new metrics
|
|
||||||
*/
|
|
||||||
Metrics.create = function(options) {
|
|
||||||
var defaults = {
|
|
||||||
extended: false,
|
|
||||||
narrowDetections: 0,
|
|
||||||
narrowphaseTests: 0,
|
|
||||||
narrowReuse: 0,
|
|
||||||
narrowReuseCount: 0,
|
|
||||||
midphaseTests: 0,
|
|
||||||
broadphaseTests: 0,
|
|
||||||
narrowEff: 0.0001,
|
|
||||||
midEff: 0.0001,
|
|
||||||
broadEff: 0.0001,
|
|
||||||
collisions: 0,
|
|
||||||
buckets: 0,
|
|
||||||
bodies: 0,
|
|
||||||
pairs: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
return Common.extend(defaults, false, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets metrics.
|
|
||||||
* @method reset
|
|
||||||
* @private
|
|
||||||
* @param {metrics} metrics
|
|
||||||
*/
|
|
||||||
Metrics.reset = function(metrics) {
|
|
||||||
if (metrics.extended) {
|
|
||||||
metrics.narrowDetections = 0;
|
|
||||||
metrics.narrowphaseTests = 0;
|
|
||||||
metrics.narrowReuse = 0;
|
|
||||||
metrics.narrowReuseCount = 0;
|
|
||||||
metrics.midphaseTests = 0;
|
|
||||||
metrics.broadphaseTests = 0;
|
|
||||||
metrics.narrowEff = 0;
|
|
||||||
metrics.midEff = 0;
|
|
||||||
metrics.broadEff = 0;
|
|
||||||
metrics.collisions = 0;
|
|
||||||
metrics.buckets = 0;
|
|
||||||
metrics.pairs = 0;
|
|
||||||
metrics.bodies = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates metrics.
|
|
||||||
* @method update
|
|
||||||
* @private
|
|
||||||
* @param {metrics} metrics
|
|
||||||
* @param {engine} engine
|
|
||||||
*/
|
|
||||||
Metrics.update = function(metrics, engine) {
|
|
||||||
if (metrics.extended) {
|
|
||||||
var world = engine.world,
|
|
||||||
bodies = Composite.allBodies(world);
|
|
||||||
|
|
||||||
metrics.collisions = metrics.narrowDetections;
|
|
||||||
metrics.pairs = engine.pairs.list.length;
|
|
||||||
metrics.bodies = bodies.length;
|
|
||||||
metrics.midEff = (metrics.narrowDetections / (metrics.midphaseTests || 1)).toFixed(2);
|
|
||||||
metrics.narrowEff = (metrics.narrowDetections / (metrics.narrowphaseTests || 1)).toFixed(2);
|
|
||||||
metrics.broadEff = (1 - (metrics.broadphaseTests / (bodies.length || 1))).toFixed(2);
|
|
||||||
metrics.narrowReuse = (metrics.narrowReuseCount / (metrics.narrowphaseTests || 1)).toFixed(2);
|
|
||||||
//var broadphase = engine.broadphase[engine.broadphase.current];
|
|
||||||
//if (broadphase.instance)
|
|
||||||
// metrics.buckets = Common.keys(broadphase.instance.buckets).length;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
||||||
// @endif
|
|
|
@ -46,7 +46,7 @@ var Common = require('./Common');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a dependency to a plugin object from the registry if it exists.
|
* Resolves a dependency to a plugin object from the registry if it exists.
|
||||||
* The `dependency` may contain a version, but only the name matters when resolving.
|
* The `dependency` may contain a version, but only the name matters when resolving.
|
||||||
* @method resolve
|
* @method resolve
|
||||||
* @param dependency {string} The dependency.
|
* @param dependency {string} The dependency.
|
||||||
|
@ -240,7 +240,7 @@ var Common = require('./Common');
|
||||||
*/
|
*/
|
||||||
Plugin.dependencyParse = function(dependency) {
|
Plugin.dependencyParse = function(dependency) {
|
||||||
if (Common.isString(dependency)) {
|
if (Common.isString(dependency)) {
|
||||||
var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?))?$/;
|
var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-+]+)?))?$/;
|
||||||
|
|
||||||
if (!pattern.test(dependency)) {
|
if (!pattern.test(dependency)) {
|
||||||
Common.warn('Plugin.dependencyParse:', dependency, 'is not a valid dependency string.');
|
Common.warn('Plugin.dependencyParse:', dependency, 'is not a valid dependency string.');
|
||||||
|
@ -259,13 +259,15 @@ var Common = require('./Common');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a version string into its components.
|
* Parses a version string into its components.
|
||||||
* Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)).
|
* Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)).
|
||||||
* Versions may optionally have a prerelease tag in the format `x.y.z-alpha`.
|
* Versions may optionally have a prerelease tag in the format `x.y.z-alpha`.
|
||||||
* Ranges are a strict subset of [npm ranges](https://docs.npmjs.com/misc/semver#advanced-range-syntax).
|
* Ranges are a strict subset of [npm ranges](https://docs.npmjs.com/misc/semver#advanced-range-syntax).
|
||||||
* Only the following range types are supported:
|
* Only the following range types are supported:
|
||||||
* - Tilde ranges e.g. `~1.2.3`
|
* - Tilde ranges e.g. `~1.2.3`
|
||||||
* - Caret ranges e.g. `^1.2.3`
|
* - Caret ranges e.g. `^1.2.3`
|
||||||
|
* - Greater than ranges e.g. `>1.2.3`
|
||||||
|
* - Greater than or equal ranges e.g. `>=1.2.3`
|
||||||
* - Exact version e.g. `1.2.3`
|
* - Exact version e.g. `1.2.3`
|
||||||
* - Any version `*`
|
* - Any version `*`
|
||||||
* @method versionParse
|
* @method versionParse
|
||||||
|
@ -273,29 +275,28 @@ var Common = require('./Common');
|
||||||
* @return {object} The version range parsed into its components.
|
* @return {object} The version range parsed into its components.
|
||||||
*/
|
*/
|
||||||
Plugin.versionParse = function(range) {
|
Plugin.versionParse = function(range) {
|
||||||
var pattern = /^\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?$/;
|
var pattern = /^(\*)|(\^|~|>=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;
|
||||||
|
|
||||||
if (!pattern.test(range)) {
|
if (!pattern.test(range)) {
|
||||||
Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.');
|
Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.');
|
||||||
}
|
}
|
||||||
|
|
||||||
var identifiers = range.split('-');
|
var parts = pattern.exec(range);
|
||||||
range = identifiers[0];
|
var major = Number(parts[4]);
|
||||||
|
var minor = Number(parts[5]);
|
||||||
var isRange = isNaN(Number(range[0])),
|
var patch = Number(parts[6]);
|
||||||
version = isRange ? range.substr(1) : range,
|
|
||||||
parts = Common.map(version.split('.'), function(part) {
|
|
||||||
return Number(part);
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isRange: isRange,
|
isRange: Boolean(parts[1] || parts[2]),
|
||||||
version: version,
|
version: parts[3],
|
||||||
range: range,
|
range: range,
|
||||||
operator: isRange ? range[0] : '',
|
operator: parts[1] || parts[2] || '',
|
||||||
parts: parts,
|
major: major,
|
||||||
prerelease: identifiers[1],
|
minor: minor,
|
||||||
number: parts[0] * 1e8 + parts[1] * 1e4 + parts[2]
|
patch: patch,
|
||||||
|
parts: [major, minor, patch],
|
||||||
|
prerelease: parts[7],
|
||||||
|
number: major * 1e8 + minor * 1e4 + patch
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -311,30 +312,36 @@ var Common = require('./Common');
|
||||||
Plugin.versionSatisfies = function(version, range) {
|
Plugin.versionSatisfies = function(version, range) {
|
||||||
range = range || '*';
|
range = range || '*';
|
||||||
|
|
||||||
var rangeParsed = Plugin.versionParse(range),
|
var r = Plugin.versionParse(range),
|
||||||
rangeParts = rangeParsed.parts,
|
v = Plugin.versionParse(version);
|
||||||
versionParsed = Plugin.versionParse(version),
|
|
||||||
versionParts = versionParsed.parts;
|
|
||||||
|
|
||||||
if (rangeParsed.isRange) {
|
if (r.isRange) {
|
||||||
if (rangeParsed.operator === '*' || version === '*') {
|
if (r.operator === '*' || version === '*') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rangeParsed.operator === '~') {
|
if (r.operator === '>') {
|
||||||
return versionParts[0] === rangeParts[0] && versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
|
return v.number > r.number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rangeParsed.operator === '^') {
|
if (r.operator === '>=') {
|
||||||
if (rangeParts[0] > 0) {
|
return v.number >= r.number;
|
||||||
return versionParts[0] === rangeParts[0] && versionParsed.number >= rangeParsed.number;
|
}
|
||||||
|
|
||||||
|
if (r.operator === '~') {
|
||||||
|
return v.major === r.major && v.minor === r.minor && v.patch >= r.patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r.operator === '^') {
|
||||||
|
if (r.major > 0) {
|
||||||
|
return v.major === r.major && v.number >= r.number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rangeParts[1] > 0) {
|
if (r.minor > 0) {
|
||||||
return versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
|
return v.minor === r.minor && v.patch >= r.patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
return versionParts[2] === rangeParts[2];
|
return v.patch === r.patch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,6 @@ var Common = require('./Common');
|
||||||
/**
|
/**
|
||||||
* A game loop utility that updates the engine and renderer by one step (a 'tick').
|
* A game loop utility that updates the engine and renderer by one step (a 'tick').
|
||||||
* Features delta smoothing, time correction and fixed or dynamic timing.
|
* Features delta smoothing, time correction and fixed or dynamic timing.
|
||||||
* Triggers `beforeTick`, `tick` and `afterTick` events on the engine.
|
|
||||||
* Consider just `Engine.update(engine, delta)` if you're using your own loop.
|
* Consider just `Engine.update(engine, delta)` if you're using your own loop.
|
||||||
* @method tick
|
* @method tick
|
||||||
* @param {runner} runner
|
* @param {runner} runner
|
||||||
|
@ -119,7 +118,6 @@ var Common = require('./Common');
|
||||||
};
|
};
|
||||||
|
|
||||||
Events.trigger(runner, 'beforeTick', event);
|
Events.trigger(runner, 'beforeTick', event);
|
||||||
Events.trigger(engine, 'beforeTick', event); // @deprecated
|
|
||||||
|
|
||||||
if (runner.isFixed) {
|
if (runner.isFixed) {
|
||||||
// fixed timestep
|
// fixed timestep
|
||||||
|
@ -164,35 +162,13 @@ var Common = require('./Common');
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.trigger(runner, 'tick', event);
|
Events.trigger(runner, 'tick', event);
|
||||||
Events.trigger(engine, 'tick', event); // @deprecated
|
|
||||||
|
|
||||||
// if world has been modified, clear the render scene graph
|
|
||||||
if (engine.world.isModified
|
|
||||||
&& engine.render
|
|
||||||
&& engine.render.controller
|
|
||||||
&& engine.render.controller.clear) {
|
|
||||||
engine.render.controller.clear(engine.render); // @deprecated
|
|
||||||
}
|
|
||||||
|
|
||||||
// update
|
// update
|
||||||
Events.trigger(runner, 'beforeUpdate', event);
|
Events.trigger(runner, 'beforeUpdate', event);
|
||||||
Engine.update(engine, delta, correction);
|
Engine.update(engine, delta, correction);
|
||||||
Events.trigger(runner, 'afterUpdate', event);
|
Events.trigger(runner, 'afterUpdate', event);
|
||||||
|
|
||||||
// render
|
|
||||||
// @deprecated
|
|
||||||
if (engine.render && engine.render.controller) {
|
|
||||||
Events.trigger(runner, 'beforeRender', event);
|
|
||||||
Events.trigger(engine, 'beforeRender', event); // @deprecated
|
|
||||||
|
|
||||||
engine.render.controller.world(engine.render);
|
|
||||||
|
|
||||||
Events.trigger(runner, 'afterRender', event);
|
|
||||||
Events.trigger(engine, 'afterRender', event); // @deprecated
|
|
||||||
}
|
|
||||||
|
|
||||||
Events.trigger(runner, 'afterTick', event);
|
Events.trigger(runner, 'afterTick', event);
|
||||||
Events.trigger(engine, 'afterTick', event); // @deprecated
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -271,28 +247,6 @@ var Common = require('./Common');
|
||||||
* @param {} event.name The name of the event
|
* @param {} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired before rendering
|
|
||||||
*
|
|
||||||
* @event beforeRender
|
|
||||||
* @param {} event An event object
|
|
||||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
|
||||||
* @param {} event.source The source object of the event
|
|
||||||
* @param {} event.name The name of the event
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired after rendering
|
|
||||||
*
|
|
||||||
* @event afterRender
|
|
||||||
* @param {} event An event object
|
|
||||||
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
|
||||||
* @param {} event.source The source object of the event
|
|
||||||
* @param {} event.name The name of the event
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Properties Documentation
|
* Properties Documentation
|
||||||
|
|
|
@ -18,7 +18,6 @@ var Common = require('../core/Common');
|
||||||
var Body = require('../body/Body');
|
var Body = require('../body/Body');
|
||||||
var Bounds = require('../geometry/Bounds');
|
var Bounds = require('../geometry/Bounds');
|
||||||
var Vector = require('../geometry/Vector');
|
var Vector = require('../geometry/Vector');
|
||||||
var decomp = require('../../poly-decomp');
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
@ -177,29 +176,46 @@ var decomp = require('../../poly-decomp');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a body using the supplied vertices (or an array containing multiple sets of vertices).
|
* Utility to create a compound body based on set(s) of vertices.
|
||||||
* If the vertices are convex, they will pass through as supplied.
|
*
|
||||||
* Otherwise if the vertices are concave, they will be decomposed if [poly-decomp.js](https://github.com/schteppe/poly-decomp.js) is available.
|
* _Note:_ To optionally enable automatic concave vertices decomposition the [poly-decomp](https://github.com/schteppe/poly-decomp.js)
|
||||||
* Note that this process is not guaranteed to support complex sets of vertices (e.g. those with holes may fail).
|
* package must be first installed and provided see `Common.setDecomp`, otherwise the convex hull of each vertex set will be used.
|
||||||
* By default the decomposition will discard collinear edges (to improve performance).
|
*
|
||||||
* It can also optionally discard any parts that have an area less than `minimumArea`.
|
* The resulting vertices are reorientated about their centre of mass,
|
||||||
* If the vertices can not be decomposed, the result will fall back to using the convex hull.
|
* and offset such that `body.position` corresponds to this point.
|
||||||
* The options parameter is an object that specifies any `Matter.Body` properties you wish to override the defaults.
|
*
|
||||||
|
* The resulting offset may be found if needed by subtracting `body.bounds` from the original input bounds.
|
||||||
|
* To later move the centre of mass see `Body.setCentre`.
|
||||||
|
*
|
||||||
|
* Note that automatic conconcave decomposition results are not always optimal.
|
||||||
|
* For best results, simplify the input vertices as much as possible first.
|
||||||
|
* By default this function applies some addtional simplification to help.
|
||||||
|
*
|
||||||
|
* Some outputs may also require further manual processing afterwards to be robust.
|
||||||
|
* In particular some parts may need to be overlapped to avoid collision gaps.
|
||||||
|
* Thin parts and sharp points should be avoided or removed where possible.
|
||||||
|
*
|
||||||
|
* The options parameter object specifies any `Matter.Body` properties you wish to override the defaults.
|
||||||
|
*
|
||||||
* See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
|
* See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
|
||||||
* @method fromVertices
|
* @method fromVertices
|
||||||
* @param {number} x
|
* @param {number} x
|
||||||
* @param {number} y
|
* @param {number} y
|
||||||
* @param [[vector]] vertexSets
|
* @param {array} vertexSets One or more arrays of vertex points e.g. `[[{ x: 0, y: 0 }...], ...]`.
|
||||||
* @param {object} [options]
|
* @param {object} [options] The body options.
|
||||||
* @param {bool} [flagInternal=false]
|
* @param {bool} [flagInternal=false] Optionally marks internal edges with `isInternal`.
|
||||||
* @param {number} [removeCollinear=0.01]
|
* @param {number} [removeCollinear=0.01] Threshold when simplifying vertices along the same edge.
|
||||||
* @param {number} [minimumArea=10]
|
* @param {number} [minimumArea=10] Threshold when removing small parts.
|
||||||
|
* @param {number} [removeDuplicatePoints=0.01] Threshold when simplifying nearby vertices.
|
||||||
* @return {body}
|
* @return {body}
|
||||||
*/
|
*/
|
||||||
Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) {
|
Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea, removeDuplicatePoints) {
|
||||||
var body,
|
var decomp = Common.getDecomp(),
|
||||||
|
canDecomp,
|
||||||
|
body,
|
||||||
parts,
|
parts,
|
||||||
isConvex,
|
isConvex,
|
||||||
|
isConcave,
|
||||||
vertices,
|
vertices,
|
||||||
i,
|
i,
|
||||||
j,
|
j,
|
||||||
|
@ -207,16 +223,16 @@ var decomp = require('../../poly-decomp');
|
||||||
v,
|
v,
|
||||||
z;
|
z;
|
||||||
|
|
||||||
|
// check decomp is as expected
|
||||||
|
canDecomp = Boolean(decomp && decomp.quickDecomp);
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
parts = [];
|
parts = [];
|
||||||
|
|
||||||
flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false;
|
flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false;
|
||||||
removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01;
|
removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01;
|
||||||
minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10;
|
minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10;
|
||||||
|
removeDuplicatePoints = typeof removeDuplicatePoints !== 'undefined' ? removeDuplicatePoints : 0.01;
|
||||||
if (!decomp) {
|
|
||||||
Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure vertexSets is an array of arrays
|
// ensure vertexSets is an array of arrays
|
||||||
if (!Common.isArray(vertexSets[0])) {
|
if (!Common.isArray(vertexSets[0])) {
|
||||||
|
@ -226,8 +242,15 @@ var decomp = require('../../poly-decomp');
|
||||||
for (v = 0; v < vertexSets.length; v += 1) {
|
for (v = 0; v < vertexSets.length; v += 1) {
|
||||||
vertices = vertexSets[v];
|
vertices = vertexSets[v];
|
||||||
isConvex = Vertices.isConvex(vertices);
|
isConvex = Vertices.isConvex(vertices);
|
||||||
|
isConcave = !isConvex;
|
||||||
|
|
||||||
if (isConvex || !decomp) {
|
if (isConcave && !canDecomp) {
|
||||||
|
Common.warnOnce(
|
||||||
|
'Bodies.fromVertices: Install the \'poly-decomp\' library and use Common.setDecomp or provide \'decomp\' as a global to decompose concave vertices.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isConvex || !canDecomp) {
|
||||||
if (isConvex) {
|
if (isConvex) {
|
||||||
vertices = Vertices.clockwiseSort(vertices);
|
vertices = Vertices.clockwiseSort(vertices);
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,6 +272,8 @@ var decomp = require('../../poly-decomp');
|
||||||
decomp.makeCCW(concave);
|
decomp.makeCCW(concave);
|
||||||
if (removeCollinear !== false)
|
if (removeCollinear !== false)
|
||||||
decomp.removeCollinearPoints(concave, removeCollinear);
|
decomp.removeCollinearPoints(concave, removeCollinear);
|
||||||
|
if (removeDuplicatePoints !== false && decomp.removeDuplicatePoints)
|
||||||
|
decomp.removeDuplicatePoints(concave, removeDuplicatePoints);
|
||||||
|
|
||||||
// use the quick decomposition algorithm (Bayazit)
|
// use the quick decomposition algorithm (Bayazit)
|
||||||
var decomposed = decomp.quickDecomp(concave);
|
var decomposed = decomp.quickDecomp(concave);
|
||||||
|
@ -283,14 +308,45 @@ var decomp = require('../../poly-decomp');
|
||||||
parts[i] = Body.create(Common.extend(parts[i], options));
|
parts[i] = Body.create(Common.extend(parts[i], options));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flagInternal)
|
// flag internal edges (coincident part edges)
|
||||||
{
|
if (flagInternal) {
|
||||||
Bodies.flagCoincidentParts(parts, 5);
|
var coincident_max_dist = 5;
|
||||||
|
|
||||||
|
for (i = 0; i < parts.length; i++) {
|
||||||
|
var partA = parts[i];
|
||||||
|
|
||||||
|
for (j = i + 1; j < parts.length; j++) {
|
||||||
|
var partB = parts[j];
|
||||||
|
|
||||||
|
if (Bounds.overlaps(partA.bounds, partB.bounds)) {
|
||||||
|
var pav = partA.vertices,
|
||||||
|
pbv = partB.vertices;
|
||||||
|
|
||||||
|
// iterate vertices of both parts
|
||||||
|
for (k = 0; k < partA.vertices.length; k++) {
|
||||||
|
for (z = 0; z < partB.vertices.length; z++) {
|
||||||
|
// find distances between the vertices
|
||||||
|
var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])),
|
||||||
|
db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length]));
|
||||||
|
|
||||||
|
// if both vertices are very close, consider the edge concident (internal)
|
||||||
|
if (da < coincident_max_dist && db < coincident_max_dist) {
|
||||||
|
pav[k].isInternal = true;
|
||||||
|
pbv[z].isInternal = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parts.length > 1) {
|
if (parts.length > 1) {
|
||||||
// create the parent body to be returned, that contains generated compound parts
|
// create the parent body to be returned, that contains generated compound parts
|
||||||
body = Body.create(Common.extend({ parts: parts.slice(0) }, options));
|
body = Body.create(Common.extend({ parts: parts.slice(0) }, options));
|
||||||
|
|
||||||
|
// offset such that body.position is at the centre off mass
|
||||||
Body.setPosition(body, { x: x, y: y });
|
Body.setPosition(body, { x: x, y: y });
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
|
@ -299,54 +355,4 @@ var decomp = require('../../poly-decomp');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes an array of Body objects and flags all internal edges (coincident parts) based on the maxDistance
|
|
||||||
* value. The array is changed in-place and returned, so you can pass this function a `Body.parts` property.
|
|
||||||
*
|
|
||||||
* @method flagCoincidentParts
|
|
||||||
* @param {body[]} parts - The Body parts, or array of bodies, to flag.
|
|
||||||
* @param {number} [maxDistance=5]
|
|
||||||
* @return {body[]} The modified `parts` parameter.
|
|
||||||
*/
|
|
||||||
Bodies.flagCoincidentParts = function (parts, maxDistance)
|
|
||||||
{
|
|
||||||
if (maxDistance === undefined) { maxDistance = 5; }
|
|
||||||
|
|
||||||
for (var i = 0; i < parts.length; i++)
|
|
||||||
{
|
|
||||||
var partA = parts[i];
|
|
||||||
|
|
||||||
for (var j = i + 1; j < parts.length; j++)
|
|
||||||
{
|
|
||||||
var partB = parts[j];
|
|
||||||
|
|
||||||
if (Bounds.overlaps(partA.bounds, partB.bounds))
|
|
||||||
{
|
|
||||||
var pav = partA.vertices;
|
|
||||||
var pbv = partB.vertices;
|
|
||||||
|
|
||||||
// iterate vertices of both parts
|
|
||||||
for (var k = 0; k < partA.vertices.length; k++)
|
|
||||||
{
|
|
||||||
for (var z = 0; z < partB.vertices.length; z++)
|
|
||||||
{
|
|
||||||
// find distances between the vertices
|
|
||||||
var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z]));
|
|
||||||
var db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length]));
|
|
||||||
|
|
||||||
// if both vertices are very close, consider the edge concident (internal)
|
|
||||||
if (da < maxDistance && db < maxDistance)
|
|
||||||
{
|
|
||||||
pav[k].isInternal = true;
|
|
||||||
pbv[z].isInternal = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts;
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -16,6 +16,7 @@ var Constraint = require('../constraint/Constraint');
|
||||||
var Common = require('../core/Common');
|
var Common = require('../core/Common');
|
||||||
var Body = require('../body/Body');
|
var Body = require('../body/Body');
|
||||||
var Bodies = require('./Bodies');
|
var Bodies = require('./Bodies');
|
||||||
|
var deprecated = Common.deprecated;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
@ -202,7 +203,8 @@ var Bodies = require('./Bodies');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a composite with a Newton's Cradle setup of bodies and constraints.
|
* This has now moved to the [newtonsCradle example](https://github.com/liabru/matter-js/blob/master/examples/newtonsCradle.js), follow that instead as this function is deprecated here.
|
||||||
|
* @deprecated moved to newtonsCradle example
|
||||||
* @method newtonsCradle
|
* @method newtonsCradle
|
||||||
* @param {number} xx
|
* @param {number} xx
|
||||||
* @param {number} yy
|
* @param {number} yy
|
||||||
|
@ -226,9 +228,12 @@ var Bodies = require('./Bodies');
|
||||||
|
|
||||||
return newtonsCradle;
|
return newtonsCradle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deprecated(Composites, 'newtonsCradle', 'Composites.newtonsCradle ➤ moved to newtonsCradle example');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a composite with simple car setup of bodies and constraints.
|
* This has now moved to the [car example](https://github.com/liabru/matter-js/blob/master/examples/car.js), follow that instead as this function is deprecated here.
|
||||||
|
* @deprecated moved to car example
|
||||||
* @method car
|
* @method car
|
||||||
* @param {number} xx
|
* @param {number} xx
|
||||||
* @param {number} yy
|
* @param {number} yy
|
||||||
|
@ -294,8 +299,12 @@ var Bodies = require('./Bodies');
|
||||||
return car;
|
return car;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deprecated(Composites, 'car', 'Composites.car ➤ moved to car example');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a simple soft body like object.
|
* This has now moved to the [softBody example](https://github.com/liabru/matter-js/blob/master/examples/softBody.js)
|
||||||
|
* and the [cloth example](https://github.com/liabru/matter-js/blob/master/examples/cloth.js), follow those instead as this function is deprecated here.
|
||||||
|
* @deprecated moved to softBody and cloth examples
|
||||||
* @method softBody
|
* @method softBody
|
||||||
* @param {number} xx
|
* @param {number} xx
|
||||||
* @param {number} yy
|
* @param {number} yy
|
||||||
|
@ -324,4 +333,5 @@ var Bodies = require('./Bodies');
|
||||||
return softBody;
|
return softBody;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deprecated(Composites, 'softBody', 'Composites.softBody ➤ moved to softBody and cloth examples');
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -44,17 +44,9 @@ var Common = require('../core/Common');
|
||||||
y: point.y,
|
y: point.y,
|
||||||
index: i,
|
index: i,
|
||||||
body: body,
|
body: body,
|
||||||
isInternal: false,
|
isInternal: false
|
||||||
contact: null,
|
|
||||||
offset: null
|
|
||||||
};
|
};
|
||||||
|
|
||||||
vertex.contact = {
|
|
||||||
vertex: vertex,
|
|
||||||
normalImpulse: 0,
|
|
||||||
tangentImpulse: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
vertices.push(vertex);
|
vertices.push(vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,17 +169,16 @@ var Common = require('../core/Common');
|
||||||
* @param {number} scalar
|
* @param {number} scalar
|
||||||
*/
|
*/
|
||||||
Vertices.translate = function(vertices, vector, scalar) {
|
Vertices.translate = function(vertices, vector, scalar) {
|
||||||
var i;
|
scalar = typeof scalar !== 'undefined' ? scalar : 1;
|
||||||
if (scalar) {
|
|
||||||
for (i = 0; i < vertices.length; i++) {
|
var verticesLength = vertices.length,
|
||||||
vertices[i].x += vector.x * scalar;
|
translateX = vector.x * scalar,
|
||||||
vertices[i].y += vector.y * scalar;
|
translateY = vector.y * scalar,
|
||||||
}
|
i;
|
||||||
} else {
|
|
||||||
for (i = 0; i < vertices.length; i++) {
|
for (i = 0; i < verticesLength; i++) {
|
||||||
vertices[i].x += vector.x;
|
vertices[i].x += translateX;
|
||||||
vertices[i].y += vector.y;
|
vertices[i].y += translateY;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vertices;
|
return vertices;
|
||||||
|
@ -205,15 +196,21 @@ var Common = require('../core/Common');
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var cos = Math.cos(angle),
|
var cos = Math.cos(angle),
|
||||||
sin = Math.sin(angle);
|
sin = Math.sin(angle),
|
||||||
|
pointX = point.x,
|
||||||
|
pointY = point.y,
|
||||||
|
verticesLength = vertices.length,
|
||||||
|
vertex,
|
||||||
|
dx,
|
||||||
|
dy,
|
||||||
|
i;
|
||||||
|
|
||||||
for (var i = 0; i < vertices.length; i++) {
|
for (i = 0; i < verticesLength; i++) {
|
||||||
var vertice = vertices[i],
|
vertex = vertices[i];
|
||||||
dx = vertice.x - point.x,
|
dx = vertex.x - pointX;
|
||||||
dy = vertice.y - point.y;
|
dy = vertex.y - pointY;
|
||||||
|
vertex.x = pointX + (dx * cos - dy * sin);
|
||||||
vertice.x = point.x + (dx * cos - dy * sin);
|
vertex.y = pointY + (dx * sin + dy * cos);
|
||||||
vertice.y = point.y + (dx * sin + dy * cos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vertices;
|
return vertices;
|
||||||
|
@ -227,12 +224,21 @@ var Common = require('../core/Common');
|
||||||
* @return {boolean} True if the vertices contains point, otherwise false
|
* @return {boolean} True if the vertices contains point, otherwise false
|
||||||
*/
|
*/
|
||||||
Vertices.contains = function(vertices, point) {
|
Vertices.contains = function(vertices, point) {
|
||||||
for (var i = 0; i < vertices.length; i++) {
|
var pointX = point.x,
|
||||||
var vertice = vertices[i],
|
pointY = point.y,
|
||||||
nextVertice = vertices[(i + 1) % vertices.length];
|
verticesLength = vertices.length,
|
||||||
if ((point.x - vertice.x) * (nextVertice.y - vertice.y) + (point.y - vertice.y) * (vertice.x - nextVertice.x) > 0) {
|
vertex = vertices[verticesLength - 1],
|
||||||
|
nextVertex;
|
||||||
|
|
||||||
|
for (var i = 0; i < verticesLength; i++) {
|
||||||
|
nextVertex = vertices[i];
|
||||||
|
|
||||||
|
if ((pointX - vertex.x) * (nextVertex.y - vertex.y)
|
||||||
|
+ (pointY - vertex.y) * (vertex.x - nextVertex.x) > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vertex = nextVertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -9,7 +9,7 @@ var MatterAttractors =
|
||||||
{
|
{
|
||||||
name: 'matter-attractors',
|
name: 'matter-attractors',
|
||||||
version: '0.1.7',
|
version: '0.1.7',
|
||||||
for: 'matter-js@^0.14.2',
|
for: 'matter-js@^0.18.0',
|
||||||
silent: true,
|
silent: true,
|
||||||
|
|
||||||
// installs the plugin where `base` is `Matter`
|
// installs the plugin where `base` is `Matter`
|
||||||
|
|
|
@ -8,7 +8,7 @@ var MatterCollisionEvents = {
|
||||||
|
|
||||||
name: 'matter-collision-events',
|
name: 'matter-collision-events',
|
||||||
version: '0.1.6',
|
version: '0.1.6',
|
||||||
for: 'matter-js@^0.14.2',
|
for: 'matter-js@^0.18.0',
|
||||||
silent: true,
|
silent: true,
|
||||||
|
|
||||||
install: function (matter)
|
install: function (matter)
|
||||||
|
|
|
@ -9,7 +9,7 @@ var MatterWrap = {
|
||||||
// plugin meta
|
// plugin meta
|
||||||
name: 'matter-wrap', // PLUGIN_NAME
|
name: 'matter-wrap', // PLUGIN_NAME
|
||||||
version: '0.1.4', // PLUGIN_VERSION
|
version: '0.1.4', // PLUGIN_VERSION
|
||||||
for: 'matter-js@^0.14.2',
|
for: 'matter-js@^0.18.0',
|
||||||
silent: true, // no console log please
|
silent: true, // no console log please
|
||||||
|
|
||||||
// installs the plugin where `base` is `Matter`
|
// installs the plugin where `base` is `Matter`
|
||||||
|
@ -90,8 +90,8 @@ var MatterWrap = {
|
||||||
|
|
||||||
Body: {
|
Body: {
|
||||||
/**
|
/**
|
||||||
* Wraps the `body` position such that it always stays within the given bounds.
|
* Wraps the `body` position such that it always stays within the given bounds.
|
||||||
* Upon crossing a boundary the body will appear on the opposite side of the bounds,
|
* Upon crossing a boundary the body will appear on the opposite side of the bounds,
|
||||||
* while maintaining its velocity.
|
* while maintaining its velocity.
|
||||||
* This is called automatically by the plugin.
|
* This is called automatically by the plugin.
|
||||||
* @function MatterWrap.Body.wrap
|
* @function MatterWrap.Body.wrap
|
||||||
|
@ -121,7 +121,7 @@ var MatterWrap = {
|
||||||
bounds: function(composite) {
|
bounds: function(composite) {
|
||||||
var bodies = Matter.Composite.allBodies(composite),
|
var bodies = Matter.Composite.allBodies(composite),
|
||||||
vertices = [];
|
vertices = [];
|
||||||
|
|
||||||
for (var i = 0; i < bodies.length; i += 1) {
|
for (var i = 0; i < bodies.length; i += 1) {
|
||||||
var body = bodies[i];
|
var body = bodies[i];
|
||||||
vertices.push(body.bounds.min, body.bounds.max);
|
vertices.push(body.bounds.min, body.bounds.max);
|
||||||
|
@ -131,8 +131,8 @@ var MatterWrap = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the `composite` position such that it always stays within the given bounds.
|
* Wraps the `composite` position such that it always stays within the given bounds.
|
||||||
* Upon crossing a boundary the composite will appear on the opposite side of the bounds,
|
* Upon crossing a boundary the composite will appear on the opposite side of the bounds,
|
||||||
* while maintaining its velocity.
|
* while maintaining its velocity.
|
||||||
* This is called automatically by the plugin.
|
* This is called automatically by the plugin.
|
||||||
* @function MatterWrap.Composite.wrap
|
* @function MatterWrap.Composite.wrap
|
||||||
|
@ -142,7 +142,7 @@ var MatterWrap = {
|
||||||
*/
|
*/
|
||||||
wrap: function(composite, bounds) {
|
wrap: function(composite, bounds) {
|
||||||
var translation = MatterWrap.Bounds.wrap(
|
var translation = MatterWrap.Bounds.wrap(
|
||||||
MatterWrap.Composite.bounds(composite),
|
MatterWrap.Composite.bounds(composite),
|
||||||
bounds
|
bounds
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -163,15 +163,15 @@ module.exports = MatterWrap;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This plugin adds a new property `body.plugin.wrap` to instances of `Matter.Body`.
|
* This plugin adds a new property `body.plugin.wrap` to instances of `Matter.Body`.
|
||||||
* This is a `Matter.Bounds` instance that specifies the wrapping region.
|
* This is a `Matter.Bounds` instance that specifies the wrapping region.
|
||||||
* @property {Matter.Bounds} body.plugin.wrap
|
* @property {Matter.Bounds} body.plugin.wrap
|
||||||
* @memberof Matter.Body
|
* @memberof Matter.Body
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This plugin adds a new property `composite.plugin.wrap` to instances of `Matter.Composite`.
|
* This plugin adds a new property `composite.plugin.wrap` to instances of `Matter.Composite`.
|
||||||
* This is a `Matter.Bounds` instance that specifies the wrapping region.
|
* This is a `Matter.Bounds` instance that specifies the wrapping region.
|
||||||
* @property {Matter.Bounds} composite.plugin.wrap
|
* @property {Matter.Bounds} composite.plugin.wrap
|
||||||
* @memberof Matter.Composite
|
* @memberof Matter.Composite
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -44,4 +44,6 @@ if (typeof window.Uint32Array !== 'function' && typeof window.Uint32Array !== 'o
|
||||||
CheapArray('Uint16Array'); // jshint ignore:line
|
CheapArray('Uint16Array'); // jshint ignore:line
|
||||||
CheapArray('Int16Array'); // jshint ignore:line
|
CheapArray('Int16Array'); // jshint ignore:line
|
||||||
CheapArray('ArrayBuffer'); // jshint ignore:line
|
CheapArray('ArrayBuffer'); // jshint ignore:line
|
||||||
|
CheapArray('Int8Array'); // jshint ignore:line
|
||||||
|
CheapArray('Uint8Array'); // jshint ignore:line
|
||||||
}
|
}
|
||||||
|
|
|
@ -818,7 +818,10 @@ var CanvasRenderer = new Class({
|
||||||
sprite.mask.preRenderCanvas(this, sprite, camera);
|
sprite.mask.preRenderCanvas(this, sprite, camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.drawImage(frame.source.image, frameX, frameY, frameWidth, frameHeight, x, y, frameWidth / res, frameHeight / res);
|
if (frameWidth > 0 && frameHeight > 0)
|
||||||
|
{
|
||||||
|
ctx.drawImage(frame.source.image, frameX, frameY, frameWidth, frameHeight, x, y, frameWidth / res, frameHeight / res);
|
||||||
|
}
|
||||||
|
|
||||||
if (sprite.mask)
|
if (sprite.mask)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ var GetFastValue = require('../../utils/object/GetFastValue');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a snapshot of an area from the current frame displayed by a canvas.
|
* Takes a snapshot of an area from the current frame displayed by a canvas.
|
||||||
*
|
*
|
||||||
* This is then copied to an Image object. When this loads, the results are sent
|
* This is then copied to an Image object. When this loads, the results are sent
|
||||||
* to the callback provided in the Snapshot Configuration object.
|
* to the callback provided in the Snapshot Configuration object.
|
||||||
*
|
*
|
||||||
|
@ -45,10 +45,13 @@ var CanvasSnapshot = function (canvas, config)
|
||||||
var copyCanvas = CanvasPool.createWebGL(this, width, height);
|
var copyCanvas = CanvasPool.createWebGL(this, width, height);
|
||||||
var ctx = copyCanvas.getContext('2d');
|
var ctx = copyCanvas.getContext('2d');
|
||||||
|
|
||||||
ctx.drawImage(canvas, x, y, width, height, 0, 0, width, height);
|
if (width > 0 && height > 0)
|
||||||
|
{
|
||||||
|
ctx.drawImage(canvas, x, y, width, height, 0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
var image1 = new Image();
|
var image1 = new Image();
|
||||||
|
|
||||||
image1.onerror = function ()
|
image1.onerror = function ()
|
||||||
{
|
{
|
||||||
callback.call(null);
|
callback.call(null);
|
||||||
|
@ -69,7 +72,7 @@ var CanvasSnapshot = function (canvas, config)
|
||||||
{
|
{
|
||||||
// Full Grab
|
// Full Grab
|
||||||
var image2 = new Image();
|
var image2 = new Image();
|
||||||
|
|
||||||
image2.onerror = function ()
|
image2.onerror = function ()
|
||||||
{
|
{
|
||||||
callback.call(null);
|
callback.call(null);
|
||||||
|
|
|
@ -17,12 +17,12 @@ var GetFastValue = require('../../utils/object/GetFastValue');
|
||||||
* @function Phaser.Renderer.Snapshot.WebGL
|
* @function Phaser.Renderer.Snapshot.WebGL
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
*
|
||||||
* @param {HTMLCanvasElement} sourceCanvas - The canvas to take a snapshot of.
|
* @param {WebGLRenderingContext} sourceContext - The WebGL context to take a snapshot of.
|
||||||
* @param {Phaser.Types.Renderer.Snapshot.SnapshotState} config - The snapshot configuration object.
|
* @param {Phaser.Types.Renderer.Snapshot.SnapshotState} config - The snapshot configuration object.
|
||||||
*/
|
*/
|
||||||
var WebGLSnapshot = function (sourceCanvas, config)
|
var WebGLSnapshot = function (sourceContext, config)
|
||||||
{
|
{
|
||||||
var gl = sourceCanvas.getContext('experimental-webgl');
|
var gl = sourceContext;
|
||||||
|
|
||||||
var callback = GetFastValue(config, 'callback');
|
var callback = GetFastValue(config, 'callback');
|
||||||
var type = GetFastValue(config, 'type', 'image/png');
|
var type = GetFastValue(config, 'type', 'image/png');
|
||||||
|
|
|
@ -2654,7 +2654,7 @@ var WebGLRenderer = new Class({
|
||||||
|
|
||||||
if (state.callback)
|
if (state.callback)
|
||||||
{
|
{
|
||||||
WebGLSnapshot(this.canvas, state);
|
WebGLSnapshot(this.gl, state);
|
||||||
|
|
||||||
state.callback = null;
|
state.callback = null;
|
||||||
}
|
}
|
||||||
|
@ -2814,7 +2814,7 @@ var WebGLRenderer = new Class({
|
||||||
|
|
||||||
this.setFramebuffer(framebuffer);
|
this.setFramebuffer(framebuffer);
|
||||||
|
|
||||||
WebGLSnapshot(this.canvas, state);
|
WebGLSnapshot(this.gl, state);
|
||||||
|
|
||||||
this.setFramebuffer(currentFramebuffer);
|
this.setFramebuffer(currentFramebuffer);
|
||||||
|
|
||||||
|
|
|
@ -194,30 +194,28 @@ var BaseSoundManager = new Class({
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
var body = document.body;
|
var body = document.body;
|
||||||
var bodyAdd = body.addEventListener;
|
|
||||||
var bodyRemove = body.removeEventListener;
|
|
||||||
|
|
||||||
var unlockHandler = function unlockHandler ()
|
|
||||||
{
|
|
||||||
if (!_this.pendingUnlock)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_this.unlockHandler();
|
|
||||||
|
|
||||||
bodyRemove('touchstart', unlockHandler);
|
|
||||||
bodyRemove('touchend', unlockHandler);
|
|
||||||
bodyRemove('click', unlockHandler);
|
|
||||||
bodyRemove('keydown', unlockHandler);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (body)
|
if (body)
|
||||||
{
|
{
|
||||||
bodyAdd('touchstart', unlockHandler, false);
|
var unlockHandler = function unlockHandler ()
|
||||||
bodyAdd('touchend', unlockHandler, false);
|
{
|
||||||
bodyAdd('click', unlockHandler, false);
|
if (!_this.pendingUnlock)
|
||||||
bodyAdd('keydown', unlockHandler, false);
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.unlockHandler();
|
||||||
|
|
||||||
|
body.removeEventListener('touchstart', unlockHandler);
|
||||||
|
body.removeEventListener('touchend', unlockHandler);
|
||||||
|
body.removeEventListener('click', unlockHandler);
|
||||||
|
body.removeEventListener('keydown', unlockHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
body.addEventListener('touchstart', unlockHandler, false);
|
||||||
|
body.addEventListener('touchend', unlockHandler, false);
|
||||||
|
body.addEventListener('click', unlockHandler, false);
|
||||||
|
body.addEventListener('keydown', unlockHandler, false);
|
||||||
|
|
||||||
this.pendingUnlock = true;
|
this.pendingUnlock = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,15 @@ var WebAudioSoundManager = new Class({
|
||||||
}
|
}
|
||||||
else if (window.hasOwnProperty('webkitAudioContext'))
|
else if (window.hasOwnProperty('webkitAudioContext'))
|
||||||
{
|
{
|
||||||
context = new window.webkitAudioContext({ latencyHint: 'interactive' });
|
try
|
||||||
|
{
|
||||||
|
context = new window.webkitAudioContext({ latencyHint: 'interactive' });
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
// For iOS10 and legacy devices we create without arguments:
|
||||||
|
context = new window.webkitAudioContext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setAudioContext(context);
|
this.setAudioContext(context);
|
||||||
|
|
|
@ -331,17 +331,20 @@ var TextureManager = new Class({
|
||||||
var canvas = CanvasPool.create2D(this, cd.width, cd.height);
|
var canvas = CanvasPool.create2D(this, cd.width, cd.height);
|
||||||
var ctx = canvas.getContext('2d');
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
ctx.drawImage(
|
if (cd.width > 0 && cd.height > 0)
|
||||||
textureFrame.source.image,
|
{
|
||||||
cd.x,
|
ctx.drawImage(
|
||||||
cd.y,
|
textureFrame.source.image,
|
||||||
cd.width,
|
cd.x,
|
||||||
cd.height,
|
cd.y,
|
||||||
0,
|
cd.width,
|
||||||
0,
|
cd.height,
|
||||||
cd.width,
|
0,
|
||||||
cd.height
|
0,
|
||||||
);
|
cd.width,
|
||||||
|
cd.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
data = canvas.toDataURL(type, encoderOptions);
|
data = canvas.toDataURL(type, encoderOptions);
|
||||||
|
|
||||||
|
|
|
@ -90,15 +90,14 @@ var TilemapLayerCanvasRenderer = function (renderer, src, camera, parentMatrix)
|
||||||
var image = tileset.image.getSourceImage();
|
var image = tileset.image.getSourceImage();
|
||||||
|
|
||||||
var tileTexCoords = tileset.getTileTextureCoordinates(tile.index);
|
var tileTexCoords = tileset.getTileTextureCoordinates(tile.index);
|
||||||
|
var tileWidth = tileset.tileWidth;
|
||||||
|
var tileHeight = tileset.tileHeight;
|
||||||
|
|
||||||
if (tileTexCoords === null)
|
if (tileTexCoords === null || tileWidth === 0 || tileHeight === 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tileWidth = tileset.tileWidth;
|
|
||||||
var tileHeight = tileset.tileHeight;
|
|
||||||
|
|
||||||
var halfWidth = tileWidth * 0.5;
|
var halfWidth = tileWidth * 0.5;
|
||||||
var halfHeight = tileHeight * 0.5;
|
var halfHeight = tileHeight * 0.5;
|
||||||
|
|
||||||
|
|
|
@ -967,13 +967,16 @@ var Tween = new Class({
|
||||||
this.state = TWEEN_CONST.ACTIVE;
|
this.state = TWEEN_CONST.ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isSeeking = true;
|
if (toPosition > 0)
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
this.update(0, delta);
|
this.isSeeking = true;
|
||||||
|
|
||||||
} while (this.totalProgress < toPosition);
|
do
|
||||||
|
{
|
||||||
|
this.update(0, delta);
|
||||||
|
|
||||||
|
} while (this.totalProgress < toPosition);
|
||||||
|
}
|
||||||
|
|
||||||
this.isSeeking = false;
|
this.isSeeking = false;
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,7 @@ var SafeRange = function (array, startIndex, endIndex, throwError)
|
||||||
if (startIndex < 0 ||
|
if (startIndex < 0 ||
|
||||||
startIndex > len ||
|
startIndex > len ||
|
||||||
startIndex >= endIndex ||
|
startIndex >= endIndex ||
|
||||||
endIndex > len ||
|
endIndex > len)
|
||||||
startIndex + endIndex > len)
|
|
||||||
{
|
{
|
||||||
if (throwError)
|
if (throwError)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,47 +4,79 @@
|
||||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Source object
|
|
||||||
// The key as a string, or an array of keys, i.e. 'banner', or 'banner.hideBanner'
|
|
||||||
// The default value to use if the key doesn't exist
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a value from an object.
|
* Retrieves a value from an object, or an alternative object, falling to a back-up default value if not found.
|
||||||
|
*
|
||||||
|
* The key is a string, which can be split based on the use of the period character.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
*
|
||||||
|
* ```javascript
|
||||||
|
* const source = {
|
||||||
|
* lives: 3,
|
||||||
|
* render: {
|
||||||
|
* screen: {
|
||||||
|
* width: 1024
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* const lives = GetValue(source, 'lives', 1);
|
||||||
|
* const width = GetValue(source, 'render.screen.width', 800);
|
||||||
|
* const height = GetValue(source, 'render.screen.height', 600);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* In the code above, `lives` will be 3 because it's defined at the top level of `source`.
|
||||||
|
* The `width` value will be 1024 because it can be found inside the `render.screen` object.
|
||||||
|
* The `height` value will be 600, the default value, because it is missing from the `render.screen` object.
|
||||||
*
|
*
|
||||||
* @function Phaser.Utils.Objects.GetValue
|
* @function Phaser.Utils.Objects.GetValue
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
*
|
||||||
* @param {object} source - The object to retrieve the value from.
|
* @param {object} source - The primary object to try to retrieve the value from. If not found in here, `altSource` is checked.
|
||||||
* @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object.
|
* @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object.
|
||||||
* @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object.
|
* @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object.
|
||||||
|
* @param {object} [altSource] - An alternative object to retrieve the value from. If the property exists in `source` then `altSource` will not be used.
|
||||||
*
|
*
|
||||||
* @return {*} The value of the requested key.
|
* @return {*} The value of the requested key.
|
||||||
*/
|
*/
|
||||||
var GetValue = function (source, key, defaultValue)
|
var GetValue = function (source, key, defaultValue, altSource)
|
||||||
{
|
{
|
||||||
if (!source || typeof source === 'number')
|
if ((!source && !altSource) || typeof source === 'number')
|
||||||
{
|
{
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
else if (source.hasOwnProperty(key))
|
else if (source && source.hasOwnProperty(key))
|
||||||
{
|
{
|
||||||
return source[key];
|
return source[key];
|
||||||
}
|
}
|
||||||
|
else if (altSource && altSource.hasOwnProperty(key))
|
||||||
|
{
|
||||||
|
return altSource[key];
|
||||||
|
}
|
||||||
else if (key.indexOf('.') !== -1)
|
else if (key.indexOf('.') !== -1)
|
||||||
{
|
{
|
||||||
var keys = key.split('.');
|
var keys = key.split('.');
|
||||||
var parent = source;
|
var parentA = source;
|
||||||
|
var parentB = altSource;
|
||||||
var value = defaultValue;
|
var value = defaultValue;
|
||||||
|
|
||||||
// Use for loop here so we can break early
|
// Use for loop here so we can break early
|
||||||
for (var i = 0; i < keys.length; i++)
|
for (var i = 0; i < keys.length; i++)
|
||||||
{
|
{
|
||||||
if (parent.hasOwnProperty(keys[i]))
|
if (parentA && parentA.hasOwnProperty(keys[i]))
|
||||||
{
|
{
|
||||||
// Yes it has a key property, let's carry on down
|
// Yes parentA has a key property, let's carry on down
|
||||||
value = parent[keys[i]];
|
value = parentA[keys[i]];
|
||||||
|
|
||||||
parent = parent[keys[i]];
|
parentA = parentA[keys[i]];
|
||||||
|
}
|
||||||
|
else if (parentB && parentB.hasOwnProperty(keys[i]))
|
||||||
|
{
|
||||||
|
// Yes parentB has a key property, let's carry on down
|
||||||
|
value = parentB[keys[i]];
|
||||||
|
|
||||||
|
parentB = parentB[keys[i]];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue