2011-02-07 51 views
1

我有我的面板中点击鼠标时将画一个球的代码。现在,我想要的是当我点击面板时,不仅球出现,而且它也以某种速度移动。现在我并不在乎球是否通过了小组的边界。我该怎么做呢?如何使用WinForms绘制在面板中移动的球?

public partial class Form1 : Form 
{ 
    ArrayList dotPts = new ArrayList(); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void mainPanel_Paint(object sender, PaintEventArgs e) 
    { 
     foreach (Point p in dotPts) 
     { 
      e.Graphics.FillEllipse(Brushes.Black, p.X, p.Y, 20, 20); 
     } 
    } 

    private void mainPanel_MouseUp(object sender, MouseEventArgs e) 
    { 
     Graphics g = Graphics.FromHwnd(this.Handle); 
     dotPts.Add(new Point(e.X - 10, e.Y - 10)); 
     mainPanel.Invalidate(); 
    } 
} 

的InitializeComponent():

private void InitializeComponent() 
    { 
     this.mainPanel = new System.Windows.Forms.Panel(); 
     this.SuspendLayout(); 
     // 
     // mainPanel 
     // 
     this.mainPanel.BackColor = System.Drawing.SystemColors.GradientInactiveCaption; 
     this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 
     this.mainPanel.Location = new System.Drawing.Point(12, 12); 
     this.mainPanel.Name = "mainPanel"; 
     this.mainPanel.Size = new System.Drawing.Size(790, 424); 
     this.mainPanel.TabIndex = 0; 
     this.mainPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.mainPanel_Paint); 
     this.mainPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.mainPanel_MouseUp); 
     // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(821, 447); 
     this.Controls.Add(this.mainPanel); 
     this.Name = "Form1"; 
     this.Text = "Form1"; 
     this.ResumeLayout(false); 

    } 
+0

以什么速度移动? – 2011-02-07 16:09:17

+0

我想你的意思是恒定的速度?您可以使用“定时器”来“动画”球的运动。您还应该指定球应该如何移动(从左到右,随机,反弹,...)。 – 2011-02-07 16:11:12

回答

2

你需要一个定时器。在Tick事件处理程序中计算对象的新位置并调用面板的Invalidate()方法,以便重新绘制它。如果闪烁变得太明显,您可以使用PictureBox而不是面板。

也在ArrayList上工作。这需要变成List<Ball>,Ball类存储位置以及速度矢量。再加上未来将添加的任何其他属性,如颜色或半径。

1

一般的解决方法得到的东西随着时间的推移平滑地移动是使计时器对象由速度改变球的位置(或一些部分它)每刻度:

ball.x += xVelocity; 
    ball.y += yVelocity; 
0

我有一个例子(快速和肮脏的)代码,我想给你一个想法。(在LINQPAD运行)

void Main() 
{ 
    Application.Run(new Form1()); 
} 

public class Form1 :Form 
{ 
    float time3 =0, time =0,time2=1000000,height=20,width=20;int a = -1; 
    PointF Location = new PointF(0,0); 
    PointF Velocity = new PointF(50,50); 
    DateTime dt; 
    float x=0; 
    System.Timers.Timer tmr = new System.Timers.Timer(); 
    System.Timers.Timer gmlp = new System.Timers.Timer(); 
    public Form1() 
    { 
     this.Size = new Size(700,700);  
     Label lb = new Label(); 

     tmr.Interval =20; 
     tmr.Elapsed += (s,e) => { 

      //if(Location.X >= 500) Velocity.X *= a; 

      //if(time3 >= 1000) time=0; else 
      time3 +=20;// (DateTime.Now.Ticks - dt.Ticks)/10000; 
      Location.X = Velocity.X * (time3/1000); 
      Location.Y = Velocity.Y * (time3/1000); 
      this.Invalidate(); 
      if(time >= time2) {tmr.Stop(); tmr.Enabled = false; gmlp.Stop(); gmlp.Enabled = false;} 
     }; 
     this.DoubleBuffered =true; 


     gmlp.Interval = 1000; 
     gmlp.Elapsed += (s,e) => { 
      //dt = dt.AddSeconds(1); 
      lb.Text = 
      "time: " + time + 
      "\ntime2: " + time2 + 
      "\ntime3: " +time3 + 
      "\nlocx: " +Location.X + 
      "\ntimespan: " + (DateTime.Now.Ticks - dt.Ticks)/10000 + 
      "\nx moved: " + (Location.X - x); 
     }; 
     gmlp.Enabled = true; 
     gmlp.Start(); 
     tmr.Enabled =true; 
     tmr.Start(); 
     lb.Location = new Point(20,20); 
     lb.Size = new Size(80,200); 
     this.Controls.Add(lb); 
     dt = DateTime.Now; 
    } 

    protected override void OnPaint(PaintEventArgs pe) 
    {  
     base.OnPaint(pe); 
     pe.Graphics.FillEllipse(Brushes.Tomato, new Rectangle((int)Location.X,(int)Location.Y,(int)height,(int)width));  
    } 
}