playif / play_phaser

A Dart port for Phaser 2D game engine.
MIT License
71 stars 13 forks source link

Question - Is it possible to make a function not return until a tween (started in the same function) finishes? #30

Closed TheIceMageX50 closed 9 years ago

TheIceMageX50 commented 9 years ago

Posted a question on HTML5 gamedev forum but unfortunately the one person trying to help so far doesn't have experience with Dart...so I'm wondering if anyone reading this here might know if there's a way to achieve this.

derrick56007 commented 9 years ago

Not entirely sure what you implied by "I want my moveTo function to only return when the tween it does is complete" but you could just call a function on the onComplete signal.

create() {
  image = game.add.sprite(game.world.centerX, game.world.centerY, 'car');
  image.anchor.set(0.5);

  Tween tween = game.add
      .tween(image)
      .to({'x': 300,}, 500, Easing.Linear.None, false, 0, 0, false)
      .yoyo(true)
      .repeat(1)
      .start();

  tween.onComplete.add((_) {
    functionToCall('args');
  });
}

void functionToCall(args) {
  //move player
}
TheIceMageX50 commented 9 years ago

Perhaps seeing the code would help? I dunno It's here

The return type is void but it still "returns" in the sense that it goes back to whatever called it. What I was saying is I want it to return only once the tween is finished, i.e. if it was main() that called moveTo() then when the code is running main() should call moveTo() and it should not get back to main until the tween is all done. Does that make it any clearer?

derrick56007 commented 9 years ago

I think I understand now. This can be done using Futures.

Future<String> waitForTween(Tween tween, returnValue) async{
  Completer completer = new Completer();
  tween..start()..onComplete.add((_){
    completer.complete(returnValue);
  });

  return completer.future;
}

create() async {

  sprite = game.add.sprite(100, 100, 'diamond');

  Tween tween = game.add.tween(sprite).to({
      'x': 300,
  }, 500, Easing.Linear.None, false, 0, 0, false)
  .yoyo(true)
  .repeat(1);

  String returnValue = await waitForTween(tween, 'returned');

  print(returnValue);
  print('continuing on');
}

In this case the function "waitForTween" would be your moveTo function. Make sure to import dart:async

TheIceMageX50 commented 9 years ago

Oh yes, thanks! I'll try this then. I actually have used Futures in one or two parts of this project already but I guess having used it so infrequently I didn't come up with a solution like this...I tried messing around earlier with Futures but I guess I never thought to try something with a Completer.

derrick56007 commented 9 years ago

No problem! Good luck on your project.

TheIceMageX50 commented 9 years ago

Hmm. I think I am going in a good direction with this but now I have a follow up question if you don't mind since this doesn't seem to have entirely solved my "issue". To elaborate, why I wanted to do this in the first place is for making enemy characters move, and only move one at a time so that the second waits for the first to finish moving and so on.

Now, having implemented code like what you showed above they do seem to wait but only until the first "step" (this is a tile-based game) of the move. Is it something to do with how I'm making multiple tween.to() calls, set up via a for loop, and for some reason that makes the onComplete fire when the result of the first tween.to() is done? If so, what would I need to do to actually make it fire just when all those tweens are done?

derrick56007 commented 9 years ago

Do you want for the enemy to finish their movement completely, and then go on to the next? Or each enemy takes a step first?

TheIceMageX50 commented 9 years ago

I want the enemy to finish moving completely and then go to the next.

derrick56007 commented 9 years ago

It seems like there is no such thing as an onComplete for a chain of tweens. You are either going to have to manage tween completions yourself or request this feature.

TheIceMageX50 commented 9 years ago

That's unfortunate...how would I go about managing Tween completions? Or alternatively would there be any other way to (even if somewhat hackily) achieve what I want?

derrick56007 commented 9 years ago

Not at my computer right now, but you could make all of the tweens separate and store them in a List. Start the first one and when it finishes call the next in that list and make it so that it returns on the last tween onComplete.

TheIceMageX50 commented 9 years ago

Oooh, thanks. Hopefully that'll work out. :)

TheIceMageX50 commented 9 years ago

Well yea, that approach seems to have worked perfectly. The reformed code can be seen over here. Once again, thanks for the help! :smile:

derrick56007 commented 9 years ago

No problem! :)