Home Tutorials Forums Articles Blogs Movies Library Employment Press
Old 01-02-2009, 01:53 PM   #1
bobaloo1349
Helllooooo!
 
Join Date: Mar 2007
Posts: 52
Default Trouble with tweenlite used in for loop

I'm developing a board game in AS2, using tweenlite to move the players after a dice roll. Each player is a human character facing different directions in its timeline, and a walking animation of each character in that timeline. To keep the walking relatively smooth, I have the player movement set up in a FOR LOOP to iterate x times (the dice roll = moveCount) and walk from space to space, turning direction if the board direction changes.

The only challenge is when the dice rolls a number higher than 1, the player piece sort of "scoots" directly to that next space (kind of running in air), not stepping thru the tween the required number of times.

Here's a simplified version of my code:

ActionScript Code:
//This is part of the function that calls the movePlayer function, which contains the TweenLite.to    //step the number of spaces on this roll    for (var i:Number = 1; i <= moveCount; i++)    {            movePlayer(playerID, startNum, nextNum);          startNum++;       nextNum++;    }*/ function movePlayer(playerID:Number, startNum:Number, nextNum:Number):Void {        //move the current player, exec walk motion while tweening    TweenLite.to (currentPlayer, 2,               {                  _x:(thePoint.x)-offsetX,                  _y:(thePoint.y)-offsetY,                  delay:.25,                  onStart:doTheWalk,                  onStartParams:[currentPlayer, walkDir],                  onComplete:doTheRest,                  onCompleteParams:[currentPlayer, restDir]                }             );     } //rotate player into exit position function doTheExit(thePlayer:MovieClip, exitDirection:String):Void {    thePlayer.gotoAndPlay(exitDirection);    } //player walk animation function doTheWalk(thePlayer:MovieClip, walkDirection:String):Void {    thePlayer.gotoAndPlay(walkDirection); } //rotate player into rest position function doTheRest(thePlayer:MovieClip, restDirection:String):Void {    thePlayer.gotoAndPlay(restDirection);    }


I've tried using the overwrite property to prevent the next tween from running before the current one finishes to no avail. I've also tried using a simple timing loop within the for...next code, that doesn't work either.

