【问题标题】:Which is faster when animating the UI: a Control or a Picture?动画 UI 时哪个更快:控件还是图片?
【发布时间】:2012-10-17 22:59:43
【问题描述】:

/我正在使用以下设备构建计算机并在其上进行测试: {1 GB RAM(现为 1.5 GB)、1.7 GHz Intel Pentium 处理器、ATI Mobility Radeon X600 GFX}

我需要缩放/变换控件并使其流畅。目前,我每 24-33 毫秒(30 fps)±3 像素处理一次控件的大小和位置。当我向图像添加“淡入淡出”效果时,它会平滑地淡入淡出,但它的大小只有 25x25 像素。控件的大小为 450x75 像素到 450x250 像素。在宝石迷阵 3 等 2D 游戏中,精灵的动画没有断断续续的动画。

正如标题所暗示的那样:在处理器上哪个更容易/更快:动画位图(在动画期间将其渲染到父控件)或动画控件它本身?

编辑: 嘿,我认为这是一个很有帮助的社区,而不是一个对似乎没有挑战性的问题进行评分的社区! (而且我在这里看到了更荒谬的问题,评分也更高!)请先给我留言,然后再对我的问题进行负面评价!

【问题讨论】:

  • 为什么不自己测试一下呢?有大量的基准测试方法/工具。
  • 我没有时间...我忙于其他需要尽快完成的任务。此外,这个问题还没有在网上问过(据我所知)。 ;)
  • 什么 API?表格? WPF? XNA? ActiveX?
  • @DourHighArch 对不起,我想我添加了。赢表格。 (使用计时器)

标签: c# winforms animation bitmap controls


【解决方案1】:

我设法在我的日程安排中找到了一些空闲时间,以快速启动一个新项目。我敢肯定我的时间本可以花在其他地方更好,但希望我的鞋子里的其他人可能会发现这个有用...

答案是:控件上的图片。将位图渲染到画布上时,几乎不会触发任何事件(如果有的话)。至于控件,它充满了事件——一些是链式的,一些是循环式的,还有递归的添加,所以一个简单的“LocationChanged”事件甚至不会覆盖引擎盖下实际发生的一半。

对于在运行时应用了很多动态动画的控件,我会做的是开发一个两部分集:控件 [渲染] 模板或活动界面(当控件处于静止状态或在动画播放之前),以及具有基本定义属性的动画结构,例如显示图像[渲染的控件]、矩形边界和任何稍后可能应用的动画算法。

编辑:根据要求,以下是之前和之后的代码示例:

// This is the triggering event of the translating animation
private void object_Click(object sender, EventArgs e)
{
      // the starting point is at (75,75)
      element.Transform(new Point(500, 250));
}

之前:

public class ControlElement : UserControl
{
      private Timer tick;
      private Point pT0;
      public ControlElement() : base()
      {
            tick = new Timer();
            tick.Interval = 30; // about 30fps
            tick.Tick += new EventHandler(tick_Tick);
      }
      void tick_Tick(object sender, EventArgs e)
      {
            // get the new point from distance and current location/destination
            this.Location = Utils.Transform(this.Location, pT0, 3);
            if ((pT0.X - this.Location.X)+(pT0.Y - this.Location.Y) <= 0)
            {
                this.Location = pT0;
                tick.Stop();
                //this.Visible = true;
            }
      }
      public void Transform(Point destination)
      {
            pT0 = destination;
            //this.Visible = false;
            tick.Start();
      }
}

之后:我使用DrawToBitmap 功能创建了一个包含控件外观图片的类。它仍然包含与上面相同的动画方法。我不得不添加LocationLocationChanged 元素,因为这个类不再是一个控件。如果需要访问实际控件时,我会停止渲染并显示它自身的控件实例。
这是渲染调用:

void element_LocationChanged(object sender, EventArgs e)
{
      canvas.Invalidate();
}
void canvas_Paint(object sender, PaintEventArgs e)
{
      if (element != null)
      {
            Bitmap bmp = new Bitmap(element.Display);
            Pen p = new Pen(Color.FromArgb(128, 128, 128), 1);
            e.Graphics.DrawImage(bmp, element.Location);
            e.Graphics.DrawRectangle(p, 
                 element.Location.X, element.Location.Y, 
                 bmp.Width, bmp.Height);
      }
}

【讨论】:

  • 感谢您的回复,但您是在 System.Windows.Controls.Canvas 上绘制自己的 UI 吗?这不会继承所有Control 事件吗?一些代码会很有帮助。
  • 我的画布是一个继承 System.Windows.Forms.Panel 控件并启用优化的双缓冲、用户绘画和调整大小重绘属性以消除闪烁的类。之前,我创建了一个普通的 UserControl 并操作了它的属性;现在我只绘制控件的渲染位图,并且仅在静止时显示控件本身。
猜你喜欢
  • 2014-05-16
  • 2011-03-26
  • 2012-06-12
  • 2010-09-29
  • 2011-03-14
  • 2012-07-15
  • 2011-09-22
  • 2018-10-31
  • 1970-01-01
相关资源
最近更新 更多