From f7329e0661bfde848e719801515c274b1a4f755f Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Fri, 3 Jan 2014 02:24:06 +0000 Subject: [PATCH] Further physics modifications --- examples/wip/demo worm.js | 22 +++-- examples/wip/physics-motion.js | 10 +-- src/physics/arcade/ArcadePhysics.js | 72 +++-------------- src/physics/arcade/Body.js | 119 +++++++++++++++++++++------- src/utils/Debug.js | 1 + 5 files changed, 124 insertions(+), 100 deletions(-) diff --git a/examples/wip/demo worm.js b/examples/wip/demo worm.js index e5878e54..8c764ee1 100644 --- a/examples/wip/demo worm.js +++ b/examples/wip/demo worm.js @@ -18,9 +18,9 @@ var ad = 0; function create() { - bmd = game.add.bitmapData(640, 480); + bmd = game.add.bitmapData(800, 600); - for (var i = 0; i < 30; i++) + for (var i = 0; i < 60; i++) { particles.push(new Phaser.Point(0, 0)); } @@ -31,6 +31,8 @@ function create() { function mycircle(context, x, y, R, color) { + //R = 64; + context.fillStyle = color; context.beginPath(); context.arc(x, y, R, 0, Math.PI * 2, true); @@ -49,22 +51,26 @@ function update() { { var p = particles[t]; - p.x = Math.sin(n) * 50 + Math.cos(n * 1.5) * 200; - p.y = Math.sin(n / 2) * 20 + Math.sin(n * 2) * 150; + // p.x = Math.sin(n) * 50 + Math.cos(n * 1.5) * 300; + // p.y = Math.sin(n / 2) * 20 + Math.sin(n * 2) * 250; + + p.x = Math.cos(n) * 50 + Math.sin(n * 1.5) * 300; + p.y = Math.cos(n / 2) * 20 + Math.cos(n * 2) * 250; var tx = p.x; var ty = p.y; bmd.context.globalCompositeOperation = 'xor'; - mycircle(bmd.context, p.x + 320, p.y + 240, Math.sin(t * 360 / particles.length / 2 * Math.PI / 180) * 60, 'rgba(255, 255, 255, 1)'); + //mycircle(bmd.context, p.x + 400, p.y + 300, Math.sin(t * 360 / particles.length / 2 * Math.PI / 180) * 50, 'rgba(255, 255, 0, 1)'); + mycircle(bmd.context, p.x + 400, p.y + 300, Math.sin(t * 360 / particles.length / 2 * Math.PI / 180) * 50, 'rgba(255, 255, 0, 1)'); - n += 0.1; + n += 0.05; - bmd.context.globalCompositeOperation = 'source-over'; + //bmd.context.globalCompositeOperation = 'source-over'; } - n = oldn + 0.03; + n = oldn + 0.02; } diff --git a/examples/wip/physics-motion.js b/examples/wip/physics-motion.js index 7dcfccf3..8494df67 100644 --- a/examples/wip/physics-motion.js +++ b/examples/wip/physics-motion.js @@ -18,12 +18,12 @@ function create() { bmd.fillStyle('#ffffff'); game.add.sprite(0, 0, bmd); - sprite = game.add.sprite(32, 600, 'chunk'); + sprite = game.add.sprite(732, 0, 'chunk'); sprite.body.collideWorldBounds = true; sprite.body.bounce.setTo(0.5, 0.5); - sprite.body.drag.setTo(0, -20); - // sprite.body.drag.setTo(2, 0); + //sprite.body.drag.setTo(0, -20); + sprite.body.drag.setTo(5, 0); // sprite.body.sleepMin.setTo(-50, -20); // sprite.body.sleepMax.setTo(50, 20); // sprite.body.sleepDuration = 1000; @@ -38,9 +38,9 @@ function create() { function launch() { - sprite.body.velocity.setTo(0, -300); + sprite.body.velocity.setTo(-100, 300); - // sprite.body.gravity.setTo(0, 200); + sprite.body.gravity.setTo(0, -100); } diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index 62ced8f5..25b06ac5 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -221,8 +221,8 @@ Phaser.Physics.Arcade.prototype = { if (body.allowGravity) { - this._gravityX = (this.gravity.x + body.gravity.x); - this._gravityY = (this.gravity.y + body.gravity.y); + this._gravityX = (this.gravity.x + body.gravity.x) * this.game.time.physicsElapsed; + this._gravityY = (this.gravity.y + body.gravity.y) * this.game.time.physicsElapsed; } else { @@ -236,61 +236,22 @@ Phaser.Physics.Arcade.prototype = { // body.rotation += (body.angularVelocity * this.game.time.physicsElapsed); // body.angularVelocity += this._velocityDelta; - // body.motionVelocity.x = (this.computeVelocity(body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x, this._gravityX) - body.velocity.x) * 0.5; - // body.motionVelocity.y = (this.computeVelocity(body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y, this._gravityY) - body.velocity.y) * 0.5; - // velocity = velocity + gravity*delta_time/2 // position = position + velocity*delta_time // velocity = velocity + gravity*delta_time/2 + body.velocity.x += this._gravityX; + body.velocity.y += this._gravityY; + + body.motionVelocity.x = body.acceleration.x * this.game.time.physicsElapsed; + body.motionVelocity.y = body.acceleration.y * this.game.time.physicsElapsed; + // temp = acc*dt // pos = pos + dt*(vel + temp/2) // vel = vel + temp - this._drag = 0; - - if (body.drag.x !== 0 && body.velocity.x !== 0 && body.acceleration.x === 0) - { - if (body.velocity.x - body.drag.x > 0) - { - this._drag = -body.drag.x; - } - else if (body.velocity.x + body.drag.x < 0) - { - this._drag = body.drag.x; - } - } - - // body.motionVelocity.x = body.acceleration.x + this._gravityX - body.drag.x * this.game.time.physicsElapsed; - // body.motionVelocity.x = body.acceleration.x + this._gravityX * this.game.time.physicsElapsed; - body.motionVelocity.x = (body.acceleration.x + this._gravityX + this._drag) * this.game.time.physicsElapsed; - - this._drag = 0; - - if (body.drag.y !== 0 && body.velocity.y !== 0 && body.acceleration.y === 0) - { - if (body.velocity.y - body.drag.y > 0) - { - this._drag = -body.drag.y; - } - else if (body.velocity.y + body.drag.y < 0) - { - this._drag = body.drag.y; - } - } - - // body.motionVelocity.y = body.acceleration.y + this._gravityY - body.drag.y * this.game.time.physicsElapsed; - // body.motionVelocity.y = body.acceleration.y + this._gravityY * this.game.time.physicsElapsed; - body.motionVelocity.y = (body.acceleration.y + this._gravityY + this._drag) * this.game.time.physicsElapsed; - - // if (body.sleeping === false) - // { - // body.x = body.x + this.game.time.physicsElapsed * (body.velocity.x + body.motionVelocity.x / 2); - // body.velocity.x = body.velocity.x + body.motionVelocity.x; - - // body.y = body.y + this.game.time.physicsElapsed * (body.velocity.y + body.motionVelocity.y / 2); - // body.velocity.y = body.velocity.y + body.motionVelocity.y; - // } + // body.motionVelocity.x = (body.acceleration.x + this._gravityX) * this.game.time.physicsElapsed; + // body.motionVelocity.y = (body.acceleration.y + this._gravityY) * this.game.time.physicsElapsed; }, @@ -306,11 +267,11 @@ Phaser.Physics.Arcade.prototype = { * @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) { + computeVelocity: function (body, velocity, acceleration, drag, max, gravity) { max = max || 10000; - velocity += acceleration; + velocity += (acceleration + gravity) * this.game.time.physicsElapsed; if (acceleration === 0 && drag !== 0) { @@ -330,15 +291,6 @@ Phaser.Physics.Arcade.prototype = { } } - if (velocity > max) - { - velocity = max; - } - else if (velocity < -max) - { - velocity = -max; - } - return velocity; }, diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index 38fe5e76..b1e6dff5 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -141,6 +141,10 @@ Phaser.Physics.Arcade.Body = function (sprite) { */ this.acceleration = new Phaser.Point(); + this.speed = 0; + this.angle = 0; + + /** * @property {Phaser.Point} drag - The drag applied to the motion of the Body. */ @@ -303,12 +307,14 @@ Phaser.Physics.Arcade.Body = function (sprite) { * @property {boolean} canSleep - A Body that canSleep will have its velocity set to zero if it falls below sleepThreshold for longer than sleepDuration. * @default */ - this.sleeping = true; - this.canSleep = true; + this.sleeping = false; + this.canSleep = false; this.sleepMin = new Phaser.Point(-20, -20); this.sleepMax = new Phaser.Point(20, 20); this.sleepDuration = 2000; // ms this._sleepTimer = 0; // ms + this._drag = 0; + this._debug = 0; /** * 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. @@ -389,6 +395,9 @@ Phaser.Physics.Arcade.Body.prototype = { this.y = this.preY; this.rotation = this.preRotation; + this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y); + this.angle = Math.atan2(this.velocity.y, this.velocity.x); + this.blocked.up = false; this.blocked.down = false; this.blocked.left = false; @@ -398,20 +407,6 @@ Phaser.Physics.Arcade.Body.prototype = { { this.game.physics.updateMotion(this); - if (this.collideWorldBounds) - { - this.checkWorldBounds(); - } - - if (this.velocity.x > this.maxVelocity.x) - { - this.velocity.x = this.maxVelocity.x; - } - else if (this.velocity.x < -this.maxVelocity.x) - { - this.velocity.x = -this.maxVelocity.x; - } - if (this.canSleep) { if (!this.sleeping) @@ -422,8 +417,6 @@ Phaser.Physics.Arcade.Body.prototype = { { console.log('sleeping true'); this.sleeping = true; - // this.velocity.setTo(0, 0); - // this.motionVelocity.setTo(0, 0); // this.preX = this.x; // this.preY = this.y; } @@ -458,11 +451,74 @@ Phaser.Physics.Arcade.Body.prototype = { applyMotion: function () { - this.x = this.x + this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2); - this.velocity.x = this.velocity.x + this.motionVelocity.x; + // Apply drag + if (this.drag.x !== 0 && this.acceleration.x === 0) + { + this._drag = this.drag.x * this.game.time.physicsElapsed; - this.y = this.y + this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2); - this.velocity.y = this.velocity.y + this.motionVelocity.y; + if (this.velocity.x - this._drag > 0) + { + this.velocity.x -= this._drag; + } + else if (this.velocity.x + this.drag.x < 0) + { + this.velocity.x += this._drag; + } + else + { + this.velocity.x = 0; + // this.motionVelocity.x = 0; + } + + this.x += this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2); + this.velocity.x += this.motionVelocity.x; + } + else + { + this.x += this.game.time.physicsElapsed * (this.velocity.x + this.motionVelocity.x / 2); + this.velocity.x += this.motionVelocity.x; + } + + if (this.drag.y !== 0 && this.acceleration.y === 0) + { + this._drag = this.drag.y * this.game.time.physicsElapsed; + + if (this.velocity.y - this._drag > 0) + { + this.velocity.y -= this._drag; + } + else if (this.velocity.y + this.drag.y < 0) + { + this.velocity.y += this._drag; + } + else + { + this.velocity.y = 0; + // this.motionVelocity.y = 0; + } + + this.y += this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2); + this.velocity.y += this.motionVelocity.y; + } + else + { + this.y += this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2); + this.velocity.y += this.motionVelocity.y; + } + + if (this.velocity.x > this.maxVelocity.x) + { + // this.velocity.x = this.maxVelocity.x; + } + else if (this.velocity.x < -this.maxVelocity.x) + { + // this.velocity.x = -this.maxVelocity.x; + } + + if (this.collideWorldBounds) + { + this.checkWorldBounds(); + } }, @@ -476,11 +532,6 @@ Phaser.Physics.Arcade.Body.prototype = { if (this.moves) { - if (this.collideWorldBounds) - { - // this.checkWorldBounds(); - } - if (this.deltaX() < 0 && this.blocked.left === false) { this.facing = Phaser.LEFT; @@ -503,6 +554,11 @@ Phaser.Physics.Arcade.Body.prototype = { this.sprite.y += this.deltaY(); } + if (this.collideWorldBounds) + { + this.checkWorldBounds(); + } + this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); if (this.allowRotation) @@ -511,6 +567,8 @@ Phaser.Physics.Arcade.Body.prototype = { } } + this._debug++; + }, /** @@ -521,17 +579,22 @@ Phaser.Physics.Arcade.Body.prototype = { */ checkWorldBounds: function () { + var vx = this.velocity.x; + var vy = this.velocity.y; + if (this.x < this.game.world.bounds.x) { this.blocked.left = true; this.x = this.game.world.bounds.x; this.velocity.x *= -this.bounce.x; + console.log(this._debug, 'hit left', vx,'to',this.velocity.x); } else if (this.right > this.game.world.bounds.right) { this.blocked.right = true; this.x = this.game.world.bounds.right - this.width; this.velocity.x *= -this.bounce.x; + console.log(this._debug, 'hit right', vx,'to',this.velocity.x); } if (this.y < this.game.world.bounds.y) @@ -539,12 +602,14 @@ Phaser.Physics.Arcade.Body.prototype = { this.blocked.up = true; this.y = this.game.world.bounds.y; this.velocity.y *= -this.bounce.y; + console.log(this._debug, 'hit top', vy,'to',this.velocity.y); } else if (this.bottom > this.game.world.bounds.bottom) { this.blocked.down = true; this.y = this.game.world.bounds.bottom - this.height; this.velocity.y *= -this.bounce.y; + console.log(this._debug, 'hit bottom', vy,'to',this.velocity.y); } }, diff --git a/src/utils/Debug.js b/src/utils/Debug.js index dfe038d1..30087e92 100644 --- a/src/utils/Debug.js +++ b/src/utils/Debug.js @@ -456,6 +456,7 @@ Phaser.Utils.Debug.prototype = { this.splitline('Width: ' + sprite.width, 'Height: ' + sprite.height); this.splitline('x: ' + sprite.body.x.toFixed(2), 'y: ' + sprite.body.y.toFixed(2)); + this.splitline('speed: ' + sprite.body.speed.toFixed(2), 'angle: ' + sprite.body.angle.toFixed(2)); this.splitline('old x: ' + sprite.body.preX.toFixed(2), 'y: ' + sprite.body.preY.toFixed(2)); this.splitline('drag x: ' + sprite.body.drag.x, 'y: ' + sprite.body.drag.y); this.splitline('gravity x: ' + sprite.body.gravity.x, 'y: ' + sprite.body.gravity.y);