Autor Beitrag
Rolf1981
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Do 05.01.12 19:35 
Hallo zusammen,

zuerst möchte ich mich mal vorstellen. Mein Name ist Rolf und ich habe in den letzten Jahren hin und wieder mit Delphi programmiert. Nun bin ich am Umsteigen auf C# und habe vor, mich an einem kleinen Strategiespiel zu versuchen. Mir geht es mehr um eine grundsätzliche Frage bzw. darum, ob mein Vorgehen grundsätzlich richtig und sinnvoll ist.

Für das Spiel würde ich als Karte ein Hintergrundbild nehmen und darauf alle weiteren Objekte (Felsen, Bäume) aber auch die Einheiten als Bild (PictureBox) positionieren. Ist dieses Vorgehen sinnvoll?

Bisher habe ich nämlich das Problem, dass das Hintergrundbild schon ziemlich flackert und ruckelt.
Gibt es elegantere oder bessere Wege?

Vielen Dank!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 05.01.12 20:56 
Hallo Rolf und :welcome: hier im C#-Forum,

PictureBoxen solltest du dafür nicht benutzen (da diese recht resourcenintensiv sind - besonders wenn du viele kleine Bilder hast), sondern selber zeichnen (lassen).
Gute Tutorials dafür gibt es im myCSharp-Forum unter
[Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox)
[Artikel] Flackernde Controls und flackerndes Zeichnen vermeiden
Wenn du nach Einarbeitung noch weitere Fragen dazu hast, helfe ich dir gerne weiter.
Rolf1981 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Fr 06.01.12 18:52 
Hi,

danke erstmal!

Ich hab mich durch dein verlinktes Tutorial und einige andere nun durchgekämpft. Alles verstanden habe ich zwar nicht, aber ich kann jetzt immerhin alle Bilder per DrawImage zeichnen lassen. Sieht auch schon deutlich flüssiger aus. Super!
Das mit dem DoubleBuffering war bei Delphi immer so, dass die Anweisung doublebuffered := true genügt hat für eine extrem flüssige Darstellung!

Nun ein weiteres C#-Anfängerproblem. Meine Landkarte soll eine Größe von 10.000 x 10.000 Pixel haben, also recht groß sein. Dazu habe ich folgenden Code:

ausblenden C#-Quelltext
1:
2:
3:
Image newImage1 = Image.FromFile("C:\\Background_medium.jpg");
Rectangle destRect = new Rectangle(111000010000);
Bilder.DrawImage(newImage, destRect);

Das Bild erscheint, muss ja aber neu gezeichnet werden, wenn ich scrolle. Ansonsten verschwindet es ja durch das Scrollen. Gibt es eine einfache Anweisung, mit der sich bewerkrstelligen lässt, dass alle auf diese Art gezeichneten Bilder neu gezeichnet werden, wenn

a.) ich scrolle oder
b.) sich die Bilder (also sich bewegende Objekte im Spiel) bewegen?

Vermutlich suche ich mit den falschen Suchbegriffen, da ich in Foren und Tutorials nichts gefunden habe. Danke schonmal im Voraus! Ich werde mir auch weitere Bücher bestellen aber es wäre cool, wenn ich übers Wochenende da etwas weiterarbeiten könnte.

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19274
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 06.01.12 20:13 
Du musst das Paint-Ereignis deiner Paintbox zum Zeichnen benutzen. ;-)
Rolf1981 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Sa 07.01.12 02:39 
Hi,

also erstmal nochmas Danke! Falls mir jemand einen guten Tipp für ein Buch hat (v.a. Thema Zeichnen, Bilder... in C#) nehmr ich das gerne an. Bis dahin bin ich leider auf etwas Starthilfe hier angewiesen, sorry.
Ich habe jetzt eine PictureBox erzeugt und das Zeichnen des Bildes dort in das Paint-Ereignis geschrieben. Nur tauchen jetzt zwei neue Probleme auf:

1. Es ruckelt extrem
2. Nach einigem Scrollen erscheint die Meldung: Nicht genügend Arbeitsspeicher


Mein Code sieht jetzt so aus:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {

        private Graphics Bilder;
        private PictureBox pb = new PictureBox();


        public Form1()
        {
            InitializeComponent();
            Bilder = this.CreateGraphics();
            
        }

                    
        private void Form1_Load(object sender, EventArgs e)
        {
           
            pb.Paint += new System.Windows.Forms.PaintEventHandler(this.pb_Paint);
            this.Controls.Add(pb);
            pb.Width = 1760;
            pb.Height = 1200;
        }
          

        private void pb_Paint(object sender, PaintEventArgs e)
        {
            
            Image newImage = Image.FromFile("C:\\Background_medium.jpg");
            Rectangle destRect = new Rectangle(111000010000);
            Bilder.DrawImage(newImage, destRect); 
        }
    }
}


Moderiert von user profile iconKha: C#-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19274
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 07.01.12 07:25 
Das Bild einmal laden genügt auch, sprich in Form1_Load zum Beispiel. Du solltest nur das reine Zeichnen in Paint erledigen. Denn das wird immer aufgerufen, wenn ein Neuzeichnen erforderlich ist. Und wenn du jedesmal erst einmal die Datei nimmst und neu in den Arbeitsspeicher lädst, dauert das immer kurz (daher ruckelt es) und verbraucht weiteren Arbeitsspeicher (daher 2., weil der offenbar nicht schnell genug wieder aufgeräumt wird).

Die andere Frage:
Wie groß ist denn dein Hintergrundbild eigentlich? (Weil mich die 10000 Pixel im destRect ein wenig irritieren.)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 07.01.12 14:38 
Hallo Rolf,

du solltest dir die verlinkten Artikel noch mal genauer anschauen (insb. den ersten).
Wie jaenicke schon geschrieben hat, immer in dem Paint-Ereignis zeichnen. Und dann die EventArgs-Parameter benutzen (d.h. e.Graphics) - ganz, ganz selten benötigt man selber CreateGraphics()!).

Und wie schon geschrieben, vergiß die PictureBox, sondern zeichne direkt auf der Form (oder alternativ auf einem Panel).

Und wenn du ein Neuzeichnen veranlassen willst, dann gibt es dafür die Methode Invalidate. Mit den Parametern kannst du zusätzlich noch ein Rechteck bestimmen, welches dann nur aktualisiert wird (anstatt den gesamten Bereich).

Aber als erstes mal den Rat von jaenicke befolgen...
Rolf1981 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: So 08.01.12 01:03 
Hi zusammen,

vielen Dank!

Ich hab mich weiter reingearbeitet dank eurer Tipps und Links und es klappt :-) Juhu, Erfolgserlebnis :-)

10000 x 10000 war schon richtig, wollte das Bild als Hintergrundbild (Karte) nehmen. Hab das aber inzwischen aufgesplittet, dass es nicht immer das ganze laden muss.

Danke!