Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Rallentamenti consigli?
Forum - C# / VB.NET - Rallentamenti consigli?

Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2306
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 8:38
Lunedì, 07/03/2016
Buongiorno a tutti.

Volevo un consiglio sull'ottimizzazione del mio codice.
Durante l'inserimento di alcuni elementi in una lista di tipo

Codice sorgente - presumibilmente C#

  1. [Serializable()]
  2.         public struct _obstacle
  3.         {
  4.             public string name;
  5.             public bool evento;
  6.             public int x;
  7.             public int y;
  8.         }
  9.  
  10. List<_obstacle> Ostacoli;



Ogni tile misura 32x32 pixel

Fin quando mi trovo in un area di disegno la quale ho 32 x 25 Blocchi.
che sarebbe

(Width) 32 * 32 pixel = 1024
(Height)  25 * 32 pixel = 800

Sembrerebbe andare bene ma anche non molto, ogni volta che al mouse_down sulla picturebox
vado ad inserire un elemento nella lista ho un lag improvviso per 2 o 3 secondi
avvolte anche 5 o 6 secondi dipende da quanto è grande la mappa di disegno.

Vi mostro il mio codice.

Per velocizzare il disegno, avevo anche evitato di andare a recuperare prima il valore dalla lista e poi disegnarlo a video.
ho preferito utilizzare un'immagine anziché andar a disegnare i vari pezzi uno per uno ogni volta.



Questo metodo viene chiamato ogni qual volta che viene aperto un file.
Quindi viene chiamato solo una volta all'apertura di un file o progetto
proprio per ripulire tutte le varie immagini.

Codice sorgente - presumibilmente C++

  1. public void ReInitialize()
  2.         {
  3.  
  4.             Grid = new Bitmap(map.Width, map.Height); //Layer Griglia
  5.             empty = new Bitmap(map.Width, map.Height); //Mappa vuota
  6.             LayerOstacoli = new Bitmap(map.Width, map.Height); //Ostacoli vuoti
  7.             LayerEventi = new Bitmap(map.Width, map.Height); //Eventi vuoti
  8.             LayerLuci = new Bitmap(map.Width, map.Height); // Luci vuote
  9.  
  10.             Graphics g = Graphics.FromImage(empty); //Eredito la grafica
  11.             g.FillRectangle(Brushes.Magenta, new Rectangle(0, 0, empty.Width, empty.Height)); //Riempio di colore vuoto
  12.             empty.MakeTransparent(Color.Magenta); //Svuoto tutto rendendo trasparente
  13.  
  14.             map.Image = empty;
  15.  
  16.             //Creo tot immagine vuote per i layer
  17.             Bitmap b = new Bitmap(map.Width, map.Height);
  18.  
  19.             for (int i = 0; i < 20; i++)
  20.             {
  21.                 Layers[i] = new Bitmap(map.Width, map.Height);
  22.             }
  23.  
  24.             CompositeGrid(); //Vado a costruire la griglia di disegno per lo Snap To Grid
  25.         }






Qui credo di avere il problema..

