Erix
Erix

Reputation: 69

WPF triggering different Storyboard for the same Target multiple times

Creating a card game and when the game starts, 5 cards are given to a hand. Using the storyboard the card goes from the deck to the hand position 0-4 respectively. There is 5 story, one for each 5 hand position.

The story are being called from a for loop which:

The problem is only the last story called from the for loop is being played. If I change the loop number of occurrence, the stories are working for all the positions, but always only play the last one called .

<Page.Resources>

    <Storyboard x:Name="sDeckToHandPositionOne" TargetName="HandPositionOne"> 
        <DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)" To="0" Duration="0:0:1"/>
        <DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.Y)" To="0" Duration="0:0:1"/>
    </Storyboard>

    <Storyboard x:Name="sDeckToHandOne" TargetName="HandPositionOne"> 
        <DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)" To="0" Duration="0:0:1"/>
        <DoubleAnimation Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.Y)" To="0" Duration="0:0:1"/>
    </Storyboard>

</Page.Resources>
RunDeckToHandStory(string target) {

    string myStory = "sDeckToHandPositionOne";
    Storyboard story = (Storyboard)UI.Ctrl.Resources[myStory] as Storyboard;
    var moveX = (DoubleAnimation)story.Children[0];
    var moveY = (DoubleAnimation)story.Children[1];
    moveX.To = ImgHandCoordinates[Position][target] - ImgHandCoordinates[DeckOfCards][0];
    moveY.To = ImgHandCoordinates[Position][target] - ImgHandCoordinates[DeckOfCards][1];
    story.Begin();

}

For (i=0; i<5; i++) {

    int targetHandPosition = i;
    newCard = GetNewCardFromDeck();
    RunDeckToHandStory(targetHandPosition);
    DisplayNewCard(targetHandPosition, newCard);
    ResetDeckCardPosition();

}

note: This is an example, it might contain typo.

Upvotes: 0

Views: 210

Answers (1)

kennyzx
kennyzx

Reputation: 12993

If I understand your problem correctly, you are trying to run a collection of Storyboard sequentially, that is, the next Storyboard needs to wait for the completion of the current Storyboard; however, your code is playing the collection of Storyboard in parallel, and the outcome is, only the last Storyboard is played, the others are simply ignored.

I think you can line up the Storyboards in a queue, and only play the first Storyboard, and register a handler for the Storyboard's Completed event, in which you play the next Storyboard in the queue. Like this

var storyboardQueue = new Queue<Storyboard>();
storyboardQueue.Enqueue((Resources["sDeckToHandPositionOne"] as Storyboard));
storyboardQueue.Enqueue((Resources["sResetPosition"] as Storyboard)); 
storyboardQueue.Enqueue((Resources["sDeckToHandPositionTwo"] as Storyboard));
storyboardQueue.Enqueue((Resources["sResetPosition"] as Storyboard));
storyboardQueue.Enqueue((Resources["sDeckToHandPositionThree"] as Storyboard));
storyboardQueue.Enqueue((Resources["sResetPosition"] as Storyboard));
//... other storyboards

PlayNextStoryBoard(storyboardQueue);

private void PlayNextStoryBoard(Queue<Storyboard> storyboardQueue)
{
    if (storyboardQueue.Count > 0)
    {
        var sb = storyboardQueue.Dequeue();
        sb.Completed += (o, e) =>
        {
            PlayNextStoryBoard(storyboardQueue);
        };
        sb.Begin();
    }
}

Upvotes: 1

Related Questions