New split physics system is implemented. Still tidying-up, but ArcadePhysics, P2 and Ninja Physics are in and configured. Lots more examples required, and tilemap collision mostly broken in Arcade at the moment. Time to implement in Ninja.
@@ -180,14 +180,26 @@ module.exports = function (grunt) {
|
||||
'src/utils/Debug.js',
|
||||
'src/utils/Color.js',
|
||||
|
||||
'src/physics/World.js',
|
||||
'src/physics/PointProxy.js',
|
||||
'src/physics/InversePointProxy.js',
|
||||
'src/physics/Body.js',
|
||||
'src/physics/Spring.js',
|
||||
'src/physics/Material.js',
|
||||
'src/physics/ContactMaterial.js',
|
||||
'src/physics/CollisionGroup.js',
|
||||
'/src/physics/Physics.js',
|
||||
|
||||
'/src/physics/arcade/World.js',
|
||||
'/src/physics/arcade/Body.js',
|
||||
'/src/physics/arcade/QuadTree.js',
|
||||
|
||||
'/src/physics/ninja/World.js',
|
||||
'/src/physics/ninja/Body.js',
|
||||
'/src/physics/ninja/AABB.js',
|
||||
'/src/physics/ninja/Tile.js',
|
||||
'/src/physics/ninja/Circle.js',
|
||||
|
||||
'/src/physics/p2/World.js',
|
||||
'/src/physics/p2/PointProxy.js',
|
||||
'/src/physics/p2/InversePointProxy.js',
|
||||
'/src/physics/p2/Body.js',
|
||||
'/src/physics/p2/Spring.js',
|
||||
'/src/physics/p2/Material.js',
|
||||
'/src/physics/p2/ContactMaterial.js',
|
||||
'/src/physics/p2/CollisionGroup.js',
|
||||
|
||||
'src/particles/Particles.js',
|
||||
'src/particles/arcade/ArcadeParticles.js',
|
||||
|
||||
@@ -14,6 +14,7 @@ By Richard Davey, [Photon Storm](http://www.photonstorm.com)
|
||||
* Join the [Forum](http://www.html5gamedevs.com/forum/14-phaser/)
|
||||
* Try out 220+ [Phaser Examples](http://examples.phaser.io)
|
||||
* Read the [documentation online](http://docs.phaser.io)
|
||||
* Join our [#phaserio IRC channel](http://www.html5gamedevs.com/topic/4470-official-phaserio-irc-channel-phaserio-on-freenode/) on freenode
|
||||
|
||||
[Subscribe to our new Phaser Newsletter](https://confirmsubscription.com/h/r/369DE48E3E86AF1E). We'll email you when new versions are released as well as send you our regular Phaser game making magazine.
|
||||
|
||||
|
||||
@@ -141,6 +141,12 @@
|
||||
<script src="$path/src/physics/arcade/Body.js"></script>
|
||||
<script src="$path/src/physics/arcade/QuadTree.js"></script>
|
||||
|
||||
<script src="$path/src/physics/ninja/World.js"></script>
|
||||
<script src="$path/src/physics/ninja/Body.js"></script>
|
||||
<script src="$path/src/physics/ninja/AABB.js"></script>
|
||||
<script src="$path/src/physics/ninja/Tile.js"></script>
|
||||
<script src="$path/src/physics/ninja/Circle.js"></script>
|
||||
|
||||
<script src="$path/src/physics/p2/World.js"></script>
|
||||
<script src="$path/src/physics/p2/PointProxy.js"></script>
|
||||
<script src="$path/src/physics/p2/InversePointProxy.js"></script>
|
||||
|
||||
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 272 KiB |
@@ -0,0 +1,122 @@
|
||||
|
||||
// var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.spritesheet('ninja-tiles', 'assets/physics/ninja-tiles.png', 128, 128, 34);
|
||||
game.load.image('a', 'assets/sprites/firstaid.png');
|
||||
|
||||
}
|
||||
|
||||
var sprite1;
|
||||
var cursors;
|
||||
|
||||
var tile1;
|
||||
var tile2;
|
||||
|
||||
var t;
|
||||
var running = false;
|
||||
|
||||
function create() {
|
||||
|
||||
game.stage.smoothed = true;
|
||||
|
||||
// Activate the Ninja physics system
|
||||
game.physics.startSystem(Phaser.Physics.NINJA);
|
||||
|
||||
// game.physics.ninja.gravity = 0.1;
|
||||
|
||||
sprite1 = game.add.sprite(500, 200, 'a');
|
||||
|
||||
// Enable the physics body for the Ninja physics system
|
||||
// By default it will create an AABB body for the sprite
|
||||
game.physics.ninja.enableAABB(sprite1);
|
||||
|
||||
// But you can change it to either a Tile or a Circle
|
||||
tile1 = game.add.sprite(0, 550, 'ninja-tiles', 14);
|
||||
tile1.width = 100;
|
||||
tile1.height = 100;
|
||||
|
||||
game.physics.ninja.enableTile(tile1, 14);
|
||||
|
||||
// sprite1.body.aabb.friction = 0;
|
||||
|
||||
// tile1 = new Phaser.Physics.Ninja.Tile(game.physics.ninja, 100, 500, 100, 100, Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn);
|
||||
// tile1 = new Phaser.Physics.Ninja.Tile(game.physics.ninja, 100, 500, 100, 100, 15);
|
||||
// tile2 = new Phaser.Physics.Ninja.Tile(game.physics.ninja, 300, 500, 100, 100, 7);
|
||||
|
||||
cursors = game.input.keyboard.createCursorKeys();
|
||||
|
||||
}
|
||||
|
||||
function collisionHandler() {
|
||||
game.stage.backgroundColor = 0xff0000;
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
game.physics.ninja.collide(sprite1, tile1, collisionHandler, null, this);
|
||||
|
||||
tile1.body.moveRight(1);
|
||||
|
||||
/*
|
||||
if (cursors.up.isDown && !running)
|
||||
{
|
||||
running = true;
|
||||
t = Date.now();
|
||||
}
|
||||
|
||||
sprite1.body.setZeroVelocity();
|
||||
|
||||
if (running)
|
||||
{
|
||||
sprite1.body.moveRight(100);
|
||||
|
||||
if (sprite1.body.x >= 200)
|
||||
{
|
||||
var ms = Date.now() - t;
|
||||
console.log('100px in ', ms);
|
||||
running = false;
|
||||
sprite1.body.setZeroVelocity();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// sprite1.body.setZeroVelocity();
|
||||
|
||||
if (cursors.left.isDown)
|
||||
{
|
||||
sprite1.body.moveLeft(20);
|
||||
}
|
||||
else if (cursors.right.isDown)
|
||||
{
|
||||
sprite1.body.moveRight(20);
|
||||
}
|
||||
|
||||
if (cursors.up.isDown)
|
||||
{
|
||||
sprite1.body.moveUp(20);
|
||||
}
|
||||
else if (cursors.down.isDown)
|
||||
{
|
||||
sprite1.body.moveUp(20);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.text(sprite1.body.shape.velocity.x, 32, 32);
|
||||
game.debug.text(sprite1.body.shape.velocity.y, 32, 64);
|
||||
game.debug.text(game.math.radToDeg(sprite1.body.angle), 32, 96);
|
||||
|
||||
// tile1.render(game.context, 'ninja-tiles');
|
||||
// tile2.render(game.context, 'ninja-tiles');
|
||||
|
||||
// game.debug.geom(sprite1.body, 'rgba(0,255,0,0.4)', true, 1);
|
||||
|
||||
// game.debug.geom(tile1, 'rgba(0,255,0,0.4)', true, 1);
|
||||
// game.debug.geom(tile1, 'rgba(0,255,0,0.4)', true, 1);
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ function create() {
|
||||
|
||||
sprite1 = game.add.sprite(50, 200, 'atari');
|
||||
sprite1.name = 'atari';
|
||||
// sprite1.anchor.set(0.5);
|
||||
|
||||
sprite2 = game.add.sprite(700, 220, 'mushroom');
|
||||
sprite2.name = 'mushroom';
|
||||
@@ -37,6 +38,9 @@ function update() {
|
||||
// object1, object2, collideCallback, processCallback, callbackContext
|
||||
game.physics.arcade.collide(sprite1, sprite2, collisionHandler, null, this);
|
||||
|
||||
// var b = sprite1.getBounds();
|
||||
// console.log(b);
|
||||
|
||||
}
|
||||
|
||||
function collisionHandler (obj1, obj2) {
|
||||
@@ -46,9 +50,14 @@ function collisionHandler (obj1, obj2) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
function render() {
|
||||
|
||||
// game.debug.physicsBody(sprite1.body);
|
||||
// game.debug.physicsBody(sprite2.body);
|
||||
// var b = sprite1.getBounds();
|
||||
|
||||
// game.debug.geom(b, 'rgba(255,0,0,0.8)', true, 1);
|
||||
|
||||
game.debug.geom(sprite1.body, 'rgba(0,255,0,0.4)', true, 1);
|
||||
game.debug.geom(sprite2.body, 'rgba(0,255,0,0.4)', true, 1);
|
||||
|
||||
}
|
||||
@@ -52,7 +52,7 @@ function create() {
|
||||
|
||||
game.physics.enable(sprite);
|
||||
|
||||
sprite.body.setSize(14, 14, 2, 0);
|
||||
// sprite.body.setSize(14, 14, 2, 0);
|
||||
|
||||
console.log(sprite.body);
|
||||
|
||||
@@ -107,6 +107,8 @@ function render() {
|
||||
// game.debug.text(game.physics.arcade._intersection.width, 32, 32);
|
||||
// game.debug.text(game.physics.arcade._intersection.height, 32, 64);
|
||||
|
||||
game.debug.geom(sprite.body, 'rgba(0,255,0,0.4)', true, 1);
|
||||
|
||||
game.debug.text(sprite.body.overlapX, 32, 32);
|
||||
game.debug.text(sprite.body.overlapY, 32, 64);
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.tilemap('map', 'assets/tilemaps/maps/collision_test.json', null, Phaser.Tilemap.TILED_JSON);
|
||||
game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png');
|
||||
game.load.image('phaser', 'assets/sprites/phaser-dude.png');
|
||||
// game.load.image('phaser', 'assets/sprites/phaser-ship.png');
|
||||
|
||||
}
|
||||
|
||||
var map;
|
||||
var layer;
|
||||
var cursors;
|
||||
var sprite;
|
||||
|
||||
function create() {
|
||||
|
||||
map = game.add.tilemap('map');
|
||||
|
||||
map.addTilesetImage('ground_1x1');
|
||||
|
||||
layer = map.createLayer('Tile Layer 1');
|
||||
|
||||
layer.resizeWorld();
|
||||
|
||||
map.setCollisionBetween(1, 12);
|
||||
|
||||
layer.debug = true;
|
||||
|
||||
sprite = game.add.sprite(260, 70, 'phaser');
|
||||
|
||||
game.physics.enable(sprite);
|
||||
|
||||
game.camera.follow(sprite);
|
||||
|
||||
// game.physics.arcade.gravity.y = 500;
|
||||
// sprite.body.velocity.x = 100;
|
||||
|
||||
cursors = game.input.keyboard.createCursorKeys();
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
game.physics.arcade.collide(sprite, layer);
|
||||
|
||||
sprite.body.velocity.x = 0;
|
||||
sprite.body.velocity.y = 0;
|
||||
|
||||
if (cursors.up.isDown)
|
||||
{
|
||||
sprite.body.velocity.y = -100;
|
||||
}
|
||||
else if (cursors.down.isDown)
|
||||
{
|
||||
sprite.body.velocity.y = 100;
|
||||
}
|
||||
|
||||
if (cursors.left.isDown)
|
||||
{
|
||||
sprite.body.velocity.x = -100;
|
||||
}
|
||||
else if (cursors.right.isDown)
|
||||
{
|
||||
sprite.body.velocity.x = 100;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.text(sprite.body.velocity.x, 32, 32);
|
||||
game.debug.text(sprite.body.velocity.y, 64, 32);
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ function create() {
|
||||
// sprite = game.add.tileSprite(100, 100, 400, 300, 'starfield');
|
||||
|
||||
sprite = game.add.tileSprite(100, 100, 400, 300, 'mummy');
|
||||
sprite.pivot.setTo(200, 200);
|
||||
|
||||
sprite.animations.add('walk');
|
||||
|
||||
@@ -32,6 +33,8 @@ function create() {
|
||||
|
||||
function update() {
|
||||
|
||||
sprite.rotation += 0.01;
|
||||
|
||||
if (cursors.left.isDown)
|
||||
{
|
||||
sprite.tilePosition.x += 8;
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 392 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 502 B |
|
After Width: | Height: | Size: 484 B |
|
After Width: | Height: | Size: 482 B |
|
After Width: | Height: | Size: 559 B |
|
After Width: | Height: | Size: 626 B |
|
After Width: | Height: | Size: 623 B |
|
After Width: | Height: | Size: 773 B |
|
After Width: | Height: | Size: 623 B |
|
After Width: | Height: | Size: 684 B |
|
After Width: | Height: | Size: 807 B |
|
After Width: | Height: | Size: 851 B |
|
After Width: | Height: | Size: 774 B |
|
After Width: | Height: | Size: 863 B |
|
After Width: | Height: | Size: 806 B |
|
After Width: | Height: | Size: 782 B |
|
After Width: | Height: | Size: 837 B |
|
After Width: | Height: | Size: 838 B |
|
After Width: | Height: | Size: 785 B |
|
After Width: | Height: | Size: 278 B |
|
After Width: | Height: | Size: 395 B |
|
After Width: | Height: | Size: 273 B |
|
After Width: | Height: | Size: 399 B |
|
After Width: | Height: | Size: 771 B |
|
After Width: | Height: | Size: 796 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 30 KiB |
@@ -99,7 +99,15 @@ Phaser.Sprite = function (game, x, y, key, frame) {
|
||||
this.input = null;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Arcade.Body|Phaser.Physics.P2.Body|null} body - The Sprites physics Body. Will be null unless physics has been enabled via `Sprite.physicsEnabled = true`.
|
||||
* By default Sprites won't add themselves to any physics system and their physics body will be `null`.
|
||||
* To enable them for physics you need to call `game.physics.enable(sprite, system)` where `sprite` is this object
|
||||
* and `system` is the Physics system you want to use to manage this body. Once enabled you can access all physics related properties via `Sprite.body`.
|
||||
*
|
||||
* Important: Enabling a Sprite for P2 or Ninja physics will automatically set `Sprite.anchor` to 0.5 so the physics body is centered on the Sprite.
|
||||
* If you need a different result then adjust or re-create the Body shape offsets manually, and/or reset the anchor after enabling physics.
|
||||
*
|
||||
* @property {Phaser.Physics.Arcade.Body|Phaser.Physics.P2.Body|Phaser.Physics.Ninja.Body|null} body
|
||||
* @default
|
||||
*/
|
||||
this.body = null;
|
||||
|
||||
@@ -850,46 +858,6 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* By default Sprites won't add themselves to the physics simulation. By setting physicsEnabled to true a Rectangle physics body is
|
||||
* attached to this Sprite matching its placement and dimensions, and will then start to process physics world updates.
|
||||
* You can access all physics related properties via Sprite.body.
|
||||
*
|
||||
* Important: Enabling a Sprite for physics will automatically set `Sprite.anchor` to 0.5 so the physics body is centered on the Sprite.
|
||||
* If you need a different result then adjust or re-create the Body shape offsets manually, and/or reset the anchor after enabling physics.
|
||||
*
|
||||
* @name Phaser.Sprite#physicsEnabled
|
||||
* @property {boolean} physicsEnabled - Set to true to add this Sprite to the physics world. Set to false to destroy the body and remove it from the physics world.
|
||||
Object.defineProperty(Phaser.Sprite.prototype, "physicsEnabled", {
|
||||
|
||||
get: function () {
|
||||
|
||||
return (this.body !== null);
|
||||
|
||||
},
|
||||
|
||||
set: function (value) {
|
||||
|
||||
if (value)
|
||||
{
|
||||
if (this.body === null)
|
||||
{
|
||||
this.body = new Phaser.Physics.Body(this.game, this, this.x, this.y, 1);
|
||||
this.anchor.set(0.5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.body)
|
||||
{
|
||||
this.body.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sprite.exists controls if the core game loop and physics update this Sprite or not.
|
||||
* When you set Sprite.exists to false it will remove its Body from the physics world (if it has one) and also set Sprite.visible to false.
|
||||
@@ -913,7 +881,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "exists", {
|
||||
// exists = true
|
||||
this._cache[6] = 1;
|
||||
|
||||
if (this.body)
|
||||
if (this.body && this.body.type === Phaser.Physics.P2)
|
||||
{
|
||||
this.body.addToWorld();
|
||||
}
|
||||
@@ -925,7 +893,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "exists", {
|
||||
// exists = false
|
||||
this._cache[6] = 0;
|
||||
|
||||
if (this.body)
|
||||
if (this.body && this.body.type === Phaser.Physics.P2)
|
||||
{
|
||||
this.body.removeFromWorld();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @author Antony Woods <antony@teamwoods.org>
|
||||
* @copyright 2013 Photon Storm Ltd.
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,12 +5,15 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Physics manager.
|
||||
* The Physics Manager is responsible for looking after all of the running physics systems.
|
||||
* Phaser supports 3 physics systems: Arcade Physics, P2 and Ninja Physics (with Box2D and Chipmunk in development)
|
||||
* Game Objects can belong to only 1 physics system, but you can have multiple systems active in a single game.
|
||||
*
|
||||
* For example you could have P2 managing a polygon-built terrain landscape that an vehicle drives over, while it could be firing bullets that use the
|
||||
* faster (due to being much simpler) Arcade Physics system.
|
||||
*
|
||||
* @class Phaser.Physics
|
||||
*
|
||||
* @classdesc todo
|
||||
*
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game - A reference to the currently running game.
|
||||
* @param {object} [physicsConfig=null] - A physics configuration object to pass to the Physics world on creation.
|
||||
@@ -22,14 +25,34 @@ Phaser.Physics = function (game, config) {
|
||||
*/
|
||||
this.game = game;
|
||||
|
||||
/**
|
||||
* @property {object} config - The physics configuration object as passed to the game on creation.
|
||||
*/
|
||||
this.config = config;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Arcade} arcade - The Arcade Physics system.
|
||||
*/
|
||||
this.arcade = new Phaser.Physics.Arcade(game);
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.P2} p2 - The P2.JS Physics system.
|
||||
*/
|
||||
this.p2 = null;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Ninja} ninja - The N+ Ninja Physics System.
|
||||
*/
|
||||
this.ninja = null;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Box2D} box2d - The Box2D Physics system (to be done).
|
||||
*/
|
||||
this.box2d = null;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Chipmunk} chipmunk - The Chipmunk Physics system (to be done).
|
||||
*/
|
||||
this.chipmunk = null;
|
||||
|
||||
};
|
||||
@@ -50,38 +73,72 @@ Phaser.Physics.P2 = 1;
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Physics.BOX2D = 2;
|
||||
Phaser.Physics.NINJA = 2;
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Physics.CHIPMUNK = 3;
|
||||
Phaser.Physics.BOX2D = 3;
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Physics.CHIPMUNK = 5;
|
||||
|
||||
Phaser.Physics.prototype = {
|
||||
|
||||
/**
|
||||
* This will create an instance of the requested physics simulation.
|
||||
* Phaser.Physics.Arcade is running by default, but all others need activating directly.
|
||||
* You can start the following physics systems:
|
||||
* Phaser.Physics.P2 - A full-body advanced physics system by Stefan Hedman.
|
||||
* Phaser.Physics.NINJA - A port of the metanet N+ physics system.
|
||||
* Phaser.Physics.BOX2D and Phaser.Physics.CHIPMUNK are still in development.
|
||||
*
|
||||
* @method Phaser.Physics#startSystem
|
||||
* @param {number} The physics system to start.
|
||||
*/
|
||||
startSystem: function (system) {
|
||||
|
||||
if (system === Phaser.Physics.ARCADE)
|
||||
if (system === Phaser.Physics.ARCADE && this.arcade === null)
|
||||
{
|
||||
this.arcade = new Phaser.Physics.Arcade(this.game);
|
||||
}
|
||||
else if (system === Phaser.Physics.P2)
|
||||
else if (system === Phaser.Physics.P2 && this.p2 === null)
|
||||
{
|
||||
this.p2 = new Phaser.Physics.P2(this.game, this.config);
|
||||
}
|
||||
else if (system === Phaser.Physics.BOX2D)
|
||||
if (system === Phaser.Physics.NINJA && this.ninja === null)
|
||||
{
|
||||
this.ninja = new Phaser.Physics.Ninja(this.game);
|
||||
}
|
||||
else if (system === Phaser.Physics.BOX2D && this.box2d === null)
|
||||
{
|
||||
// Coming soon
|
||||
}
|
||||
else if (system === Phaser.Physics.CHIPMUNK)
|
||||
else if (system === Phaser.Physics.CHIPMUNK && this.chipmunk === null)
|
||||
{
|
||||
// Coming soon
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Enables a sprites physics body
|
||||
/**
|
||||
* This will create a physics body on the given game object.
|
||||
* A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed.
|
||||
* It can be for any of the physics systems that have been started:
|
||||
*
|
||||
* Phaser.Physics.Arcade - A light weight AABB based collision system with basic separation.
|
||||
* Phaser.Physics.P2 - A full-body advanced physics system supporting multiple object shapes, polygon loading, contact materials, springs and constraints.
|
||||
* Phaser.Physics.NINJA - A port of the metanet N+ physics system. Advanced AABB and Circle vs. Tile collision.
|
||||
* Phaser.Physics.BOX2D and Phaser.Physics.CHIPMUNK are still in development.
|
||||
*
|
||||
* @method Phaser.Physics#enable
|
||||
* @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array.
|
||||
* @param {number} [system=0] - The physics system that will be used to create the body. Defaults to Arcade Physics.
|
||||
*/
|
||||
enable: function (object, system) {
|
||||
|
||||
if (typeof system === 'undefined') { system = Phaser.Physics.ARCADE; }
|
||||
@@ -111,14 +168,25 @@ Phaser.Physics.prototype = {
|
||||
object[i].body = new Phaser.Physics.P2.Body(this.game, object[i], object[i].x, object[i].y, 1);
|
||||
object[i].anchor.set(0.5);
|
||||
}
|
||||
else if (system === Phaser.Physics.NINJA)
|
||||
{
|
||||
object[i].body = new Phaser.Physics.Ninja.Body(this.ninja, object[i]);
|
||||
object[i].anchor.set(0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates all running physics systems.
|
||||
*
|
||||
* @method Phaser.Physics#update
|
||||
* @protected
|
||||
*/
|
||||
update: function () {
|
||||
|
||||
// ArcadePhysics doesn't have a core to update
|
||||
// ArcadePhysics / Ninja don't have a core to update
|
||||
|
||||
if (this.p2)
|
||||
{
|
||||
@@ -127,10 +195,22 @@ Phaser.Physics.prototype = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the physics bounds to match the world dimensions.
|
||||
*
|
||||
* @method Phaser.Physics#setBoundsToWorld
|
||||
* @protected
|
||||
*/
|
||||
setBoundsToWorld: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears down all active physics systems. This doesn't destroy them, it just clears them of objects and is called when the State changes.
|
||||
*
|
||||
* @method Phaser.Physics#clear
|
||||
* @protected
|
||||
*/
|
||||
clear: function () {
|
||||
|
||||
if (this.p2)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2013 Photon Storm Ltd.
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
@@ -25,34 +25,27 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this.game = sprite.game;
|
||||
|
||||
/**
|
||||
* @property {number} type - The type of physics system this body belongs to.
|
||||
*/
|
||||
this.type = Phaser.Physics.ARCADE;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} offset - The offset of the Physics Body from the Sprite x/y position.
|
||||
*/
|
||||
this.offset = new Phaser.Point();
|
||||
this.offset = new Phaser.Point(-(sprite.anchor.x * sprite.width), -(sprite.anchor.y * sprite.height));
|
||||
|
||||
/**
|
||||
* @property {number} x - The x position of the physics body.
|
||||
* @property {Phaser.Point} position - The position of the physics body.
|
||||
* @readonly
|
||||
*/
|
||||
this.x = sprite.x;
|
||||
this.position = new Phaser.Point(sprite.x + this.offset.x, sprite.y + this.offset.y);
|
||||
|
||||
/**
|
||||
* @property {number} y - The y position of the physics body.
|
||||
* @property {Phaser.Point} prev - The previous position of the physics body.
|
||||
* @readonly
|
||||
*/
|
||||
this.y = sprite.y;
|
||||
|
||||
/**
|
||||
* @property {number} preX - The previous x position of the physics body.
|
||||
* @readonly
|
||||
*/
|
||||
this.preX = sprite.x;
|
||||
|
||||
/**
|
||||
* @property {number} preY - The previous y position of the physics body.
|
||||
* @readonly
|
||||
*/
|
||||
this.preY = sprite.y;
|
||||
this.prev = new Phaser.Point(this.position.x, this.position.y);
|
||||
|
||||
/**
|
||||
* @property {number} preRotation - The previous rotation of the physics body.
|
||||
@@ -60,18 +53,6 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this.preRotation = sprite.angle;
|
||||
|
||||
/**
|
||||
* @property {number} screenX - The x position of the physics body translated to screen space.
|
||||
* @readonly
|
||||
*/
|
||||
this.screenX = sprite.x;
|
||||
|
||||
/**
|
||||
* @property {number} screenY - The y position of the physics body translated to screen space.
|
||||
* @readonly
|
||||
*/
|
||||
this.screenY = sprite.y;
|
||||
|
||||
/**
|
||||
* @property {number} sourceWidth - The un-scaled original size.
|
||||
* @readonly
|
||||
@@ -97,17 +78,17 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
/**
|
||||
* @property {number} halfWidth - The calculated width / 2 of the physics body.
|
||||
*/
|
||||
this.halfWidth = Math.floor(sprite.width / 2);
|
||||
this.halfWidth = Math.abs(sprite.width / 2);
|
||||
|
||||
/**
|
||||
* @property {number} halfHeight - The calculated height / 2 of the physics body.
|
||||
*/
|
||||
this.halfHeight = Math.floor(sprite.height / 2);
|
||||
this.halfHeight = Math.abs(sprite.height / 2);
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} center - The center coordinate of the Physics Body.
|
||||
*/
|
||||
this.center = new Phaser.Point(this.x + this.halfWidth, this.y + this.halfHeight);
|
||||
this.center = new Phaser.Point(sprite.x + this.halfWidth, sprite.y + this.halfHeight);
|
||||
|
||||
/**
|
||||
* @property {number} _sx - Internal cache var.
|
||||
@@ -126,6 +107,12 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this.velocity = new Phaser.Point();
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} newVelocity - New velocity.
|
||||
* @readonly
|
||||
*/
|
||||
this.newVelocity = new Phaser.Point(0, 0);
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} acceleration - The velocity in pixels per second sq. of the Body.
|
||||
*/
|
||||
@@ -137,9 +124,9 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
this.drag = new Phaser.Point();
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} gravity - A private Gravity setting for the Body.
|
||||
* @property {Phaser.Point} gravityScale - Gravity scaling factor. If you want the body to ignore gravity, set this to zero. If you want to reverse gravity, set it to -1.
|
||||
*/
|
||||
this.gravity = new Phaser.Point();
|
||||
this.gravityScale = new Phaser.Point(1, 1);
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity.
|
||||
@@ -218,12 +205,6 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this.allowRotation = true;
|
||||
|
||||
/**
|
||||
* @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity?
|
||||
* @default
|
||||
*/
|
||||
this.allowGravity = true;
|
||||
|
||||
/**
|
||||
* This flag allows you to disable the custom x separation that takes place by Physics.Arcade.separate.
|
||||
* Used in combination with your own collision processHandler you can create whatever type of collision response you need.
|
||||
@@ -252,18 +233,6 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this.overlapY = 0;
|
||||
|
||||
this.hull = new Phaser.Rectangle();
|
||||
|
||||
/**
|
||||
* @property {Phaser.Rectangle} hullX - The dynamically calculated hull used during collision.
|
||||
*/
|
||||
this.hullX = new Phaser.Rectangle();
|
||||
|
||||
/**
|
||||
* @property {Phaser.Rectangle} hullY - The dynamically calculated hull used during collision.
|
||||
*/
|
||||
this.hullY = new Phaser.Rectangle();
|
||||
|
||||
/**
|
||||
* If a body is overlapping with another body, but neither of them are moving (maybe they spawned on-top of each other?) this is set to true.
|
||||
* @property {boolean} embedded - Body embed value.
|
||||
@@ -303,10 +272,29 @@ Phaser.Physics.Arcade.Body = function (sprite) {
|
||||
*/
|
||||
this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false };
|
||||
|
||||
/**
|
||||
* This object is populated with boolean values when the Body collides with the World bounds or a Tile.
|
||||
* For example if blocked.up is true then the Body cannot move up.
|
||||
* @property {object} blocked - An object containing on which faces this Body is blocked from moving, if any.
|
||||
*/
|
||||
this.result = { x: 0, y: 0, px: 0, py: 0, tx: 0, ty: 0, slope: false };
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Arcade.Body.prototype = {
|
||||
|
||||
resetResult: function () {
|
||||
|
||||
this.result.x = false;
|
||||
this.result.y = false;
|
||||
this.result.slope = false;
|
||||
this.result.px = this.position.x;
|
||||
this.result.py = this.position.y;
|
||||
this.result.tx = 0;
|
||||
this.result.ty = 0;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal method.
|
||||
*
|
||||
@@ -336,6 +324,8 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
*/
|
||||
preUpdate: function () {
|
||||
|
||||
this.resetResult();
|
||||
|
||||
// Store and reset collision flags
|
||||
this.wasTouching.none = this.touching.none;
|
||||
this.wasTouching.up = this.touching.up;
|
||||
@@ -354,27 +344,41 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
// this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
||||
// this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
||||
|
||||
this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
||||
this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
||||
// this is where the Sprite currently is, in world coordinates
|
||||
// this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
||||
// this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
||||
// this.preRotation = this.sprite.angle;
|
||||
|
||||
this.preRotation = this.sprite.angle;
|
||||
|
||||
this.x = this.preX;
|
||||
this.y = this.preY;
|
||||
this.rotation = this.preRotation;
|
||||
// this.x = this.preX;
|
||||
// this.y = this.preY;
|
||||
// this.rotation = this.preRotation;
|
||||
|
||||
// this.overlapX = 0;
|
||||
// this.overlapY = 0;
|
||||
|
||||
this.blocked.up = false;
|
||||
this.blocked.down = false;
|
||||
this.blocked.left = false;
|
||||
this.blocked.right = false;
|
||||
this.prev.set(this.position.x, this.position.y);
|
||||
|
||||
// this.position.x = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
||||
// this.position.y = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
||||
|
||||
|
||||
// this.blocked.up = false;
|
||||
// this.blocked.down = false;
|
||||
// this.blocked.left = false;
|
||||
// this.blocked.right = false;
|
||||
|
||||
if (this.moves)
|
||||
{
|
||||
this.game.physics.arcade.updateMotion(this);
|
||||
|
||||
this.newVelocity.set(this.velocity.x * this.game.time.physicsElapsed, this.velocity.y * this.game.time.physicsElapsed);
|
||||
|
||||
this.position.x += this.newVelocity.x;
|
||||
this.position.y += this.newVelocity.y;
|
||||
|
||||
// Now the State update will throw collision checks at the Body
|
||||
// And finally we'll integrate the new position back to the Sprite in postUpdate
|
||||
|
||||
if (this.collideWorldBounds)
|
||||
{
|
||||
this.checkWorldBounds();
|
||||
@@ -391,6 +395,56 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
*/
|
||||
postUpdate: function () {
|
||||
|
||||
// if (this.result.x)
|
||||
// {
|
||||
// this.position.x = this.result.px;
|
||||
// this.velocity.x = 0;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.position.x += this.newVelocity.x;
|
||||
// }
|
||||
|
||||
// this.position.y += this.newVelocity.y;
|
||||
|
||||
// this.position.add(this.newVelocity.x, this.newVelocity.y);
|
||||
|
||||
this.sprite.x = (this.position.x - this.offset.x);
|
||||
this.sprite.y = (this.position.y - this.offset.y);
|
||||
|
||||
|
||||
/* if (this.deltaX() < 0)
|
||||
{
|
||||
this.facing = Phaser.LEFT;
|
||||
this.sprite.x += this.deltaX();
|
||||
}
|
||||
else if (this.deltaX() > 0)
|
||||
{
|
||||
this.facing = Phaser.RIGHT;
|
||||
this.sprite.x += this.deltaX();
|
||||
}
|
||||
|
||||
if (this.deltaY() < 0)
|
||||
{
|
||||
this.facing = Phaser.UP;
|
||||
this.sprite.y += this.deltaY();
|
||||
}
|
||||
else if (this.deltaY() > 0)
|
||||
{
|
||||
this.facing = Phaser.DOWN;
|
||||
this.sprite.y += this.deltaY();
|
||||
}
|
||||
*/
|
||||
|
||||
// this.sprite.x += this.overlapX;
|
||||
// this.sprite.y += this.overlapY;
|
||||
|
||||
// this is where the Sprite currently is, in world coordinates
|
||||
// this.sprite.x = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
|
||||
// this.sprite.y = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
|
||||
|
||||
|
||||
/*
|
||||
if (this.deltaX() < 0 && this.blocked.left === false)
|
||||
{
|
||||
this.facing = Phaser.LEFT;
|
||||
@@ -412,6 +466,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
this.facing = Phaser.DOWN;
|
||||
this.sprite.y += this.deltaY();
|
||||
}
|
||||
*/
|
||||
|
||||
this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
||||
|
||||
@@ -533,7 +588,7 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
* @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
|
||||
*/
|
||||
deltaX: function () {
|
||||
return this.x - this.preX;
|
||||
return this.position.x - this.prev.x;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -543,9 +598,15 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
* @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
|
||||
*/
|
||||
deltaY: function () {
|
||||
return this.y - this.preY;
|
||||
return this.position.y - this.prev.y;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the delta z value. The difference between Body.rotation now and in the previous step.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade.Body#deltaZ
|
||||
* @return {number} The delta value. Positive if the motion was clockwise, negative if anti-clockwise.
|
||||
*/
|
||||
deltaZ: function () {
|
||||
return this.rotation - this.preRotation;
|
||||
}
|
||||
@@ -555,35 +616,18 @@ Phaser.Physics.Arcade.Body.prototype = {
|
||||
/**
|
||||
* @name Phaser.Physics.Arcade.Body#bottom
|
||||
* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", {
|
||||
|
||||
/**
|
||||
* The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
|
||||
* The sum of the y and height properties.
|
||||
* @method bottom
|
||||
* @return {number}
|
||||
* @readonly
|
||||
*/
|
||||
get: function () {
|
||||
// return Math.floor(this.y + this.height);
|
||||
return this.y + this.height;
|
||||
},
|
||||
|
||||
/**
|
||||
* The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
|
||||
* @method bottom
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
|
||||
if (value <= this.y)
|
||||
{
|
||||
this.height = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.height = (this.y - value);
|
||||
}
|
||||
|
||||
return this.position.y + this.height;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -591,37 +635,72 @@ Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", {
|
||||
/**
|
||||
* @name Phaser.Physics.Arcade.Body#right
|
||||
* @property {number} right - The right value of this Body (same as Body.x + Body.width)
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", {
|
||||
|
||||
/**
|
||||
* The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
|
||||
* However it does affect the width property.
|
||||
* The sum of the x and width properties.
|
||||
* @method right
|
||||
* @return {number}
|
||||
* @readonly
|
||||
*/
|
||||
get: function () {
|
||||
// return Math.floor(this.x + this.width);
|
||||
return this.x + this.width;
|
||||
},
|
||||
|
||||
/**
|
||||
* The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
|
||||
* However it does affect the width property.
|
||||
* @method right
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
|
||||
if (value <= this.x)
|
||||
{
|
||||
this.width = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.width = this.x + value;
|
||||
}
|
||||
|
||||
return this.position.x + this.width;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Arcade.Body#x
|
||||
* @property {number} x - The x position.
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "x", {
|
||||
|
||||
/**
|
||||
* The x position.
|
||||
* @method x
|
||||
* @return {number}
|
||||
*/
|
||||
get: function () {
|
||||
return this.position.x;
|
||||
},
|
||||
|
||||
/**
|
||||
* The x position.
|
||||
* @method x
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
this.position.x = value;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Arcade.Body#y
|
||||
* @property {number} y - The y position.
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "y", {
|
||||
|
||||
/**
|
||||
* The y position.
|
||||
* @method y
|
||||
* @return {number}
|
||||
*/
|
||||
get: function () {
|
||||
return this.position.y;
|
||||
},
|
||||
|
||||
/**
|
||||
* The y position.
|
||||
* @method y
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
this.position.y = value;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Phaser.Physics.Arcade.Body.prototype.constructor = Phaser.Physics.Arcade.Body;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2013 Photon Storm Ltd.
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2013 Photon Storm Ltd.
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
@@ -161,6 +161,8 @@ Phaser.Physics.Arcade = function (game) {
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Arcade.prototype.constructor = Phaser.Physics.Arcade;
|
||||
|
||||
Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
/**
|
||||
@@ -172,56 +174,41 @@ Phaser.Physics.Arcade.prototype = {
|
||||
updateMotion: function (body) {
|
||||
|
||||
// Rotation
|
||||
this._velocityDelta = (this.computeVelocity(body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular, 0) - body.angularVelocity) * 0.5;
|
||||
this._velocityDelta = (this.computeVelocity(body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular, 0) - body.angularVelocity) * 0.5;
|
||||
body.angularVelocity += this._velocityDelta;
|
||||
body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
|
||||
body.angularVelocity += this._velocityDelta;
|
||||
|
||||
if (body.allowGravity)
|
||||
{
|
||||
// Gravity was previously applied without taking physicsElapsed into account
|
||||
// so it needs to be multiplied by 60 (fps) for compatibility with existing games
|
||||
this._gravityX = (this.gravity.x + body.gravity.x) * 60;
|
||||
this._gravityY = (this.gravity.y + body.gravity.y) * 60;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._gravityX = this._gravityY = 0;
|
||||
}
|
||||
// Apply gravity using the p2 style gravityScale
|
||||
body.velocity.x += this.gravity.x * this.game.time.physicsElapsed * body.gravityScale.x;
|
||||
body.velocity.y += this.gravity.y * this.game.time.physicsElapsed * body.gravityScale.y;
|
||||
|
||||
// Horizontal
|
||||
this._velocityDelta = (this.computeVelocity(body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x, this._gravityX) - body.velocity.x) * 0.5;
|
||||
body.velocity.x += this._velocityDelta;
|
||||
body.x += (body.velocity.x * this.game.time.physicsElapsed);
|
||||
body.velocity.x += this._velocityDelta;
|
||||
|
||||
// Vertical
|
||||
this._velocityDelta = (this.computeVelocity(body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y, this._gravityY) - body.velocity.y) * 0.5;
|
||||
body.velocity.y += this._velocityDelta;
|
||||
body.y += (body.velocity.y * this.game.time.physicsElapsed);
|
||||
body.velocity.y += this._velocityDelta;
|
||||
// Apply velocity
|
||||
body.velocity.x = this.computeVelocity(body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x);
|
||||
body.velocity.y = this.computeVelocity(body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
|
||||
* Based on a function in Flixel by @ADAMATOMIC
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#computeVelocity
|
||||
* @param {Phaser.Physics.Arcade.Body} body - The Body object to be updated.
|
||||
* @param {number} velocity - Any component of velocity (e.g. 20).
|
||||
* @param {number} acceleration - Rate at which the velocity is changing.
|
||||
* @param {number} drag - Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
|
||||
* @param {number} [max=10000] - An absolute value cap for the velocity.
|
||||
* @param {number} gravity - The acceleration due to gravity. Gravity will not induce drag.
|
||||
* @return {number} The altered Velocity value.
|
||||
*/
|
||||
computeVelocity: function (body, velocity, acceleration, drag, max, gravity) {
|
||||
computeVelocity: function (velocity, acceleration, drag, max) {
|
||||
|
||||
max = max || 10000;
|
||||
|
||||
velocity += (acceleration + gravity) * this.game.time.physicsElapsed;
|
||||
|
||||
if (acceleration === 0 && drag !== 0)
|
||||
if (acceleration)
|
||||
{
|
||||
velocity + acceleration * this.game.time.physicsElapsed;
|
||||
}
|
||||
else if (drag)
|
||||
{
|
||||
this._drag = drag * this.game.time.physicsElapsed;
|
||||
|
||||
@@ -537,17 +524,30 @@ Phaser.Physics.Arcade.prototype = {
|
||||
collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
|
||||
|
||||
// this._mapData = tilemapLayer.getTiles(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height, true);
|
||||
this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true);
|
||||
// this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true);
|
||||
|
||||
this._mapData = tilemapLayer.getIntersectingTiles(sprite.body.position.x, sprite.body.position.y, sprite.body.width, sprite.body.height, true);
|
||||
|
||||
// var vx = sprite.body.x;
|
||||
// var vy = sprite.body.y;
|
||||
|
||||
// vx += sprite.body.newVelocity.x;
|
||||
// vy += sprite.body.newVelocity.y;
|
||||
|
||||
// this._mapData = tilemapLayer.getIntersectingTiles(vx, vy, sprite.body.width, sprite.body.height, true);
|
||||
|
||||
if (this._mapData.length === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._mapData.length > 1)
|
||||
{
|
||||
// if (this._mapData.length > 1)
|
||||
// {
|
||||
// Needs process callback added
|
||||
this.separateTiles(sprite.body, this._mapData);
|
||||
}
|
||||
// }
|
||||
|
||||
/*
|
||||
else
|
||||
{
|
||||
var i = 0;
|
||||
@@ -578,6 +578,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
},
|
||||
|
||||
@@ -870,62 +871,15 @@ Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs a rect intersection test against the two objects.
|
||||
* Objects must expose properties: width, height, left, right, top, bottom.
|
||||
* @method Phaser.Physics.Arcade#tileIntersects
|
||||
* @param {object} body - The Body to test.
|
||||
* @param {object} tile - The Tile to test.
|
||||
* @returns {boolean} Returns true if the objects intersect, otherwise false.
|
||||
*/
|
||||
tileIntersects: function (body, tile) {
|
||||
|
||||
this._intersection[0] = 0;
|
||||
this._intersection[1] = 0;
|
||||
this._intersection[2] = 0;
|
||||
this._intersection[3] = 0;
|
||||
this._intersection[4] = 0;
|
||||
|
||||
if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0)
|
||||
{
|
||||
this._intersection[4] = 0;
|
||||
return this._intersection;
|
||||
}
|
||||
|
||||
if (!(body.right < tile.x || body.bottom < tile.y || body.x > tile.right || body.y > tile.bottom))
|
||||
{
|
||||
this._intersection[0] = Math.max(body.x, tile.x); // x
|
||||
this._intersection[1] = Math.max(body.y, tile.y); // y
|
||||
this._intersection[2] = Math.min(body.right, tile.right) - this._intersection[0]; // width
|
||||
this._intersection[3] = Math.min(body.bottom, tile.bottom) - this._intersection[1]; // height
|
||||
this._intersection[4] = 1;
|
||||
|
||||
return this._intersection;
|
||||
}
|
||||
|
||||
this._intersection[4] = 0;
|
||||
|
||||
return this._intersection;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The core separation function to separate a physics body and an array of tiles.
|
||||
* @method Phaser.Physics.Arcade#separateTiles
|
||||
* @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
|
||||
* @param {array<Phaser.Tile>} tiles - The array of tiles to collide against.
|
||||
* @returns {boolean} Returns true if the body was separated, otherwise false.
|
||||
*/
|
||||
separateTiles: function (body, tiles) {
|
||||
|
||||
var tile;
|
||||
body.resetResult();
|
||||
|
||||
var result = false;
|
||||
|
||||
for (var i = 0; i < tiles.length; i++)
|
||||
{
|
||||
tile = tiles[i];
|
||||
|
||||
if (this.separateTile(body, tile))
|
||||
if (this.separateTile(i, body, tiles[i]))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
@@ -935,6 +889,86 @@ Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
},
|
||||
|
||||
separateTile: function (i, body, tile) {
|
||||
|
||||
// we re-check for collision in case body was separated in a previous step
|
||||
if (i > 0 && !tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
||||
{
|
||||
// no collision so bail out (separted in a previous step)
|
||||
console.log('no collision so bail out (separted in a previous step');
|
||||
return false;
|
||||
}
|
||||
|
||||
// console.log('body intersecting tile');
|
||||
// console.log('x', body.position.x, 'y', body.position.y, 'r', body.right, 'b', body.bottom, 'wh', body.width, body.height);
|
||||
// console.log('x', tile.x, 'y', tile.y, 'r', tile.right, 'b', tile.bottom);
|
||||
|
||||
if (body.newVelocity.x && (tile.faceLeft || tile.faceRight))
|
||||
{
|
||||
var px = 0;
|
||||
var tx = 0;
|
||||
|
||||
if (body.newVelocity.x > 0 && tile.faceLeft)
|
||||
{
|
||||
px = body.width;
|
||||
}
|
||||
else if (body.newVelocity.x < 0 && tile.faceRight)
|
||||
{
|
||||
tx = tile.width;
|
||||
}
|
||||
|
||||
body.position.x = tile.worldX - px + tx;
|
||||
|
||||
body.velocity.x = 0; // rebound check
|
||||
// body.newVelocity.x = 0; // rebound check
|
||||
}
|
||||
|
||||
// Vertical only if still colliding
|
||||
|
||||
// if (tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
||||
// if (body.newVelocity.y && tile.intersects(body.position.x, body.position.y, body.right, body.bottom))
|
||||
if (body.newVelocity.y && (tile.faceTop || tile.faceBottom))
|
||||
{
|
||||
var py = 0;
|
||||
var ty = 0;
|
||||
|
||||
if (body.newVelocity.y > 0 && tile.faceBottom)
|
||||
{
|
||||
py = body.height;
|
||||
}
|
||||
else if (body.newVelocity.y < 0 && tile.faceTop)
|
||||
{
|
||||
ty = tile.height;
|
||||
}
|
||||
|
||||
// console.log('cy', body.newVelocity.y, py, ty);
|
||||
|
||||
body.position.y = tile.worldY - py + ty;
|
||||
|
||||
body.velocity.y = 0; // rebound check
|
||||
// body.newVelocity.y = 0; // rebound check
|
||||
}
|
||||
|
||||
// var pxOffsetX = (body.newVelocity.x > 0 ? body.width : 0);
|
||||
// var tileOffsetX = (body.newVelocity.x < 0 ? tile.width : 0);
|
||||
// var pxOffsetY = (body.newVelocity.y > 0 ? body.height : 0);
|
||||
// var tileOffsetY = (body.newVelocity.y < 0 ? tile.height : 0);
|
||||
|
||||
// Assume fully solid for now
|
||||
|
||||
// body.result.x = true;
|
||||
// body.result.tile = tile;
|
||||
// body.result.px = tile.x - pxOffsetX + tileOffsetX;
|
||||
// body.position.x = tile.x - pxOffsetX + tileOffsetX;
|
||||
|
||||
// res.pos.y = tileY * this.tilesize - pxOffsetY + tileOffsetY;
|
||||
|
||||
|
||||
|
||||
// console.log('nv', body.newVelocity.x, 'tile.xy', tile.x, tile.y, 'p', pxOffsetX, 't', tileOffsetX, 'body xy', body.position.x, body.position.y);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The core separation function to separate a physics body and a tile.
|
||||
* @method Phaser.Physics.Arcade#separateTile
|
||||
@@ -942,7 +976,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
* @param {Phaser.Tile} tile - The tile to collide against.
|
||||
* @returns {boolean} Returns true if the body was separated, otherwise false.
|
||||
*/
|
||||
separateTile: function (body, tile) {
|
||||
XXXseparateTile: function (body, tile) {
|
||||
|
||||
/*
|
||||
this._intersection = this.tileIntersects(body, tile);
|
||||
@@ -952,7 +986,6 @@ Phaser.Physics.Arcade.prototype = {
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
Phaser.Rectangle.intersection(body, tile, this._intersection);
|
||||
|
||||
@@ -960,6 +993,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// console.log(this._intersection);
|
||||
// console.log(tile, body.x, body.y);
|
||||
@@ -982,6 +1016,16 @@ Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
body.overlapX = 0;
|
||||
|
||||
if (body.deltaX() < 0 && body.checkCollision.left)
|
||||
{
|
||||
// Body is moving LEFT
|
||||
if (tile.tile.faceRight && body.x < tile.right)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var process = false;
|
||||
|
||||
if (this._intersection.width > 0)
|
||||
@@ -989,18 +1033,21 @@ Phaser.Physics.Arcade.prototype = {
|
||||
// Tile is blocking to the right and body is moving left
|
||||
if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight)
|
||||
{
|
||||
process = true;
|
||||
body.overlapX = -this._intersection.width;
|
||||
body.x = tile.right;
|
||||
// process = true;
|
||||
// body.overlapX = -this._intersection.width;
|
||||
}
|
||||
|
||||
// Tile is blocking to the left and body is moving right
|
||||
if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft)
|
||||
{
|
||||
process = true;
|
||||
body.overlapX = this._intersection.width;
|
||||
body.right = tile.x;
|
||||
// process = true;
|
||||
// body.overlapX = this._intersection.width;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (body.overlapX !== 0)
|
||||
{
|
||||
if (body.overlapX < 0)
|
||||
@@ -1013,7 +1060,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
}
|
||||
|
||||
body.x -= body.overlapX;
|
||||
body.preX -= body.overlapX;
|
||||
// body.preX -= body.overlapX;
|
||||
body.blocked.x = Math.floor(body.x);
|
||||
body.blocked.y = Math.floor(body.y);
|
||||
|
||||
@@ -1026,6 +1073,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
body.velocity.x = -body.velocity.x * body.bounce.x;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Phaser.Rectangle.intersection(body, tile, this._intersection);
|
||||
|
||||
@@ -1043,8 +1091,9 @@ Phaser.Physics.Arcade.prototype = {
|
||||
// Tile is blocking to the bottom and body is moving up
|
||||
if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom)
|
||||
{
|
||||
process = true;
|
||||
body.overlapY = -this._intersection.height;
|
||||
|
||||
// process = true;
|
||||
// body.overlapY = -this._intersection.height;
|
||||
}
|
||||
|
||||
// Tile is blocking to the top and body is moving down
|
||||
@@ -1067,7 +1116,7 @@ Phaser.Physics.Arcade.prototype = {
|
||||
}
|
||||
|
||||
body.y -= body.overlapY;
|
||||
body.preY -= body.overlapY;
|
||||
// body.preY -= body.overlapY;
|
||||
body.blocked.x = Math.floor(body.x);
|
||||
body.blocked.y = Math.floor(body.y);
|
||||
|
||||
@@ -1240,274 +1289,6 @@ Phaser.Physics.Arcade.prototype = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The core separation function to separate a physics body and an array of tiles.
|
||||
* @method Phaser.Physics.Arcade#separateTiles
|
||||
* @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
|
||||
* @param {Phaser.Tile} tile - The tile to collide against.
|
||||
* @returns {boolean} Returns true if the bodies were separated, otherwise false.
|
||||
*/
|
||||
OLDseparateTiles: function (body, tiles) {
|
||||
|
||||
// Can't separate two immovable objects (tiles are always immovable)
|
||||
// if (body.immovable)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
body.overlapX = 0;
|
||||
body.overlapY = 0;
|
||||
|
||||
var tile;
|
||||
var localOverlapX = 0;
|
||||
var localOverlapY = 0;
|
||||
|
||||
for (var i = 0; i < tiles.length; i++)
|
||||
{
|
||||
tile = tiles[i];
|
||||
|
||||
if (Phaser.Rectangle.intersects(body, tile))
|
||||
{
|
||||
if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight)
|
||||
{
|
||||
// LEFT
|
||||
localOverlapX = body.x - tile.right;
|
||||
|
||||
if (localOverlapX >= body.deltaX())
|
||||
{
|
||||
// console.log('m left overlapX', localOverlapX, body.deltaX());
|
||||
// use touching instead of blocked?
|
||||
body.blocked.left = true;
|
||||
body.touching.left = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft)
|
||||
{
|
||||
// RIGHT
|
||||
localOverlapX = body.right - tile.x;
|
||||
|
||||
// Distance check
|
||||
if (localOverlapX <= body.deltaX())
|
||||
{
|
||||
// console.log('m right overlapX', localOverlapX, body.deltaX());
|
||||
body.blocked.right = true;
|
||||
body.touching.right = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom)
|
||||
{
|
||||
// UP
|
||||
localOverlapY = body.y - tile.bottom;
|
||||
|
||||
// Distance check
|
||||
if (localOverlapY >= body.deltaY())
|
||||
{
|
||||
// console.log('m up overlapY', localOverlapY, body.deltaY());
|
||||
body.blocked.up = true;
|
||||
body.touching.up = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop)
|
||||
{
|
||||
// DOWN
|
||||
localOverlapY = body.bottom - tile.y;
|
||||
|
||||
if (localOverlapY <= body.deltaY())
|
||||
{
|
||||
// console.log('m down overlapY', localOverlapY, body.deltaY());
|
||||
body.blocked.down = true;
|
||||
body.touching.down = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (localOverlapX !== 0)
|
||||
{
|
||||
body.overlapX = localOverlapX;
|
||||
}
|
||||
|
||||
if (localOverlapY !== 0)
|
||||
{
|
||||
body.overlapY = localOverlapY;
|
||||
}
|
||||
|
||||
if (body.touching.none)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (body.overlapX !== 0)
|
||||
if (body.touching.left || body.touching.right)
|
||||
{
|
||||
body.x -= body.overlapX;
|
||||
body.preX -= body.overlapX;
|
||||
|
||||
if (body.bounce.x === 0)
|
||||
{
|
||||
body.velocity.x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
body.velocity.x = -body.velocity.x * body.bounce.x;
|
||||
}
|
||||
}
|
||||
|
||||
// if (body.overlapY !== 0)
|
||||
if (body.touching.up || body.touching.down)
|
||||
{
|
||||
body.y -= body.overlapY;
|
||||
body.preY -= body.overlapY;
|
||||
|
||||
if (body.bounce.y === 0)
|
||||
{
|
||||
body.velocity.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
body.velocity.y = -body.velocity.y * body.bounce.y;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The core separation function to separate a physics body and a tile.
|
||||
* @method Phaser.Physics.Arcade#separateTile
|
||||
* @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
|
||||
* @param {Phaser.Tile} tile - The tile to collide against.
|
||||
* @returns {boolean} Returns true if the bodies were separated, otherwise false.
|
||||
*/
|
||||
OLDseparateTile: function (body, tile) {
|
||||
|
||||
// Can't separate two immovable objects (tiles are always immovable)
|
||||
// if (body.immovable || Phaser.Rectangle.intersects(body, tile) === false)
|
||||
if (Phaser.Rectangle.intersects(body, tile) === false)
|
||||
{
|
||||
// console.log('no intersects');
|
||||
// console.log('tx', tile.x, 'ty', tile.y, 'tw', tile.width, 'th', tile.height, 'tr', tile.right, 'tb', tile.bottom);
|
||||
// console.log('bx', body.x, 'by', body.y, 'bw', body.width, 'bh', body.height, 'br', body.right, 'bb', body.bottom);
|
||||
return false;
|
||||
}
|
||||
|
||||
// use body var instead
|
||||
body.overlapX = 0;
|
||||
body.overlapY = 0;
|
||||
|
||||
// Remember - this happens AFTER the body has been moved by the motion update, so it needs moving back again
|
||||
// console.log('---------------------------------------------------------------------------------------------');
|
||||
// console.log('tx', tile.x, 'ty', tile.y, 'tw', tile.width, 'th', tile.height, 'tr', tile.right, 'tb', tile.bottom);
|
||||
// console.log('bx', body.x, 'by', body.y, 'bw', body.width, 'bh', body.height, 'br', body.right, 'bb', body.bottom);
|
||||
// console.log(Phaser.Rectangle.intersects(body, tile));
|
||||
// console.log('dx', body.deltaX(), 'dy', body.deltaY(), 'dax', body.deltaAbsX(), 'day', body.deltaAbsY(), 'cax', Math.ceil(body.deltaAbsX()), 'cay', Math.ceil(body.deltaAbsY()));
|
||||
|
||||
if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight)
|
||||
{
|
||||
// LEFT
|
||||
body.overlapX = body.x - tile.right;
|
||||
|
||||
if (body.overlapX >= body.deltaX())
|
||||
{
|
||||
// console.log('left overlapX', body.overlapX, body.deltaX());
|
||||
// use touching instead of blocked?
|
||||
body.blocked.left = true;
|
||||
body.touching.left = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft)
|
||||
{
|
||||
// RIGHT
|
||||
body.overlapX = body.right - tile.x;
|
||||
|
||||
// Distance check
|
||||
if (body.overlapX <= body.deltaX())
|
||||
{
|
||||
// console.log('right overlapX', body.overlapX, body.deltaX());
|
||||
body.blocked.right = true;
|
||||
body.touching.right = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom)
|
||||
{
|
||||
// UP
|
||||
body.overlapY = body.y - tile.bottom;
|
||||
|
||||
// Distance check
|
||||
if (body.overlapY >= body.deltaY())
|
||||
{
|
||||
// console.log('up overlapY', body.overlapY, body.deltaY());
|
||||
body.blocked.up = true;
|
||||
body.touching.up = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop)
|
||||
{
|
||||
// DOWN
|
||||
body.overlapY = body.bottom - tile.y;
|
||||
|
||||
if (body.overlapY <= body.deltaY())
|
||||
{
|
||||
// console.log('down overlapY', body.overlapY, body.deltaY());
|
||||
body.blocked.down = true;
|
||||
body.touching.down = true;
|
||||
body.touching.none = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Separate in a single sweep
|
||||
|
||||
if (body.touching.none)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (body.overlapX !== 0)
|
||||
if (body.touching.left || body.touching.right)
|
||||
{
|
||||
body.x -= body.overlapX;
|
||||
body.preX -= body.overlapX;
|
||||
|
||||
if (body.bounce.x === 0)
|
||||
{
|
||||
body.velocity.x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
body.velocity.x = -body.velocity.x * body.bounce.x;
|
||||
}
|
||||
}
|
||||
|
||||
// if (body.overlapY !== 0)
|
||||
if (body.touching.up || body.touching.down)
|
||||
{
|
||||
body.y -= body.overlapY;
|
||||
body.preY -= body.overlapY;
|
||||
|
||||
if (body.bounce.y === 0)
|
||||
{
|
||||
body.velocity.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
body.velocity.y = -body.velocity.y * body.bounce.y;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Move the given display object towards the destination object at a steady velocity.
|
||||
* If you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds.
|
||||
|
||||
@@ -0,0 +1,842 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ninja Physics AABB constructor.
|
||||
*
|
||||
* @class Phaser.Physics.Ninja.AABB
|
||||
* @classdesc Arcade Physics Constructor
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game reference to the current game instance.
|
||||
*/
|
||||
Phaser.Physics.Ninja.AABB = function (system, x, y, width, height) {
|
||||
|
||||
this.system = system;
|
||||
this.pos = new Phaser.Point(x, y);
|
||||
this.oldpos = new Phaser.Point(x, y);
|
||||
|
||||
this.xw = Math.abs(width / 2);
|
||||
this.yw = Math.abs(height / 2);
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.oH = 0;
|
||||
this.oV = 0;
|
||||
|
||||
// Setting drag to 0 and friction to 0 means you get a normalised speed (px psec)
|
||||
this.drag = 1;
|
||||
this.friction = 0.05;
|
||||
this.gravityScale = 1;
|
||||
this.bounce = 0.3;
|
||||
this.velocity = new Phaser.Point();
|
||||
|
||||
// temp collision values
|
||||
this.px = 0;
|
||||
this.py = 0;
|
||||
|
||||
// collision mappings
|
||||
this.aabbTileProjections = {};
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL] = this.projAABB_Full;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG] = this.projAABB_45Deg;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE] = this.projAABB_Concave;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX] = this.projAABB_Convex;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs] = this.projAABB_22DegS;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb] = this.projAABB_22DegB;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs] = this.projAABB_67DegS;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb] = this.projAABB_67DegB;
|
||||
this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF] = this.projAABB_Half;
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Ninja.AABB.prototype.constructor = Phaser.Physics.Ninja.AABB;
|
||||
|
||||
Phaser.Physics.Ninja.AABB.COL_NONE = 0;
|
||||
Phaser.Physics.Ninja.AABB.COL_AXIS = 1;
|
||||
Phaser.Physics.Ninja.AABB.COL_OTHER = 2;
|
||||
|
||||
Phaser.Physics.Ninja.AABB.prototype = {
|
||||
|
||||
/**
|
||||
* Updates this AABBs position.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#integrate
|
||||
*/
|
||||
integrate: function () {
|
||||
|
||||
var px = this.pos.x;
|
||||
var py = this.pos.y;
|
||||
|
||||
// integrate
|
||||
this.pos.x += (this.drag * this.pos.x) - (this.drag * this.oldpos.x);
|
||||
this.pos.y += (this.drag * this.pos.y) - (this.drag * this.oldpos.y) + (this.system.gravity * this.gravityScale);
|
||||
|
||||
// store
|
||||
this.velocity.set(this.pos.x - px, this.pos.y - py);
|
||||
this.oldpos.set(px, py);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Process a world collision and apply the resulting forces.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#reportCollisionVsWorld
|
||||
* @param {number} px - The tangent velocity
|
||||
* @param {number} py - The tangent velocity
|
||||
* @param {number} dx - Collision normal
|
||||
* @param {number} dy - Collision normal
|
||||
* @param {number} obj - Object this AABB collided with
|
||||
*/
|
||||
reportCollisionVsWorld: function (px, py, dx, dy, obj) {
|
||||
|
||||
var p = this.pos;
|
||||
var o = this.oldpos;
|
||||
|
||||
//calc velocity
|
||||
var vx = p.x - o.x;
|
||||
var vy = p.y - o.y;
|
||||
|
||||
//find component of velocity parallel to collision normal
|
||||
var dp = (vx * dx + vy * dy);
|
||||
var nx = dp * dx;//project velocity onto collision normal
|
||||
|
||||
var ny = dp * dy;//nx,ny is normal velocity
|
||||
|
||||
var tx = vx - nx;//px,py is tangent velocity
|
||||
var ty = vy - ny;
|
||||
|
||||
//we only want to apply collision response forces if the object is travelling into, and not out of, the collision
|
||||
var b, bx, by, f, fx, fy;
|
||||
|
||||
if (dp < 0)
|
||||
{
|
||||
//f = FRICTION;
|
||||
fx = tx * this.friction;
|
||||
fy = ty * this.friction;
|
||||
|
||||
b = 1 + this.bounce;
|
||||
|
||||
bx = (nx * b);
|
||||
by = (ny * b);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//moving out of collision, do not apply forces
|
||||
bx = by = fx = fy = 0;
|
||||
}
|
||||
|
||||
p.x += px;//project object out of collision
|
||||
p.y += py;
|
||||
|
||||
o.x += px + bx + fx;//apply bounce+friction impulses which alter velocity
|
||||
o.y += py + by + fy;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Collides this AABB against a Tile.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#collideAABBVsTile
|
||||
* @param {Phaser.Physics.Ninja.Tile} tile - The Tile to collide against.
|
||||
*/
|
||||
collideAABBVsTile: function (tile) {
|
||||
|
||||
var pos = this.pos;
|
||||
var c = tile;
|
||||
|
||||
var tx = c.pos.x;
|
||||
var ty = c.pos.y;
|
||||
var txw = c.xw;
|
||||
var tyw = c.yw;
|
||||
|
||||
var dx = pos.x - tx;//tile->obj delta
|
||||
var px = (txw + this.xw) - Math.abs(dx);//penetration depth in x
|
||||
|
||||
if (0 < px)
|
||||
{
|
||||
var dy = pos.y - ty;//tile->obj delta
|
||||
var py = (tyw + this.yw) - Math.abs(dy);//pen depth in y
|
||||
|
||||
if (0 < py)
|
||||
{
|
||||
//object may be colliding with tile; call tile-specific collision function
|
||||
|
||||
//calculate projection vectors
|
||||
if (px < py)
|
||||
{
|
||||
//project in x
|
||||
if (dx < 0)
|
||||
{
|
||||
//project to the left
|
||||
px *= -1;
|
||||
py = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//proj to right
|
||||
py = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//project in y
|
||||
if (dy < 0)
|
||||
{
|
||||
//project up
|
||||
px = 0;
|
||||
py *= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//project down
|
||||
px = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return this.resolveTile(px, py, this, c);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Collides this AABB against the world bounds.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#collideWorldBounds
|
||||
*/
|
||||
collideWorldBounds: function () {
|
||||
|
||||
var p = this.pos;
|
||||
var xw = this.xw;
|
||||
var yw = this.yw;
|
||||
|
||||
var XMIN = this.system.bounds.x;
|
||||
var XMAX = this.system.bounds.width;
|
||||
var YMIN = this.system.bounds.y;
|
||||
var YMAX = this.system.bounds.height;
|
||||
|
||||
var dx = this.system.bounds.x - (this.pos.x - this.xw);
|
||||
|
||||
if (0 < dx)
|
||||
{
|
||||
this.reportCollisionVsWorld(dx, 0, 1, 0, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = (this.pos.x + this.xw) - this.system.bounds.width;
|
||||
|
||||
if (0 < dx)
|
||||
{
|
||||
this.reportCollisionVsWorld(-dx, 0, -1, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
var dy = this.system.bounds.y - (this.pos.y - this.yw);
|
||||
|
||||
if (0 < dy)
|
||||
{
|
||||
this.reportCollisionVsWorld(0, dy, 0, 1, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
dy = (this.pos.y + this.yw) - this.system.bounds.height;
|
||||
|
||||
if (0 < dy)
|
||||
{
|
||||
this.reportCollisionVsWorld(0, -dy, 0, -1, null);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders this AABB to the context.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#render
|
||||
*/
|
||||
render: function (context) {
|
||||
|
||||
context.beginPath();
|
||||
context.strokeStyle = 'rgb(0,255,0)';
|
||||
context.strokeRect(this.pos.x - this.xw, this.pos.y - this.yw, this.xw * 2, this.yw * 2);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
|
||||
context.fillStyle = 'rgb(0,255,0)';
|
||||
context.fillRect(this.pos.x, this.pos.y, 2, 2);
|
||||
|
||||
/*
|
||||
if (this.oH == 1)
|
||||
{
|
||||
context.beginPath();
|
||||
context.strokeStyle = 'rgb(255,0,0)';
|
||||
context.moveTo(this.pos.x - this.radius, this.pos.y - this.radius);
|
||||
context.lineTo(this.pos.x - this.radius, this.pos.y + this.radius);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
}
|
||||
else if (this.oH == -1)
|
||||
{
|
||||
context.beginPath();
|
||||
context.strokeStyle = 'rgb(255,0,0)';
|
||||
context.moveTo(this.pos.x + this.radius, this.pos.y - this.radius);
|
||||
context.lineTo(this.pos.x + this.radius, this.pos.y + this.radius);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
}
|
||||
|
||||
if (this.oV == 1)
|
||||
{
|
||||
context.beginPath();
|
||||
context.strokeStyle = 'rgb(255,0,0)';
|
||||
context.moveTo(this.pos.x - this.radius, this.pos.y - this.radius);
|
||||
context.lineTo(this.pos.x + this.radius, this.pos.y - this.radius);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
}
|
||||
else if (this.oV == -1)
|
||||
{
|
||||
context.beginPath();
|
||||
context.strokeStyle = 'rgb(255,0,0)';
|
||||
context.moveTo(this.pos.x - this.radius, this.pos.y + this.radius);
|
||||
context.lineTo(this.pos.x + this.radius, this.pos.y + this.radius);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
}
|
||||
*/
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#resolveTile
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} body - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} tile - The Tile involved in the collision.
|
||||
* @return {boolean} True if the collision was processed, otherwise false.
|
||||
*/
|
||||
resolveTile: function (x, y, body, tile) {
|
||||
|
||||
if (0 < tile.id)
|
||||
{
|
||||
return this.aabbTileProjections[tile.type](x, y, body, tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.warn("Ninja.AABB.resolveTile was called with an empty (or unknown) tile!: id=" + tile.id + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves Full tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_Full
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_Full: function (x, y, obj, t) {
|
||||
|
||||
var l = Math.sqrt(x * x + y * y);
|
||||
obj.reportCollisionVsWorld(x, y, x / l, y / l, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves Half tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_Half
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_Half: function (x, y, obj, t) {
|
||||
|
||||
//signx or signy must be 0; the other must be -1 or 1
|
||||
//calculate the projection vector for the half-edge, and then
|
||||
//(if collision is occuring) pick the minimum
|
||||
|
||||
var sx = t.signx;
|
||||
var sy = t.signy;
|
||||
|
||||
var ox = (obj.pos.x - (sx*obj.xw)) - t.pos.x;//this gives is the coordinates of the innermost
|
||||
var oy = (obj.pos.y - (sy*obj.yw)) - t.pos.y;//point on the AABB, relative to the tile center
|
||||
|
||||
//we perform operations analogous to the 45deg tile, except we're using
|
||||
//an axis-aligned slope instead of an angled one..
|
||||
|
||||
//if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope
|
||||
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
|
||||
var dp = (ox*sx) + (oy*sy);
|
||||
|
||||
if (dp < 0)
|
||||
{
|
||||
//collision; project delta onto slope and use this to displace the object
|
||||
sx *= -dp;//(sx,sy) is now the projection vector
|
||||
sy *= -dp;
|
||||
|
||||
var lenN = Math.sqrt(sx*sx + sy*sy);
|
||||
var lenP = Math.sqrt(x*x + y*y);
|
||||
|
||||
if (lenP < lenN)
|
||||
{
|
||||
//project along axis; note that we're assuming that this tile is horizontal OR vertical
|
||||
//relative to the AABB's current tile, and not diagonal OR the current tile.
|
||||
obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
//note that we could use -= instead of -dp
|
||||
obj.reportCollisionVsWorld(sx,sy,t.signx, t.signy, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves 45 Degree tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_45Deg
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_45Deg: function (x, y, obj, t) {
|
||||
|
||||
var signx = t.signx;
|
||||
var signy = t.signy;
|
||||
|
||||
var ox = (obj.pos.x - (signx*obj.xw)) - t.pos.x;//this gives is the coordinates of the innermost
|
||||
var oy = (obj.pos.y - (signy*obj.yw)) - t.pos.y;//point on the AABB, relative to the tile center
|
||||
|
||||
var sx = t.sx;
|
||||
var sy = t.sy;
|
||||
|
||||
//if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope
|
||||
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
|
||||
var dp = (ox*sx) + (oy*sy);
|
||||
|
||||
if (dp < 0)
|
||||
{
|
||||
//collision; project delta onto slope and use this to displace the object
|
||||
sx *= -dp;//(sx,sy) is now the projection vector
|
||||
sy *= -dp;
|
||||
|
||||
var lenN = Math.sqrt(sx*sx + sy*sy);
|
||||
var lenP = Math.sqrt(x*x + y*y);
|
||||
|
||||
if (lenP < lenN)
|
||||
{
|
||||
//project along axis
|
||||
obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
//project along slope
|
||||
obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves 22 Degree tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_22DegS
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_22DegS: function (x, y, obj, t) {
|
||||
|
||||
var signx = t.signx;
|
||||
var signy = t.signy;
|
||||
|
||||
//first we need to check to make sure we're colliding with the slope at all
|
||||
var py = obj.pos.y - (signy*obj.yw);
|
||||
var penY = t.pos.y - py;//this is the vector from the innermost point on the box to the highest point on
|
||||
//the tile; if it is positive, this means the box is above the tile and
|
||||
//no collision is occuring
|
||||
if (0 < (penY*signy))
|
||||
{
|
||||
var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost
|
||||
var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope
|
||||
|
||||
var sx = t.sx;//get slope unit normal
|
||||
var sy = t.sy;
|
||||
|
||||
//if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope
|
||||
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
|
||||
var dp = (ox*sx) + (oy*sy);
|
||||
|
||||
if (dp < 0)
|
||||
{
|
||||
//collision; project delta onto slope and use this to displace the object
|
||||
sx *= -dp;//(sx,sy) is now the projection vector
|
||||
sy *= -dp;
|
||||
|
||||
var lenN = Math.sqrt(sx*sx + sy*sy);
|
||||
var lenP = Math.sqrt(x*x + y*y);
|
||||
|
||||
var aY = Math.abs(penY);
|
||||
|
||||
if (lenP < lenN)
|
||||
{
|
||||
if (aY < lenP)
|
||||
{
|
||||
obj.reportCollisionVsWorld(0, penY, 0, penY/aY, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aY < lenN)
|
||||
{
|
||||
obj.reportCollisionVsWorld(0, penY, 0, penY/aY, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if we've reached this point, no collision has occured
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves 22 Degree tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_22DegB
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_22DegB: function (x, y, obj, t) {
|
||||
|
||||
var signx = t.signx;
|
||||
var signy = t.signy;
|
||||
|
||||
var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost
|
||||
var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope
|
||||
|
||||
var sx = t.sx;//get slope unit normal
|
||||
var sy = t.sy;
|
||||
|
||||
//if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope
|
||||
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
|
||||
var dp = (ox*sx) + (oy*sy);
|
||||
|
||||
if (dp < 0)
|
||||
{
|
||||
//collision; project delta onto slope and use this to displace the object
|
||||
sx *= -dp;//(sx,sy) is now the projection vector
|
||||
sy *= -dp;
|
||||
|
||||
var lenN = Math.sqrt(sx*sx + sy*sy);
|
||||
var lenP = Math.sqrt(x*x + y*y);
|
||||
|
||||
if (lenP < lenN)
|
||||
{
|
||||
obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves 67 Degree tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_67DegS
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_67DegS: function (x, y, obj, t) {
|
||||
|
||||
var signx = t.signx;
|
||||
var signy = t.signy;
|
||||
|
||||
var px = obj.pos.x - (signx*obj.xw);
|
||||
var penX = t.pos.x - px;
|
||||
|
||||
if (0 < (penX*signx))
|
||||
{
|
||||
var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x - (signx*t.xw));//this gives is the coordinates of the innermost
|
||||
var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y + (signy*t.yw));//point on the AABB, relative to a point on the slope
|
||||
|
||||
var sx = t.sx;//get slope unit normal
|
||||
var sy = t.sy;
|
||||
|
||||
//if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope
|
||||
//and we need to project it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
|
||||
var dp = (ox*sx) + (oy*sy);
|
||||
|
||||
if (dp < 0)
|
||||
{
|
||||
//collision; project delta onto slope and use this to displace the object
|
||||
sx *= -dp;//(sx,sy) is now the projection vector
|
||||
sy *= -dp;
|
||||
|
||||
var lenN = Math.sqrt(sx*sx + sy*sy);
|
||||
var lenP = Math.sqrt(x*x + y*y);
|
||||
|
||||
var aX = Math.abs(penX);
|
||||
|
||||
if (lenP < lenN)
|
||||
{
|
||||
if (aX < lenP)
|
||||
{
|
||||
obj.reportCollisionVsWorld(penX, 0, penX/aX, 0, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aX < lenN)
|
||||
{
|
||||
obj.reportCollisionVsWorld(penX, 0, penX/aX, 0, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if we've reached this point, no collision has occured
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves 67 Degree tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_67DegB
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_67DegB: function (x, y, obj, t) {
|
||||
|
||||
var signx = t.signx;
|
||||
var signy = t.signy;
|
||||
|
||||
var ox = (obj.pos.x - (signx*obj.xw)) - (t.pos.x + (signx*t.xw));//this gives is the coordinates of the innermost
|
||||
var oy = (obj.pos.y - (signy*obj.yw)) - (t.pos.y - (signy*t.yw));//point on the AABB, relative to a point on the slope
|
||||
|
||||
var sx = t.sx;//get slope unit normal
|
||||
var sy = t.sy;
|
||||
|
||||
//if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope
|
||||
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
|
||||
var dp = (ox*sx) + (oy*sy);
|
||||
|
||||
if (dp < 0)
|
||||
{
|
||||
//collision; project delta onto slope and use this to displace the object
|
||||
sx *= -dp;//(sx,sy) is now the projection vector
|
||||
sy *= -dp;
|
||||
|
||||
var lenN = Math.sqrt(sx*sx + sy*sy);
|
||||
var lenP = Math.sqrt(x*x + y*y);
|
||||
|
||||
if (lenP < lenN)
|
||||
{
|
||||
obj.reportCollisionVsWorld(x,y,x/lenP, y/lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.reportCollisionVsWorld(sx,sy,t.sx,t.sy,t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves Convex tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_Convex
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_Convex: function (x, y, obj, t) {
|
||||
|
||||
//if distance from "innermost" corner of AABB is less than than tile radius,
|
||||
//collision is occuring and we need to project
|
||||
|
||||
var signx = t.signx;
|
||||
var signy = t.signy;
|
||||
|
||||
var ox = (obj.pos.x - (signx * obj.xw)) - (t.pos.x - (signx * t.xw));//(ox,oy) is the vector from the circle center to
|
||||
var oy = (obj.pos.y - (signy * obj.yw)) - (t.pos.y - (signy * t.yw));//the AABB
|
||||
var len = Math.sqrt(ox * ox + oy * oy);
|
||||
|
||||
var twid = t.xw * 2;
|
||||
var rad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile;
|
||||
//note that this should be precomputed at compile-time since it's constant
|
||||
|
||||
var pen = rad - len;
|
||||
|
||||
if (((signx * ox) < 0) || ((signy * oy) < 0))
|
||||
{
|
||||
//the test corner is "outside" the 1/4 of the circle we're interested in
|
||||
var lenP = Math.sqrt(x * x + y * y);
|
||||
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;//we need to report
|
||||
}
|
||||
else if (0 < pen)
|
||||
{
|
||||
//project along corner->circle vector
|
||||
ox /= len;
|
||||
oy /= len;
|
||||
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves Concave tile collision.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#projAABB_Concave
|
||||
* @param {number} x - Penetration depth on the x axis.
|
||||
* @param {number} y - Penetration depth on the y axis.
|
||||
* @param {Phaser.Physics.Ninja.AABB} obj - The AABB involved in the collision.
|
||||
* @param {Phaser.Physics.Ninja.Tile} t - The Tile involved in the collision.
|
||||
* @return {number} The result of the collision.
|
||||
*/
|
||||
projAABB_Concave: function (x, y, obj, t) {
|
||||
|
||||
//if distance from "innermost" corner of AABB is further than tile radius,
|
||||
//collision is occuring and we need to project
|
||||
|
||||
var signx = t.signx;
|
||||
var signy = t.signy;
|
||||
|
||||
var ox = (t.pos.x + (signx * t.xw)) - (obj.pos.x - (signx * obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the
|
||||
var oy = (t.pos.y + (signy * t.yw)) - (obj.pos.y - (signy * obj.yw));//circle's center
|
||||
|
||||
var twid = t.xw * 2;
|
||||
var rad = Math.sqrt(twid * twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile;
|
||||
//note that this should be precomputed at compile-time since it's constant
|
||||
|
||||
var len = Math.sqrt(ox * ox + oy * oy);
|
||||
var pen = len - rad;
|
||||
|
||||
if (0 < pen)
|
||||
{
|
||||
//collision; we need to either project along the axes, or project along corner->circlecenter vector
|
||||
|
||||
var lenP = Math.sqrt(x * x + y * y);
|
||||
|
||||
if (lenP < pen)
|
||||
{
|
||||
//it's shorter to move along axis directions
|
||||
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_AXIS;
|
||||
}
|
||||
else
|
||||
{
|
||||
//project along corner->circle vector
|
||||
ox /= len;//len should never be 0, since if it IS 0, rad should be > than len
|
||||
oy /= len;//and we should never reach here
|
||||
|
||||
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_OTHER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Phaser.Physics.Ninja.AABB.COL_NONE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Physics Body is linked to a single Sprite. All physics operations should be performed against the body rather than
|
||||
* the Sprite itself. For example you can set the velocity, bounce values etc all on the Body.
|
||||
*
|
||||
* @class Phaser.Physics.Ninja.Body
|
||||
* @classdesc Ninja Physics Body Constructor
|
||||
* @constructor
|
||||
* @param {Phaser.Physics.Ninja} system - The physics system this Body belongs to.
|
||||
* @param {Phaser.Sprite} sprite - The Sprite object this physics body belongs to.
|
||||
* @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile.
|
||||
* @param {number} [id=1] - If this body is using a Tile shape, you can set the Tile id here, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc.
|
||||
*/
|
||||
Phaser.Physics.Ninja.Body = function (system, sprite, type, id) {
|
||||
|
||||
if (typeof type === 'undefined') { type = 1; }
|
||||
if (typeof id === 'undefined') { id = 1; }
|
||||
|
||||
/**
|
||||
* @property {Phaser.Sprite} sprite - Reference to the parent Sprite.
|
||||
*/
|
||||
this.sprite = sprite;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Game} game - Local reference to game.
|
||||
*/
|
||||
this.game = sprite.game;
|
||||
|
||||
/**
|
||||
* @property {number} type - The type of physics system this body belongs to.
|
||||
*/
|
||||
this.type = Phaser.Physics.NINJA;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Ninja} system - The parent physics system.
|
||||
*/
|
||||
this.system = system;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Ninja.AABB} aabb - The AABB object this body is using for collision.
|
||||
*/
|
||||
this.aabb = null;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Ninja.Tile} tile - The Tile object this body is using for collision.
|
||||
*/
|
||||
this.tile = null;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Physics.Ninja.Circle} circle - The Circle object this body is using for collision.
|
||||
*/
|
||||
this.circle = null;
|
||||
|
||||
/**
|
||||
* @property {object} shape - A local reference to the body shape.
|
||||
*/
|
||||
this.shape = null;
|
||||
|
||||
if (type === 1)
|
||||
{
|
||||
this.aabb = new Phaser.Physics.Ninja.AABB(system, sprite.x, sprite.y, sprite.width, sprite.height);
|
||||
this.shape = this.aabb;
|
||||
}
|
||||
else if (type === 2)
|
||||
{
|
||||
this.circle = new Phaser.Physics.Ninja.Circle(system, sprite.x, sprite.y, sprite.width, sprite.height);
|
||||
this.shape = this.circle;
|
||||
}
|
||||
else if (type === 3)
|
||||
{
|
||||
this.tile = new Phaser.Physics.Ninja.Tile(system, sprite.x, sprite.y, sprite.width, sprite.height, id);
|
||||
this.shape = this.tile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body.
|
||||
*/
|
||||
this.velocity = new Phaser.Point();
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} drag - The drag applied to the motion of the Body.
|
||||
*/
|
||||
this.drag = new Phaser.Point();
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity.
|
||||
*/
|
||||
this.bounce = new Phaser.Point();
|
||||
|
||||
/**
|
||||
* @property {boolean} skipQuadTree - If the Body is an irregular shape you can set this to true to avoid it being added to any QuadTrees.
|
||||
* @default
|
||||
*/
|
||||
this.skipQuadTree = false;
|
||||
|
||||
/**
|
||||
* @property {number} facing - A const reference to the direction the Body is traveling or facing.
|
||||
* @default
|
||||
*/
|
||||
this.facing = Phaser.NONE;
|
||||
|
||||
/**
|
||||
* @property {boolean} immovable - An immovable Body will not receive any impacts from other bodies.
|
||||
* @default
|
||||
*/
|
||||
this.immovable = false;
|
||||
|
||||
/**
|
||||
* A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
|
||||
* @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
|
||||
*/
|
||||
this.collideWorldBounds = true;
|
||||
|
||||
/**
|
||||
* This object is populated with boolean values when the Body collides with another.
|
||||
* touching.up = true means the collision happened to the top of this Body for example.
|
||||
* @property {object} touching - An object containing touching results.
|
||||
*/
|
||||
this.touching = { none: true, up: false, down: false, left: false, right: false };
|
||||
|
||||
/**
|
||||
* This object is populated with previous touching values from the bodies previous collision.
|
||||
* @property {object} wasTouching - An object containing previous touching results.
|
||||
*/
|
||||
this.wasTouching = { none: true, up: false, down: false, left: false, right: false };
|
||||
|
||||
this.maxSpeed = 8;
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Ninja.Body.prototype = {
|
||||
|
||||
/**
|
||||
* Internal method.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.Body#updateBounds
|
||||
* @protected
|
||||
*/
|
||||
updateBounds: function (centerX, centerY, scaleX, scaleY) {
|
||||
|
||||
if (scaleX != this._sx || scaleY != this._sy)
|
||||
{
|
||||
// this.width = this.sourceWidth * scaleX;
|
||||
// this.height = this.sourceHeight * scaleY;
|
||||
// this.halfWidth = Math.floor(this.width / 2);
|
||||
// this.halfHeight = Math.floor(this.height / 2);
|
||||
// this._sx = scaleX;
|
||||
// this._sy = scaleY;
|
||||
// this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal method.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.Body#preUpdate
|
||||
* @protected
|
||||
*/
|
||||
preUpdate: function () {
|
||||
|
||||
// Store and reset collision flags
|
||||
this.wasTouching.none = this.touching.none;
|
||||
this.wasTouching.up = this.touching.up;
|
||||
this.wasTouching.down = this.touching.down;
|
||||
this.wasTouching.left = this.touching.left;
|
||||
this.wasTouching.right = this.touching.right;
|
||||
|
||||
this.touching.none = true;
|
||||
this.touching.up = false;
|
||||
this.touching.down = false;
|
||||
this.touching.left = false;
|
||||
this.touching.right = false;
|
||||
|
||||
this.shape.integrate();
|
||||
|
||||
if (this.collideWorldBounds)
|
||||
{
|
||||
this.shape.collideWorldBounds();
|
||||
}
|
||||
|
||||
this.speed = Math.sqrt(this.shape.velocity.x * this.shape.velocity.x + this.shape.velocity.y * this.shape.velocity.y);
|
||||
this.angle = Math.atan2(this.shape.velocity.y, this.shape.velocity.x);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal method.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.Body#postUpdate
|
||||
* @protected
|
||||
*/
|
||||
postUpdate: function () {
|
||||
|
||||
this.sprite.x = this.shape.pos.x;
|
||||
this.sprite.y = this.shape.pos.y;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops all movement of this body.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.Body#setZeroVelocity
|
||||
*/
|
||||
setZeroVelocity: function () {
|
||||
|
||||
this.shape.oldpos.x = this.shape.pos.x;
|
||||
this.shape.oldpos.y = this.shape.pos.y;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Moves the Body forwards based on its current angle and the given speed.
|
||||
* The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
|
||||
*
|
||||
* @method Phaser.Physics.Body#moveTo
|
||||
* @param {number} speed - The speed at which it should move forwards.
|
||||
* @param {number} angle - The angle in which it should move, given in degrees.
|
||||
*/
|
||||
moveTo: function (speed, angle) {
|
||||
|
||||
var magnitude = speed * this.game.time.physicsElapsed;
|
||||
var angle = this.game.math.degToRad(angle);
|
||||
|
||||
this.shape.pos.x = this.shape.oldpos.x + (magnitude * Math.cos(angle));
|
||||
this.shape.pos.y = this.shape.oldpos.y + (magnitude * Math.sin(angle));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Moves the Body backwards based on its current angle and the given speed.
|
||||
* The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
|
||||
*
|
||||
* @method Phaser.Physics.Body#moveBackward
|
||||
* @param {number} speed - The speed at which it should move backwards.
|
||||
* @param {number} angle - The angle in which it should move, given in degrees.
|
||||
*/
|
||||
moveFrom: function (speed, angle) {
|
||||
|
||||
var magnitude = -speed * this.game.time.physicsElapsed;
|
||||
var angle = this.game.math.degToRad(angle);
|
||||
|
||||
this.shape.pos.x = this.shape.oldpos.x + (magnitude * Math.cos(angle));
|
||||
this.shape.pos.y = this.shape.oldpos.y + (magnitude * Math.sin(angle));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* If this Body is dynamic then this will move it to the left by setting its x velocity to the given speed.
|
||||
* The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
|
||||
*
|
||||
* @method Phaser.Physics.Body#moveLeft
|
||||
* @param {number} speed - The speed at which it should move to the left, in pixels per second.
|
||||
*/
|
||||
moveLeft: function (speed) {
|
||||
|
||||
var fx = -speed * this.game.time.physicsElapsed;
|
||||
|
||||
this.shape.pos.x = this.shape.oldpos.x + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.x - this.shape.oldpos.x + fx));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* If this Body is dynamic then this will move it to the right by setting its x velocity to the given speed.
|
||||
* The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
|
||||
*
|
||||
* @method Phaser.Physics.Body#moveRight
|
||||
* @param {number} speed - The speed at which it should move to the right, in pixels per second.
|
||||
*/
|
||||
moveRight: function (speed) {
|
||||
|
||||
var fx = speed * this.game.time.physicsElapsed;
|
||||
|
||||
this.shape.pos.x = this.shape.oldpos.x + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.x - this.shape.oldpos.x + fx));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* If this Body is dynamic then this will move it up by setting its y velocity to the given speed.
|
||||
* The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
|
||||
*
|
||||
* @method Phaser.Physics.Body#moveUp
|
||||
* @param {number} speed - The speed at which it should move up, in pixels per second.
|
||||
*/
|
||||
moveUp: function (speed) {
|
||||
|
||||
var fx = -speed * this.game.time.physicsElapsed;
|
||||
|
||||
this.shape.pos.y = this.shape.oldpos.y + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.y - this.shape.oldpos.y + fx));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* If this Body is dynamic then this will move it down by setting its y velocity to the given speed.
|
||||
* The speed is represented in pixels per second. So a value of 100 would move 100 pixels in 1 second (1000ms).
|
||||
*
|
||||
* @method Phaser.Physics.Body#moveDown
|
||||
* @param {number} speed - The speed at which it should move down, in pixels per second.
|
||||
*/
|
||||
moveDown: function (speed) {
|
||||
|
||||
var fx = speed * this.game.time.physicsElapsed;
|
||||
|
||||
this.shape.pos.y = this.shape.oldpos.y + Math.min(this.maxSpeed, Math.max(-this.maxSpeed, this.shape.pos.y - this.shape.oldpos.y + fx));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets all Body values (velocity, acceleration, rotation, etc)
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.Body#reset
|
||||
*/
|
||||
reset: function () {
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Body#x
|
||||
* @property {number} x - The x position.
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "x", {
|
||||
|
||||
/**
|
||||
* The x position.
|
||||
* @method x
|
||||
* @return {number}
|
||||
*/
|
||||
get: function () {
|
||||
return this.shape.pos.x;
|
||||
},
|
||||
|
||||
/**
|
||||
* The x position.
|
||||
* @method x
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
this.shape.pos.x = value;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Body#y
|
||||
* @property {number} y - The y position.
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "y", {
|
||||
|
||||
/**
|
||||
* The y position.
|
||||
* @method y
|
||||
* @return {number}
|
||||
*/
|
||||
get: function () {
|
||||
return this.shape.pos.y;
|
||||
},
|
||||
|
||||
/**
|
||||
* The y position.
|
||||
* @method y
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
this.shape.pos.y = value;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Body#bottom
|
||||
* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "bottom", {
|
||||
|
||||
/**
|
||||
* The sum of the y and height properties.
|
||||
* @method bottom
|
||||
* @return {number}
|
||||
* @readonly
|
||||
*/
|
||||
get: function () {
|
||||
return this.shape.pos.y + this.shape.height;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Body#right
|
||||
* @property {number} right - The right value of this Body (same as Body.x + Body.width)
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Body.prototype, "right", {
|
||||
|
||||
/**
|
||||
* The sum of the x and width properties.
|
||||
* @method right
|
||||
* @return {number}
|
||||
* @readonly
|
||||
*/
|
||||
get: function () {
|
||||
return this.shape.pos.x + this.shape.width;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ninja Physics Circle constructor.
|
||||
*
|
||||
* @class Phaser.Physics.Ninja.Circle
|
||||
* @classdesc Arcade Physics Constructor
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game reference to the current game instance.
|
||||
*/
|
||||
Phaser.Physics.Ninja.Circle = function (system, x, y, width, height) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,616 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ninja Physics Tile constructor.
|
||||
*
|
||||
* @class Phaser.Physics.Ninja.Tile
|
||||
* @classdesc Arcade Physics Constructor
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game reference to the current game instance.
|
||||
*/
|
||||
Phaser.Physics.Ninja.Tile = function (system, x, y, width, height, type) {
|
||||
|
||||
if (typeof type === 'undefined') { type = Phaser.Physics.Ninja.Tile.EMPTY; }
|
||||
|
||||
this.system = system;
|
||||
|
||||
this.id = type;
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY;
|
||||
|
||||
this.pos = new Phaser.Point(x, y);
|
||||
this.oldpos = new Phaser.Point(x, y);
|
||||
|
||||
if (this.id > 1 && this.id < 30)
|
||||
{
|
||||
// Tile Types 2 to 29 require square tile dimensions, so use the width as the base
|
||||
height = width;
|
||||
}
|
||||
|
||||
this.xw = Math.abs(width / 2);
|
||||
this.yw = Math.abs(height / 2);
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.drag = 1;
|
||||
this.friction = 0.05;
|
||||
this.gravityScale = 1;
|
||||
this.bounce = 0.3;
|
||||
this.velocity = new Phaser.Point();
|
||||
|
||||
// This stores tile-specific collision information
|
||||
this.signx = 0;
|
||||
this.signy = 0;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
|
||||
if (this.id > 0)
|
||||
{
|
||||
this.setType(this.id);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Ninja.Tile.prototype.constructor = Phaser.Physics.Ninja.Tile;
|
||||
|
||||
Phaser.Physics.Ninja.Tile.prototype = {
|
||||
|
||||
/**
|
||||
* Updates this AABBs position.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja.AABB#integrate
|
||||
*/
|
||||
integrate: function () {
|
||||
|
||||
var px = this.pos.x;
|
||||
var py = this.pos.y;
|
||||
|
||||
this.pos.x += (this.drag * this.pos.x) - (this.drag * this.oldpos.x);
|
||||
this.pos.y += (this.drag * this.pos.y) - (this.drag * this.oldpos.y);
|
||||
|
||||
this.velocity.set(this.pos.x - px, this.pos.y - py);
|
||||
this.oldpos.set(px, py);
|
||||
|
||||
},
|
||||
|
||||
collideWorldBounds: function () {
|
||||
},
|
||||
|
||||
//these functions are used to update the cell
|
||||
//note: id is assumed to NOT be "empty" state..
|
||||
//if it IS the empty state, the tile clears itself
|
||||
setType: function (id) {
|
||||
|
||||
if (id === Phaser.Physics.Ninja.Tile.EMPTY)
|
||||
{
|
||||
this.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
//set tile state to a non-emtpy value, and update it's edges and those of the neighbors
|
||||
this.id = id;
|
||||
this.updateType();
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
|
||||
this.id = Phaser.Physics.Ninja.Tile.EMPTY;
|
||||
this.updateType();
|
||||
|
||||
},
|
||||
|
||||
render: function (context, key) {
|
||||
|
||||
if (this.id === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var image = this.system.game.cache.getImage(key);
|
||||
var data = this.system.game.cache.getFrameData(key);
|
||||
var frame = data._frames[this.id - 1];
|
||||
|
||||
context.drawImage(image, frame.x, frame.y, frame.width, frame.height, this.x, this.y, this.width, this.height);
|
||||
|
||||
// context.beginPath();
|
||||
// context.strokeStyle = 'rgb(255,255,0)';
|
||||
// context.strokeRect(this.x, this.y, this.width, this.height);
|
||||
// context.strokeRect(this.pos.x, this.pos.y, 2, 2); // center point
|
||||
// context.closePath();
|
||||
|
||||
},
|
||||
|
||||
//this converts a tile from implicitly-defined (via id), to explicit (via properties)
|
||||
updateType: function () {
|
||||
|
||||
if (this.id === 0)
|
||||
{
|
||||
//EMPTY
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_EMPTY;
|
||||
this.signx = 0;
|
||||
this.signy = 0;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//tile is non-empty; collide
|
||||
if (this.id < Phaser.Physics.Ninja.Tile.TYPE_45DEG)
|
||||
{
|
||||
//FULL
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_FULL;
|
||||
this.signx = 0;
|
||||
this.signy = 0;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONCAVE)
|
||||
{
|
||||
// 45deg
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_45DEG;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = -1;
|
||||
this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
|
||||
this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = -1;
|
||||
this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
|
||||
this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 1;
|
||||
this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
|
||||
this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 1;
|
||||
this.sx = this.signx / Math.SQRT2;//get slope _unit_ normal
|
||||
this.sy = this.signy / Math.SQRT2;//since normal is (1,-1), length is sqrt(1*1 + -1*-1) = sqrt(2)
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_CONVEX)
|
||||
{
|
||||
// Concave
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_CONCAVE;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpn)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = -1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnn)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = -1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEnp)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.CONCAVEpp)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGs)
|
||||
{
|
||||
// Convex
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_CONVEX;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpn)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = -1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnn)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = -1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXnp)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.CONVEXpp)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 1;
|
||||
this.sx = 0;
|
||||
this.sy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_22DEGb)
|
||||
{
|
||||
// 22deg small
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGs;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGs)
|
||||
{
|
||||
// 22deg big
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_22DEGb;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 1) / slen;
|
||||
this.sy = (this.signy * 2) / slen;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_67DEGb)
|
||||
{
|
||||
// 67deg small
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGs;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (this.id < Phaser.Physics.Ninja.Tile.TYPE_HALF)
|
||||
{
|
||||
// 67deg big
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_67DEGb;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = -1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 1;
|
||||
var slen = Math.sqrt(2 * 2 + 1 * 1);
|
||||
this.sx = (this.signx * 2) / slen;
|
||||
this.sy = (this.signy * 1) / slen;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Half-full tile
|
||||
this.type = Phaser.Physics.Ninja.Tile.TYPE_HALF;
|
||||
|
||||
if (this.id == Phaser.Physics.Ninja.Tile.HALFd)
|
||||
{
|
||||
this.signx = 0;
|
||||
this.signy = -1;
|
||||
this.sx = this.signx;
|
||||
this.sy = this.signy;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.HALFu)
|
||||
{
|
||||
this.signx = 0;
|
||||
this.signy = 1;
|
||||
this.sx = this.signx;
|
||||
this.sy = this.signy;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.HALFl)
|
||||
{
|
||||
this.signx = 1;
|
||||
this.signy = 0;
|
||||
this.sx = this.signx;
|
||||
this.sy = this.signy;
|
||||
}
|
||||
else if (this.id == Phaser.Physics.Ninja.Tile.HALFr)
|
||||
{
|
||||
this.signx = -1;
|
||||
this.signy = 0;
|
||||
this.sx = this.signx;
|
||||
this.sy = this.signy;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Tile#x
|
||||
* @property {number} x - The x position.
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "x", {
|
||||
|
||||
/**
|
||||
* The x position.
|
||||
* @method x
|
||||
* @return {number}
|
||||
*/
|
||||
get: function () {
|
||||
return this.pos.x - this.xw;
|
||||
},
|
||||
|
||||
/**
|
||||
* The x position.
|
||||
* @method x
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
this.pos.x = value;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Tile#y
|
||||
* @property {number} y - The y position.
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "y", {
|
||||
|
||||
/**
|
||||
* The y position.
|
||||
* @method y
|
||||
* @return {number}
|
||||
*/
|
||||
get: function () {
|
||||
return this.pos.y - this.yw;
|
||||
},
|
||||
|
||||
/**
|
||||
* The y position.
|
||||
* @method y
|
||||
* @param {number} value
|
||||
*/
|
||||
set: function (value) {
|
||||
this.pos.y = value;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Tile#bottom
|
||||
* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "bottom", {
|
||||
|
||||
/**
|
||||
* The sum of the y and height properties.
|
||||
* @method bottom
|
||||
* @return {number}
|
||||
* @readonly
|
||||
*/
|
||||
get: function () {
|
||||
return this.pos.y + this.yw;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Physics.Ninja.Tile#right
|
||||
* @property {number} right - The right value of this Body (same as Body.x + Body.width)
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Physics.Ninja.Tile.prototype, "right", {
|
||||
|
||||
/**
|
||||
* The sum of the x and width properties.
|
||||
* @method right
|
||||
* @return {number}
|
||||
* @readonly
|
||||
*/
|
||||
get: function () {
|
||||
return this.pos.x + this.xw;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// TILETYPE ENUMERATION
|
||||
Phaser.Physics.Ninja.Tile.EMPTY = 0;
|
||||
Phaser.Physics.Ninja.Tile.FULL = 1;//fullAABB tile
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn = 2;//45-degree triangle, whose normal is (+ve,-ve)
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_45DEGnn = 3;//(+ve,+ve)
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_45DEGnp = 4;//(-ve,+ve)
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_45DEGpp = 5;//(-ve,-ve)
|
||||
Phaser.Physics.Ninja.Tile.CONCAVEpn = 6;//1/4-circle cutout
|
||||
Phaser.Physics.Ninja.Tile.CONCAVEnn = 7;
|
||||
Phaser.Physics.Ninja.Tile.CONCAVEnp = 8;
|
||||
Phaser.Physics.Ninja.Tile.CONCAVEpp = 9;
|
||||
Phaser.Physics.Ninja.Tile.CONVEXpn = 10;//1/4/circle
|
||||
Phaser.Physics.Ninja.Tile.CONVEXnn = 11;
|
||||
Phaser.Physics.Ninja.Tile.CONVEXnp = 12;
|
||||
Phaser.Physics.Ninja.Tile.CONVEXpp = 13;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnS = 14;//22.5 degree slope
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnS = 15;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpS = 16;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGppS = 17;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGpnB = 18;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnnB = 19;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGnpB = 20;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_22DEGppB = 21;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnS = 22;//67.5 degree slope
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnS = 23;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpS = 24;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGppS = 25;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGpnB = 26;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnnB = 27;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGnpB = 28;
|
||||
Phaser.Physics.Ninja.Tile.SLOPE_67DEGppB = 29;
|
||||
Phaser.Physics.Ninja.Tile.HALFd = 30;//half-full tiles
|
||||
Phaser.Physics.Ninja.Tile.HALFr = 31;
|
||||
Phaser.Physics.Ninja.Tile.HALFu = 32;
|
||||
Phaser.Physics.Ninja.Tile.HALFl = 33;
|
||||
|
||||
//collision shape "types"
|
||||
Phaser.Physics.Ninja.Tile.TYPE_EMPTY = 0;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_FULL = 1;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_45DEG = 2;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_CONCAVE = 6;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_CONVEX = 10;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_22DEGs = 14;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_22DEGb = 18;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_67DEGs = 22;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_67DEGb = 26;
|
||||
Phaser.Physics.Ninja.Tile.TYPE_HALF = 30;
|
||||
@@ -0,0 +1,449 @@
|
||||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2014 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ninja Physics constructor.
|
||||
*
|
||||
* @class Phaser.Physics.Ninja
|
||||
* @classdesc Arcade Physics Constructor
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game reference to the current game instance.
|
||||
*/
|
||||
Phaser.Physics.Ninja = function (game) {
|
||||
|
||||
/**
|
||||
* @property {Phaser.Game} game - Local reference to game.
|
||||
*/
|
||||
this.game = game;
|
||||
|
||||
this.time = this.game.time;
|
||||
|
||||
/**
|
||||
* @property {number} gravity - The World gravity setting.
|
||||
*/
|
||||
this.gravity = 0.2;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Rectangle} bounds - The bounds inside of which the physics world exists. Defaults to match the world bounds.
|
||||
*/
|
||||
this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height);
|
||||
|
||||
/**
|
||||
* @property {Phaser.QuadTree} quadTree - The world QuadTree.
|
||||
*/
|
||||
// this.quadTree = new Phaser.Physics.Ninja.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
|
||||
|
||||
/**
|
||||
* @property {Array} _mapData - Internal cache var.
|
||||
* @private
|
||||
*/
|
||||
this._mapData = [];
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.Ninja.prototype.constructor = Phaser.Physics.Ninja;
|
||||
|
||||
Phaser.Physics.Ninja.prototype = {
|
||||
|
||||
/**
|
||||
* This will create a Ninja Physics AABB body on the given game object. Its dimensions will match the width and height of the object at the point it is created.
|
||||
* A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja#enableAABB
|
||||
* @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array.
|
||||
*/
|
||||
enableAABB: function (object) {
|
||||
|
||||
this.enable(object, 1);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* This will create a Ninja Physics Circle body on the given game object.
|
||||
* A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja#enableCircle
|
||||
* @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array.
|
||||
* @param {number} radius - The radius of the Circle.
|
||||
*/
|
||||
enableCircle: function (object, radius) {
|
||||
|
||||
this.enable(object, 2, 0, radius);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* This will create a Ninja Physics Tile body on the given game object. There are 34 different types of tile you can create, including 45 degree slopes,
|
||||
* convex and concave circles and more. The id parameter controls which Tile type is created, but you can also change it at run-time.
|
||||
* Note that for all degree based tile types they need to have an equal width and height. If the given object doesn't have equal width and height it will use the width.
|
||||
* A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja#enableTile
|
||||
* @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array.
|
||||
* @param {number} radius - The radius of the Circle.
|
||||
*/
|
||||
enableTile: function (object, id) {
|
||||
|
||||
this.enable(object, 3, id);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* This will create a Ninja Physics Tile body on the given game object. There are 34 different types of tile you can create, including 45 degree slopes,
|
||||
* convex and concave circles and more. The id parameter controls which Tile type is created, but you can also change it at run-time.
|
||||
* Note that for all degree based tile types they need to have an equal width and height. If the given object doesn't have equal width and height it will use the width.
|
||||
* A game object can only have 1 physics body active at any one time, and it can't be changed until the object is destroyed.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja#enable
|
||||
* @param {object|array} object - The game object to create the physics body on. Can also be an array of objects, a body will be created on every object in the array.
|
||||
* @param {number} [type=1] - The type of Ninja shape to create. 1 = AABB, 2 = Circle or 3 = Tile.
|
||||
* @param {number} [id=1] - If this body is using a Tile shape, you can set the Tile id here, i.e. Phaser.Physics.Ninja.Tile.SLOPE_45DEGpn, Phaser.Physics.Ninja.Tile.CONVEXpp, etc.
|
||||
* @param {number} [radius=0] - If this body is using a Circle shape this controls the radius.
|
||||
*/
|
||||
enable: function (object, type, id, radius) {
|
||||
|
||||
if (typeof type === 'undefined') { type = 1; }
|
||||
if (typeof id === 'undefined') { id = 1; }
|
||||
|
||||
var i = 1;
|
||||
|
||||
if (Array.isArray(object))
|
||||
{
|
||||
// Add to Group
|
||||
i = object.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
object = [object];
|
||||
}
|
||||
|
||||
while (i--)
|
||||
{
|
||||
if (object[i].body === null)
|
||||
{
|
||||
object[i].body = new Phaser.Physics.Ninja.Body(this, object[i], type, id);
|
||||
object[i].anchor.set(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Called automatically by a Physics body, it updates all motion related values on the Body.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja#updateMotion
|
||||
* @param {Phaser.Physics.Ninja.Body} The Body object to be updated.
|
||||
*/
|
||||
update: function () {
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks for overlaps between two game objects. The objects can be Sprites, Groups or Emitters.
|
||||
* You can perform Sprite vs. Sprite, Sprite vs. Group and Group vs. Group overlap checks.
|
||||
* Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.
|
||||
* The second parameter can be an array of objects, of differing types.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#overlap
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
|
||||
* @param {function} [overlapCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then overlapCallback will only be called if processCallback returns true.
|
||||
* @param {object} [callbackContext] - The context in which to run the callbacks.
|
||||
* @returns {boolean} True if an overlap occured otherwise false.
|
||||
*/
|
||||
overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) {
|
||||
|
||||
overlapCallback = overlapCallback || null;
|
||||
processCallback = processCallback || null;
|
||||
callbackContext = callbackContext || overlapCallback;
|
||||
|
||||
this._result = false;
|
||||
this._total = 0;
|
||||
|
||||
if (Array.isArray(object2))
|
||||
{
|
||||
for (var i = 0, len = object2.length; i < len; i++)
|
||||
{
|
||||
this.collideHandler(object1, object2[i], overlapCallback, processCallback, callbackContext, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true);
|
||||
}
|
||||
|
||||
return (this._total > 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.
|
||||
* The second parameter can be an array of objects, of differing types.
|
||||
* The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead.
|
||||
* An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place,
|
||||
* giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped.
|
||||
* The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called.
|
||||
*
|
||||
* @method Phaser.Physics.Ninja#collide
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.
|
||||
* @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {object} [callbackContext] - The context in which to run the callbacks.
|
||||
* @returns {boolean} True if a collision occured otherwise false.
|
||||
*/
|
||||
collide: function (object1, object2, collideCallback, processCallback, callbackContext) {
|
||||
|
||||
collideCallback = collideCallback || null;
|
||||
processCallback = processCallback || null;
|
||||
callbackContext = callbackContext || collideCallback;
|
||||
|
||||
this._result = false;
|
||||
this._total = 0;
|
||||
|
||||
if (Array.isArray(object2))
|
||||
{
|
||||
for (var i = 0, len = object2.length; i < len; i++)
|
||||
{
|
||||
this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false);
|
||||
}
|
||||
|
||||
return (this._total > 0);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal collision handler.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#collideHandler
|
||||
* @private
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
|
||||
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. Can also be an array of objects to check.
|
||||
* @param {function} collideCallback - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {function} processCallback - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
|
||||
* @param {object} callbackContext - The context in which to run the callbacks.
|
||||
* @param {boolean} overlapOnly - Just run an overlap or a full collision.
|
||||
*/
|
||||
collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) {
|
||||
|
||||
// Only collide valid objects
|
||||
if (typeof object2 === 'undefined' && (object1.type === Phaser.GROUP || object1.type === Phaser.EMITTER))
|
||||
{
|
||||
this.collideGroupVsSelf(object1, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
return;
|
||||
}
|
||||
|
||||
if (object1 && object2 && object1.exists && object2.exists)
|
||||
{
|
||||
// SPRITES
|
||||
if (object1.type == Phaser.SPRITE || object1.type == Phaser.TILESPRITE)
|
||||
{
|
||||
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
|
||||
{
|
||||
this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
|
||||
{
|
||||
this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
else if (object2.type == Phaser.TILEMAPLAYER)
|
||||
{
|
||||
this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
|
||||
}
|
||||
}
|
||||
// GROUPS
|
||||
else if (object1.type == Phaser.GROUP)
|
||||
{
|
||||
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
|
||||
{
|
||||
this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
|
||||
{
|
||||
this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
else if (object2.type == Phaser.TILEMAPLAYER)
|
||||
{
|
||||
this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
|
||||
}
|
||||
}
|
||||
// TILEMAP LAYERS
|
||||
else if (object1.type == Phaser.TILEMAPLAYER)
|
||||
{
|
||||
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
|
||||
{
|
||||
this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
|
||||
}
|
||||
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
|
||||
{
|
||||
this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
|
||||
}
|
||||
}
|
||||
// EMITTER
|
||||
else if (object1.type == Phaser.EMITTER)
|
||||
{
|
||||
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
|
||||
{
|
||||
this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
|
||||
{
|
||||
this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
else if (object2.type == Phaser.TILEMAPLAYER)
|
||||
{
|
||||
this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* An internal function. Use Phaser.Physics.Arcade.collide instead.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#collideSpriteVsSprite
|
||||
* @private
|
||||
*/
|
||||
collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) {
|
||||
|
||||
if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly))
|
||||
{
|
||||
if (collideCallback)
|
||||
{
|
||||
collideCallback.call(callbackContext, sprite1, sprite2);
|
||||
}
|
||||
|
||||
this._total++;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* An internal function. Use Phaser.Physics.Arcade.collide instead.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#collideSpriteVsGroup
|
||||
* @private
|
||||
*/
|
||||
collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) {
|
||||
|
||||
if (group.length === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// What is the sprite colliding with in the quadtree?
|
||||
// this.quadTree.clear();
|
||||
|
||||
// this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
|
||||
|
||||
// this.quadTree.populate(group);
|
||||
|
||||
// this._potentials = this.quadTree.retrieve(sprite);
|
||||
|
||||
for (var i = 0, len = group.children.length; i < len; i++)
|
||||
{
|
||||
// We have our potential suspects, are they in this group?
|
||||
if (group.children[i].exists && group.children[i].body && this.separate(sprite.body, group.children[i].body, processCallback, callbackContext, overlapOnly))
|
||||
{
|
||||
if (collideCallback)
|
||||
{
|
||||
collideCallback.call(callbackContext, sprite, group.children[i]);
|
||||
}
|
||||
|
||||
this._total++;
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* An internal function. Use Phaser.Physics.Arcade.collide instead.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#collideGroupVsSelf
|
||||
* @private
|
||||
*/
|
||||
collideGroupVsSelf: function (group, collideCallback, processCallback, callbackContext, overlapOnly) {
|
||||
|
||||
if (group.length === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var len = group.children.length;
|
||||
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
for (var j = i + 1; j <= len; j++)
|
||||
{
|
||||
if (group.children[i] && group.children[j] && group.children[i].exists && group.children[j].exists)
|
||||
{
|
||||
this.collideSpriteVsSprite(group.children[i], group.children[j], collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* An internal function. Use Phaser.Physics.Arcade.collide instead.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#collideGroupVsGroup
|
||||
* @private
|
||||
*/
|
||||
collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) {
|
||||
|
||||
if (group1.length === 0 || group2.length === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0, len = group1.children.length; i < len; i++)
|
||||
{
|
||||
if (group1.children[i].exists)
|
||||
{
|
||||
this.collideSpriteVsGroup(group1.children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The core separation function to separate two physics bodies.
|
||||
* @method Phaser.Physics.Arcade#separate
|
||||
* @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
|
||||
* @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
|
||||
* @param {function} [processCallback=null] - UN-USED: A callback function that lets you perform additional checks against the two objects if they overlap. If this function is set then the sprites will only be collided if it returns true.
|
||||
* @param {object} [callbackContext] - UN-USED: The context in which to run the process callback.
|
||||
* @returns {boolean} Returns true if the bodies collided, otherwise false.
|
||||
*/
|
||||
separate: function (body1, body2, processCallback, callbackContext, overlapOnly) {
|
||||
|
||||
if (body1.type !== Phaser.Physics.NINJA || body2.type !== Phaser.Physics.NINJA)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (body1.aabb && body2.tile)
|
||||
{
|
||||
return body1.aabb.collideAABBVsTile(body2.tile);
|
||||
}
|
||||
|
||||
if (body1.tile && body2.aabb)
|
||||
{
|
||||
return body2.aabb.collideAABBVsTile(body1.tile);
|
||||
}
|
||||
|
||||
// circles next
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
@@ -37,6 +37,11 @@ Phaser.Physics.Body = function (game, sprite, x, y, mass) {
|
||||
*/
|
||||
this.sprite = sprite;
|
||||
|
||||
/**
|
||||
* @property {number} type - The type of physics system this body belongs to.
|
||||
*/
|
||||
this.type = Phaser.Physics.P2;
|
||||
|
||||
/**
|
||||
* @property {Phaser.Point} offset - The offset of the Physics Body from the Sprite x/y position.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,16 @@ Phaser.Tile = function (layer, index, x, y, width, height) {
|
||||
*/
|
||||
this.y = y;
|
||||
|
||||
/**
|
||||
* @property {number} x - The x map coordinate of this tile.
|
||||
*/
|
||||
this.worldX = x * width;
|
||||
|
||||
/**
|
||||
* @property {number} y - The y map coordinate of this tile.
|
||||
*/
|
||||
this.worldY = y * height;
|
||||
|
||||
/**
|
||||
* @property {number} width - The width of the tile in pixels.
|
||||
*/
|
||||
@@ -49,6 +59,16 @@ Phaser.Tile = function (layer, index, x, y, width, height) {
|
||||
*/
|
||||
this.height = height;
|
||||
|
||||
/**
|
||||
* @property {number} width - The width of the tile in pixels.
|
||||
*/
|
||||
this.centerX = Math.abs(width / 2);
|
||||
|
||||
/**
|
||||
* @property {number} height - The height of the tile in pixels.
|
||||
*/
|
||||
this.centerY = Math.abs(height / 2);
|
||||
|
||||
/**
|
||||
* @property {number} alpha - The alpha value at which this tile is drawn to the canvas.
|
||||
*/
|
||||
@@ -135,6 +155,32 @@ Phaser.Tile = function (layer, index, x, y, width, height) {
|
||||
|
||||
Phaser.Tile.prototype = {
|
||||
|
||||
intersects: function (x, y, right, bottom) {
|
||||
|
||||
if (right <= this.worldX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bottom <= this.worldY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x >= this.worldX + this.width)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (y >= this.worldY + this.height)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a callback to be called when this tile is hit by an object.
|
||||
* The callback must true true for collision processing to take place.
|
||||
|
||||
@@ -454,6 +454,93 @@ Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) {
|
||||
|
||||
}
|
||||
|
||||
Phaser.TilemapLayer.prototype.getIntersectingTiles = function (x, y, width, height) {
|
||||
|
||||
// var tiles = this.getTiles(x, y, width,height, true);
|
||||
var tiles = this.getTiles(x, y, width,height, false);
|
||||
|
||||
var right = x + width;
|
||||
var bottom = y + height;
|
||||
|
||||
// We only want the ones that we actually intersect with
|
||||
var i = tiles.length;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
if (tiles[i].intersects(x, y, right, bottom))
|
||||
{
|
||||
// tiles[i].debug = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// console.log('sliced off tile', i);
|
||||
// tiles.pop();
|
||||
}
|
||||
}
|
||||
|
||||
return tiles;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Phaser.TilemapLayer.prototype.getTilesX = function (x, y, width, height, collides) {
|
||||
|
||||
// Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all)
|
||||
if (typeof collides === 'undefined') { collides = false; }
|
||||
|
||||
// adjust the x,y coordinates for scrollFactor
|
||||
x = this._fixX(x);
|
||||
y = this._fixY(y);
|
||||
|
||||
if (width > this.layer.widthInPixels)
|
||||
{
|
||||
width = this.layer.widthInPixels;
|
||||
}
|
||||
|
||||
if (height > this.layer.heightInPixels)
|
||||
{
|
||||
height = this.layer.heightInPixels;
|
||||
}
|
||||
|
||||
// Convert the pixel values into tile coordinates
|
||||
// this._tx = this.game.math.snapToFloor(x, this._cw) / this._cw;
|
||||
// this._ty = this.game.math.snapToFloor(y, this._ch) / this._ch;
|
||||
// this._tw = (this.game.math.snapToCeil(width, this._cw) + this._cw) / this._cw;
|
||||
// this._th = (this.game.math.snapToCeil(height, this._ch) + this._ch) / this._ch;
|
||||
|
||||
// var firstTileX = Math.max( Math.floor(res.pos.x / this.tilesize), 0 );
|
||||
// var lastTileX = Math.min( Math.ceil((res.pos.x + width) / this.tilesize), this.width );
|
||||
// var tileY = Math.floor( (res.pos.y + pxOffsetY) / this.tilesize );
|
||||
|
||||
this._tx = Math.max(Math.floor(x / this.tileWidth), 0);
|
||||
this._tw = Math.min(Math.ceil((x + width) / this.tileWidth), this.width);
|
||||
this._ty = Math.floor((y + px) / this.tileHeight);
|
||||
|
||||
this._results.length = 0;
|
||||
|
||||
for (var wy = this._ty; wy < this._ty + this._th; wy++)
|
||||
{
|
||||
for (var wx = this._tx; wx < this._tx + this._tw; wx++)
|
||||
{
|
||||
if (this.layer.data[wy] && this.layer.data[wy][wx])
|
||||
{
|
||||
if (collides === false || (collides && this.layer.data[wy][wx].canCollide))
|
||||
{
|
||||
this._results.push(this.layer.data[wy][wx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG ONLY - REMOVE
|
||||
this.layer.dirty = true;
|
||||
|
||||
return this._results;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Get all tiles that exist within the given area, defined by the top-left corner, width and height. Values given are in pixels, not tiles.
|
||||
* @method Phaser.TilemapLayer#getTiles
|
||||
@@ -491,7 +578,8 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
|
||||
this._th = (this.game.math.snapToCeil(height, this._ch) + this._ch) / this._ch;
|
||||
|
||||
// This should apply the layer x/y here
|
||||
this._results.length = 0;
|
||||
// this._results.length = 0;
|
||||
this._results = [];
|
||||
|
||||
for (var wy = this._ty; wy < this._ty + this._th; wy++)
|
||||
{
|
||||
@@ -501,6 +589,7 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
|
||||
{
|
||||
if (collides === false || (collides && this.layer.data[wy][wx].canCollide))
|
||||
{
|
||||
/*
|
||||
// Convert tile coordinates back to camera space for return
|
||||
var _wx = this._unfixX(wx * this._cw) / this._cw;
|
||||
var _wy = this._unfixY(wy * this._ch) / this._ch;
|
||||
@@ -513,11 +602,18 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
|
||||
tile: this.layer.data[wy][wx],
|
||||
layer: this.layer.data[wy][wx].layer
|
||||
});
|
||||
*/
|
||||
|
||||
this._results.push(this.layer.data[wy][wx]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG ONLY - REMOVE
|
||||
this.layer.dirty = true;
|
||||
|
||||
return this._results;
|
||||
|
||||
}
|
||||
|
||||
@@ -227,6 +227,7 @@ Phaser.Time.prototype = {
|
||||
this.timeToCall = this.game.math.max(0, 16 - (time - this.lastTime));
|
||||
|
||||
this.elapsed = this.now - this.time;
|
||||
this.physicsElapsed = this.elapsed / 1000;
|
||||
|
||||
if (this.advancedTiming)
|
||||
{
|
||||
@@ -248,8 +249,6 @@ Phaser.Time.prototype = {
|
||||
this.time = this.now;
|
||||
this.lastTime = time + this.timeToCall;
|
||||
|
||||
this.physicsElapsed = 1.0 * (this.elapsed / 1000);
|
||||
|
||||
// Paused but still running?
|
||||
if (!this.game.paused)
|
||||
{
|
||||
|
||||
@@ -518,33 +518,35 @@ Phaser.Utils.Debug.prototype = {
|
||||
* @param {Phaser.Rectangle|Phaser.Circle|Phaser.Point|Phaser.Line} object - The geometry object to render.
|
||||
* @param {string} [color] - Color of the debug info to be rendered (format is css color string).
|
||||
* @param {boolean} [filled=true] - Render the objected as a filled (default, true) or a stroked (false)
|
||||
* @param {number} [forceType=0] - Force rendering of a specific type. If 0 no type will be forced, otherwise 1 = Rectangle, 2 = Circle, 3 = Point and 4 = Line.
|
||||
*/
|
||||
geom: function (object, color, filled) {
|
||||
geom: function (object, color, filled, forceType) {
|
||||
|
||||
if (typeof filled === 'undefined') { filled = true; }
|
||||
if (typeof forceType === 'undefined') { forceType = 0; }
|
||||
|
||||
color = color || 'rgba(0,255,0,0.3)';
|
||||
color = color || 'rgba(0,255,0,0.4)';
|
||||
|
||||
this.start();
|
||||
|
||||
this.context.fillStyle = color;
|
||||
this.context.strokeStyle = color;
|
||||
|
||||
if (object instanceof Phaser.Rectangle)
|
||||
if (object instanceof Phaser.Rectangle || forceType === 1)
|
||||
{
|
||||
if (filled)
|
||||
{
|
||||
this.context.fillRect(object.x, object.y, object.width, object.height);
|
||||
this.context.fillRect(object.x - this.game.camera.x, object.y - this.game.camera.y, object.width, object.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.context.strokeRect(object.x, object.y, object.width, object.height);
|
||||
this.context.strokeRect(object.x - this.game.camera.x, object.y - this.game.camera.y, object.width, object.height);
|
||||
}
|
||||
}
|
||||
else if (object instanceof Phaser.Circle)
|
||||
else if (object instanceof Phaser.Circle || forceType === 2)
|
||||
{
|
||||
this.context.beginPath();
|
||||
this.context.arc(object.x, object.y, object.radius, 0, Math.PI * 2, false);
|
||||
this.context.arc(object.x - this.game.camera.x, object.y - this.game.camera.y, object.radius, 0, Math.PI * 2, false);
|
||||
this.context.closePath();
|
||||
|
||||
if (filled)
|
||||
@@ -556,16 +558,16 @@ Phaser.Utils.Debug.prototype = {
|
||||
this.context.stroke();
|
||||
}
|
||||
}
|
||||
else if (object instanceof Phaser.Point)
|
||||
else if (object instanceof Phaser.Point || forceType === 3)
|
||||
{
|
||||
this.context.fillRect(object.x, object.y, 4, 4);
|
||||
this.context.fillRect(object.x - this.game.camera.x, object.y - this.game.camera.y, 4, 4);
|
||||
}
|
||||
else if (object instanceof Phaser.Line)
|
||||
else if (object instanceof Phaser.Line || forceType === 4)
|
||||
{
|
||||
this.context.lineWidth = 1;
|
||||
this.context.beginPath();
|
||||
this.context.moveTo(object.start.x + 0.5, object.start.y + 0.5);
|
||||
this.context.lineTo(object.end.x + 0.5, object.end.y + 0.5);
|
||||
this.context.moveTo((object.start.x + 0.5) - this.game.camera.x, (object.start.y + 0.5) - this.game.camera.y);
|
||||
this.context.lineTo((object.end.x + 0.5) - this.game.camera.x, (object.end.y + 0.5) - this.game.camera.y);
|
||||
this.context.closePath();
|
||||
this.context.stroke();
|
||||
}
|
||||
|
||||