65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Forms 上的动画

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.04/5 (9投票s)

2008年3月26日

CPOL

3分钟阅读

viewsIcon

74874

downloadIcon

3736

在 Windows Form 上实现基本动画。

引言

本文旨在解释如何在 Windows Form 中添加动画。第一部分将简要解释通过设计 Windows Form 背后的过程。接下来是一个使用 Graphics 类在 Form 上绘制的示例。最后,本文将以可以在 .NET Framework 的 DOS 提示符下编译的代码结束,或者可以使用组成 Visual Studio 项目的单独文件来构建。

当使用 Windows Forms 时,Form 对象用于表示应用程序中的任何窗口。这包括 SDI(单文档界面)中最顶层的主窗口,以及 MDI(多文档界面)应用程序的父窗口和子窗口。要创建主窗口,您必须

  1. System.Windows.Forms.Form 派生自定义类。
  2. 配置应用程序的 Main 方法以调用 Application.Run(),并将新的 Form 派生类的实例作为参数传递
  3. using System;
    using System.Windows.Forms;
    public class MainForm : Form // derive custom class
    {
        public MainForm(){}
        // run the application
        public static int Main(string[] args)
        {
            Application.Run(new MainForm());
            return 0;
        }
      }
    }

在 Windows Forms 的世界中,空白表单通常会拖放控件到其上。控件是表单上的一个元素,它具有可以设置的属性。将控件拖放到 Visual Studio 2005 的设计界面上,然后设置它们的属性,会导致 IDE 生成代码,该代码在一个 Form.cs 文件和一个 Form.Designer.cs 文件中定义 Form 文件。但是,假设我们想在一个表单上使用图形,我们想在表单或控件上绘制。

此外,假设我们想在主窗口内构建另一个窗口以实现动画。要在控件或表单上绘制,您必须首先

  1. 通过调用 System.Windows.Forms.CreateGraphics 方法创建一个 Graphics 对象。
  2. 创建一个 Pen 对象。
  3. 调用 Graphics 类的成员,使用 Pen 在控件上绘制。这是一个例子

(文件:DrawLine.cs;要编译:c:\Windows\Microsoft.NET\Framework\v2.0.50727>csc.exe /target:winexe DrawLine.cs。)

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

public class MainForm : System.Windows.Forms.Form
{

    private System.ComponentModel.Container components;

    public MainForm()
    {
        InitializeComponent();
        CenterToScreen();
        SetStyle(ControlStyles.ResizeRedraw, true); 
    }

    protected override void Dispose( bool disposing )
    {
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }


#region Windows Form Designer generated code

    private void InitializeComponent()
    {
        this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Text = "Fun with graphics";
        this.Resize += new System.EventHandler(this.Form1_Resize);
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint);
    }
#endregion

    [STAThread]
    static void Main() 
    {
        Application.Run(new MainForm());
    }

    private void MainForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Graphics g = this.CreateGraphics();

        // Make a big red pen.
        Pen p= new Pen(Color.Red, 7);

        g.DrawLine(p, 1, 1, 100, 100);
    } 

    private void Form1_Resize(object sender, System.EventArgs e)
    {
    }
}

动画

如果在 .NET Framework 目录的 DOS 提示符下编译,您将看到一条形成 60 度角的线。尝试想象一条平行线,其端点连接形成一个正方形。如果该线逆时针移动,它将形成一个旋转,如果跟踪,将形成一条路径。在视频中,帧速率是人眼每秒看到的单个帧的数量。虽然它看起来像正常运动,但它实际上是一组帧,通常是 60 帧,每秒显示,同时存在水平和垂直同步速率。但是,图形通过动画来描绘运动。动画是通过实例化 System.Windows.Forms.Timer 类来实现的,该类负责通过窗口上的线程定期调用方法。请注意,动画发生在主窗口内,因此必须构建另一个窗口,在这种情况下,该窗口将旋转。

如前所述,Microsoft Visual Studio 2005 IDE 生成代码,以便控件的属性被设置为实际定义组件为字段,而控件是表单上的一个元素。如果您下载示例并运行解决方案文件,您应该会看到动画。由于 .NET Framework 2.0 支持分部类,我们可以将两个源代码文件拆分下来以形成一个 Form 文件。下载的 zip 文件包含 C# 中的整个项目。下面的代码旨在在命令行上运行。读者应注意组成项目的 program.csForm1.csForm1.Desinger.cs 文件。在检查了源代码及其划分方式后,检查下面呈现的单个源代码文件

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

public partial class AnimForm : Form {
    private float angle;
    private Timer timer = new Timer();
    private BufferedGraphics bufferedGraphics;

    public AnimForm() {
        BufferedGraphicsContext context = BufferedGraphicsManager.Current;
        context.MaximumBuffer = new Size( this.Width + 1, this.Height + 1 );
        bufferedGraphics = context.Allocate( this.CreateGraphics(),
        new Rectangle( 0, 0, this.Width, this.Height) );
        timer.Enabled = true;
        timer.Tick += OnTimer;
        timer.Interval = 20; // 50 images per second.
        timer.Start();
    }

    private void OnTimer( object sender, System.EventArgs e ) {
        angle ++;
        if (angle > 359)
            angle = 0;
        Graphics g = bufferedGraphics.Graphics;
        g.Clear( Color.Black );
        Matrix matrix = new Matrix();
        matrix.Rotate( angle, MatrixOrder.Append );
        matrix.Translate( this.ClientSize.Width / 2, 
            this.ClientSize.Height/ 2, MatrixOrder.Append );
        g.Transform = matrix;
        g.FillRectangle( Brushes.Azure, -100, -100, 200, 200 );
        bufferedGraphics.Render( Graphics.FromHwnd( this.Handle ) );
    }

    [System.STAThread]
    public static void Main() {
        Application.Run( new AnimForm() );
    }
}

这个动画示例并不是要替代学习 GDI+ 库和涉及的 .NET 基础类。代码应该是自我解释的。请记住,坐标从窗口的左上角开始。欢迎评论和更正。

参考文献

  • Patrick Smacchia 的 Practical .NET2 和 C#2
© . All rights reserved.