【问题标题】:How do I remove flickering from a moving object?如何消除移动物体的闪烁?
【发布时间】:2015-02-25 08:14:15
【问题描述】:

我已经做了几个星期了......归结为最简单的组件,我想以平滑的动作将一个圆圈从屏幕左侧移动到右侧,没有任何闪烁。

这是我的代码:我实例化了一个计时器 (timer1) 并在表单的属性窗口中启用,并尝试了 1-100 之间的值。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        private int _y;
        private int _x;

        public Form1()
        {
            InitializeComponent();
            _x = 0;
            _y = 200;
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillEllipse(Brushes.Green, _x, _y, 30, 30);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            _x += 1;
            Invalidate();  //ie: redraw
        }

    }
}

【问题讨论】:

  • 可以使用双缓冲吗?
  • 那不应该闪烁那么多。您可以将e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; 添加到您的绘画方法中,以使圆圈看起来更平滑一些。不知道你的投诉是什么。如果您正在寻找游戏质量的流畅度,那么您使用了错误的技术。
  • 闪烁消失 this=doublebuffered;但是运动总是会跳动,因为没有与显示器同步。也许使用this 会有所帮助,但我还没有尝试过..
  • 考虑使用Stopwatch 来跟踪实际经过的时间,然后根据Paint 中经过的时间计算_x,而不是在计时器中增加它。然后你可以让你的定时器调用无效。这仍然不会完全顺利,但它比 Timer 回调口吃要好得多。

标签: c# winforms flicker


【解决方案1】:

定时器是离散的,所以总会有一些滞后或卡顿。

当 WPF 内置动画(或一般的对象转换)时,我不会使用 WinForms 执行此类动画。以下 XAML 在 5 秒内平滑地将红点从 (0,200) 动画到 (350,200)动画。

<Canvas>
    <Canvas.Resources>
        <PathGeometry x:Key="AnimationPath">
            <PathGeometry.Figures>
                <PathFigure>
                    <LineSegment Point="0,200" />
                    <LineSegment Point="350,200" />
                </PathFigure>
            </PathGeometry.Figures>
        </PathGeometry>
    </Canvas.Resources>
    <Ellipse Canvas.Top="200" Width="30" Height="30" Fill="Red">
        <Ellipse.RenderTransform>
            <TranslateTransform x:Name="AnimatedTranslation" />
        </Ellipse.RenderTransform>
        <Ellipse.Triggers>
            <EventTrigger RoutedEvent="Path.Loaded">
                <BeginStoryboard>
                    <Storyboard RepeatBehavior="Forever">
                        <DoubleAnimationUsingPath
                            Storyboard.TargetName="AnimatedTranslation"
                            Storyboard.TargetProperty="X"
                            PathGeometry="{StaticResource AnimationPath}"
                            Source="X"
                            Duration="0:0:5" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Ellipse.Triggers>
    </Ellipse>
</Canvas>

【讨论】:

  • 谢谢! '会试试这个。由于我从未使用过 QPF / XAML,我需要弄清楚在哪里粘贴此代码:)....
  • @EdLandau 您需要创建一个 WPF 项目,然后将 XAML 粘贴到将显示的 XAML 编辑器中。不过,WPF 及其编程方式确实与 WinForms 编程有点不同。
  • 你太棒了。谢谢。现在我有了一条可以在隧道尽头用光学习的路径。非常感谢!
  • 快速问题:我希望它可以拉伸到窗口的大小,所以我将 作为父级放置到 并使画布“水平拉伸”......它可以工作...但是有没有办法让结束 LineSegment "X" 的值成为 Canvas.width (到窗口的末尾)?
  • UN*#&$^#@Believable。从 Visual Studio 运行时路径平滑。我发表了它。我将它安装在同一台机器上并运行。这是生涩的。难以置信的。我在 Mac 上使用 Motion5 创建了平滑的动作,导出到 MP4,在 PC 上它很生涩。电脑有那么不稳定吗?!?!?
猜你喜欢
  • 1970-01-01
  • 2012-04-09
  • 2011-07-06
  • 2015-04-05
  • 2017-05-13
  • 1970-01-01
  • 2014-04-21
  • 2010-10-02
  • 1970-01-01
相关资源
最近更新 更多