2012-03-18 76 views
2

我對編程有點新鮮感,並對什麼是良好實踐提出了疑問。Winforms:調用來自不同類別的輸入表單功能

我創建了一個表示一個球的類,它有一個函數Jump(),它使用2個計時器並上下移動球。

我知道在Winforms中,每次要重畫屏幕或其中的一部分時,都必須撥打Invalidate()。我沒有找到一個好的方法來做到這一點,所以我在課堂上參考了這個表格,並且每次我需要重新繪製球的運動時,在我的球類內部調用Invalidate()

(這個工作,但我有一種感覺,這是不是一個好的做法)

這裏是我創建的類:我wondring是否有更好的方法做

public class Ball 
{ 
    public Form1 parent;//----> here is the reference to the form 
    public Rectangle ball; 
    Size size; 
    public Point p; 
    Timer timerBallGoUp = new Timer(); 
    Timer timerBallGDown = new Timer(); 

    public int ballY; 

    public Ball(Size _size, Point _p) 
    { 
     size = _size; 
     p = _p; 
     ball = new Rectangle(p, size); 
    } 

    public void Jump() 
    { 
     ballY = p.Y; 
     timerBallGDown.Elapsed += ballGoDown; 
     timerBallGDown.Interval = 50; 
     timerBallGoUp.Elapsed += ballGoUp; 
     timerBallGoUp.Interval = 50; 
     timerBallGoUp.Start(); 
    } 

    private void ballGoUp(object obj,ElapsedEventArgs e) 
    { 
     p.Y++; 
     ball.Location = new Point(ball.Location.X, p.Y); 
     if (p.Y >= ballY + 50) 
     { 
      timerBallGoUp.Stop(); 
      timerBallGDown.Start(); 
     } 

     parent.Invalidate(); // here i call parent.Invalidate() 1 
    } 

    private void ballGoDown(object obj, ElapsedEventArgs e) 
    { 
     p.Y--; 
     ball.Location = new Point(ball.Location.X, p.Y); 

     if (p.Y <= ballY) 
     { 
      timerBallGDown.Stop(); 
      timerBallGoUp.Start(); 
     } 

     parent.Invalidate(); // here i call parent.Invalidate() 2 
    } 
} 

那?

(對不起,我的英語)

+1

正確;這不是一個好習慣。大拇指認識到這一點;許多開發人員不。 – SLaks 2012-03-18 16:57:44

+0

順便說一句,如果你使用二次函數,你的跳躍看起來更自然: pY = a * t * t + b * t 其中t是當前動畫時間,a = -4 * h /(T * T),b = 4 * h/T 其中T是整體跳躍時間,h是跳躍高度。 – 2012-03-18 17:08:46

+0

@NicoSchertler謝謝你,我會試試:) – samy 2012-03-18 17:10:27

回答

3

你應該在你的球Changed事件,每當球需要火災重繪。
然後您可以處理這個事件的形式和Invalidate()

但是,最好用一個在每個對象(球,磚,無論)中調用公共方法Tick()的單個計時器替換所有計時器。
然後,您可以在勾選每個對象後單擊一個Invalidate()
這也確保您的所有對象都同步。