Skip to content

Commit d908005

Browse files
committed
Disabled World bounds by default.
Body.collides now takes a group level callback. Added Body.createBodyCallback and Body.createGroupCallback.
1 parent f6807e2 commit d908005

5 files changed

Lines changed: 279 additions & 40 deletions

File tree

examples/wip/contact1.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,22 @@ function create() {
4646
box.physicsEnabled = true;
4747
box.body.static = true;
4848
box.body.fixedRotation = true;
49+
box.body.createBodyCallback(player.body, gotBox, this);
4950
}
5051

5152
cursors = game.input.keyboard.createCursorKeys();
5253
jumpButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
5354

5455
}
5556

57+
function gotBox(body1, body2, shape1, shape2) {
58+
59+
console.log('gotBox');
60+
61+
body1.sprite.kill();
62+
63+
}
64+
5665
function update() {
5766

5867
if (cursors.left.isDown)

examples/wip/contact2.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
2+
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
3+
4+
function preload() {
5+
6+
game.load.spritesheet('dude', 'assets/games/starstruck/dude.png', 32, 48);
7+
game.load.image('background', 'assets/games/starstruck/background2.png');
8+
game.load.image('box', 'assets/sprites/block.png');
9+
10+
}
11+
12+
var player;
13+
var facing = 'left';
14+
var jumpTimer = 0;
15+
var cursors;
16+
var jumpButton;
17+
var boxes;
18+
19+
function create() {
20+
21+
game.stage.backgroundColor = '#000000';
22+
23+
bg = game.add.tileSprite(0, 0, 800, 600, 'background');
24+
bg.fixedToCamera = true;
25+
26+
game.physics.gravity.y = 20;
27+
game.physics.friction = 0.5;
28+
game.physics.setBoundsToWorld();
29+
30+
var playerCG = game.physics.createCollisionGroup();
31+
var boxCG = game.physics.createCollisionGroup();
32+
33+
player = game.add.sprite(50, 400, 'dude');
34+
player.physicsEnabled = true;
35+
player.body.fixedRotation = true;
36+
player.body.setCollisionGroup(playerCG);
37+
38+
player.animations.add('left', [0, 1, 2, 3], 10, true);
39+
player.animations.add('turn', [4], 20, true);
40+
player.animations.add('right', [5, 6, 7, 8], 10, true);
41+
42+
boxes = game.add.group();
43+
44+
for (var i = 0; i < 10; i++)
45+
{
46+
var box = boxes.create(200 + (i * 50), 550, 'box');
47+
box.scale.set(0.5);
48+
box.physicsEnabled = true;
49+
box.body.setCollisionGroup(boxCG);
50+
box.body.collides(playerCG);
51+
box.body.fixedRotation = true;
52+
}
53+
54+
// Because player is creating the collides callback, the parameter order will be: callback (playerBody, boxBody, playerShape, boxShape)
55+
player.body.collides(boxCG, gotBox, this);
56+
57+
58+
cursors = game.input.keyboard.createCursorKeys();
59+
jumpButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
60+
61+
}
62+
63+
function gotBox(body1, body2, shape1, shape2) {
64+
65+
console.log('gotBox');
66+
67+
body2.sprite.kill();
68+
69+
}
70+
71+
function update() {
72+
73+
if (cursors.left.isDown)
74+
{
75+
player.body.moveLeft(200);
76+
77+
if (facing != 'left')
78+
{
79+
player.animations.play('left');
80+
facing = 'left';
81+
}
82+
}
83+
else if (cursors.right.isDown)
84+
{
85+
player.body.moveRight(200);
86+
87+
if (facing != 'right')
88+
{
89+
player.animations.play('right');
90+
facing = 'right';
91+
}
92+
}
93+
else
94+
{
95+
player.body.velocity.x = 0;
96+
97+
if (facing != 'idle')
98+
{
99+
player.animations.stop();
100+
101+
if (facing == 'left')
102+
{
103+
player.frame = 0;
104+
}
105+
else
106+
{
107+
player.frame = 5;
108+
}
109+
110+
facing = 'idle';
111+
}
112+
}
113+
114+
if (jumpButton.isDown && game.time.now > jumpTimer && checkIfCanJump())
115+
{
116+
player.body.moveUp(300);
117+
jumpTimer = game.time.now + 750;
118+
}
119+
120+
}
121+
122+
function checkIfCanJump(){
123+
var yAxis = p2.vec2.fromValues(0,1);
124+
var result = false;
125+
for(var i=0; i<game.physics.world.narrowphase.contactEquations.length; i++){
126+
var c = game.physics.world.narrowphase.contactEquations[i];
127+
if(c.bi === player.body.data || c.bj === player.body.data){
128+
var d = p2.vec2.dot(c.ni,yAxis); // Normal dot Y-axis
129+
if(c.bi === player.body.data) d *= -1;
130+
if(d > 0.5) result = true;
131+
}
132+
}
133+
return result;
134+
}
135+
136+
137+
function render () {
138+
139+
game.debug.renderPhysicsBody(player.body);
140+
141+
}

src/gameobjects/Sprite.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -903,11 +903,9 @@ Object.defineProperty(Phaser.Sprite.prototype, "exists", {
903903
{
904904
// exists = false
905905
this._cache[6] = 0;
906-
console.log('exists false');
907906

908907
if (this.body)
909908
{
910-
console.log('exists false remove from world');
911909
this.body.removeFromWorld();
912910
}
913911

src/physics/Body.js

Lines changed: 99 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,51 +70,126 @@ Phaser.Physics.Body = function (game, sprite, x, y, mass) {
7070
*/
7171
this.collideWorldBounds = true;
7272

73+
/**
74+
* @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.
75+
*/
76+
this.onImpact = new Phaser.Signal();
77+
7378
/**
7479
* @property {array} collidesWith - Array of CollisionGroups that this Bodies shapes collide with.
7580
* @private
7681
*/
7782
this.collidesWith = [];
7883

84+
/**
85+
* @property {array} _bodyCallbacks - Array of Body callbacks.
86+
* @private
87+
*/
88+
this._bodyCallbacks = [];
7989

90+
/**
91+
* @property {array} _bodyCallbackContext - Array of Body callback contexts.
92+
* @private
93+
*/
94+
this._bodyCallbackContext = [];
8095

81-
// this.onAdded = new Phaser.Signal();
82-
// this.onRemoved = new Phaser.Signal();
96+
/**
97+
* @property {array} _groupCallbacks - Array of Group callbacks.
98+
* @private
99+
*/
100+
this._groupCallbacks = [];
101+
102+
/**
103+
* @property {array} _bodyCallbackContext - Array of Grouo callback contexts.
104+
* @private
105+
*/
106+
this._groupCallbackContext = [];
83107

84108
// Set-up the default shape
85109
if (sprite)
86110
{
87111
this.setRectangleFromSprite(sprite);
88112

89-
// Default collision mask
90-
// this.data.shapes[0].collisionMask = this.game.physics.boundsCollisionGroup.mask;
91-
92113
this.game.physics.addBody(this);
93114
}
94115

95116
};
96117

97118
Phaser.Physics.Body.prototype = {
98119

120+
/**
121+
* Sets a callback to be fired any time this Body impacts with the given Body. The impact test is performed against body.id values.
122+
* 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.
123+
*
124+
* @method Phaser.Physics.Body#createBodyCallback
125+
* @param {Phaser.Physics.Body} body - The Body to send impact events for.
126+
* @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback.
127+
* @param {object} callbackContext - The context under which the callback will fire.
128+
*/
129+
createBodyCallback: function (body, callback, callbackContext) {
130+
131+
this._bodyCallbacks[body.data.id] = callback;
132+
this._bodyCallbackContext[body.data.id] = callbackContext;
133+
134+
},
135+
136+
/**
137+
* Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified.
138+
*
139+
* @method Phaser.Physics.Body#createGroupCallback
140+
* @param {Phaser.Physics.CollisionGroup} group - The Group to send impact events for.
141+
* @param {function} callback - The callback to fire on impact. Set to null to clear a previously set callback.
142+
* @param {object} callbackContext - The context under which the callback will fire.
143+
*/
144+
createGroupCallback: function (group, callback, callbackContext) {
145+
146+
this._groupCallbacks[group.mask] = callback;
147+
this._groupCallbackContext[group.mask] = callbackContext;
148+
149+
},
150+
151+
getCollisionMask: function () {
152+
153+
var mask = 0;
154+
155+
if (this.collideWorldBounds)
156+
{
157+
mask = this.game.physics.boundsCollisionGroup.mask;
158+
}
159+
160+
for (var i = 0; i < this.collidesWith.length; i++)
161+
{
162+
mask = mask | this.collidesWith[i].mask;
163+
}
164+
165+
return mask;
166+
167+
},
168+
99169
/**
100170
* Sets the given CollisionGroup to be the collision group for all shapes in this Body, unless a shape is specified.
171+
* This also resets the collisionMask.
101172
*
102173
* @method Phaser.Physics.Body#setCollisionGroup
103174
* @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group that this Bodies shapes will use.
104175
* @param {p2.Shape} [shape] - An optional Shape. If not provided the collision group will be added to all Shapes in this Body.
105176
*/
106177
setCollisionGroup: function (group, shape) {
107178

179+
var mask = this.getCollisionMask();
180+
108181
if (typeof shape === 'undefined')
109182
{
110183
for (var i = this.data.shapes.length - 1; i >= 0; i--)
111184
{
112185
this.data.shapes[i].collisionGroup = group.mask;
186+
this.data.shapes[i].collisionMask = mask;
113187
}
114188
}
115189
else
116190
{
117191
shape.collisionGroup = group.mask;
192+
shapes.collisionMask = mask;
118193
}
119194

120195
},
@@ -157,16 +232,23 @@ Phaser.Physics.Body.prototype = {
157232
}
158233
}
159234

235+
if (clearGroup)
236+
{
237+
this.collidesWith.length = 0;
238+
}
239+
160240
},
161241

162242
/**
163243
* Adds the given CollisionGroup, or array of CollisionGroups, to the list of groups that this body will collide with and updates the collision masks.
164244
*
165245
* @method Phaser.Physics.Body#collides
166246
* @param {Phaser.Physics.CollisionGroup|array} group - The Collision Group or Array of Collision Groups that this Bodies shapes will collide with.
247+
* @param {function} [callback] - Optional callback that will be triggered when this Body impacts with the given Group.
248+
* @param {object} [callbackContext] - The context under which the callback will be called.
167249
* @param {p2.Shape} [shape] - An optional Shape. If not provided the collision mask will be added to all Shapes in this Body.
168250
*/
169-
collides: function (group, shape) {
251+
collides: function (group, callback, callbackContext, shape) {
170252

171253
if (Array.isArray(group))
172254
{
@@ -175,6 +257,11 @@ Phaser.Physics.Body.prototype = {
175257
if (this.collidesWith.indexOf(group[i]) === -1)
176258
{
177259
this.collidesWith.push(group[i]);
260+
261+
if (callback)
262+
{
263+
this.createGroupCallback(group[i], callback, callbackContext);
264+
}
178265
}
179266
}
180267
}
@@ -183,20 +270,15 @@ Phaser.Physics.Body.prototype = {
183270
if (this.collidesWith.indexOf(group) === -1)
184271
{
185272
this.collidesWith.push(group);
186-
}
187-
}
188273

189-
var mask = 0;
190-
191-
if (this.collideWorldBounds)
192-
{
193-
mask = this.game.physics.boundsCollisionGroup.mask;
274+
if (callback)
275+
{
276+
this.createGroupCallback(group, callback, callbackContext);
277+
}
278+
}
194279
}
195280

196-
for (var i = 0; i < this.collidesWith.length; i++)
197-
{
198-
mask = mask | this.collidesWith[i].mask;
199-
}
281+
var mask = this.getCollisionMask();
200282

201283
if (typeof shape === 'undefined')
202284
{

0 commit comments

Comments
 (0)