Any ideas what I'm missing here? I'm pulling my hair out (and I don't have too much of that left).
bobaloo1349 is offline   Reply With Quote
Old 01-02-2009, 03:13 PM   #2
rrh
throw a trace() in there
 
Join Date: Dec 2006
Posts: 1,982
Default

Create an array and push all of these to it:
ActionScript Code:
{                  _x:(thePoint.x)-offsetX,                  _y:(thePoint.y)-offsetY,                  delay:.25,                  onStart:doTheWalk,                  onStartParams:[currentPlayer, walkDir],                  onComplete:doTheRest,                  onCompleteParams:[currentPlayer, restDir]                }
Then, inside doTheRest, test to see if the array is empty, if it isn't, shift another entry off the array and tween to that entry.
rrh is offline   Reply With Quote
Old 01-04-2009, 05:33 AM   #3
invision-studios
Registered User
 
Join Date: Jun 2008
Posts: 33
Default

RRH,

Are you suggesting I store all the parameters for the tween in an array, then pull those parameters into the tweenlite code? I didn't think that was possible.

Can you give me a little more detail? I'm not sure I understand what you're suggesting in your reply.
invision-studios is offline   Reply With Quote
Old 01-04-2009, 05:04 PM   #4
rrh
throw a trace() in there
 
Join Date: Dec 2006
Posts: 1,982
Default

Array.push(object) pushes the object onto the end of the array.
Array.shift() pulls an object off the start of the array. Use this instead of Array.pop() because pop would give you the reverse order from how you put them into the Array.

You'll also need to actually vary the _x and _y value for each step. I notice now that the for loop doesn't actually change any of the values passed to the .to() call. It changes two of the three parameters passed to the movePlayer() function but none of those parameters are use in the .to() call. Obviously if you just use the same values five times in a row, that's not going to make a series of steps, that's going to make one step, followed by four turns of standing still.
rrh is offline   Reply With Quote
Old 01-04-2009, 11:29 PM   #5
invision-studios
Registered User
 
Join Date: Jun 2008
Posts: 33
Default

The intent of the "startNum++;" and "nextNum++;" statements is to increment the space count after each calling of the advancePlayer function.

Shouldn't the FOR loop increment those every time it loops back thru?
invision-studios is offline   Reply With Quote
Old 01-05-2009, 12:25 AM   #6
rrh
throw a trace() in there
 
Join Date: Dec 2006
Posts: 1,982
Default

I don't see any function called advancePlayer. I do see one called movePlayer.

When I said
Quote:
It changes two of the three parameters passed to the movePlayer() function
startNum and nextNum were the two parameters I was referring to. But notice I also said
Quote:
but none of those parameters are use[d] in the .to() call.
So, yes they are being incremented, but why does it matter if they aren't being used?
rrh is offline   Reply With Quote
Old 01-05-2009, 01:37 AM   #7
invision-studios
Registered User
 
Join Date: Jun 2008
Posts: 33
Default Trouble with tweenlite used in for loop

Sorry, I meant movePlayer function. Actually, I oversimplified the code for this forum.

The actual move of the player is in the _x and _y coordinates of the to. call. The doTheWalk() function is called at the beginning of the to. call and runs while the player is moving across the board to simulate leg movement.

The FOR loop should call the to. function, move the player a single space (while moving his legs in place with the doTheWalk() function), then return to the FOR loop. It should then increment the nextSpace until the move count is complete.

Instead, the player floats directly to the final space in the move, rather than following the path of the game board one space at a time.


Here's the real code. Keep in mind there are four possible players with their own quadrants on each board space, so a lot of this is calculating which quad each player should land on. Spaces are movieClips instances named "space01" etc.

I appreciate your time looking at this, rrh.


ActionScript Code:
function advancePlayer(playerID:Number, moveCount:Number):Void {     //current player location     var currentLocation:String = currentSpace[playerID];     //extract number from currentLocation     var origNum:String = substring(currentLocation, 6, 2);     //add the moveCount to currentLocation     var newNum:Number = Number(origNum) + Number(moveCount);     //build string for the new space, store in array for next move     var newSpace:String;     if (newNum < 10)     {         newSpace = "space0" + newNum;     }     else     {         newSpace = "space" + newNum;     }     currentSpace[playerID] = newSpace; //store in Array     //build var to step forward one from current space     var startNum:Number = Number(origNum);     var nextNum:Number = Number(origNum) + 1;     //step the number of spaces on this roll     for (var i:Number = 1; i <= moveCount; i++)     {         movePlayer(playerID,startNum,nextNum);         startNum++;         nextNum++;     } } ///////////////////////////////// physically move player object function movePlayer(playerID:Number, startNum:Number, nextNum:Number):Void {     //map playerID numbers to MC names     var playerName:String;     switch (playerID)     {         case 1 :             playerName = "player2_mc";             break;         case 2 :             playerName = "player3_mc";             break;         case 3 :             playerName = "player4_mc";             break;         default :             playerName = "player1_mc";             break;     }     //build string for the spaces     var startString:String;     if (startNum < 10)     {         startString = "0" + startNum;     }     else     {         startString = String(startNum);     }     var nextSpace:String;     if (nextNum < 10)     {         nextSpace = "space0" + nextNum;     }     else     {         nextSpace = "space" + nextNum;     }     // build location expression to determine new space's x/y coordinates (in proper quadrant)     var theSpace:MovieClip = eval(nextSpace + ".quad" + Number(playerID));     //create object to mark x/y coord of quadrant     var thePoint:Object = {x:(theSpace._x), y:theSpace._y};     //convert playerName string to MovieClip object     var currentPlayer:MovieClip = eval(playerName);     //map local x/y to stage x/y     theSpace.localToGlobal(thePoint);     //coordinate adjustments for proper placement (bug in localToGlobal?)     switch (playerID)     {         case 1 :             offsetX = 30;             offsetY = 24;             break;         case 2 :             offsetX = 19;             offsetY = 12;             break;         case 3 :             offsetX = 49;             offsetY = 12;             break;         default :             offsetX = 0;             offsetY = 29;             break;     }     //rotate player - id current space     var xID:String = "exit" + startString;     //build string for the rest direction     var r:Number = Number(startString);     r++;     var rID:String;     if (r < 10)     {         rID = "rest0" + r;     }     else     {         rID = "rest" + r;     }     //get exit directions from spaceDirection object     var exitDir:String = spaceDirection[xID];     var restDir:String = spaceDirection[rID];     doTheExit(currentPlayer,exitDir);     //create pointer to walk animation in player movieclip     var walkDir:String = "walk_" + exitDir;     //move the current player, exec walk motion while tweening     TweenLite.to(currentPlayer,2,{ _x:(thePoint.x) - offsetX, _y:(thePoint.y) - offsetY, delay:.25, onStart:doTheWalk, onStartParams:[currentPlayer, walkDir, nextSpace, playerID], onComplete:doTheRest, onCompleteParams:[currentPlayer, restDir], overWrite:0}); } //rotate player into exit position function doTheExit(thePlayer:MovieClip, exitDirection:String):Void {     thePlayer.gotoAndPlay(exitDirection);     //trace("doing the exit!!"); } //player walk animation function doTheWalk(thePlayer:MovieClip, walkDirection:String, nextSpace:String, playerID:Number):Void {     thePlayer.gotoAndPlay(walkDirection);     adjustPlayerDepth(thePlayer,nextSpace,playerID);     //trace("doing the walk!!"); } //rotate player into rest position function doTheRest(thePlayer:MovieClip, restDirection:String):Void {     thePlayer.gotoAndPlay(restDirection);     //trace("doing the rest!!");     trace(thePlayer + " depth: " + thePlayer.getDepth()); }

Last edited by invision-studios; 01-05-2009 at 01:38 AM. Reason: fix wrapping problem
invision-studios is offline   Reply With Quote
Old 01-05-2009, 02:45 AM   #8
rrh
throw a trace() in there
 
Join Date: Dec 2006
Posts: 1,982
Default

Okay. That makes sense. We do sometimes get people who haven't fully grasped how a loop or function call works.

So back to my original idea, yeah, you can store anything in an array, so you could easily enough push the { object } into the array and then in your onComplete function, you pull one from the array, and tween there. (And if the array's length==0 then it's finished moving.)


Another approach is you could build a nested object from the last square backwards and then pass that through the parameters:
ActionScript Code:
var lastStep:Object = {                  _x:(thePoint.x)-offsetX,                  _y:(thePoint.y)-offsetY,                   delay:.25,                   onStart:doTheWalk,                   onStartParams:[currentPlayer, walkDir],                   onComplete:doTheRest,                   onCompleteParams:[currentPlayer, restDir]  } var otherStep:Object = lastStep; for (from second last step backwards to first step) { calculate position for another step    otherStep = {                  _x:(thePoint.x)-offsetX,                  _y:(thePoint.y)-offsetY,                   delay:.25,                   onStart:doTheWalk,                   onStartParams:[currentPlayer, walkDir],                   onComplete:doNextStep,                   onCompleteParams:[currentPlayer, otherStep]    } } doNextStep(currentPlayer,otherStep);

Then in your doNextStep function, you call the TweenLite.to()
rrh is offline   Reply With Quote
Old 01-07-2009, 07:41 AM   #9
invision-studios
Registered User
 
Join Date: Jun 2008
Posts: 33
Default

FWIW, the script actually pulls the x y values from the board pieces, which are instances of a movieclip w/embedded instances of the quadrants movieclip. I was trying to be efficient... and thinking there might be changes made to the board layout in the future. Since all the space instances are named, the player always knows which space to go to next.

I just don't see what advantage there would be to having to create an array for the entire game board at this point.

One thing I haven't gotten answered here or on any other forum about this issue -- is my logic sound? It sure seems like the tweenlite tweens are all firing consecutively without actually running back thru the for loop. Even with a delay parameter set in tweenlite, even with the overwrite set to not step on the next tween. Is tweenlite doing something that causes the timeline to flake out? Just curious.

Still looking for an answer. Sigh.

RRH, I truly appreciate your assistance.
invision-studios is offline   Reply With Quote
Old 01-07-2009, 03:10 PM   #10
rrh
throw a trace() in there
 
Join Date: Dec 2006
Posts: 1,982
Default

I'm not telling you to create an array for the entire board, but an array of the moves that this piece is going to make in this turn.

I think the sticking point is you're expecting the .to() call to not complete until the entire tween is finished. The .to() call just *starts* the tween, so what you are doing is starting all the tweens at the same time.
rrh is offline   Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
trouble implementing a hit test object newsteve ActionScript 3.0 1 10-21-2008 05:59 PM
TweenMax Released! - TweenLite on Steroids greensock ActionScript 3.0 2 04-09-2008 07:27 PM
TweenMax Released! - TweenLite on Steroids greensock ActionScript 2.0 5 04-08-2008 06:42 PM
Trouble loading JPGs into MCs from XML file hgzee ActionScript 2.0 7 04-21-2007 12:13 PM
onMotionFinished trouble - or is it attachMovie trouble? fourthdimension ActionScript 2.0 4 03-11-2005 07:02 AM


All times are GMT. The time now is 05:44 PM.

///
Follow actionscriptorg on Twitter

 


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Ad Management plugin by RedTyger
Copyright 2000-2013 ActionScript.org. All Rights Reserved.
Your use of this site is subject to our Privacy Policy and Terms of Use.