Codice sorgente - presumibilmente C++

  1. private void map_MouseDown(object sender, MouseEventArgs e)
  2.         {
  3.  
  4.  
  5.  
  6.  
  7.  //Ostacoli  Qui è dove ho il problema
  8.                 if (_ostacoli.Checked)
  9.                 {
  10.                     Graphics g = Graphics.FromImage(LayerOstacoli);
  11.                     g.DrawImage(_2D_Mappy.Properties.Resources.X, new Point(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height)); //Disegno una X per indicare all'utente di aver appena definito un ostacolo
  12.                    
  13.                     //Aggiungo un ostacolo
  14.                     MappyLib.IOSystem._obstacle ob = new MappyLib.IOSystem._obstacle();
  15.                     ob.x = e.X / Block_Width * Block_Width;
  16.                     ob.y = e.Y / Block_Height * Block_Height;
  17.                     ob.evento = false;
  18.                     ob.name = "Obstacle";
  19.                     Ostacoli.Add(ob);
  20.                     //----
  21.  
  22.                     CompositeMap();  //Creo la composizione della mappa
  23.                 }
  24.  
  25.  
  26.  
  27.   //Penna  Funzione simile agli ostacoli. Questa funziona correttamente senza causarmi problemi
  28.   //Mentre  quella sopra fà capricci
  29.                 if (e.Button == System.Windows.Forms.MouseButtons.Left && penna.Checked)
  30.                 {
  31.                     selection = true;
  32.                     SelectionStart = new Point(e.X, e.Y);
  33.  
  34.                     //Disegno dello sprite
  35.  
  36.                     Graphics g = Graphics.FromImage(Layers[(int)numericUpDown1.Value]);
  37.  
  38.  
  39.                     g.FillRectangle(Brushes.Magenta, new Rectangle(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height, CroppedTile.Width, CroppedTile.Height));
  40.                     g.DrawImage(CroppedTile, new Point(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height));
  41.  
  42.                     Layers[(int)numericUpDown1.Value].MakeTransparent(Color.Magenta);
  43.  
  44.  
  45.                     //Questa funzione serve solo la prima volta
  46.                     //per far aggiornare la mappa al primo click
  47.                     //impostando l'immagine come quella del layer di default
  48.                     //successivamente, il CompositeMap farà il resto
  49.                     if (!primo)
  50.                     {
  51.                         map.Image = empty;
  52.  
  53.                         map.Image = Layers[(int)numericUpDown1.Value];
  54.                         CompositeMap();
  55.                         primo = true;
  56.                     }
  57.                     else
  58.                     {
  59.                         CompositeMap();
  60.                     }
  61.  
  62.                     mapDrawDow = true;
  63.  
  64.                     //Assegnazione Pezzo
  65.                     AddPice(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height, CroppedTile.Width, CroppedTile.Height, (int)numericUpDown1.Value);
  66.  
  67.                 }
  68.  
  69.  
  70. }








Metodo Composite Map
ovvero la funzione che compone la mappa.

