phaser-arcade-slopes
Version:
A Phaser CE plugin that brings sloped tile collision handling to Phaser's Arcade Physics engine
532 lines (480 loc) • 10.1 kB
JavaScript
/**
* @author Chris Andrew <chris@hexus.io>
* @copyright 2016-2021 Chris Andrew
* @license MIT
*/
/**
* Defines the slope of a tile.
*
* @class Phaser.Plugin.ArcadeSlopes.TileSlope
* @constructor
* @param {integer} type - The type of the tile slope.
* @param {Phaser.Tile} tile - The tile this slope definition belongs to.
* @param {SAT.Polygon} polygon - The polygon representing the shape of the tile.
* @param {Phaser.Line} line - The line representing the slope of the tile.
* @param {object} edges - The flags for each edge of the tile.
* @param {SAT.Vector} axis - The preferred axis for separating physics bodies.
* @param {SAT.Vector[]} [ignormals] - An optional set of collision normals to ignore.
*/
Phaser.Plugin.ArcadeSlopes.TileSlope = function (type, tile, polygon, line, edges, axis, ignormals) {
/**
* The type of the tile slope.
*
* @property {integer} type
*/
this.type = type;
/**
* The tile this slope definition is for.
*
* @property {Phaser.Tile} tile
*/
this.tile = tile;
/**
* The polygon representing the shape of the tile.
*
* @property {SAT.Polygon} polygon
*/
this.polygon = polygon;
/**
* The line representing the slope of the tile.
*
* @property {Phaser.Tile} line
*/
this.line = line;
/**
* The flags for each edge of the tile: empty, solid or interesting?
*
* @property {object} edges
*/
this.edges = Phaser.Utils.mixin(edges || {}, {
top: Phaser.Plugin.ArcadeSlopes.TileSlope.SOLID,
bottom: Phaser.Plugin.ArcadeSlopes.TileSlope.SOLID,
left: Phaser.Plugin.ArcadeSlopes.TileSlope.SOLID,
right: Phaser.Plugin.ArcadeSlopes.TileSlope.SOLID
});
/**
* The preferred axis for separating physics bodies.
*
* @property {SAT.Vector} axis
*/
this.axis = axis || null;
/**
* An optional set of collision normals to ignore.
*
* @property {SAT.Vector[]} ignormals
*/
this.ignormals = ignormals || [];
/**
* The preferred solver to use for this slope.
*
* @property {string} solver
*/
this.solver = null;
/**
* The friction of this slope.
*
* @property {Phaser.Point} friction
*/
this.friction = new Phaser.Point();
};
/**
* Determine whether the start or end of one slope line meets the start or end
* of another's.
*
* @param {Phaser.Plugin.ArcadeSlopes.TileSlope} slope - The tile slope to check intersection with.
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.prototype.meets = function (slope) {
return this.line.start.equals(slope.line.end)
|| this.line.end.equals(slope.line.start);
};
/**
* Resolve a tile slope type constant from the given value.
*
* Returns any successfully parsed non-negative integers regardless of whether
* they are valid slope tile types. This method is really for strings.
*
* @method Phaser.Plugin.ArcadeSlopes.TileSlope#resolveType
* @param {string|integer} type - The value to resolve.
* @return {integer} - The resolved tile slope type constant.
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.resolveType = function (type) {
if (parseInt(type) >= 0) {
return type;
}
if (typeof type === 'string') {
type = type.toUpperCase();
}
if (Phaser.Plugin.ArcadeSlopes.TileSlope.hasOwnProperty(type)) {
return Phaser.Plugin.ArcadeSlopes.TileSlope[type];
}
console.warn('Unknown slope type \'' + type + '\'');
return Phaser.Plugin.ArcadeSlopes.TileSlope.UNKNOWN;
};
/**
* The slope of the tile.
*
* @name Phaser.Plugin.ArcadeSlopes.TileSlope#slope
* @property {number} slope
*/
Object.defineProperty(Phaser.Plugin.ArcadeSlopes.TileSlope.prototype, 'slope', {
get: function () {
if (!this.line) {
return 0;
}
return (this.line.start.y - this.line.end.y) / (this.line.start.x - this.line.end.x);
}
});
/**
* The name of the tile slope type.
*
* @name Phaser.Plugin.ArcadeSlopes.TileSlope#typeName
* @property {string} typeName
*/
Object.defineProperty(Phaser.Plugin.ArcadeSlopes.TileSlope.prototype, 'typeName', {
get: function () {
return Phaser.Plugin.ArcadeSlopes.TileSlope.resolveTypeName(this.type);
},
set: function (type) {
this.type = Phaser.Plugin.ArcadeSlopes.TileSlope.resolveType(type);
}
});
/**
* Resolve a tile slope type name from the given type constant.
*
* @static
* @method Phaser.Plugin.ArcadeSlopes.TileSlope#resolveTypeName
* @param {integer} type - The type constant.
* @return {integer} - The type name.
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.resolveTypeName = function (type) {
if (Phaser.Plugin.ArcadeSlopes.TileSlope.typeNames.hasOwnProperty(type)) {
return Phaser.Plugin.ArcadeSlopes.TileSlope.typeNames[type];
}
return Phaser.Plugin.ArcadeSlopes.TileSlope.typeNames[-1];
};
/**
* The map of tile slope types to their corresponding type names.
*
* @static
* @property {object} typeNames
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.typeNames = {
'-1': 'UNKNOWN',
0: 'FULL',
21: 'HALF_BOTTOM',
22: 'HALF_TOP',
23: 'HALF_LEFT',
24: 'HALF_RIGHT',
1: 'HALF_BOTTOM_LEFT',
2: 'HALF_BOTTOM_RIGHT',
3: 'HALF_TOP_LEFT',
4: 'HALF_TOP_RIGHT',
5: 'QUARTER_BOTTOM_LEFT_LOW',
6: 'QUARTER_BOTTOM_LEFT_HIGH',
7: 'QUARTER_BOTTOM_RIGHT_LOW',
8: 'QUARTER_BOTTOM_RIGHT_HIGH',
9: 'QUARTER_LEFT_BOTTOM_LOW',
10: 'QUARTER_LEFT_BOTTOM_HIGH',
11: 'QUARTER_RIGHT_BOTTOM_LOW',
12: 'QUARTER_RIGHT_BOTTOM_HIGH',
13: 'QUARTER_LEFT_TOP_LOW',
14: 'QUARTER_LEFT_TOP_HIGH',
15: 'QUARTER_RIGHT_TOP_LOW',
16: 'QUARTER_RIGHT_TOP_HIGH',
17: 'QUARTER_TOP_LEFT_LOW',
18: 'QUARTER_TOP_LEFT_HIGH',
19: 'QUARTER_TOP_RIGHT_LOW',
20: 'QUARTER_TOP_RIGHT_HIGH',
};
// TODO: Misleading constants here - they aren't tile slope types, they're edges
/**
* An empty tile edge.
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.EMPTY = 0;
/**
* A solid tile edge.
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.SOLID = 1;
/**
* An interesting tile edge.
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.INTERESTING = 2;
/**
* An undefined tile slope type.
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.UNKNOWN = -1;
/**
* A full square tile.
* .___
* | |
* |___|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.FULL = 0;
/**
* A half bottom tile.
* .
* ___
* |___|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_BOTTOM = 21;
/**
* A half top tile.
* .___
* |___|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_TOP = 22;
/**
* A half left tile.
* ._
* | |
* |_|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_LEFT = 23;
/**
* A half right tile.
* . _
* | |
* |_|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_RIGHT = 24;
/**
* A 45 degree bottom left slope.
*
* |\
* | \
* |__\
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_BOTTOM_LEFT = 1;
/**
* A 45 degree bottom right slope.
*
* /|
* / |
* /__|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_BOTTOM_RIGHT = 2;
/**
* A 45 degree top left slope.
* __
* | /
* | /
* |/
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_TOP_LEFT = 3;
/**
* A 45 degree top right slope.
* __
* \ |
* \ |
* \|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.HALF_TOP_RIGHT = 4;
/**
* |\
* | | |\
* |_| |_\ <--
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_BOTTOM_LEFT_LOW = 5;
/**
* |\
* | | |\
* -->|_| |_\
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_BOTTOM_LEFT_HIGH = 6;
/**
* /|
* /| | |
* -->/_| |_|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_BOTTOM_RIGHT_LOW = 7;
/**
* /|
* /| | |
* /_| |_|<--
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_BOTTOM_RIGHT_HIGH = 8;
/**
* |\
* |_\
* __
* | \ <--
* |___\
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_LEFT_BOTTOM_LOW = 9;
/**
* |\
* |_\ <--
* __
* | \
* |___\
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_LEFT_BOTTOM_HIGH = 10;
/**
* /|
* /_|
* __
* / | <--
* /___|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_RIGHT_BOTTOM_LOW = 11;
/**
* /|
* /_| <--
* __
* / |
* /___|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_RIGHT_BOTTOM_HIGH = 12;
/**
* ____
* | /
* |___/
* __
* | / <--
* |/
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_LEFT_TOP_LOW = 13;
/**
* ____
* | / <--
* |___/
* __
* | /
* |/
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_LEFT_TOP_HIGH = 14;
/**
* ____
* \ |
* \___|
* __
* \ | <--
* \|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_RIGHT_TOP_LOW = 15;
/**
* ____
* \ | <--
* \___|
* __
* \ |
* \|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_RIGHT_TOP_HIGH = 16;
/**
* __ __
* | | | / <--
* | | |/
* | /
* |/
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_TOP_LEFT_LOW = 17;
/**
* __ __
* | | | /
* --> | | |/
* | /
* |/
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_TOP_LEFT_HIGH = 18;
/**
* __ __
* \ | | |
* --> \| | |
* \ |
* \|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_TOP_RIGHT_LOW = 19;
/**
* __ __
* \ | | |
* \| | | <--
* \ |
* \|
*
* @constant
* @type {integer}
*/
Phaser.Plugin.ArcadeSlopes.TileSlope.QUARTER_TOP_RIGHT_HIGH = 20;