andrewspy Posted April 19, 2016 Share Posted April 19, 2016 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 More sharing options...
drhayes Posted April 19, 2016 Share Posted April 19, 2016 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 More sharing options...
andrewspy Posted April 19, 2016 Author Share Posted April 19, 2016 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 More sharing options...
andrewspy Posted April 20, 2016 Author Share Posted April 20, 2016 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 More sharing options...
drhayes Posted April 20, 2016 Share Posted April 20, 2016 Here you go: https://jsfiddle.net/drhayes/m74uLhke/1/ What I did was create an entirely separate property, "this.shadowOffset". We tween the shadowOffset and, in an update function, make sure the shadow is always positioned on the sprite we care about + the offset. Take a look, let me know if that works. Link to comment Share on other sites More sharing options...
andrewspy Posted April 20, 2016 Author Share Posted April 20, 2016 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 More sharing options...
drhayes Posted April 21, 2016 Share Posted April 21, 2016 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 More sharing options...
andrewspy Posted April 22, 2016 Author Share Posted April 22, 2016 Noted. Thanks for showing the way. I'll give it a try later. Cheers! and Have a nice day! Link to comment Share on other sites More sharing options...
Recommended Posts