Codice sorgente - presumibilmente C#

  1. //Composizione della mappa
  2.         private void CompositeMap()
  3.         {
  4.             //La composizione della mappa prevede di
  5.             //selezionare l'array completo delle mappe
  6.             //e di sfumarle in trasparenza come background
  7.             //in modo da poter lavorare pulito in primo piano
  8.             //mentre gli altri layer sono in secondo piano
  9.  
  10.             Bitmap temp = new Bitmap(map.Width, map.Height);
  11.             Graphics g = Graphics.FromImage(temp);
  12.  
  13.            
  14.  
  15.  
  16.             //Disegno la griglia infine
  17.  
  18.             Pen p = new Pen(Brushes.Silver);
  19.             p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
  20.  
  21.             for (int i = 0; i < map.Width; i += Block_Width)
  22.             {
  23.                 g.DrawLine(p, new Point(i, 0), new Point(i, map.Height));
  24.             }
  25.  
  26.             for (int i = 0; i < map.Height; i += Block_Height)
  27.             {
  28.                 g.DrawLine(p, new Point(0, i), new Point(map.Width, i));
  29.             }
  30.  
  31.                        
  32.  
  33.  
  34.  
  35.             if ((int)numericUpDown1.Value > 0)
  36.             {
  37.                 for (int i = 0; i < Layers.Length; i++)
  38.                 {
  39.                     g.DrawImage(Layers[i], new Point(0, 0));
  40.                 }
  41.             }
  42.  
  43.  
  44.  
  45.             temp = (Bitmap)SetImageOpacity(temp, 0.4f);
  46.  
  47.             map.BackgroundImage = temp;
  48.  
  49.            
  50.             //Se selezionato strumento ostacli
  51.            
  52.             if (_ostacoli.Checked)
  53.             {
  54.                 for (int i = 0; i < Layers.Length; i++)
  55.                 {
  56.                     g.DrawImage(Layers[i], new Point(0, 0));
  57.                 }
  58.  
  59.                 g.DrawImage(LayerOstacoli, new Point(0, 0));
  60.                 map.Image = temp;
  61.                 map.BackgroundImage = temp;
  62.  
  63.                 Graphics s = Graphics.FromImage(map.Image);
  64.                 s.DrawImage(LayerOstacoli, new Point(0, 0));
  65.                 numericUpDown1.Value = 1;
  66.                 map.Refresh();
  67.  
  68.             }
  69.  
  70.  
  71.             //Se selezionato strumento evento
  72.             if (eventi.Checked)
  73.             {
  74.                 for (int i = 0; i < Layers.Length; i++)
  75.                 {
  76.                     g.DrawImage(Layers[i], new Point(0, 0));
  77.                 }
  78.  
  79.                 g.DrawImage(LayerEventi, new Point(0, 0));
  80.                 map.Image = temp;
  81.                 map.BackgroundImage = temp;
  82.  
  83.                 Graphics s = Graphics.FromImage(map.Image);
  84.                 s.DrawImage(LayerEventi, new Point(0, 0));
  85.                 numericUpDown1.Value = 1;
  86.                 map.Refresh();
  87.  
  88.             }
  89.            
  90.             //Se selezionato strumento luci
  91.             if (luci.Checked)
  92.             {
  93.                 for (int i = 0; i < Layers.Length; i++)
  94.                 {
  95.                     g.DrawImage(Layers[i], new Point(0, 0));
  96.                 }
  97.  
  98.  
  99.                 Graphics s = Graphics.FromImage(LayerLuci);
  100.                 s.Clear(Color.Transparent);
  101.  
  102.                 for (int i = 0; i < Lights.Count; i++)
  103.                 {
  104.                     SolidBrush sb2 = new SolidBrush(Color.FromArgb(55, (int)Lights[i].Color1, (int)Lights[i].Color2, (int)Lights[i].Color3));
  105.                     s.FillEllipse(sb2, new Rectangle((int)Lights[i].x / Block_Width * Block_Width - Lights[i].decay / 3 - 16, (int)Lights[i].y / Block_Height * Block_Height - 200 / 3 - 16, Lights[i].decay, 200));
  106.                     s.DrawImage(_2D_Mappy.Properties.Resources.Lamp_icon, Lights[i].x / Block_Width * Block_Width, Lights[i].y / Block_Height * Block_Height, 32, 32);
  107.                 }
  108.  
  109.  
  110.                 g.DrawImage(LayerLuci, new Point(0, 0));
  111.                 map.Image = temp;
  112.                 map.BackgroundImage = temp;
  113.  
  114.                 Graphics ss = Graphics.FromImage(map.Image);
  115.                 ss.DrawImage(LayerLuci, new Point(0, 0));
  116.                 numericUpDown1.Value = 1;
  117.                 map.Refresh();
  118.  
  119.                
  120.             }
  121.  
  122.         }




Riuscite a trovare il problema?
Il perché ho questo rallentamento solo per la parte Ostacoli?

Ultima modifica effettuata da Thejuster il 07/03/2016 alle 8:53


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 23:29
Lunedì, 07/03/2016
Potresti spiegare meglio qual'è il risultato finale che cerchi?

Ultima modifica effettuata da Roby94 il 07/03/2016 alle 23:30
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2306
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 16:06
Martedì, 08/03/2016
Ho un rallentamento di 2 o 3 secondi quando vado aggiungere nella lista ostacoli un elemento.
Mentre tutto il resto funziona benissimo.

non capisco il perché di questo rallentamento.
e' solo un  Ostacoli.add

Non avviene nessuna ricostruzione della grafica mediante un ciclo.

proprio per evitare ulteriori rallentamenti disegono direttamente su un immagine e salvo la coordinata in una lista.



https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Snogar (Normal User)
Pro


Messaggi: 145
Iscritto: 09/01/2012

Segnala al moderatore
Postato alle 21:12
Martedì, 08/03/2016
Così a naso direi che il problema è questa riga:   Graphics g = Graphics.FromImage(LayerOstacoli);
ma potrei aver detto una cazzata  ....dipende da quante volte ci entri li.

PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2306
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 23:28
Martedì, 08/03/2016
Testo quotato

Postato originariamente da Snogar:

Così a naso direi che il problema è questa riga:   Graphics g = Graphics.FromImage(LayerOstacoli);
ma potrei aver detto una cazzata  ....dipende da quante volte ci entri li.



ogni volta che clicco nell'area di disegno

il dubbio mi viene perché la funzione Penna fa la stessa cosa ma senza causarmi problemi

