2016-08-11 5 views
1

Ich mache ein basiertes Fensterspiel in C# und kann kein einfaches Bitmap für den Bildschirm erstellen. Ich habe ein Panel über den Bildschirm, und ich möchte in der Lage sein, um es zu zeichnen, so dass ich mit dem folgenden Code:C# -Bitmap - Parameter ist nicht gültig

public partial class GameWIndow : Form 
{ 
    public GameWIndow() 
    { 
     InitializeComponent(); 
    } 





    private void panel1_Paint(object sender, PaintEventArgs e) 
    { 
     Bitmap buffer; 
     buffer = new Bitmap(Width, Height); 
     Task.Factory.StartNew(() => 
     { 
      using (Graphics g = Graphics.FromImage(buffer)) 
      { 
       g.FillRectangle(new SolidBrush(Color.PaleGoldenrod), 10, 10, 100, 100); 
      } 
      this.Invoke(new Action(() => 
      { 
       this.BackgroundImage = buffer; 
      })); 
     }); 
    } 

wenn dieser läuft es gibt mir den Fehler „Parameter ist ungültig“ für die Linie

buffer = new Bitmap(Width, Height); 

Breite und Höhe sind 900 und 700 bzw. beide Ganzzahlen.

Wenn das Problem ist, dass ich das völlig falsch mache, was wäre ein besserer Weg, dies zu schaffen.

-------- ------- bearbeiten

Ich habe auf Ihre Kommentare geschaut und es scheint, dass das, was ich oben getan sehr schrecklich ist, so habe ich versucht, einen anderen Ansatz, und Ich bin mir nicht sicher, ob das viel besser ist.

private Game game; 
    private Thread renderThread; 
    private Stopwatch stopwatch = new Stopwatch(); 

    public GameWindow() 
    { 
     InitializeComponent(); 

     //Starts game 
     game = new Game(); 

     //Starts rendering 
     this.DoubleBuffered = true; 
     renderThread = new Thread(new ThreadStart(draw)); 
     renderThread.Start(); 
    } 

    //Runs when screen is asked to refresh 
    private void panel1_Paint(object sender, PaintEventArgs e) 
    { 
     //Sends graphics to game class where it draws game 
     game.draw(e.Graphics); 

    } 

    private void draw() 
    { 
     stopwatch.Start(); 

     while (true) 
     { 

      //If 1/60th of a sec has passed 
      if (stopwatch.ElapsedMilliseconds > 1000D/60D) 
      { 

       stopwatch.Restart(); 
       Invalidate(); 

      } 
     } 

    } 

Der obige Code nicht korrekt ausgeführt wird, bin ich nicht ganz sicher, warum, und wenn jemand dabei helfen könnte, würde ich das schätzen. Aber meine Hauptfrage ist nicht, wie man es beheben kann, aber ob dies sogar eine effektive oder "richtige" Art ist, zu zeichnen.

+0

Das Problem ist wahrscheinlich, dass Sie das völlig falsch machen. Ich weiß nicht genau, warum Sie diesen Fehler erhalten, aber das Ändern der GUI von einem anderen Thread als dem, auf dem er erstellt wurde, ist verboten. (Bei näherer Betrachtung ist das definitiv nicht der Grund, warum Sie diesen Fehler erhalten, aber die Regel gilt immer noch.) – adv12

+1

Was möchten Sie tun? Das sieht ein bisschen verdächtig aus. Die 'PaintEventArgs' enthalten bereits eine Instanz von' Graphics', auf die Sie zeichnen sollten. – vcsjones

+0

Wenn Sie den doppelt gepufferten Stil für dieses Steuerelement aktivieren, können Sie einfach den Ereignisbehandlungscode "Paint" auf einfachste Weise schreiben. –

Antwort

0

Wie @TaW vorschlägt, gibt es viele Probleme. Ich nehme an, dass dies der Paint-Ereignishandler einer WinForms-Anwendung ist? Das sind wichtige Informationen, die Sie uns hätten sagen sollen.

Der Paint-Ereignishandler wird vom Betriebssystem jedes Mal aufgerufen, wenn in Ihrem Formularinhalt etwas neu gezeichnet werden muss. PaintEventArgs liefert Ihnen die ClipRectangle, in die Sie zeichnen müssen, und den Graphics Kontext, mit dem Sie zeichnen müssen. Sie sollten nur zu diesem in Ihrem Handler zeichnen; Sie dürfen keine andere Verarbeitung durchführen, Threads starten oder E/A durchführen. Wenn Sie Bilder laden oder E/A ausführen müssen, müssen Sie dies außerhalb des Handlers tun, das Ergebnis in einer Formulareigenschaft speichern, das Rechteck, das gezeichnet werden soll, ungültig machen und dann die gespeicherte Eigenschaft zum Zeichnen in Ihrem Paint-Handler verwenden. Es sollte in etwa so aussehen:

private void Panel1_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.DrawImage(_buffer, _position); 
} 

Was ist _buffer? Ein Image füllen Sie außerhalb des Handlers. _position? Ein Standort, den Sie außerhalb Ihres Handlers aktualisieren.

Ordnen Sie keine Puffer, Brush es oder Bilder in Ihrem Paint-Handler zu; Erstellen Sie sie außerhalb des Handlers und verwenden Sie sie erneut. Wenn Sie Ihr Steuerelement mit dem Ergebnis eines langen Prozesses oder einer Netzwerkverbindung aktualisieren müssen, erstellen Sie außerhalb Ihres Handlers eine Task oder BackgroundWorker und lassen Sie die Abschlussroutine das Ergebnis speichern und Ihr Steuerelement ungültig machen. Verwenden Sie das gespeicherte Ergebnis in Ihrem Handler. Wenn Sie eine Animation ausführen müssen, erstellen Sie alle Animationsframes vor, verwenden Sie einen Timer, um die Anzeige ungültig zu machen, und zeichnen Sie den richtigen Frame in Ihrem Handler.

WinForm-Grafik ist ein großes Thema, Sie müssen ein Buch oder ein Tutorial folgen.

Verwandte Themen