Hugbot Posted April 11, 2014 Share Posted April 11, 2014 Hello there. Been playing with Phaser, it's pretty cool. Not sure if this has been asked before, I tried fairly hard in order to answer this on my own. I have a sprite (a space ship) that has has had input.enableDrag set for it. This works without issue.I have also enabled arcade physics. Which also work fine. The issue here is that when I drag the sprite the body associated with the sprite, the body lags behind on movement. This creates an interesting "race condition" where the body is updating to the position that the sprite actually is at, and in turn is having the wrong collision location being checked. I'm not quite sure how to fix this. Are there any suggested work arounds or ways to fix this? Link to comment Share on other sites More sharing options...
Hugbot Posted April 11, 2014 Author Share Posted April 11, 2014 Is there anything I can add to help out for this question? Am I misinterpreting how Phaser's physics work. Please let me know if I can provide anything else to help with my question. Link to comment Share on other sites More sharing options...
rich Posted April 12, 2014 Share Posted April 12, 2014 This should help: http://examples.phaser.io/_site/view_full.html?d=arcade%20physics&f=gravity+and+drag.js&t=gravity%20and%20drag Link to comment Share on other sites More sharing options...
Hugbot Posted April 15, 2014 Author Share Posted April 15, 2014 Rich, Thank you so much for taking the time to respond to this question. I really appreciate the input you provided, however, by default my Ship "class" already disabled the moves property for the body portion of the sprite. Is there something else that could be contributing to this? Below is my class declaration for the ship.Ship = function(x, y) { //Object configurations // self = this; this.imageName = 'rocket'; this.fakeStartY = 0; this.fakeEndY = -1000; this.fakeVelocityY = 0; this.fakeAccelerationY = 1; this.distanceTravelledY = 0; this.playerPressingShip = false; this.shipMaxYVelocity = 10; this.numberOfHitsCanTake = 10000; //Phaser creation Phaser.Sprite.call(this, game, x, y, this.imageName); //Phaser Configurations this.anchor.setTo(0.5, 0.5); this.inputEnabled = true; this.alive = true; game.add.existing(this); game.physics.enable(this, Phaser.Physics.ARCADE); this.input.enableDrag(); this.input.allowVerticalDrag = false; this.body.collideWorldBounds = true; this.body.moves = false; this.body.immovable = true; this.body.bounce.set(0);};Ship.prototype = Object.create(Phaser.Sprite.prototype);Ship.prototype.constructor = Ship;Ship.prototype.update = function() { this.detectPlayerInput(); this.performFakePhysicsStep(); if(this.numberOfHitsCanTake == 0) { this.body.velocity.setTo(0,0); this.kill(); this.destroy(); }};Ship.prototype.detectPlayerInput = function() { if((game.input.mousePointer.isDown || game.input.pointer1.isDown) && Phaser.Rectangle.contains(this.body, game.input.worldX, game.input.worldY)) { this.playerPressingShip = true; } else { this.playerPressingShip = false; }};Ship.prototype.performFakePhysicsStep = function() { if(this.playerPressingShip) { this.body.velocity.y += this.fakeAccelerationY; if(this.body.velocity.y > this.shipMaxYVelocity) { //console.log("derp"); this.body.velocity.y = this.shipMaxYVelocity; } } else { this.body.velocity.y -= (this.fakeAccelerationY*.5); if(this.body.velocity.y < 0) { this.body.velocity.y = 0; } } this.distanceTravelledY += this.body.velocity.y;}; Link to comment Share on other sites More sharing options...
rich Posted April 15, 2014 Share Posted April 15, 2014 Does it still lag (or whatever happens) if you comment out performFakePhysicsStep() in the update? Link to comment Share on other sites More sharing options...
Hugbot Posted April 18, 2014 Author Share Posted April 18, 2014 Hey there Rich! I'm sorry about my delayed response. If I comment that line out it changes nothing, and the bug is still reproducible by dragging the ship. Link to comment Share on other sites More sharing options...
Hugbot Posted April 18, 2014 Author Share Posted April 18, 2014 Hey Rich, In order to provide more information I'm attaching the main state script I'm using for gameplay.var playerShip;function Play() { //var self = this; this.background; this.playerShip; this.shipStartX = 380; this.shipStartY = 500; //0 - randomly generating along x, with random 15 degree angles, at random speeds //1 - generating a line //2 - generating a sin wave this.asteroidGenerationType = 0; this.asteroidGenerationTimer = 0; this.asteroidGenerationTimeLimit = 50; this.asteroidGenerationTypeIsRandom = false; this.asteroidTimerIsRandom = false; this.asteroidTimerRandomMin = 30; this.asteroidTimerRandomMax = 60; this.asteroidMinRotation = 225; this.asteroidMaxRotation = 315; this.asteroidDefaultSpeed = 100;};Play.prototype = { preload: function() { game.load.image('asteroid', 'images/asteroid_1.png'); game.load.image('starfieldBackground', 'images/Starfield.png'); game.load.image('rocket', 'images/white_rocket.png'); game.load.spritesheet('explosion', 'images/cartoon_explosion.png', 283, 237, 10); }, create: function() { game.world.setBounds(0,0,800,600); game.physics.startSystem(Phaser.Physics.ARCADE); //------------------------------------------------------------------------- this.background = game.add.tileSprite(0,0,800,600,'starfieldBackground') //------------------------------------------------------------------------- playerShip = new Ship(this.shipStartX, this.shipStartY); this.playerShip = playerShip; game.camera.follow(this.playerShip, Phaser.Camera.FOLLOW_LOCKON); //------------------------------------------------------------------------- asteroidGroup = game.add.group(); this.asteroidGroup = asteroidGroup; this.asteroidGroup.enableBody = true; // var style = { font: "52px Arial", fill: "#ffffff", align: "center" }; this.gameOverText = game.add.text(game.world.centerX, game.world.centerY-100, "Game Over!\nWould you like to play again?", style); this.gameOverText.anchor.set(0.5); }, render: function() { // game.debug.spriteBounds(this.playerShip); game.debug.body(this.playerShip); for(var i = 0; i < this.asteroidGroup.children.length; i++) { // game.debug.spriteBounds(asteroidGroup.children[i]); game.debug.body(asteroidGroup.children[i]); } // game.debug.spriteInfo(playerShip, 32, 32); //game.debug.spriteInfo(asteroid, 32, 32); game.debug.text("Distance Travelled: " + this.playerShip.distanceTravelledY, 500, 32); game.debug.text("Asteroid Generation Timer: " + this.asteroidGenerationTimer, 450, 64); }, update: function() { // if(game.input.keyboard.isDown(Phaser.Keyboard.M)) { // this.generateExplosion(200, 200); // } if(!this.playerShip.alive) { //console.log("player is dead"); this.gameOverText.visible = true; } else { this.gameOverText.visible = false; } game.physics.arcade.collide(this.asteroidGroup, this.asteroidGroup); game.physics.arcade.collide(this.playerShip, this.asteroidGroup, this.performShipCollisionWithAsteroidLogic, null, this); this.changeAsteroidGroupsSpeedRelativeToShip(); this.performAsteroidGenerationLogic(); this.moveTileBackgroundBasedOnShipVelocity(this.playerShip); this.modifyAsteroidGroupSpeedBasedOnShipVelocity(this.asteroidGroup, this.playerShip); this.performAsteroidDestroyCheck(); }, performShipCollisionWithAsteroidLogic: function(player, asteroid) { this.generateExplosion(asteroid.x, asteroid.y); asteroid.destroy(); player.numberOfHitsCanTake -= 1; }, generateExplosion: function(x,y) { var explosion = game.add.sprite(x, y, 'explosion', 5); animation = explosion.animations.add('explode'); explosion.animations.play('explode', 25, false); explosion.anchor.setTo(.5,.5); explosion.scale.setTo(.5,.5); animation.onComplete.add(function() { explosion.kill(); }, this); }, changeAsteroidGroupsSpeedRelativeToShip: function() { for(var i = 0; i < this.asteroidGroup.children.length; i++) { if(this.playerShip.body.velocity.y == 0) { this.asteroidGroup.children[i].asteroidDefaultSpeed = 300; } else { this.asteroidGroup.children[i].asteroidDefaultSpeed = 100; } } }, performAsteroidDestroyCheck: function() { for(var i = 0; i < asteroidGroup.children.length; i++) { asteroidGroup.children[i].performDestroyLogic(this.playerShip); } }, performAsteroidGenerationLogic: function() { this.asteroidGenerationTimer += 1; if(this.asteroidGenerationTimer > this.asteroidGenerationTimeLimit) { var leftBounds = game.camera.world.x; var rightBounds = game.camera.world.x + game.camera.width; var startYGeneration = game.camera.y - 50; if(this.asteroidGenerationType == 0) { for(var i = 0; i < (Math.floor(Math.random()*4) + 4); i++) { var selectedPositionX = (Math.random() * (rightBounds - leftBounds)); var selectedRotaion = this.selectRandomNumberInRangeWithIncrement(225,315,15); var topLineBound = 300; var bottomLineBound = 10; var selectedPositionY = game.camera.world.y - (Math.random() * (topLineBound - bottomLineBound)); this.generateAsteroidInGroup(asteroidGroup, selectedPositionX, selectedPositionY, selectedRotaion, this.asteroidDefaultSpeed); } } else if(this.asteroidGenerationType == 1) { var topLineBound = 300; var bottomLineBound = 10; var startY = game.camera.world.y - (Math.random() * (topLineBound - bottomLineBound)); var endY = game.camera.world.y - (Math.random() * (topLineBound - bottomLineBound)); var numberOfAsteroidsToGenerate = Math.floor(Math.random() * 8); var generateSameAngle = Math.floor(Math.random() * 2); this.generateAsteroidGroupLine(asteroidGroup, game.camera.world.x, (game.camera.world.x + game.camera.world.width), startY, endY, numberOfAsteroidsToGenerate, generateSameAngle); } else if(this.asteroidGenerationType == 2) { } else { console.log("asteroid generation type not anticipated"); } this.asteroidGenerationTimer = 0; //Resets the generation type settings if(this.asteroidGenerationTypeIsRandom) { this.asteroidGenerationType = Math.floor(Math.random()*2); if(this.asteroidGenerationType == 0) { this.asteroidTimerIsRandom = false; this.asteroidGenerationTimeLimit = 30; } else if(this.asteroidGenerationType == 0) { this.asteroidTimerIsRandom = true; this.asteroidTimerRandomMin = 30; this.asteroidTimerRandomMax = 50; } } //Resets the timer settings if(this.asteroidTimerIsRandom) { var newTimeOffset = Math.random() * (this.asteroidTimerRandomMax - this.asteroidTimerRandomMin) this.asteroidGenerationTimeLimit = this.asteroidTimerRandomMin + newTimeOffset; } } }, generateAsteroidGroupLine: function(groupToAddTo, startX, EndX, startY, EndY, numberOfAsteroidsToGenerate, generateSameAngle ) { var xStepSize = (EndX - startX)/numberOfAsteroidsToGenerate; var yStepSize = (EndY - startY)/numberOfAsteroidsToGenerate; var currentX = startX; var currentY = startY; var startingAngle = this.selectRandomNumberInRangeWithIncrement(225,315,15); for(var i = 0; i < numberOfAsteroidsToGenerate; i++) { if(!generateSameAngle) { startingAngle = this.selectRandomNumberInRangeWithIncrement(225,315,15); } var new_asteroid = new Asteroid(currentX, currentY); new_asteroid.fireBasedOnAngle(startingAngle, this.asteroidDefaultSpeed); groupToAddTo.add(new_asteroid); //console.log(currentY); currentX += xStepSize; currentY += yStepSize; } }, generateAsteroidInGroup: function(groupToAddTo, startX, startY, startingAngle, startingSpeed) { var new_asteroid = new Asteroid(startX, startY); new_asteroid.fireBasedOnAngle(startingAngle, startingSpeed); groupToAddTo.add(new_asteroid); }, modifyAsteroidGroupSpeedBasedOnShipVelocity: function(asteroidGroup, ship){ for(var i=0; i < asteroidGroup.children.length; i++) { this.modifyAsteroidSpeedBasedOnShipVelocity(asteroidGroup.children[i], ship); } }, modifyAsteroidSpeedBasedOnShipVelocity: function(asteroid, ship) { asteroid.x += ship.body.velocity.x; asteroid.y += ship.body.velocity.y; }, moveTileBackgroundBasedOnShipVelocity: function(ship) { this.background.tilePosition.y += ship.body.velocity.y; }, selectRandomNumberInRangeWithIncrement: function(rangeStart, rangeEnd, incrementStep) { var numberOfIndices = ((rangeEnd - rangeStart)/incrementStep)+1; var randomNum = (((Math.floor(Math.random()*numberOfIndices))*incrementStep)+rangeStart); return randomNum; }}; Link to comment Share on other sites More sharing options...
Hugbot Posted April 26, 2014 Author Share Posted April 26, 2014 Not sure if anyone else has taken a look at this, but i've managed to sort of resolve the issue with this bit of code being applied in the update function.//cludgy fix for draggable body laggingthis.playerShip.body.x = this.playerShip.world.x - this.playerShip.width/2;this.playerShip.body.y = this.playerShip.world.y - this.playerShip.height/2;I'm not thrilled with the solution, so I'd be more than happy to hear any alternative suggestions to this fix as it still lags behind the sprite just a bit. Link to comment Share on other sites More sharing options...
Recommended Posts