Codice sorgente - presumibilmente C# / VB.NET

  1. if (e.Button == System.Windows.Forms.MouseButtons.Left && penna.Checked)
  2.                 {
  3.                     selection = true;
  4.                     SelectionStart = new Point(e.X, e.Y);
  5.  
  6.                     //Disegno dello sprite
  7.  
  8.                     Graphics g = Graphics.FromImage(Layers[(int)numericUpDown1.Value]);
  9.  
  10.  
  11.                     g.FillRectangle(Brushes.Magenta, new Rectangle(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height, CroppedTile.Width, CroppedTile.Height));
  12.  
  13. }



https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Snogar (Normal User)
Pro


Messaggi: 145
Iscritto: 09/01/2012

Segnala al moderatore
Postato alle 11:36
Mercoledì, 09/03/2016
Hai già provato a commentare il blocco "//Aggiungo un ostacolo" ? Giusto per eliminarlo dall'equazione.

Ultima modifica effettuata da Snogar il 09/03/2016 alle 11:36
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2306
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 12:11
Mercoledì, 09/03/2016
si snogar.

Mi sembra una cosa veramente assurda.

essendo solo una chiamata ad evento non dovrebbe provocare nemmeno un minimo di lag.

ho provato ad eliminare sia

Codice sorgente - presumibilmente C# / VB.NET

  1. //Ostacoli  Qui è dove ho il problema
  2.                 if (_ostacoli.Checked)
  3.                 {
  4.                     Graphics g = Graphics.FromImage(LayerOstacoli);
  5.                     g.DrawImage(_2D_Mappy.Properties.Resources.X, new Point(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height)); //Disegno una X per indicare all'utente di aver appena definito un ostacolo
  6.                    
  7.            
  8.                     /*-------------------------  Eliminato tutto questo -----
  9.                   //Aggiungo un ostacolo
  10.                     MappyLib.IOSystem._obstacle ob = new MappyLib.IOSystem._obstacle();
  11.                     ob.x = e.X / Block_Width * Block_Width;
  12.                     ob.y = e.Y / Block_Height * Block_Height;
  13.                     ob.evento = false;
  14.                     ob.name = "Obstacle";
  15.                     Ostacoli.Add(ob);
  16.                     //----
  17.                      */
  18.  
  19.                     CompositeMap();  //Creo la composizione della mappa  Guarda sotto
  20.                    
  21.                 }




che questo


Codice sorgente - presumibilmente C# / VB.NET

  1. if (_ostacoli.Checked)
  2.             {
  3.  
  4.                 g.DrawImage(LayerOstacoli, new Point(0, 0));
  5.                 map.Image = temp;
  6.                 map.BackgroundImage = temp;
  7.  
  8.                 Graphics s = Graphics.FromImage(map.Image);
  9.                 s.DrawImage(LayerOstacoli, new Point(0, 0));
  10.                 numericUpDown1.Value = 1;
  11.                 map.Refresh();
  12.  
  13.             }




per evitare il lag, ho appunto evitato di andare a recuperare pezzettini uno alla volta
per poi ridisegnarli.
Quindi ho usato direttamente un'immagine su cui disegnare ed aggiungere solo alla lista le coordinate del pezzo
inserito, così poi successivamente non questo programma ma l'engine ricrea dei BoundingBox per realizzare ostacoli
dove il player non può oltrepassarli.



https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Snogar (Normal User)
Pro


Messaggi: 145
Iscritto: 09/01/2012

Segnala al moderatore
Postato alle 12:37
Mercoledì, 09/03/2016
Toglimi l'ultimo dubbio ....prova a mettere Graphics g = Graphics.FromImage(LayerOstacoli); all'esterno del mouse down.

PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2306
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 12:49
Giovedì, 10/03/2016
ora sono a lavoro appena posso a casa provo come dici
Ma dubito che il problema sia quello.

Se ti và snogar puoi provare direttamente qui

http://www.pierotofy.it/pages/projects/project_651.html

E' una vecchia versione di quella che ho attuale.
ma comunque anche lì è disponbile la funzione delle collisioni.
visto che è di quella che parliamo

Ultima modifica effettuata da Thejuster il 10/03/2016 alle 12:54


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote