2016-09-29 4 views
-1

私はVisual Studio 2013でC#を習得していて、問題を抱えています。
私は、スクリーン上を動くドット(今、20)の束を描いています。リフレッシュ(毎ms)の間に、私はグラフィックスをクリアします。しかし、これは消去された後に私が描画しているドットを引き起こします。この最終的な結果は、ドットが画面上で点滅しているように見えることです。私はJavaプログラマーです。私はJavaでのやり方と同様にこのグラフィックスにアプローチしました。これは間違っていますか?私の問題を解決するために何ができますか?C#graphics slow

このエラーは、私のダニ法が約9ミリ秒かかることが原因と考えています。ここで

は私のコードです:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Threading; 
using System.Diagnostics; 

namespace AstroidBlast { 
    public partial class Form1 : Form { 
     Random r = new Random(); 
     System.Windows.Forms.Timer gameTimer = new System.Windows.Forms.Timer(); 
     Particle[] particles = new Particle[20]; 
     int tick = 0; 
     public Form1() { 
      InitializeComponent(); 
      gameTimer.Interval = 1; 
      gameTimer.Tick += new EventHandler(gameTimer_Tick); 
      gameTimer.Start(); 
      this.Width = 800; 
      this.Height = 600; 
      for (int i = 0; i < particles.Length; i++) { 
       particles[i] = new Particle(new Velocity(r.Next(0, 360) * (Math.PI/180), r.NextDouble() *.75 + 0.25), 100, 100, r); 
      } 
     } 
     private void Form1_Load(object sender, EventArgs e) {} 
     private void gameTimer_Tick(object sender, EventArgs e) { 
      Graphics g = this.CreateGraphics(); 
      Stopwatch s = new Stopwatch(); 
      s.Start(); 
      g.Clear(Color.White); 
      for (int i = 0; i < particles.Length; i++) 
       particles[i].draw(g, Math.Sqrt(tick++)); 
      s.Stop(); 
      Debug.Print(s.ElapsedMilliseconds + ""); 
     } 
    } 
    class Particle { 
     static SolidBrush brush = new SolidBrush(Color.FromArgb(40, 40, 40)); 
     Random r; 
     Velocity velocity; 
     double x, y; 
     public Particle(Velocity v, double x, double y, Random r){ 
      velocity = v; 
      this.x = x; 
      this.y = y; 
      this.r = r; 
     } 
     public void draw(Graphics g, double t) { 
      g.FillEllipse(brush, (int)(velocity.speed * t * Math.Cos(velocity.angle) + x), (int)(velocity.speed * t * Math.Sin(velocity.angle) + y), 8, 8); 
     } 
    } 
    class Velocity { 
     public double angle, speed; 
     public Velocity(double angle, double speed) { 
      this.angle = angle; 
      this.speed = speed; 
     } 
    } 
} 
+0

'リフレッシュ(毎ms)の間に、私はどこにあるのかグラフィックスをクリアしますか? –

+1

1)あなたは絶えず 'this.CreateGraphics()'を呼び出しており、決してそれを処分していません。 2)99.9%の時間で 'this.CreateGraphics()'を実行すべきではなく、 'OnPaint'イベントをオーバーライドして、代わりに描画を行うべきです。 –

+0

おっと、私はそれを修正したかどうかを確認するためにすべてを矩形で覆うことに置き換えました。今すぐ戻してください。 –

答えて

2

いいえ、一般的にこれはC#で描画するための正しい方法ではありません。

OnPaintイベントをオーバーライドして、Graphicsオブジェクトを提供し、それを描画する必要があります。あなたのタイマーティックの内部では、Invalidateすべてまたはエリアの一部

protected override void OnPaint(PaintEventArgs e) 
{ 
    Graphics g = e.Graphics; 
    // draw here 
} 

private void gameTimer_Tick(object sender, EventArgs e) 
{ 
    this.Invalidate(); // optionally, provide the area to invalidate for better performance 
} 

を再描画するためにまた、あなたのコードを再現DoubleBuffered

public Form1() 
{ 
    InitializeComponent(); 
    this.DoubleBuffered = true 
} 

を使用するようにフォームを伝えることにより、優れたパフォーマンス/少ないちらつきを得ることができますすることができます上記の変更は重大なちらつきを生じさせません。

+0

ありがとう! DoubleBufferedがトリックをしました。 –