c# - WPF - Storyboard 完成事件

标签 c# wpf events animation

我正在设计这样的游戏

class Anima
{
    Storyboard story;
    Random rand;
    Canvas canvas;
    Ellipse target;

    public Anima() {
        rand = new Random();
        canvas = new Canvas();
        target = new Ellipse();

        target.Fill = Brushes.Red;
        target.Width = 50;
        target.Height = 50;
        Canvas.SetLeft(target, rand.NextDouble() * 300);
        Canvas.SetTop(target, rand.NextDouble() * 300);
        canvas.Children.Add(target);

        story = new Storyboard();
        story.BeginTime = TimeSpan.FromMilliseconds(rand.Next(500, 5000));

        DoubleAnimation a = new DoubleAnimation();
        a.To = rand.NextDouble() * 300;
        a.Duration = new Duration(TimeSpan.FromMilliseconds(50));

        Storyboard.SetTarget(a, target);
        Storyboard.SetTargetProperty(a, new PropertyPath(Canvas.LeftProperty));
        story.Children.Add(a);

        DoubleAnimation b = new DoubleAnimation();
        b.To = rand.NextDouble() * 300;
        b.Duration = new Duration(TimeSpan.FromMilliseconds(50));

        Storyboard.SetTarget(b, target);
        Storyboard.SetTargetProperty(b, new PropertyPath(Canvas.TopProperty));
        story.Children.Add(b);

        story.Completed += new EventHandler(story_Completed);

        Window win = new Window();

        win.Loaded += delegate(object sender, RoutedEventArgs e) {
            story.Begin();
        };

        win.Content = canvas;
        win.Show();
    }

    void story_Completed(object sender, EventArgs e) {
        int next = rand.Next(500, 5000);
        double left = rand.NextDouble() * 300;
        double top = rand.NextDouble() * 300;

        Console.WriteLine("position: ({0:G6}, {1:G6})", Canvas.GetLeft(target), Canvas.GetTop(target));
        Console.WriteLine("state   : wait for " + next + " ms");
        Console.WriteLine("next    : ({0:G6}, {1:G6})", left, top);
        Console.WriteLine();

        (story.Children[0] as DoubleAnimation).To = left;
        (story.Children[1] as DoubleAnimation).To = top;

        story.BeginTime = TimeSpan.FromMilliseconds(next);
        story.Begin();
    }
}

一切都很好,但我发现椭圆没有得到正确的位置,大约有 2% 到 50% 的错误。 Storyboard.Completed 事件似乎在动画结束前触发。

这是怎么回事?

最佳答案

我建议您使用 CompositionTarget.Rendering 事件或 DispatcherTimer 来控制复杂的动画,尤其是在您开发游戏时。内置动画不够精确,不易控制。

这里有一些链接可以帮助您开始使用 CompositionTarget

How to: Render on a Per Frame Interval Using CompositionTarget

Using the CompositionTarget

Fun with Animation Part 1

关于c# - WPF - Storyboard 完成事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1225968/

相关文章:

C# mongo 附近查询无法找到 $geoNear 的索引

c# - 如何在 WPF 中创建一个带有绑定(bind)的验证文本框,在无效输入后切换回最后一个有效值?

events - Chrome 新标签页事件

c# - 显示错误后如何隐藏错误提供程序?

javascript - 在 div 标签中显示响应

c# - Bing map 在使用自定义图钉时需要大量性能

c# - 阻止函数并等待事件 C#

javascript - 如何在 html 或 Javascript 中创建 "first-load"事件?

c# - 使用Parallel Foreach和WhenAny的多个任务。那可能吗?

wpf - 强制 IDataErrorInfo 验证