Bilder zur laufzeit "bestimmt" zeichnen



  • hi,

    ich arbeite derzeit an einem programm welches sich aus einer datenbank 3 variablen holt (x,y,typ). x,y entsprechen einer koordinante auf in einem KoordSystem, wobei der typ ein bild (64x64px)darstellt was an dem jeweiligen punkt liegt.

    Mein erster Ansatz war die bilder einfach auf die Form zu zeichnen mit drawimage, nur leider brauche ich zum finden bzw festlegen der zeichenstelle nen umständlichen algo. (da minius werte vorkommen ganzes system ins positive verschieben, breite des bild berücksichtigen, also keine überschneidungen, usw...)

    Hat wer eine idee die einfacher wäre? im grunde ist das ganze ja nur eine tabelle mit feldern die 64x64 gross sind wobei jedes feld eine x,y koordinate hat in welches dan ein bild geladen wird.
    -.... nur wie man das in .net machen soll keine ahnung..



  • Guck Dir bitte mal tableLayoutPanel an.

    Das würde ich für diesen Fall einsetzen.
    Hatte das mal bei einem Memoryspiel eingesetzt.
    Die Bilder ab ich mir dann aus der ImageList geholt.

    Gruß...



  • ah super.. habe ich wohl übersehen... habe wie nen wilder nach einer tabele gesucht 🙂

    mal schauen ob ich damit klar komme



  • so hab mcih mal schlau gemacht, da ich die eigentliche tabelen größe während der laufzeit definieren muss hab ich mal folgendes probiert.

    this->tableLayoutPanel1->RowCount=size;
    				 this->tableLayoutPanel1->ColumnCount=size;
    
    				 for (int i = 0; i <size;i++)
    				 {
    					 this->tableLayoutPanel1->ColumnStyles[i]->Width=64;
    					 this->tableLayoutPanel1->RowStyles[i]->Height=64;
    					 System::Windows::Forms::Button ^b = gcnew System::Windows::Forms::Button;
    					 b->Name="test";
    					 b->Text="test";
    					 this->tableLayoutPanel1->Controls->Add(b);
    
    				}
    

    wobei size varable is, die buttons sind nur zum test, damit die felder gefühlt werden.
    Nur merkwürdiger weise bekomm ich schon hier eine fehler meldung
    Additional information: Index was out of range. Must be non-negative and less than the size of the collection. wobei diese bei i = 2 und size = 8 kommt... verstehe ich irgendwie nicht...

    edit:: habs

    this->tableLayoutPanel1->RowCount=size;
    				 this->tableLayoutPanel1->ColumnCount=size;
    
    				 TableLayoutColumnStyleCollection ^cstyles = this->tableLayoutPanel1->ColumnStyles;
    				 TableLayoutRowStyleCollection ^rstyles = this->tableLayoutPanel1->RowStyles;
    				 for each( ColumnStyle ^style in cstyles )
    				 {
    					 style->SizeType = SizeType::Absolute;
    					 style->Width=64;				 
    				 }
    				 for each( RowStyle ^style in rstyles )
    				 {
    					 style->SizeType = SizeType::Absolute;
    					 style->Height=64;				 
    				 }
    


  • so das mit den bildern hatte ich ja nun hinbekommen.

    ich generiere zur laufzeit die benötigten spalten/zeilen und fülle jede Zelle mit einer zur laufzeit generierten picturebox, das ganze funktioniert in der theorie super!

    so bix 25x25 felder... und auch das dauert schon eine weile bis es generiert ist... und von 50x50 will ich erst garnicht reden :)...

    gibt es evtl eine möglichkeit bilder direkt in eine Zelle zu laden, also ohne eine picturebox zur verwenden? (somit würde ich mir das anlegen der hunderten von pictureboxen sparen)

    hier mal ein bild von dem ganzen tool, damit man sich etwas darunter vorstellen kann.

    http://tko.vtcg.de/files/ip.JPG



  • Die PictureBox wird eher nicht das Problem sein, schätze ich, sondern das TableLayoutPanel. TableLayoutPanel ist recht lahm. Für so 4x4 Sachen egal, aber bei 50x50... pfuh. (Und 50x50 ist ja vermutlich immernoch zu klein, wenn ich deinen Screenshot richtig deute)

    Bau dir halt ein eigenes "ImageGrid" Control, und zeichne die Bilder selbst. Das wird vermutlich das performanteste sein.



  • kannst du mir evtl auch sagen wie ich das selber bauen kann? 🙂



  • Moin,

    tko schrieb:

    kannst du mir evtl auch sagen wie ich das selber bauen kann? 🙂

    das ist einfach ... http://www.fantasya-pbem.de/karte.jpg

    prinzipell brauchst Du erstmal die Min- und Max-Werte der Koordinaten für die Regionen die Du darstellen willst ... anschließend kannst Du die Verschiebung berechnen, damit alle Regionen im positiven Bereich (mit den Koordinaten) liegen

    jetzt brauchst Du nur noch über X und Y zu iterieren und die entsprechende Koordinate mit der Pixelbreite des Bildes zu multiplizieren ... an die Stelle malst Du dann die Region in ein extra Bild ... und das zeigst Du in der Picture-Box an

    also ganz einfach 😃

    hand, mogel

    PS: ist zwar Java aber macht ja prinzipell nix anderes 🕶

    protected void paintComponent(Graphics g)
    	{
    		super.paintComponents(g);
    
    		int x, y;	// Koordinaten für das Bild
    
    		// noch nix gefunden ^^
    		if (proxy.size() < 1) return;
    
    		// Regionen malen
    		for(int i = 0; i < proxy.size(); i++)
    		{
    			Region r = (Region) proxy.get(i);
    			x = (r.getCoords().getX() - minx) * ImageSize.x;
    			y = (r.getCoords().getY() - miny) * ImageSize.y;
    			g.drawImage(r.Image(), x, y, ImageSize.x, ImageSize.y, null);
    
    			if (Cursor.x == r.getCoords().getX() && Cursor.y == r.getCoords().getY())
    			{
    				regionframe.UpdateRegion(r);
    				g.drawImage(img_cursor, x, y, ImageSize.x, ImageSize.y, null);
    			}
    		}
    	}
    


  • also doch mit paint, das war mein ursprünglicher ansatz.
    mir schien es aber zu kompliziert, daher hab ich ne andere lsg gesucht und die table gefunden



  • so habs nun mit drawimage hinbekommen, klappt 1a!
    problem ist bei diser methode nur das die autoscroll funktion des panels nicht geht, ich zeichne allso über die anzeigefläche des panels hinaus, und würde gerne scrollen.

    da die gemalten bilder nicht als component erkannt werden geht diese methode nur so halb^^.

    meine idee nun war einfach wieder pictureboxen zunehmen

    int hor = 0,vert = 0;
    		 int row = 0;
    		 int z = 0;
    
    			 while(z!=x->Count)
    			 {
    				 System::Windows::Forms::PictureBox ^box = gcnew System::Windows::Forms::PictureBox;
    				 box->Name="bbox";
    				 box->Margin = System::Windows::Forms::Padding(0);
    				 box->Width=px;
    				 box->Height=px;
    				 box->SizeMode = System::Windows::Forms::PictureBoxSizeMode::StretchImage;
    				 box->TabIndex = 0;
    				 box->TabStop = false;
    				 box->Visible = true;
    
    				 for(row;row<size;row++)
    				 {
    
    					 for (int i = 0; i<size;i++)
    					 {
    						 try
    						 {
    						 img=Image::FromFile("land/"+t[z]+".gif");
    						 }
    						 catch (Exception^)
    						 {
    							 img=Image::FromFile("land/lerholung1.gif");
    						 }
    
    							 box->Location = System::Drawing::Point(hor,vert);	 
    							 box->Image = img;
    							 hor+=px;
    							 z++;
    						}
    					 hor=0;
    					 vert+=px;
    				 }
    				 if (z=x->Count) break;
    			 }
    			 this->label1->Text="Karte generiert!";
    		 }
    

    das ganze rufe ich über nen button klick event auf. nur passiert garnichts^^



  • okay diese zeile hat gefehlt

    this->tabPage1->Controls->Add(box);
    

    nur bräuchte ich nun ein array von pictureBoxen, weil der mir nur eine picturebox anlegt (die zuletzt generierte). Nur nen array von pictureBox geht kann man wohl nicht definieren... laut dem compiler

    edit::

    gelöst^^ zur info für alle evtl. suchenden

    List<System::Windows::Forms::PictureBox^> ^boxen = gcnew List<System::Windows::Forms::PictureBox^>();
    

    ne list nehmen.


Anmelden zum Antworten