Disabled World bounds by default.

Body.collides now takes a group level callback.
Added Body.createBodyCallback and Body.createGroupCallback.
This commit is contained in:
photonstorm
2014-02-19 05:22:37 +00:00
parent f6807e23c6
commit d9080052c3
5 changed files with 279 additions and 40 deletions
+9
View File
@@ -46,6 +46,7 @@ function create() {
box.physicsEnabled = true;
box.body.static = true;
box.body.fixedRotation = true;
box.body.createBodyCallback(player.body, gotBox, this);
}
cursors = game.input.keyboard.createCursorKeys();
@@ -53,6 +54,14 @@ function create() {
}
function gotBox(body1, body2, shape1, shape2) {
console.log('gotBox');
body1.sprite.kill();
}
function update() {
if (cursors.left.isDown)
+141
View File
@@ -0,0 +1,141 @@
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
game.load.spritesheet('dude', 'assets/games/starstruck/dude.png', 32, 48);
game.load.image('background', 'assets/games/starstruck/background2.png');
game.load.image('box', 'assets/sprites/block.png');
}
var player;
var facing = 'left';
var jumpTimer = 0;
var cursors;
var jumpButton;
var boxes;
function create() {
game.stage.backgroundColor = '#000000';
bg = game.add.tileSprite(0, 0, 800, 600, 'background');
bg.fixedToCamera = true;
game.physics.gravity.y = 20;
game.physics.friction = 0.5;
game.physics.setBoundsToWorld();
var playerCG = game.physics.createCollisionGroup();
var boxCG = game.physics.createCollisionGroup();
player = game.add.sprite(50, 400, 'dude');
player.physicsEnabled = true;
player.body.fixedRotation = true;
player.body.setCollisionGroup(playerCG);
player.animations.add('left', [0, 1, 2, 3], 10, true);
player.animations.add('turn', [4], 20, true);
player.animations.add('right', [5, 6, 7, 8], 10, true);
boxes = game.add.group();
for (var i = 0; i < 10; i++)
{
var box = boxes.create(200 + (i * 50), 550, 'box');
box.scale.set(0.5);
box.physicsEnabled = true;
box.body.setCollisionGroup(boxCG);
box.body.collides(playerCG);
box.body.fixedRotation = true;
}
// Because player is creating the collides callback, the parameter order will be: callback (playerBody, boxBody, playerShape, boxShape)
player.body.collides(boxCG, gotBox, this);
cursors = game.input.keyboard.createCursorKeys();
jumpButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
}
function gotBox(body1, body2, shape1, shape2) {
console.log('gotBox');
body2.sprite.kill();
}
function update() {
if (cursors.left.isDown)
{
player.body.moveLeft(200);
if (facing != 'left')
{
player.animations.play('left');
facing = 'left';
}
}
else if (cursors.right.isDown)
{
player.body.moveRight(200);
if (facing != 'right')
{
player.animations.play('right');
facing = 'right';
}
}
else
{
player.body.velocity.x = 0;
if (facing != 'idle')
{
player.animations.stop();
if (facing == 'left')
{
player.frame = 0;
}
else
{
player.frame = 5;
}
facing = 'idle';
}
}
if (jumpButton.isDown && game.time.now > jumpTimer && checkIfCanJump())
{
player.body.moveUp(300);
jumpTimer = game.time.now + 750;
}
}
function checkIfCanJump(){
var yAxis = p2.vec2.fromValues(0,1);
var result = false;
for(var i=0; i<game.physics.world.narrowphase.contactEquations.length; i++){
var c = game.physics.world.narrowphase.contactEquations[i];
if(c.bi === player.body.data || c.bj === player.body.data){
var d = p2.vec2.dot(c.ni,yAxis); // Normal dot Y-axis
if(c.bi === player.body.data) d *= -1;
if(d > 0.5) result = true;
}
}
return result;
}
function render () {
game.debug.renderPhysicsBody(player.body);
}
-2
View File
@@ -903,11 +903,9 @@ Object.defineProperty(Phaser.Sprite.prototype, "exists", {
{
// exists = false
this._cache[6] = 0;
console.log('exists false');
if (this.body)
{
console.log('exists false remove from world');
this.body.removeFromWorld();
}
+99 -17
View File
@@ -70,25 +70,46 @@ Phaser.Physics.Body = function (game, sprite, x, y, mass) {
*/
this.collideWorldBounds = true;
/**
* @property {Phaser.Signal} onImpact - Dispatched when the shape/s of this Body impact with another. The event will be sent 2 parameters, this Body and the impact Body.
*/
this.onImpact = new Phaser.Signal();
/**
* @property {array} collidesWith - Array of CollisionGroups that this Bodies shapes collide with.
* @private
*/
this.collidesWith = [];
/**
* @property {array} _bodyCallbacks - Array of Body callbacks.
* @private
*/
this._bodyCallbacks = [];
/**
* @property {array} _bodyCallbackContext - Array of Body callback contexts.
* @private
*/
this._bodyCallbackContext = [];
// this.onAdded = new Phaser.Signal();
// this.onRemoved = new Phaser.Signal();
/**
* @property {array} _groupCallbacks - Array of Group callbacks.
* @private
*/
this._groupCallbacks = [];
/**
* @property {array} _bodyCallbackContext - Array of Grouo callback contexts.
* @private
*/
this._groupCallbackContext = [];
// Set-up the default shape
if (sprite)
{
this.setRectangleFromSprite(sprite);
// Default collision mask
// this.data.shapes[0].collisionMask = this.game.physics.boundsCollisionGroup.mask;
this.game.physics.addBody(this);
}
@@ -96,25 +117,79 @@ Phaser.Physics.Body = function (game, sprite, x, y, mass) {
Phaser.Physics.Body.prototype = {
/**
* Sets a callback to be fired any time this Body impacts with the given Body. The impact test is performed against body.id values.
* The callback will be sent 4 parameters: This body, the body that impacted, the Shape in this body and the shape in the impacting body.
*
* @method Phaser.Physics.Body#createBodyCallback
* @param {Phaser.Physics.Body} body - The Body to send impact events for.
* @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback.
* @param {object} callbackContext - The context under which the callback will fire.
*/
createBodyCallback: function (body, callback, callbackContext) {
this._bodyCallbacks[body.data.id] = callback;
this._bodyCallbackContext[body.data.id] = callbackContext;
},
/**
* Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified.
*
* @method Phaser.Physics.Body#createGroupCallback
* @param {Phaser.Physics.CollisionGroup} group - The Group to send impact events for.
* @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback.
* @param {object} callbackContext - The context under which the callback will fire.
*/
createGroupCallback: function (group, callback, callbackContext) {
this._groupCallbacks[group.mask] = callback;
this._groupCallbackContext[group.mask] = callbackContext;
},
getCollisionMask: function () {
var mask = 0;
if (this.collideWorldBounds)
{
mask = this.game.physics.boundsCollisionGroup.mask;
}
for (var i = 0; i < this.collidesWith.length; i++)
{
mask = mask | this.collidesWith[i].mask;
}
return mask;
},
/**
* Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified.
* This also resets the collisionMask.
*
* @method Phaser.Physics.Body#setCollisionGroup
* @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group that this Bodies shapes will use.
* @param {p2.Shape} [shape] - An optional Shape. If not provided the collision group will be added to all Shapes in this Body.
*/
setCollisionGroup: function (group, shape) {
var mask = this.getCollisionMask();
if (typeof shape === 'undefined')
{
for (var i = this.data.shapes.length - 1; i >= 0; i--)
{
this.data.shapes[i].collisionGroup = group.mask;
this.data.shapes[i].collisionMask = mask;
}
}
else
{
shape.collisionGroup = group.mask;
shapes.collisionMask = mask;
}
},
@@ -157,6 +232,11 @@ Phaser.Physics.Body.prototype = {
}
}
if (clearGroup)
{
this.collidesWith.length = 0;
}
},
/**
@@ -164,9 +244,11 @@ Phaser.Physics.Body.prototype = {
*
* @method Phaser.Physics.Body#collides
* @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group or Array of Collision Groups that this Bodies shapes will collide with.
* @param {function} [callback] - Optional callback that will be triggered when this Body impacts with the given Group.
* @param {object} [callbackContext] - The context under which the callback will be called.
* @param {p2.Shape} [shape] - An optional Shape. If not provided the collision mask will be added to all Shapes in this Body.
*/
collides: function (group, shape) {
collides: function (group, callback, callbackContext, shape) {
if (Array.isArray(group))
{
@@ -175,6 +257,11 @@ Phaser.Physics.Body.prototype = {
if (this.collidesWith.indexOf(group[i]) === -1)
{
this.collidesWith.push(group[i]);
if (callback)
{
this.createGroupCallback(group[i], callback, callbackContext);
}
}
}
}
@@ -183,20 +270,15 @@ Phaser.Physics.Body.prototype = {
if (this.collidesWith.indexOf(group) === -1)
{
this.collidesWith.push(group);
if (callback)
{
this.createGroupCallback(group, callback, callbackContext);
}
}
}
var mask = 0;
if (this.collideWorldBounds)
{
mask = this.game.physics.boundsCollisionGroup.mask;
}
for (var i = 0; i < this.collidesWith.length; i++)
{
mask = mask | this.collidesWith[i].mask;
}
var mask = this.getCollisionMask();
if (typeof shape === 'undefined')
{
+30 -21
View File
@@ -152,7 +152,9 @@ Phaser.Physics.World = function (game, config) {
this.boundsCollisionGroup = new Phaser.Physics.CollisionGroup(2);
this.boundsCollidesWith = [];
this.setBoundsToWorld(true, true, true, true, false);
// Group vs. Group callbacks
// this.setBoundsToWorld(true, true, true, true, false);
};
@@ -167,8 +169,6 @@ Phaser.Physics.World.prototype = {
*/
postStepHandler: function (event) {
// console.log('postStep', event);
},
/**
@@ -205,16 +205,31 @@ Phaser.Physics.World.prototype = {
*/
impactHandler: function (event) {
if (event.bodyA.id > 1 && event.bodyB.id > 1)
if (event.bodyA.parent && event.bodyB.parent)
{
console.log('impactHandler');
console.log(event);
console.log(event.bodyA.parent.sprite.key);
// Body vs. Body callbacks
var a = event.bodyA.parent;
var b = event.bodyB.parent;
if (event.bodyB.parent.sprite.key == 'box')
if (a._bodyCallbacks[event.bodyB.id])
{
console.log(event.bodyB.parent.sprite.key + ' KILLED');
event.bodyB.parent.sprite.kill();
a._bodyCallbacks[event.bodyB.id].call(a._bodyCallbackContext[event.bodyB.id], a, b, event.shapeA, event.shapeB);
}
if (b._bodyCallbacks[event.bodyA.id])
{
b._bodyCallbacks[event.bodyA.id].call(b._bodyCallbackContext[event.bodyA.id], b, a, event.shapeB, event.shapeA);
}
// Body vs. Group callbacks
if (a._groupCallbacks[event.shapeB.collisionGroup])
{
a._groupCallbacks[event.shapeB.collisionGroup].call(a._groupCallbackContext[event.shapeB.collisionGroup], a, b, event.shapeA, event.shapeB);
}
if (b._groupCallbacks[event.shapeA.collisionGroup])
{
b._groupCallbacks[event.shapeA.collisionGroup].call(b._groupCallbackContext[event.shapeA.collisionGroup], b, a, event.shapeB, event.shapeA);
}
}
@@ -231,13 +246,11 @@ Phaser.Physics.World.prototype = {
if (event.bodyA.id > 1 && event.bodyB.id > 1)
{
console.log('beginContactHandler');
console.log(event.bodyA.parent.sprite.key);
console.log(event.bodyB.parent.sprite.key);
// console.log('beginContactHandler');
// console.log(event.bodyA.parent.sprite.key);
// console.log(event.bodyB.parent.sprite.key);
}
event = {};
},
/**
@@ -249,16 +262,12 @@ Phaser.Physics.World.prototype = {
*/
endContactHandler: function (event) {
console.log('endContactHandler');
console.log(event);
if (event.bodyA.id > 1 && event.bodyB.id > 1)
{
console.log('endContactHandler');
console.log(event);
// console.log('endContactHandler');
// console.log(event);
}
event = {};
},
/**