Reputation: 343
I have a method that animates the position of a marker on a boardgame. If players rolls the dice and the dice return 4, then marker is moved to a specific position on the board. The animation works fine.
However, the marker moves in a straight line - I would like the marker to move through all the position until it reach the end position.
Here is my int[,]
this.Path = new int[,] { { 0, 0 },{ 40, 50 }, { 95, 45 }, {130,0 }, { 110,-60 }, { 60, -100 }, { 0,-140 }, { -40, -200 }, { -30,-280 }};
It holds the X and Y position relative to startposition(margin).
And the animation method - how can I change it so the player rolls eg. 2 it should animate position 0 and 1 on the array.
private void AnimatePlayerMovement(Player player, int eyes)
{
//This will hold hour animation
Piece.RenderTransform = new CompositeTransform();
//New storyboard
Storyboard storyboard = new Storyboard();
//New DoubleAnimation - Y
DoubleAnimation translateYAnimation = new DoubleAnimation();
translateYAnimation.From = this.Path[player.position - eyes , 1];
translateYAnimation.To = this.Path[player.position , 1];
translateYAnimation.EasingFunction = new ExponentialEase();
translateYAnimation.EasingFunction.EasingMode = EasingMode.EaseOut;
translateYAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
Storyboard.SetTarget(translateYAnimation, Piece);
Storyboard.SetTargetProperty(translateYAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
storyboard.Children.Add(translateYAnimation);
//New DoubleAnimation - X
DoubleAnimation translateXAnimation = new DoubleAnimation();
translateXAnimation.From = this.Path[player.position - eyes, 0];
translateXAnimation.To = this.Path[player.position, 0];
//translateXAnimation.From = this.Path[player.position - eyes, 0];
//translateXAnimation.To = this.Path[player.position, 0];
translateXAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
Storyboard.SetTarget(translateXAnimation, Piece);
Storyboard.SetTargetProperty(translateXAnimation, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
storyboard.Children.Add(translateXAnimation);
//executing the storyboard
storyboard.Begin();
}
Upvotes: 2
Views: 952
Reputation: 2581
Well, here's an ugly solution. It will work playing animation sequentially, one after one.
Let's assume the Marker is a Rectangle
, so, we add some animation on it's TranslateX
and TranslateY
:
<Page.Resources>
<Storyboard x:Name="PathAnimationStory"
Completed="Story_Completed">
<DoubleAnimation x:Name="anim_x"
Duration="0:0:0.5"
Storyboard.TargetName="TargetTranform"
Storyboard.TargetProperty="X"/>
<DoubleAnimation x:Name="anim_y"
Duration="0:0:0.5"
Storyboard.TargetName="TargetTranform"
Storyboard.TargetProperty="Y"/>
</Storyboard>
</Page.Resources>
<Rectangle
Width="50"
Height="50"
Fill="Red"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="TargetTranform" X="0" Y="0"/>
</Rectangle.RenderTransform>
</Rectangle>
Notice the Completed
event handled in the Storyboard
. We need to chain the animation. To do that, handle the Completed
event when the animation stops, it will check if any other points are to be gone through and start the animation again if any:
private void MoveMarker(params double[] co_ordinates)
{
PathAnimationStory.Stop();
if (co_ordinates.Length == 0)
return;
/// the number of co_ordinates must be even
if (co_ordinates.Length % 2 == 1)
return;
Co_ordinates = co_ordinates;
remaining_nodes = co_ordinates.Length / 2;
Story_Completed(default, default);
}
private void Story_Completed(object sender, object e)
{
if(remaining_nodes > 0)
{
int next_node = (int)(Co_ordinates.Length / 2 - remaining_nodes);
anim_x.To = Co_ordinates[2 * next_node];
anim_y.To = Co_ordinates[2 * next_node + 1];
remaining_nodes--;
PathAnimationStory.Begin();
}
}
All done, now let's check our code:
MoveMarker(100, 0, 100, 100, 0, 100, 100, 0);
gives this output:
Which I think somewhat meets your requirement. Hope that helps.
Upvotes: 3