2011-02-07 54 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));  
    } 
}