Jump to content

Shadow tween not in-sync on drag event


andrewspy
 Share

Recommended Posts

Hi,

I am new to Phaser, and am trying to simulate shadow effect while onDragStart(), onDragStop(), and onDragUpdate() using multiple tweens. I noticed the shadow tween does not seem to be "in-sync" and if you pick up the item and move it before the tween is completed, the shadow is somehow stuck at the original place.

Below is the code:-

var game = new Phaser.Game(800, 600, Phaser.AUTO);

// Create our 'main' state that will contain the game
var mainState = {
	preload: function () {
		game.scale.pageAlignHorizontally = true;
		game.scale.pageAlignVertically = true;
		
		game.stage.backgroundColor = '#eeeeee';
		
		// Load the bird sprite
		game.load.image('bird', 'assets/bird.png');
	},
	
	create: function () {
		var bird,
			shadow;
		
		// Display the shadow on the screen
		shadow = this.game.add.sprite(game.world.centerX, game.world.centerY, 'bird');
		shadow.anchor.set(0.5);
		shadow.tint = 0x000000;
		shadow.alpha = 0.5;
		
		// Display the bird on the screen
		bird = this.game.add.sprite(game.world.centerX, game.world.centerY, 'bird');
		bird.anchor.set(0.5);
		
		bird.inputEnabled = true;
		bird.input.enableDrag(false, true); // lockCenter, bringToTop
		
		bird.events.onDragStart.add(this.onDragStart, this);
		bird.events.onDragStop.add(this.onDragStop, this);
		bird.events.onDragUpdate.add(this.onDragUpdate, this);
		
		this.bird = bird;
		this.shadow = shadow;
	},
	
	onDragStart: function (sprite, pointer) {
		var shadow = this.shadow;
		
		this.add.tween(sprite.scale).to({x: 1.1, y: 1.1}, 500, Phaser.Easing.Exponential.Out, true);
		this.add.tween(shadow).to({x: shadow.x + 10, y:  shadow.y + 10}, 500, Phaser.Easing.Exponential.Out, true);
		this.add.tween(this.shadow.scale).to({x: 1.1, y: 1.1}, 500, Phaser.Easing.Exponential.Out, true);
	},
	
	onDragStop: function (sprite, pointer) {
		var shadow = this.shadow;
		
		this.add.tween(sprite.scale).to({x: 1, y: 1}, 500, Phaser.Easing.Exponential.Out, true);
		this.add.tween(shadow).to({x: sprite.x, y: sprite.y}, 500, Phaser.Easing.Exponential.Out, true);
		this.add.tween(shadow.scale).to({x: 1, y: 1}, 500, Phaser.Easing.Exponential.Out, true);
	},
	
	onDragUpdate: function (sprite, pointer) {
		var shadow = this.shadow;
		
		shadow.x = sprite.x + 10;
		shadow.y = sprite.y + 10;
	}
};

// Add and start the 'main' state to start the game
game.state.add('main', mainState);
game.state.start('main');

Can someone advice how could I fixed the problem and what's the best recommendation for using multiple tweens on the same sprite. Thanks!

 

Regards,
Andrew

Link to comment
Share on other sites

Your problem is in this line in onDragStart:

this.add.tween(shadow).to({x: shadow.x + 10, y:  shadow.y + 10}, 500, Phaser.Easing.Exponential.Out, true);

In one place in the code you're telling Phaser to move the shadow.x and shadow.y via a tween. In onDragUpdate, you're telling Phaser to move your shadow to the position of the sprite.

You could either not use a tween on the position in onDragStart like you're doing there, or you could cancel the tween in onDragUpdate. Something like "this.spriteTween = this.add.tween(shadow).to(.......);" in onDragStart, and then "if (this.spriteTween) { this.tweens.remove(this.spriteTween); this.spriteTween = null; }" in onDragUpdate.

Link to comment
Share on other sites

My intention is to have the shadow following the sprite, and at the same time, scale the shadow by 10% and offset by 10px to simulate picking up on the sprite. Anyway, I have tested both of your suggestion, the shadow is still stuck with the initial position if you drag it click and drag it fast enough.

I have added a jsfiddle.net on original issue for your testing purposes. Thanks!

 

Link to comment
Share on other sites

After playing with the code a bit, I noticed that onDragUpdate() event will be dispatched, even if there is no movement on the input. Which means there is no point on having a tween inside onDragStart() if you need to stop it onDragUpdate(). Is that the correct behaviour? Is there anyway we can stop the tween only when we detected movement during onDragUpdate()? Thanks!

Link to comment
Share on other sites

Yes, it is working as expected now. However I don't think that's the intended way to use update() instead of onDragUpdate() for my purpose. It seems something is not right with the way onDrag() handle sprite position tweening.

On a separate case, I intend to move a sprite up from the cursor (i.e. so that the sprite is not blocked by the cursor/finger) while dragging, however I notice once I start dragging the sprite, it's position will always fallback to the initial position. Any advice on solution to this? Here's the code: https://jsfiddle.net/andrewspy/dymbwubg/

Thanks in advance!

Link to comment
Share on other sites

20 hours ago, andrewspy said:

However I don't think that's the intended way to use update() instead of onDragUpdate() for my purpose. It seems something is not right with the way onDrag() handle sprite position tweening.

What do you mean? The onDrag methods don't know about tweens at all. The way you had it written before is you had two different things setting the shadow position: the tween, and your code in onDragUpdate. These two pieces of code would fight to set the shadow position and usually do the wrong thing. In the version I wrote, now there's only one thing setting the shadow position: update.

You could probably solve the next problem in a similar way. You could make a "this.spriteOffset" and tween those values separate from updating the sprite's position. You might end up setting a "this.spritePos.x" and "this.spritePos.y" instead of setting the sprite's position directly to not have the same problem as before.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...