phaser-planck
Advanced tools
Comparing version 1.0.5 to 1.1.0
@@ -8,3 +8,2 @@ 'use strict'; | ||
var _require = require('planck-js'), | ||
Body = _require.Body, | ||
Vec2 = _require.Vec2; | ||
@@ -24,3 +23,3 @@ | ||
this._body = new Body(game.physics.planck.world, { | ||
this._body = game.physics.planck.world.createBody({ | ||
'type': type, | ||
@@ -38,2 +37,3 @@ 'position': new Vec2(x || 0, y || 0), | ||
* Adds a fixture to the body | ||
* @param {planck.Shape} shape | ||
* @param {Object} fixtureDef | ||
@@ -48,4 +48,4 @@ * @param {Number} fixtureDef.friction - friction coefficient, usually in the | ||
* @param {Number} fixtureDef.filterGroupIndex | ||
* @param {Number} filterCategoryBits | ||
* @param {Number} filterMaskBits | ||
* @param {Number} fixtureDef.filterCategoryBits | ||
* @param {Number} fixtureDef.filterMaskBits | ||
*/ | ||
@@ -56,5 +56,5 @@ | ||
key: 'addFixture', | ||
value: function addFixture(fixtureDef) { | ||
value: function addFixture(shape, fixtureDef) { | ||
fixtureDef.userData = this; | ||
this._body.createFixture(fixtureDef); | ||
this._body.createFixture(shape, fixtureDef); | ||
} | ||
@@ -61,0 +61,0 @@ }]); |
@@ -12,7 +12,9 @@ 'use strict'; | ||
var _require = require('phaser'), | ||
Plugin = _require.Plugin; | ||
Plugin = _require.Plugin, | ||
RenderTexture = _require.RenderTexture; | ||
var _require2 = require('planck-js'), | ||
World = _require2.World, | ||
Vec2 = _require2.Vec2; | ||
Vec2 = _require2.Vec2, | ||
Box = _require2.Box; | ||
@@ -32,5 +34,7 @@ var Body = require('./Body.js'); | ||
* @param {Phaser.Game} game | ||
* @param {any} parent | ||
* @param {Object} parent - Usually game.PluginManager | ||
* @param {Object=} options - Optional options object | ||
* @param {Number=} options.scaleFactor - scaling factor to employ with Box2d | ||
*/ | ||
function PhaserPlanck(game, parent) { | ||
function PhaserPlanck(game, parent, options) { | ||
_classCallCheck(this, PhaserPlanck); | ||
@@ -42,2 +46,7 @@ | ||
game.physics.planck = _this; | ||
_this._scalingFactor = options !== undefined && options.scaleFactor ? options.scaleFactor : 10; | ||
_this._inverseScaleFactor = 1 / _this._scalingFactor; | ||
_this._halfWorldWidth = game.world._width * 0.5; | ||
_this._halfWorldHeight = game.world._height * 0.5; | ||
return _this; | ||
@@ -74,2 +83,120 @@ } | ||
/** | ||
* Counts the number of tiles that are set to collide in the given tile layer's data | ||
* @param {Array} layer - 2d array of the tiles | ||
* @returns {Number} | ||
*/ | ||
}, { | ||
key: '_countCollidingTiles', | ||
value: function _countCollidingTiles(layer) { | ||
var count = 0, | ||
row, | ||
tile; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = layer[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
row = _step.value; | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
try { | ||
for (var _iterator2 = row[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
tile = _step2.value; | ||
count += tile.collides ? 1 : 0; | ||
} | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
_iterator2.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
} | ||
} | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
return count; | ||
} | ||
/** | ||
* Translates the coordinates from Phaser Space to planck space | ||
* @param {Number} x | ||
* @param {Number} y | ||
* @returns {Array} | ||
*/ | ||
}, { | ||
key: '_phaserToPlanck', | ||
value: function _phaserToPlanck(x, y) { | ||
x -= this._halfWorldWidth; | ||
y -= this._halfWorldHeight; | ||
return [x * this._inverseScaleFactor, y * -this._inverseScaleFactor]; | ||
} | ||
/** | ||
* Translates the coordinates from planck space to Phaser space | ||
* @param {Number} x | ||
* @param {Number} y | ||
* @returns {Array} | ||
*/ | ||
}, { | ||
key: '_planckToPhaser', | ||
value: function _planckToPhaser(x, y) { | ||
x += this._halfWorldWidth; | ||
y += this._halfWorldHeight; | ||
return [x * this._scalingFactor, y * -this._scalingFactor]; | ||
} | ||
/** | ||
* Creates and returns a body | ||
* @param {Phaser.Game} game | ||
* @param {Number} x | ||
* @param {Number} y | ||
* @param {Number} mass | ||
* @param {Object} options | ||
* @param {String} options.type - Required in order to define the type of body | ||
* to create: static, dynamic, or kinematic | ||
* @param {Boolean} options.addToWorld - defines whether or not to automatically | ||
* add this to the physics world | ||
* @returns {Body} | ||
*/ | ||
}, { | ||
key: 'createBody', | ||
value: function createBody(game, x, y, mass, options) { | ||
if (!options || !options.type) { | ||
throw new TypeError("'options.type' is required"); | ||
} | ||
var planckCoordinates = this._phaserToPlanck(x, y), | ||
body = new Body(game, null, options.type, planckCoordinates[0], planckCoordinates[1]); | ||
return body; | ||
} | ||
/** | ||
* Convert a tilemap into Box2D bodies | ||
@@ -89,6 +216,465 @@ * @param {Phaser.Tilemap} map | ||
key: 'convertTilemap', | ||
value: function convertTilemap(map, layer, addToWorld, optomize) { | ||
value: function convertTilemap(map, layer) { | ||
var addToWorld = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
var optomize = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; | ||
var currentLayer = map.layers[map.getLayer(layer)]; | ||
console.log(currentLayer); | ||
tiles = currentLayer.data, totalCollidingTiles = this._countCollidingTiles(currentLayer), tileWidth = currentLayer.widthInPixels / currentLayer.width, tileHeight = currentLayer.heightInPixels / currentLayer.height, currentBody, chainingVertices = [], subgraphs = this._collectSubgraphs(tiles, totalCollidingTiles, tileWidth, tileHeight), edges = this._collectEdgesFromSubgraphs(subgraphs), bodies = this._createBodiesFromEdges(edges); | ||
return bodies; | ||
} | ||
/** | ||
* Actually creates bodies from edge lists using chain shapes | ||
* @param {Array} edges | ||
* @returns {Array} bodies | ||
*/ | ||
}, { | ||
key: '_createBodiesFromEdges', | ||
value: function _createBodiesFromEdges(edges) { | ||
var edgeList, | ||
halfWidth, | ||
halfHeight, | ||
bodies = []; | ||
var _iteratorNormalCompletion3 = true; | ||
var _didIteratorError3 = false; | ||
var _iteratorError3 = undefined; | ||
try { | ||
for (var _iterator3 = edges[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | ||
edgeList = _step3.value; | ||
halfWidth = edgeList[1].x - edgeList[0].x; | ||
halfHeight = edgeList[2].y - edgeList[0].y; | ||
body = this.createBody(this.game, edgeList[0].x + halfWidth, edgeList[0].y + halfHeight, 1, // irrelevant, static bodies have infinite mass | ||
{ 'type': 'static' }); | ||
body.addFixtureDef(new Box(halfWidth * this._inverseScaleFactor, halfHeight * this._inverseScaleFactor), { | ||
'friction': 1.0 | ||
}); | ||
} | ||
} catch (err) { | ||
_didIteratorError3 = true; | ||
_iteratorError3 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion3 && _iterator3.return) { | ||
_iterator3.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError3) { | ||
throw _iteratorError3; | ||
} | ||
} | ||
} | ||
return bodies; | ||
} | ||
/** | ||
* Returns edge lists which should be used to create chain shapes from | ||
* a list of graphs | ||
* @param {Array} subgraphs - list of subgraphs | ||
* @returns {Array} | ||
*/ | ||
}, { | ||
key: '_collectEdgesFromSubgraphs', | ||
value: function _collectEdgesFromSubgraphs(subgraphs) { | ||
var graph, | ||
edges = [], | ||
collectedTiles, | ||
startPoint = [], | ||
boxEdges; | ||
var _iteratorNormalCompletion4 = true; | ||
var _didIteratorError4 = false; | ||
var _iteratorError4 = undefined; | ||
try { | ||
for (var _iterator4 = subgraphs[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { | ||
subgraphObject = _step4.value; | ||
collectedTiles = new Set(); | ||
while (collectedTiles.size < this._countCollidingTiles(subgraphObject.data)) { | ||
// Get start point | ||
startPoint = subgraphObject.offset.slice(); | ||
while (startPoint[0] < subgraphObject.width + subgraphObject.offset[0] && startPoint[1] < subgraphObject.height + subgraphObject.offset[1] && !subgraphObject.data[startPoint[1]][startPoint[0]].collides && collectedTiles.has(this._hashVector(startPoint))) { | ||
startPoint = [startPoint[0] + 1][startPoint[1]]; | ||
if (startPoint[0] >= subgraphObject.width) { | ||
startPoint = [subgraphObject.offset[0], startPoint[1] + 1]; | ||
} | ||
} | ||
// Check if we're in bounds | ||
if (startPoint[0] >= subgraphObject.width + subgraphObject.offset[0] || startPoint[1] >= subgraphObject.height + subgraphObject.offset[1]) { | ||
break; | ||
} | ||
boxEdges = this._findBox(startPoint, subgraph, collectedTiles); | ||
edges.push(boxEdges); | ||
} | ||
// Check if we got everything | ||
if (collectedTiles.size < this._countCollidingTiles(subgraphObject.data)) { | ||
console.error("Not all colliding tiles included in edges"); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError4 = true; | ||
_iteratorError4 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion4 && _iterator4.return) { | ||
_iterator4.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError4) { | ||
throw _iteratorError4; | ||
} | ||
} | ||
} | ||
return edges; | ||
} | ||
/** | ||
* Finds the biggest box from the start point and the given subgraph object | ||
* @param {Array} startPoint | ||
* @param {Object} subgraph - subgraph object from {@link _collectSubgraphs} | ||
* @returns {Array} a list of corners for the box | ||
*/ | ||
}, { | ||
key: '_findBox', | ||
value: function _findBox(startPoint, subgraph, collectedTiles) { | ||
var right = startPoint[0], | ||
bottom = startPoint[1], | ||
width = subgraph.data[0].length, | ||
height = subgraph.data.length, | ||
rowCollides, | ||
x, | ||
y, | ||
offsetVector; | ||
while (right + 1 < width && subgraph.data[bottom][right + 1].collides) { | ||
right += 1; | ||
} | ||
// Check the entire row if we can grow the box downward | ||
while (bottom + 1 < height) { | ||
rowCollides = true; | ||
for (x = startPoint[0]; x < right; x++) { | ||
if (!subgraph.data[bottom + 1][x].collides) { | ||
rowCollides = false; | ||
break; | ||
} | ||
} | ||
if (rowCollides) { | ||
bottom += 1; | ||
} | ||
} | ||
// Update the collectedTiles set | ||
for (x = startPoint[0]; x < right; x++) { | ||
for (y = startPoint[1]; y < bottom; y++) { | ||
collectedTiles.add(this._hashVector([x, y])); | ||
} | ||
} | ||
offsetVector = new Vec2(subgraph.offset[0] * subgraph.tileWidth, subgraph.offset[1] * subgraph.tileHeight); | ||
return [new Vec2(startPoint[0] * subgraph.tileWidth, startPoint[1] * subgraph.tileHeight).add(offsetVector), new Vec2(right * subgraph.tileWidth + subgraph.tileWidth - 1, startPoint[1] * subgraph.tileHeight).add(offsetVector), new Vec2(right * subgraph.tileWidth + subgraph.tileWidth - 1, bottom * subgraph.tileHeight + subgraph.tileHeight - 1).add(offsetVector), new Vec2(startPoint[0] * subgraph.tileHeight, bottom * subgraph.tileHeight + subgraph.tileHeight - 1).add(offsetVector)]; | ||
} | ||
/** | ||
* Returns an array of subgraphs from the given tile data. This each subgraph should | ||
* then be used to create its own chain shape | ||
* @param {Array} tiles - An array of arrays | ||
* @param {Number} totalCollidingTiles - the total number of tiles which are set to collide | ||
* in the given tile data | ||
* @returns {Array} an array of subgraphs, which are arrays also | ||
*/ | ||
}, { | ||
key: '_collectSubgraphs', | ||
value: function _collectSubgraphs(tiles, totalCollidingTiles, tileWidth, tileHeight) { | ||
var collectedTiles = Set(), | ||
subgraphs = [], | ||
currentTile, | ||
xIndex = 0, | ||
yIndex = 0; | ||
while (collectedTiles.length < totalCollidingTiles) { | ||
// Find a tile to start with | ||
currentTile = tiles[yIndex][xIndex]; | ||
while (!currentTile.collides || collectedTiles.has(this._hashVector(currentTile))) { | ||
xIndex += 1; | ||
if (xIndex >= currentLayer.width) { | ||
xIndex = 0; | ||
yIndex += 1; | ||
// Check if we've gone past the end of the map | ||
if (yIndex >= currentLayer.height) { | ||
console.error("Reached the end of the map before collecting all colliding tiles"); | ||
break; | ||
} | ||
} | ||
currentTile = tiles[yIndex][xIndex]; | ||
} | ||
// Couldn't find a valid tile, break | ||
if (!collidingTile) { | ||
break; | ||
} | ||
// Find all the different subgraphs, each will be a different chain shape | ||
subgraph = []; | ||
tileQueue = [currentTile]; | ||
while (tileQueue.length > 0) { | ||
currentTile = tileQueue.shift(); | ||
collectedTiles.add(this._hashVector(currentTile.x, currentTile.y)); | ||
// Left | ||
if (currentTile.x > 0 && tiles[currentTile.y][currentTile.x - 1].collides && !collectedTiles.has(this._hashVector(currentTile.x - 1, currentTile.y))) { | ||
tileQueue.push(tiles[currentTile.y][currentTile.x - 1]); | ||
} | ||
// Top | ||
if (currentTile.y > 0 && tiles[currentTile.y - 1][currentTile.x].collides && !collectedTiles.has(this._hashVector(currentTile.x, currentTile.y - 1))) { | ||
tileQueue.push(tiles[currentTile.y - 1][currentTile.x]); | ||
} | ||
// Right | ||
if (currentTile.x < tiles.width - 1 && tiles[currentTile.y][currentTile.x + 1].collides && !collectedTiles.has(this._hashVector(currentTile.x + 1, currentTile.y))) { | ||
tileQueue.push(tiles[currentTile.y][currentTile.x + 1]); | ||
} | ||
// Bottom | ||
if (currentTile.y < tiles.height - 1 && tiles[currentTile.y + 1][currentTile.x].colllides && !collectedTiles.has(this._hashVector(currentTile.x, currentTile.y + 1))) { | ||
tileQueue.push(tiles[currentTile.y + 1][currentTile.x]); | ||
} | ||
subgraph.push([currentTile.x, currentTile.y]); | ||
} | ||
// Copies the entire subgraph from the main tile data | ||
subgraphs.push(Object.assign(this._getSubgraph(tiles, subgraph), { | ||
'tileWidth': tileWidth, | ||
'tileHeight': tileHeight | ||
})); | ||
} | ||
} | ||
/** | ||
* Copies an entire subgraph from graph and returns an object describing it | ||
* @param {Array} graph - 2d array containing tile information | ||
* @param {Array} subgraph - list of points that should be included within | ||
* the returned subgraph | ||
* @returns {Object} an object describing the extracted subgraph and the offset within the | ||
* larger given 2d array | ||
*/ | ||
}, { | ||
key: '_getSubgraph', | ||
value: function _getSubgraph(graph, subgraph) { | ||
var topLeft, leftMostPoints, topMostPoints, bottomRight, rightMostPoints, bottomMostPoints, subData, subRow, i; | ||
leftMostPoints = this._findLeftMostPoint(subgraph); | ||
topMostPoints = this._findTopMostPoint(subgraph); | ||
topLeft = [leftMostPoints[0][0], topMostPoints[0][1]]; | ||
rightMostPoints = this._findRightMostPoint(subgraph); | ||
bottomMostPoints = this._findBottomMostPoint(subgraph); | ||
bottomRight = [rightMostPoints[0][0], bottomMostPoints[0][1]]; | ||
for (i = topLeft[1]; i < bottomRight[1]; i++) { | ||
subRow = graph[i].slice(topLeft[0], bottomRight[0]); | ||
subData.push(subRow); | ||
} | ||
return { | ||
'offset': topLeft, | ||
'data': subData | ||
}; | ||
} | ||
/** | ||
* Hash function for 2d vector. Primes taken from | ||
* https://stackoverflow.com/questions/5928725/hashing-2d-3d-and-nd-vectors | ||
* guessed hash table size taken from | ||
* https://stackoverflow.com/questions/286058/chosing-a-suitable-table-size-for-a-hash | ||
* @param {Object|Array} vector - an array with 2 numbers or an object with 'x' and 'y' fields | ||
* @returns {Number} | ||
*/ | ||
}, { | ||
key: '_hashVector', | ||
value: function _hashVector(vector) { | ||
if (vector.x !== undefined && vector.y !== undefined) { | ||
return vector.x * 73856093 ^ vector.y * 83492791 % 1334; | ||
} | ||
} | ||
/** | ||
* Returns a list of the farthest left points from the given list of points | ||
* @param {Array} pointList | ||
* @returns {Array} | ||
*/ | ||
}, { | ||
key: '_findLeftMostPoint', | ||
value: function _findLeftMostPoint(pointList) { | ||
var returnValue = [], | ||
point; | ||
var _iteratorNormalCompletion5 = true; | ||
var _didIteratorError5 = false; | ||
var _iteratorError5 = undefined; | ||
try { | ||
for (var _iterator5 = pointList[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { | ||
point = _step5.value; | ||
if (returnValue.length <= 0 || point[0] < returnValue[0][0]) { | ||
returnValue = [point]; | ||
} else if (point[0] == returnValue[0][0]) { | ||
returnValue.push(point); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError5 = true; | ||
_iteratorError5 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion5 && _iterator5.return) { | ||
_iterator5.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError5) { | ||
throw _iteratorError5; | ||
} | ||
} | ||
} | ||
return returnValue; | ||
} | ||
/** | ||
* Returns a list of the farthest top points from the given list of points | ||
* @param {Array} pointList | ||
* @returns {Array} | ||
*/ | ||
}, { | ||
key: '_findTopMostPoint', | ||
value: function _findTopMostPoint(pointList) { | ||
var returnValue = [], | ||
point; | ||
var _iteratorNormalCompletion6 = true; | ||
var _didIteratorError6 = false; | ||
var _iteratorError6 = undefined; | ||
try { | ||
for (var _iterator6 = pointList[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { | ||
point = _step6.value; | ||
if (returnValue.length <= 0 || point[1] < returnValue[0][1]) { | ||
returnValue = [point]; | ||
} else if (point[1] == returnValue[0][1]) { | ||
returnValue.push(point); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError6 = true; | ||
_iteratorError6 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion6 && _iterator6.return) { | ||
_iterator6.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError6) { | ||
throw _iteratorError6; | ||
} | ||
} | ||
} | ||
return returnValue; | ||
} | ||
/** | ||
* Returns a list of the farthest right point from the given list of points | ||
* @param {Array} pointlist | ||
* @returns {Array} | ||
*/ | ||
}, { | ||
key: '_findRightMostPoint', | ||
value: function _findRightMostPoint(pointList) { | ||
var returnValue = [], | ||
point; | ||
var _iteratorNormalCompletion7 = true; | ||
var _didIteratorError7 = false; | ||
var _iteratorError7 = undefined; | ||
try { | ||
for (var _iterator7 = pointList[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { | ||
point = _step7.value; | ||
if (returnValue.length <= 0 || point[0] > returnValue[0][0]) { | ||
returnValue = [point]; | ||
} else if (point[1] == returnValue[0][0]) { | ||
returnValue.push(point); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError7 = true; | ||
_iteratorError7 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion7 && _iterator7.return) { | ||
_iterator7.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError7) { | ||
throw _iteratorError7; | ||
} | ||
} | ||
} | ||
return returnValue; | ||
} | ||
/** | ||
* Returns a list of the farthest bottom point from the given list of points | ||
* @param {Array} pointList | ||
* @returns {Array} | ||
*/ | ||
}, { | ||
key: '_findBottomMostPoint', | ||
value: function _findBottomMostPoint(pointList) { | ||
var returnValue = [], | ||
point; | ||
var _iteratorNormalCompletion8 = true; | ||
var _didIteratorError8 = false; | ||
var _iteratorError8 = undefined; | ||
try { | ||
for (var _iterator8 = pointList[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { | ||
point = _step8.value; | ||
if (returnValue.length <= 0 || point[1] > returnValue[0][1]) { | ||
returnValue = [point]; | ||
} else if (point[1] == returnValue[0][1]) { | ||
returnValue.push(point); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError8 = true; | ||
_iteratorError8 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion8 && _iterator8.return) { | ||
_iterator8.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError8) { | ||
throw _iteratorError8; | ||
} | ||
} | ||
} | ||
return returnValue; | ||
} | ||
}]); | ||
@@ -95,0 +681,0 @@ |
{ | ||
"name": "phaser-planck", | ||
"version": "1.0.5", | ||
"version": "1.1.0", | ||
"description": "A Phaser plugin for planck js", | ||
@@ -5,0 +5,0 @@ "main": "./build/index.js", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
27589
650
1