diff --git a/README.md b/README.md index eebfdf13..a0b81090 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,13 @@ New Examples: * Physics - Bounce accelerator (use the keyboard) by Patrick OReilly. * Physics - Bounce knock (use the keyboard) by Patrick OReilly. * Physics - Snake (use the keyboard to control the snake like creature) by Patrick OReilly and Richard Davey. +* Physics - Launcher - Angry Birds style ball launcher demo by Patrick OReilly. +* Physics - Launcher Follow - throw the sprite anywhere in the world by Patrick OReilly. +* Physics - Launcher Follow World - an advanced version of the Launcher Follow example by Patrick OReilly. * Input - Touch Joystick example showing how to use the clay.io virtual game controller (thanks gabehollombe) * Games - Matching Pairs by Patrick OReilly. +* Games - Simon Says by Patrick OReilly. +* Games - Wabbits by Patrick OReilly. * Tweens - Example showing how to use the tween events, onStart, onLoop and onComplete. * Display - Pixi Render Texture. A Phaser conversion of the Pixi.js Render Texture example. * Input - 5 new examples showing how to use the Gamepad API (thanks Karl Macklin) @@ -128,7 +133,7 @@ Bug Fixes: * Fixed Group.scale so you can now scale a Group directly. * Removed World.scale as it was preventing Group.scale from working - you can still scale the world, but you'll need to factor in Input changes yourself. * Moved 'dirty' flag for Tilemap to a per-layer flag. Fixes #242 -* Group.length now returns the number of children in the Group regardless of their exists/alive state, or 0 if the Group is has no children. +* Group.length now returns the number of children in the Group regardless of their exists/alive state, or 0 if the Group has no children. * Switch Camera.setBoundsToWorld to match world.bounds instead of world (thanks cocoademon) * Fixed an issue where passing null as the Group parent wouldn't set it to game.world as it should have (thanks tito100) * Fixed Pixi bug (#425) incorrect width property for multi-line BitmapText (thanks jcd-as) @@ -143,6 +148,7 @@ Bug Fixes: * Buttons now clear previously set frames correctly if you call setFrames. * Sounds will now loop correctly if they are paused and resumed (thanks haden) * InputHandler.checkBoundsRect and checkBoundsSprite now take into account if the Sprite is fixedToCamera or not. +* Removed the frame property from TileSprites as it cannot use them, it tiles the whole image only, not just a section of it. You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md @@ -343,3 +349,5 @@ Phaser is released under the [MIT License](http://opensource.org/licenses/MIT). [1]: https://github.com/photonstorm/phaser/issues [phaser]: https://github.com/photonstorm/phaser + +[![Analytics](https://ga-beacon.appspot.com/UA-44006568-2/phaser/index)](https://github.com/igrigorik/ga-beacon) diff --git a/examples/_site/examples.json b/examples/_site/examples.json index afbee69a..2bb70eae 100644 --- a/examples/_site/examples.json +++ b/examples/_site/examples.json @@ -254,6 +254,10 @@ "file": "matching+pairs.js", "title": "matching pairs" }, + { + "file": "simon.js", + "title": "simon" + }, { "file": "starstruck.js", "title": "starstruck" @@ -261,6 +265,10 @@ { "file": "tanks.js", "title": "tanks" + }, + { + "file": "wabbits.js", + "title": "wabbits" } ], "geometry": [ @@ -608,6 +616,18 @@ "file": "framerate+independence.js", "title": "framerate independence" }, + { + "file": "launcher+follow+world.js", + "title": "launcher follow world" + }, + { + "file": "launcher+follow.js", + "title": "launcher follow" + }, + { + "file": "launcher.js", + "title": "launcher" + }, { "file": "mass+velocity+test.js", "title": "mass velocity test" diff --git a/examples/assets/sprites/block.png b/examples/assets/sprites/block.png new file mode 100644 index 00000000..3d3ffd20 Binary files /dev/null and b/examples/assets/sprites/block.png differ diff --git a/examples/assets/sprites/longarrow2.png b/examples/assets/sprites/longarrow2.png new file mode 100644 index 00000000..82cf0a5a Binary files /dev/null and b/examples/assets/sprites/longarrow2.png differ diff --git a/examples/assets/tests/fusia.png b/examples/assets/tests/fusia.png new file mode 100644 index 00000000..5c584a0f Binary files /dev/null and b/examples/assets/tests/fusia.png differ diff --git a/examples/games/simon.js b/examples/games/simon.js new file mode 100644 index 00000000..59bc4979 --- /dev/null +++ b/examples/games/simon.js @@ -0,0 +1,214 @@ +// mods by Patrick OReilly +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('item', 'assets/buttons/number-buttons.png', 160, 160); +} + +var simon; +var N = 1; +var userCount = 0; +var currentCount = 0; +var sequenceCount = 16; +var sequenceList = []; +var simonSez = false; +var timeCheck; +var litSquare; +var winner; +var loser; +var intro; + +function create() { + + simon = game.add.group(); + var item; + + for (var i = 0; i < 3; i++) + { + item = simon.create(150 + 168 * i, 150, 'item', i); + // Enable input. + item.input.start(0, true); + item.events.onInputDown.add(select); + item.events.onInputUp.add(release); + item.events.onInputOut.add(moveOff); + simon.getAt(i).alpha = 0; + } + + for (var i = 0; i < 3; i++) + { + item = simon.create(150 + 168 * i, 318, 'item', i + 3); + // Enable input. + item.input.start(0, true); + item.events.onInputDown.add(select); + item.events.onInputUp.add(release); + item.events.onInputOut.add(moveOff); + simon.getAt(i + 3).alpha = 0; + } + + introTween(); + setUp(); + setTimeout(function(){simonSequence(); intro = false;}, 5000); + +} + +function restart() { + + N = 1; + userCount = 0; + currentCount = 0; + sequenceList = []; + winner = false; + loser = false; + introTween(); + setUp(); + setTimeout(function(){simonSequence(); intro=false;}, 5000); + +} + +function introTween() { + + intro = true; + + for (var i = 0; i < 6; i++) + { + game.add.tween(simon.getAt(i)).to( { alpha: 1 }, 500, Phaser.Easing.Linear.None, true, 0, 4, true).to( { alpha: .25 }, 500, Phaser.Easing.Linear.None, true); + } + +} + +function update() { + + if (simonSez) + { + if (game.time.now - timeCheck >700-N*40) + { + simon.getAt(litSquare).alpha = .25; + game.paused = true; + + setTimeout(function() + { + if ( currentCount< N) + { + game.paused = false; + simonSequence(); + } + else + { + simonSez = false; + game.paused = false; + } + }, 400 - N * 20); + } + } +} + +function playerSequence(selected) { + + correctSquare = sequenceList[userCount]; + userCount++; + thisSquare = simon.getIndex(selected); + + if (thisSquare == correctSquare) + { + if (userCount == N) + { + if (N == sequenceCount) + { + winner = true; + setTimeout(function(){restart();}, 3000); + } + else + { + userCount = 0; + currentCount = 0; + N++; + simonSez = true; + } + } + } + else + { + loser = true; + setTimeout(function(){restart();}, 3000); + } + +} + +function simonSequence () { + + simonSez = true; + litSquare = sequenceList[currentCount]; + simon.getAt(litSquare).alpha = 1; + timeCheck = game.time.now; + currentCount++; + +} + +function setUp() { + + for (var i = 0; i < sequenceCount; i++) + { + thisSquare = game.rnd.integerInRange(0,6); + sequenceList.push(thisSquare); + } + +} + +function select(item, pointer) { + + if (!simonSez && !intro && !loser && !winner) + { + item.alpha = 1; + } + +} + +function release(item, pointer) { + + if (!simonSez && !intro && !loser && !winner) + { + item.alpha = .25; + playerSequence(item); + } +} + +function moveOff(item, pointer) { + + if (!simonSez && !intro && !loser && !winner) + { + item.alpha = .25; + } + +} + +function render() { + + if (!intro) + { + if (simonSez) + { + game.debug.renderText('Simon Sez', 360, 96, 'rgb(255,0,0)'); + } + else + { + game.debug.renderText('Your Turn', 360, 96, 'rgb(0,255,0)'); + } + } + else + { + game.debug.renderText('Get Ready', 360, 96, 'rgb(0,0,255)'); + } + + if (winner) + { + game.debug.renderText('You Win!', 360, 32, 'rgb(0,0,255)'); + } + else if (loser) + { + game.debug.renderText('You Lose!', 360, 32, 'rgb(0,0,255)'); + } + +} diff --git a/examples/games/wabbits.js b/examples/games/wabbits.js new file mode 100644 index 00000000..28055d11 --- /dev/null +++ b/examples/games/wabbits.js @@ -0,0 +1,162 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); + game.load.image('ball', 'assets/sprites/pangball.png'); + game.load.image('hill', 'assets/pics/atari_fujilogo.png'); + game.load.image('block', 'assets/sprites/block.png'); + game.load.image('wabbit', 'assets/sprites/wabbit.png'); + +} + +var arrow; +var ball; +var catchFlag = false; +var wabbits; +var wab; +var launchVelocity = 0; +var shotCount = 0; +var wabbitCount = 0; + +function create() { + + // set global gravity + game.physics.gravity.setTo(0, 4); + + game.stage.backgroundColor = '#0072bc'; + + var graphics = game.add.graphics(0, 0); + graphics.beginFill(0x049e0c); + graphics.drawRect(195, 450, 10, 150); + + wabbits = game.add.group(); + + for (var i = 0; i < 5; i++) + { + wab = wabbits.create(game.rnd.integerInRange(575, 650), game.rnd.integerInRange(150, 260), 'wabbit'); + wab.name = 'wab' + i; + wab.body.collideWorldBounds = true; + wab.body.mass = 0.1; + wab.body.drag.setTo(50, 50); + } + + hill = game.add.sprite(450, 400, 'hill'); + hill.body.collideWorldBounds = true; + hill.body.mass = 10; + hill.body.immovable = true; + + block = game.add.sprite(575, 300, 'block'); + block.body.collideWorldBounds = true; + block.body.mass = 5; + block.body.drag.setTo(100, 100); + + analog = game.add.sprite(200, 450, 'analog'); + analog.body.allowGravity = false; + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(200, 450, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.body.allowGravity = false; + arrow.alpha = 0; + + ball = game.add.sprite(100, 400, 'ball'); + ball.anchor.setTo(0.5, 0.5); + ball.inputEnabled = true; + ball.body.collideWorldBounds = true; + ball.body.bounce.setTo(0.9, 0.9); + ball.body.drag.setTo(100, 100); + + // Enable input. + ball.input.start(0, true); + ball.events.onInputDown.add(set); + ball.events.onInputUp.add(launch); + +} + +function set(ball, pointer) { + + ball.body.velocity.setTo(0, 0); + ball.body.allowGravity = false; + catchFlag = true; + +} + +function launch() { + + catchFlag = false; + shotCount++; + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - ball.x) * 4.1; + Yvector = (arrow.y - ball.y) * 4.1; + ball.body.allowGravity = true; + ball.body.velocity.setTo(Xvector,Yvector); + +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, ball); + + if (catchFlag == true) + { + // Track the ball sprite to the mouse + ball.x = game.input.activePointer.worldX; + ball.y = game.input.activePointer.worldY; + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - 3.14 / 2; + analog.height = game.physics.distanceToPointer(arrow); + launchVelocity = analog.height; + } + + game.physics.collide(ball, wabbits); + game.physics.collide(wabbits, wabbits); + game.physics.collide(wabbits, hill); + game.physics.collide(ball, hill); + game.physics.collide(block, hill); + game.physics.collide(block, ball); + game.physics.collide(block, wabbits); + + // check wabbits + var wabs = 0; + + for (var i = 0; i < 5; i++) + { + thisWab = wabbits.getAt(i); + + if (thisWab.x > 770 && thisWab.y > 400) + { + thisWab.alive = false; + wabs++; + } + } + + wabbitCount = 5 - wabs; + + console.log(ball.body.y, ball.body.motionVelocity.y); + +} + +function render() { + + game.debug.renderSpriteCollision(ball, 32, 32); + + // var graphics = game.add.graphics(0, 0); + // game.context.fillStyle = 'rgba(0,0,255,0.5)'; + // game.context.fillRect(770, 400, 30, 200); + // game.debug.renderText("Drag the ball to launch", 32, 32); + // game.debug.renderText("Try to get all 5 wabbits in the blue area with the least number of shots", 32, 64); + // game.debug.renderText("Shot Count: " + shotCount, 32, 96); + // game.debug.renderText("Wabbits Left: " + wabbitCount, 32, 128); + +} diff --git a/examples/physics/launcher follow world.js b/examples/physics/launcher follow world.js new file mode 100644 index 00000000..3a0dd734 --- /dev/null +++ b/examples/physics/launcher follow world.js @@ -0,0 +1,149 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('background','assets/misc/starfield.jpg'); + game.load.image('player','assets/sprites/phaser-dude.png'); + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); +} + +var myTween; +var player; +var cursors; +var arrow; +var catchFlag = false; +var launchVelocity = 0; +var launched; + +function create() { + + game.world.setBounds(0, 0, 5000, 600); + game.add.tileSprite(0, 0, 5000, 600, 'background'); + + var graphics = game.add.graphics(0,0); + graphics.beginFill(0x049e0c); + graphics.drawRect(395, 400, 10, 250); + + analog = game.add.sprite(400, 400, 'analog'); + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(400, 400, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.alpha = 0; + + player = game.add.sprite(150, 320, 'player'); + player.anchor.setTo(0.5, 0.5); + player.body.collideWorldBounds = true; + player.body.bounce.setTo(0.9, 0.9); + player.body.drag.setTo(100, 100); + player.body.gravity.setTo(0, 8); + + // Enable input. + player.inputEnabled = true; + player.input.start(0, true); + player.events.onInputDown.add(set); + player.events.onInputUp.add(launch); + //player.events.onInputOut.add(launch); + + // this tween is to make the camera return to left side of world when done launching + // so it is not used until then + myTween = game.add.tween(player).to({x: 150}, 5000, Phaser.Easing.Linear.None); + myTween.onComplete.add(reappear, this); + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); +} + +function reappear() { + + launched = false; + player.alpha = 1; +} + +function set(player,pointer) { + + //disallow launching until reset + if (!launched) + { + catchFlag = true; + game.camera.follow(null); + player.body.gravity.setTo(0,0); + player.body.velocity.setTo(0,0); + } +} + +function launch() { + + if (catchFlag) + { + catchFlag = false; + launched = true; + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); + + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - player.x)*3.8; + Yvector = (arrow.y - player.y)*3.8; + player.body.gravity.setTo(0,8); + player.body.velocity.setTo(Xvector,Yvector); + } +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, player); + + // Track the player sprite to the mouse + if (catchFlag) + { + distance = game.physics.distanceToPointer(arrow); + theta = game.physics.angleToPointer(arrow); + + // Govern the distance the sprite is dragged away from launch post + if (distance > 300) + { + distance = 300; + adjacentX = Math.cos(theta) * distance; + oppositeY = Math.sin(theta) * distance; + player.x = 400 + adjacentX; + player.y = 400 + oppositeY; + analog.height = distance; + } + else + { + player.x = game.input.activePointer.worldX; + player.y = game.input.activePointer.worldY; + analog.height = distance; + } + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - Math.PI/2; + launchVelocity = analog.height; + } + + //check sprite motion and if done, return camera to left side of world + var tweening = myTween.isRunning; + + if (!tweening && launched && (player.x >= game.world.width-20 || player.body.deltaX() == 0)) + { + player.body.velocity.setTo(0, 0); + player.alpha = 0; + myTween.start(); + } + +} + +function render() { + + game.debug.renderText("Drag the sprite and release to launch", 32, 32, 'rgb(0,255,0)'); + game.debug.renderCameraInfo(game.camera, 32, 64); + game.debug.renderSpriteCoords(player, 32, 150); + game.debug.renderText("Launch Velocity: " + parseInt(launchVelocity), 550, 32, 'rgb(0,255,0)'); + +} diff --git a/examples/physics/launcher follow.js b/examples/physics/launcher follow.js new file mode 100644 index 00000000..49ef1c69 --- /dev/null +++ b/examples/physics/launcher follow.js @@ -0,0 +1,102 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('background','assets/misc/starfield.jpg'); + game.load.image('player','assets/sprites/phaser-dude.png'); + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); + +} + +var player; +var cursors; +var arrow; +var catchFlag = false; +var launchVelocity = 0; + +function create() { + + game.world.setBounds(0, 0, 3400, 1000); + game.add.tileSprite(0, 0, 3400, 1000, 'background'); + + analog = game.add.sprite(200, 450, 'analog'); + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(200, 450, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.alpha = 0; + + player = game.add.sprite(150, 320, 'player'); + player.anchor.setTo(0.5, 0.5); + player.body.collideWorldBounds = true; + player.body.bounce.setTo(0.9, 0.9); + player.body.drag.setTo(50, 50); + + // Enable input. + player.inputEnabled = true; + player.input.start(0, true); + player.events.onInputDown.add(set); + player.events.onInputUp.add(launch); + + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); + +} + +function set(player,pointer) { + + catchFlag = true; + game.camera.follow(null); + + player.body.velocity.setTo(0, 0); + arrow.reset(player.x, player.y); + analog.reset(player.x, player.y); + +} + +function launch() { + + catchFlag = false; + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); + + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - player.x) * 4.1; + Yvector = (arrow.y - player.y) * 4.1; + player.body.velocity.setTo(Xvector,Yvector); + +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, player); + + if (catchFlag == true) + { + // Track the ball sprite to the mouse + player.x = game.input.activePointer.worldX; + player.y = game.input.activePointer.worldY; + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - 3.14 / 2; + analog.height = game.physics.distanceBetween(arrow, player); + launchVelocity = analog.height; + } + +} + +function render() { + + game.debug.renderText("Drag the sprite and release to launch", 32, 32, 'rgb(0,255,0)'); + game.debug.renderCameraInfo(game.camera, 32, 64); + game.debug.renderSpriteCoords(player, 32, 150); + game.debug.renderText("Launch Velocity: " + parseInt(launchVelocity), 550, 32, 'rgb(0,255,0)'); + +} diff --git a/examples/physics/launcher.js b/examples/physics/launcher.js new file mode 100644 index 00000000..2f48e2e0 --- /dev/null +++ b/examples/physics/launcher.js @@ -0,0 +1,101 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); + game.load.image('ball', 'assets/sprites/pangball.png'); + +} + +var arrow; +var ball; +var catchFlag = false; +var launchVelocity = 0; + +function create() { + + // set global gravity + game.physics.gravity.setTo(0,8); + game.stage.backgroundColor = '#0072bc'; + + var graphics = game.add.graphics(0,0); + graphics.beginFill(0x049e0c); + graphics.drawRect(395, 350, 10, 250); + + analog = game.add.sprite(400, 350, 'analog'); + analog.body.allowGravity = false; + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(400, 350, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.body.allowGravity = false; + arrow.alpha = 0; + + ball = game.add.sprite(100, 400, 'ball'); + ball.anchor.setTo(0.5, 0.5); + ball.body.collideWorldBounds = true; + ball.body.bounce.setTo(0.9, 0.9); + ball.body.drag.setTo(50, 50); + + // Enable input. + ball.inputEnabled = true; + ball.input.start(0, true); + ball.events.onInputDown.add(set); + ball.events.onInputUp.add(launch); + +} + +function set(ball, pointer) { + + ball.body.velocity.setTo(0, 0); + ball.body.allowGravity = false; + catchFlag = true; + +} + +function launch() { + + catchFlag = false; + + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - ball.x) * 4.1; + Yvector = (arrow.y - ball.y) * 4.1; + ball.body.allowGravity = true; + ball.body.velocity.setTo(Xvector,Yvector); + +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, ball); + + if (catchFlag == true) + { + // Track the ball sprite to the mouse + ball.x = game.input.activePointer.worldX; + ball.y = game.input.activePointer.worldY; + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - 3.14/2; + analog.height = game.physics.distanceToPointer(arrow); + launchVelocity = analog.height; + } + +} + +function render() { + + game.debug.renderText("Drag the ball and release to launch", 32, 32); + game.debug.renderSpriteInfo(ball, 32, 64); + game.debug.renderText("Launch Velocity: " + parseInt(launchVelocity), 32, 250); + +} diff --git a/examples/wip/physics-motion.js b/examples/wip/physics-motion.js new file mode 100644 index 00000000..7dcfccf3 --- /dev/null +++ b/examples/wip/physics-motion.js @@ -0,0 +1,57 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('chunk', 'assets/sprites/chunk.png'); + +} + +var sprite; +var bmd; + +function create() { + + game.stage.backgroundColor = '#2384e7'; + + bmd = game.add.bitmapData(800, 600); + bmd.fillStyle('#ffffff'); + game.add.sprite(0, 0, bmd); + + sprite = game.add.sprite(32, 600, '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.sleepMin.setTo(-50, -20); + // sprite.body.sleepMax.setTo(50, 20); + // sprite.body.sleepDuration = 1000; + + sprite.body.sleepMin.setTo(0, -5); + sprite.body.sleepMax.setTo(0, 5); + sprite.body.sleepDuration = 1000; + + game.input.onDown.add(launch, this); + +} + +function launch() { + + sprite.body.velocity.setTo(0, -300); + + // sprite.body.gravity.setTo(0, 200); + +} + +function update() { + + bmd.fillRect(sprite.x, sprite.y, 2, 2); + +} + +function render() { + + game.debug.renderBodyInfo(sprite, 16, 16); + +} diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js index 18dd5bd4..902faa4d 100644 --- a/src/gameobjects/GameObjectFactory.js +++ b/src/gameobjects/GameObjectFactory.js @@ -144,15 +144,14 @@ Phaser.GameObjectFactory.prototype = { * @param {number} width - the width of the tilesprite. * @param {number} height - the height of the tilesprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. - * @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.TileSprite} The newly created tileSprite object. */ - tileSprite: function (x, y, width, height, key, frame, group) { + tileSprite: function (x, y, width, height, key, group) { if (typeof group === 'undefined') { group = this.world; } - return group.add(new Phaser.TileSprite(this.game, x, y, width, height, key, frame)); + return group.add(new Phaser.TileSprite(this.game, x, y, width, height, key)); }, diff --git a/src/gameobjects/TileSprite.js b/src/gameobjects/TileSprite.js index 07a1ee92..8d58b530 100644 --- a/src/gameobjects/TileSprite.js +++ b/src/gameobjects/TileSprite.js @@ -15,18 +15,16 @@ * @param {number} width - the width of the tilesprite. * @param {number} height - the height of the tilesprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. -* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. */ -Phaser.TileSprite = function (game, x, y, width, height, key, frame) { +Phaser.TileSprite = function (game, x, y, width, height, key) { x = x || 0; y = y || 0; width = width || 256; height = height || 256; key = key || null; - frame = frame || null; - Phaser.Sprite.call(this, game, x, y, key, frame); + Phaser.Sprite.call(this, game, x, y, key); /** * @property {PIXI.Texture} texture - The texture that the sprite renders with. diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js index 97c27b61..62ced8f5 100644 --- a/src/physics/arcade/ArcadePhysics.js +++ b/src/physics/arcade/ArcadePhysics.js @@ -167,7 +167,7 @@ Phaser.Physics.Arcade.prototype = { * @method Phaser.Physics.Arcade#updateMotion * @param {Phaser.Physics.Arcade.Body} The Body object to be updated. */ - updateMotion: function (body) { + OLDupdateMotion: function (body) { // If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html @@ -177,27 +177,120 @@ Phaser.Physics.Arcade.prototype = { body.rotation += (body.angularVelocity * this.game.time.physicsElapsed); body.angularVelocity += this._velocityDelta; - if(body.allowGravity) + 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; + } + else + { + this._gravityX = 0; + this._gravityY = 0; } + 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; + // 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; + // 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; + // 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.motionVelocity.y = this._velocityDelta; + + // body.velocity.y += this._velocityDelta; + // body.y += (body.velocity.y * this.game.time.physicsElapsed); + // body.velocity.y += this._velocityDelta; + + }, + + /** + * Called automatically by a Physics body, it updates all motion related values on the Body. + * + * @method Phaser.Physics.Arcade#updateMotion + * @param {Phaser.Physics.Arcade.Body} The Body object to be updated. + */ + updateMotion: function (body) { + + // If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html + + if (body.allowGravity) + { + this._gravityX = (this.gravity.x + body.gravity.x); + this._gravityY = (this.gravity.y + body.gravity.y); + } + else + { + this._gravityX = 0; + this._gravityY = 0; + } + + // Rotation + // this._velocityDelta = (this.computeVelocity(body, 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; + + // 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 + + // 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; + // } }, @@ -213,7 +306,56 @@ 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, gravity) { + computeVelocity: function (body, velocity, acceleration, drag, max) { + + max = max || 10000; + + velocity += acceleration; + + if (acceleration === 0 && drag !== 0) + { + this._drag = drag; + + if (velocity - this._drag > 0) + { + velocity -= this._drag; + } + else if (velocity + this._drag < 0) + { + velocity += this._drag; + } + else + { + velocity = 0; + } + } + + if (velocity > max) + { + velocity = max; + } + else if (velocity < -max) + { + velocity = -max; + } + + return velocity; + + }, + + /** + * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity. + * + * @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. + */ + OLDcomputeVelocity: function (body, velocity, acceleration, drag, max, gravity) { max = max || 10000; diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index b0e74a02..38fe5e76 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -121,11 +121,21 @@ Phaser.Physics.Arcade.Body = function (sprite) { */ this._sy = sprite.scale.y; + /** + * @property {Phaser.Point} motionVelocity - The data from the updateMotion function. + */ + this.motionVelocity = new Phaser.Point(); + /** * @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body. */ this.velocity = new Phaser.Point(); + /** + * @property {Phaser.Point} prevVelocity - The velocity in pixels per second sq. of the Body. + */ + this.prevVelocity = new Phaser.Point(); + /** * @property {Phaser.Point} acceleration - The velocity in pixels per second sq. of the Body. */ @@ -137,7 +147,7 @@ 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} gravity - The gravity applied to the motion of the Body. */ this.gravity = new Phaser.Point(); @@ -232,7 +242,7 @@ Phaser.Physics.Arcade.Body = function (sprite) { this.facing = Phaser.NONE; /** - * @property {boolean} immovable - An immovable Body will not receive any impacts from other bodies. + * @property {boolean} immovable - An immovable Body will not receive any impacts or exchanges of velocity from other bodies. * @default */ this.immovable = false; @@ -289,17 +299,16 @@ 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. + * @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.hullX = new Phaser.Rectangle(); - - /** - * @property {Phaser.Rectangle} hullY - The dynamically calculated hull used during collision. - */ - this.hullY = new Phaser.Rectangle(); + this.sleeping = true; + this.canSleep = true; + this.sleepMin = new Phaser.Point(-20, -20); + this.sleepMax = new Phaser.Point(20, 20); + this.sleepDuration = 2000; // ms + this._sleepTimer = 0; // ms /** * 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. @@ -368,16 +377,18 @@ Phaser.Physics.Arcade.Body.prototype = { 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; + if (this.canSleep && this.sleeping && this.velocity.equals(this.prevVelocity) === false) + { + this.sleeping = false; + this._sleepTimer = 0; + } + 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; @@ -392,10 +403,46 @@ Phaser.Physics.Arcade.Body.prototype = { this.checkWorldBounds(); } - // this.hull.setTo(this.preX, this.preY, this.width, this.height); - // this.hullX.setTo(this.x, this.preY, this.width, this.height); - // this.hullY.setTo(this.preX, this.y, this.width, this.height); - // this.updateHulls(true); + 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) + { + if (this.velocity.x >= this.sleepMin.x && this.velocity.x <= this.sleepMax.x && this.velocity.y >= this.sleepMin.y && this.velocity.y <= this.sleepMax.y) + { + if (this._sleepTimer >= this.sleepDuration) + { + 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; + } + else + { + this._sleepTimer += this.game.time.elapsed; + this.applyMotion(); + } + } + else + { + this.applyMotion(); + } + } + } + else + { + this.applyMotion(); + } } if (this.skipQuadTree === false && this.allowCollision.none === false && this.sprite.visible && this.sprite.alive) @@ -405,99 +452,69 @@ Phaser.Physics.Arcade.Body.prototype = { this.game.physics.quadTree.insert(this); } + this.prevVelocity.copyFrom(this.velocity); + + }, + + 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; + + this.y = this.y + this.game.time.physicsElapsed * (this.velocity.y + this.motionVelocity.y / 2); + this.velocity.y = this.velocity.y + this.motionVelocity.y; + }, /** - * Internal method. + * Internal method. This is called directly before the sprites are sent to the renderer. * * @method Phaser.Physics.Arcade#postUpdate * @protected */ postUpdate: function () { - // if (this.overlapX !== 0) - // { - // this.x -= this.overlapX; - // } - - // if (this.overlapY !== 0) - // { - // this.y -= this.overlapY; - // } - - if (this.deltaX() < 0 && this.blocked.left === false) + if (this.moves) { - this.facing = Phaser.LEFT; - this.sprite.x += this.deltaX(); - } - else if (this.deltaX() > 0 && this.blocked.right === false) - { - this.facing = Phaser.RIGHT; - this.sprite.x += this.deltaX(); - } + if (this.collideWorldBounds) + { + // this.checkWorldBounds(); + } - if (this.deltaY() < 0 && this.blocked.up === false) - { - this.facing = Phaser.UP; - this.sprite.y += this.deltaY(); - } - else if (this.deltaY() > 0 && this.blocked.down === false) - { - this.facing = Phaser.DOWN; - this.sprite.y += this.deltaY(); - } + if (this.deltaX() < 0 && this.blocked.left === false) + { + this.facing = Phaser.LEFT; + this.sprite.x += this.deltaX(); + } + else if (this.deltaX() > 0 && this.blocked.right === false) + { + this.facing = Phaser.RIGHT; + this.sprite.x += this.deltaX(); + } - // if (this.deltaY() !== 0 && this.blocked.up === false && this.blocked.down === false) - // { - // this.sprite.y += this.deltaY(); - // } + if (this.deltaY() < 0 && this.blocked.up === false) + { + this.facing = Phaser.UP; + this.sprite.y += this.deltaY(); + } + else if (this.deltaY() > 0 && this.blocked.down === false) + { + this.facing = Phaser.DOWN; + this.sprite.y += this.deltaY(); + } - // if (this.deltaX() !== 0 || this.deltaY() !== 0) - // { - // this.sprite.x += this.deltaX(); - // this.sprite.y += this.deltaY(); - - // this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); - // } - - // if (this.deltaX() !== 0 || this.deltaY() !== 0) - // { this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); - // } - if (this.allowRotation) - { - this.sprite.angle += this.deltaZ(); + if (this.allowRotation) + { + this.sprite.angle += this.deltaZ(); + } } }, /** - * Internal method. - * - * @method Phaser.Physics.Arcade#updateHulls - * @protected - */ - updateHulls: function (separation) { - - // this.hull.setTo(this.x, this.y, this.width, this.height); - - // if (separation) - // { - // this.hullX.setTo(this.x, this.preY, this.width, this.height); - // this.hullY.setTo(this.preX, this.y, this.width, this.height); - // } - // else - // { - // if this has separated then the preX/Y values are no longer valid - // this.hullX.setTo(this.x, this.y, this.width, this.height); - // this.hullY.setTo(this.x, this.y, this.width, this.height); - // } - - }, - - /** - * Internal method. + * Internal method used to check the Body against the World Bounds. * * @method Phaser.Physics.Arcade#checkWorldBounds * @protected @@ -506,22 +523,26 @@ Phaser.Physics.Arcade.Body.prototype = { 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; } 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; } if (this.y < this.game.world.bounds.y) { + this.blocked.up = true; this.y = this.game.world.bounds.y; this.velocity.y *= -this.bounce.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; } diff --git a/src/time/Time.js b/src/time/Time.js index 17b928d9..879d3345 100644 --- a/src/time/Time.js +++ b/src/time/Time.js @@ -58,7 +58,7 @@ Phaser.Time = function (game) { this.now = 0; /** - * @property {number} elapsed - Elapsed time since the last frame. + * @property {number} elapsed - Elapsed time since the last frame (in ms). */ this.elapsed = 0; diff --git a/src/utils/Debug.js b/src/utils/Debug.js index f89d328a..dfe038d1 100644 --- a/src/utils/Debug.js +++ b/src/utils/Debug.js @@ -30,6 +30,11 @@ Phaser.Utils.Debug = function (game) { */ this.font = '14px Courier'; + /** + * @property {number} columnWidth - The spacing between columns. + */ + this.columnWidth = 100; + /** * @property {number} lineHeight - The line height between the debug text. */ @@ -65,11 +70,12 @@ Phaser.Utils.Debug.prototype = { /** * Internal method that resets and starts the debug output values. * @method Phaser.Utils.Debug#start - * @param {number} x - The X value the debug info will start from. - * @param {number} y - The Y value the debug info will start from. - * @param {string} color - The color the debug info will drawn in. + * @param {number} [x=0] - The X value the debug info will start from. + * @param {number} [y=0] - The Y value the debug info will start from. + * @param {string} [color='rgb(255,255,255)'] - The color the debug text will drawn in. + * @param {number} [columnWidth=0] - The spacing between columns. */ - start: function (x, y, color) { + start: function (x, y, color, columnWidth) { if (this.context == null) { @@ -78,13 +84,14 @@ Phaser.Utils.Debug.prototype = { if (typeof x !== 'number') { x = 0; } if (typeof y !== 'number') { y = 0; } - color = color || 'rgb(255,255,255)'; + if (typeof columnWidth === 'undefined') { columnWidth = 0; } this.currentX = x; this.currentY = y; this.currentColor = color; this.currentAlpha = this.context.globalAlpha; + this.columnWidth = columnWidth; this.context.save(); this.context.setTransform(1, 0, 0, 1, 0, 0); @@ -100,7 +107,6 @@ Phaser.Utils.Debug.prototype = { */ stop: function () { - this.context.restore(); this.context.globalAlpha = this.currentAlpha; @@ -110,8 +116,8 @@ Phaser.Utils.Debug.prototype = { * Internal method that outputs a single line of text. * @method Phaser.Utils.Debug#line * @param {string} text - The line of text to draw. - * @param {number} x - The X value the debug info will start from. - * @param {number} y - The Y value the debug info will start from. + * @param {number} [x] - The X value the debug info will start from. + * @param {number} [y] - The Y value the debug info will start from. */ line: function (text, x, y) { @@ -120,16 +126,8 @@ Phaser.Utils.Debug.prototype = { return; } - x = x || null; - y = y || null; - - if (x !== null) { - this.currentX = x; - } - - if (y !== null) { - this.currentY = y; - } + if (typeof x !== 'undefined') { this.currentX = x; } + if (typeof y !== 'undefined') { this.currentY = y; } if (this.renderShadow) { @@ -143,6 +141,38 @@ Phaser.Utils.Debug.prototype = { }, + /** + * Internal method that outputs a single line of text split over as many columns as needed, one per parameter. + * @method Phaser.Utils.Debug#splitline + * @param {string} text - The text to render. You can have as many columns of text as you want, just pass them as additional parameters. + */ + splitline: function (text) { + + if (this.context == null) + { + return; + } + + var x = this.currentX; + + for (var i = 0; i < arguments.length; i++) + { + if (this.renderShadow) + { + this.context.fillStyle = 'rgb(0,0,0)'; + this.context.fillText(arguments[i], x + 1, this.currentY + 1); + this.context.fillStyle = this.currentColor; + } + + this.context.fillText(arguments[i], x, this.currentY); + + x += this.columnWidth; + } + + this.currentY += this.lineHeight; + + }, + /** * Visually renders a QuadTree to the display. * @method Phaser.Utils.Debug#renderQuadTree @@ -399,14 +429,42 @@ Phaser.Utils.Debug.prototype = { color = color || 'rgb(255,255,255)'; - this.start(x, y, color); - this.line('Sprite Collision: (' + sprite.width + ' x ' + sprite.height + ')'); + this.start(x, y, color, 100); + + this.line('Body: (width: ' + sprite.width + ' height: ' + sprite.height + ')'); this.line('left: ' + sprite.body.touching.left); this.line('right: ' + sprite.body.touching.right); this.line('up: ' + sprite.body.touching.up); this.line('down: ' + sprite.body.touching.down); - this.line('velocity.x: ' + sprite.body.velocity.x); - this.line('velocity.y: ' + sprite.body.velocity.y); + this.stop(); + + }, + + /** + * Render Sprite Body Physics Data as text. + * @method Phaser.Utils.Debug#renderBodyInfo + * @param {Phaser.Sprite} sprite - The sprite to be rendered. + * @param {number} x - X position of the debug info to be rendered. + * @param {number} y - Y position of the debug info to be rendered. + * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string). + */ + renderBodyInfo: function (sprite, x, y, color) { + + color = color || 'rgb(255,255,255)'; + + this.start(x, y, color, 220); + + this.splitline('Width: ' + sprite.width, 'Height: ' + sprite.height); + this.splitline('x: ' + sprite.body.x.toFixed(2), 'y: ' + sprite.body.y.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); + this.splitline('acceleration x: ' + sprite.body.acceleration.x.toFixed(2), 'y: ' + sprite.body.acceleration.y.toFixed(2)); + this.splitline('velocity x: ' + sprite.body.velocity.x.toFixed(2), 'y: ' + sprite.body.velocity.y.toFixed(2)); + this.splitline('motion x: ' + sprite.body.motionVelocity.x.toFixed(2), 'y: ' + sprite.body.motionVelocity.y.toFixed(2)); + this.splitline('sleeping: ' + sprite.body.sleeping, 'sleepTimer: ' + sprite.body._sleepTimer.toFixed(2)); + this.splitline('sleepMin x: ' + sprite.body.sleepMin.x, 'y: ' + sprite.body.sleepMin.y); + this.splitline('sleepMax x: ' + sprite.body.sleepMax.x, 'y: ' + sprite.body.sleepMax.y); this.stop(); },