使用 C#/Windows 窗体的简单动画 [英] Simple animation using C#/Windows Forms

查看:28
本文介绍了使用 C#/Windows 窗体的简单动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 C#/Windows 窗体中制作一个用于万圣节展示的快速动画.只是一些在纯色背景上移动的 2D 形状.由于这只是一个快速的一次性项目,我真的不想为此安装和学习一整套新工具.(DirectX 开发工具包、Silverlight、Flash 等.)我还必须在多台计算机上安装它,因此除了基本的 .Net 框架 (2.0) 之外的任何东西都会很麻烦.

I need to knock out a quick animation in C#/Windows Forms for a Halloween display. Just some 2D shapes moving about on a solid background. Since this is just a quick one-off project I really don't want to install and learn an entire new set of tools for this. (DirectX dev kits, Silverlight, Flash, etc..) I also have to install this on multiple computers so anything beyond the basic .Net framework (2.0) would be a pain in the arse.

对于工具,我拥有 VS2k8、25 年的开发经验、手推车、大屠杀斗篷,以及大约 2 天的时间来解决这个问题.自从在我的 Atari 130XE 上使用汇编程序后,我就没有做过动画(用于翻页和播放器/导弹图形!)

For tools I've got VS2k8, 25 years of development experience, a wheelbarrow, holocaust cloak, and about 2 days to knock this out. I haven't done animation since using assembler on my Atari 130XE (hooray for page flipping and player/missile graphics!)

建议?以下是我想知道的一些事情:

Advice? Here's some of the things I'd like to know:

  • 通过摆弄 OnPaint 处理程序,我可以在任何空的小部件(如面板)上进行绘制,对吗?这就是我绘制自定义小部件的方式.还有比这更好的技术吗?
  • Windows 窗体中是否有针对此类内容的翻页技术?我不是在寻找高帧率,只是需要尽可能少的闪烁/绘图.

谢谢.

事后编辑......几天后编码"

好了,项目完成了.下面的链接派上了用场,尽管其中有几个是 404.(我希望 SO 允许将多个回复标记为正确").我必须克服的最大问题是闪烁,并且当我尝试直接在表单上绘制时,一个持续存在的错误.

Well, the project is done. The links below came in handy although a couple of them were 404. (I wish SO would allow more than one reply to be marked "correct"). The biggest problem I had to overcome was flickering, and a persistent bug when I tried to draw on the form directly.

  • 对表单使用 OnPaint 事件:坏主意.我从来没有让它起作用;许多神秘的错误(堆栈溢出或 ArgumentNullExceptions).我最终使用了一个面板大小来填充表单,效果很好.
  • 无论如何使用 OnPaint 方法都很慢.我在网上的某个地方读到构建 PaintEventArgs 很慢,他们不是在开玩笑.当我放弃这个时,很多闪烁都消失了.跳过 OnPaint/Invalidate() 并自己绘制它.
  • 在表单上设置所有双缓冲"选项仍然留下一些必须修复的闪烁.(我发现有冲突的文档说在控件上设置它们"和在表单上设置它们".控件没有 .SetStyle() 方法.)没有它们我没有测试过,所以它们可能是做某事(this 是形式):

    this.SetStyle(ControlStyles.UserPaint, true);
    this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

所以代码的主力看起来像(pf 是面板控件):

So the workhorse of the code wound up looking like (pf is the panel control):

    void PaintPlayField()
    {
        Bitmap bufl = new Bitmap(pf.Width, pf.Height);
        using (Graphics g = Graphics.FromImage(bufl))
        {
            g.FillRectangle(Brushes.Black, new Rectangle(0, 0, pf.Width, pf.Height));
            DrawItems(g);
            DrawMoreItems(g);
            pf.CreateGraphics().DrawImageUnscaled(bufl, 0, 0);
        }
    }

我刚刚从我的 Timer 循环内部调用了 PaintPlayField.完全没有闪烁.

And I just called PaintPlayField from the inside of my Timer loop. No flicker at all.

推荐答案

以您想要的帧速率启动计时器.在每个计时器触发时,根据您想要实现的动画动作在屏幕(您的模型)上旋转形状的内部表示,然后调用 Invalidate(true).在 OnPaint 中,只需在屏幕上绘制模型即可.

Set off a timer at your desired frame rate. At each timer firing twiddle the internal representation of the shapes on the screen (your model) per the animation motion you want to achieve, then call Invalidate(true). Inside the OnPaint just draw the model on the screen.

哦,是的,您可能想打开双缓冲(这就像自动翻页).

Oh yeah, and you probably want to turn Double Buffering on (this is like automatic page flipping).

这篇关于使用 C#/Windows 窗体的简单动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