Oppure

Loading
07/03/16 7:38
Thejuster
Buongiorno a tutti.

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

[Serializable()]
        public struct _obstacle
        {
            public string name;
            public bool evento;
            public int x;
            public int y;
        }

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.

     public void ReInitialize()
        {

            Grid = new Bitmap(map.Width, map.Height); //Layer Griglia
            empty = new Bitmap(map.Width, map.Height); //Mappa vuota
            LayerOstacoli = new Bitmap(map.Width, map.Height); //Ostacoli vuoti
            LayerEventi = new Bitmap(map.Width, map.Height); //Eventi vuoti
            LayerLuci = new Bitmap(map.Width, map.Height); // Luci vuote

            Graphics g = Graphics.FromImage(empty); //Eredito la grafica
            g.FillRectangle(Brushes.Magenta, new Rectangle(0, 0, empty.Width, empty.Height)); //Riempio di colore vuoto
            empty.MakeTransparent(Color.Magenta); //Svuoto tutto rendendo trasparente

            map.Image = empty;

            //Creo tot immagine vuote per i layer
            Bitmap b = new Bitmap(map.Width, map.Height);

            for (int i = 0; i < 20; i++)
            {
                Layers[i] = new Bitmap(map.Width, map.Height);
            }

            CompositeGrid(); //Vado a costruire la griglia di disegno per lo Snap To Grid
        }






Qui credo di avere il problema..


private void map_MouseDown(object sender, MouseEventArgs e)
        {




 //Ostacoli  Qui è dove ho il problema
                if (_ostacoli.Checked)
                {
                    Graphics g = Graphics.FromImage(LayerOstacoli);
                    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
                   
                    //Aggiungo un ostacolo
                    MappyLib.IOSystem._obstacle ob = new MappyLib.IOSystem._obstacle();
                    ob.x = e.X / Block_Width * Block_Width;
                    ob.y = e.Y / Block_Height * Block_Height;
                    ob.evento = false;
                    ob.name = "Obstacle";
                    Ostacoli.Add(ob);
                    //----

                    CompositeMap();  //Creo la composizione della mappa
                }



  //Penna  Funzione simile agli ostacoli. Questa funziona correttamente senza causarmi problemi
  //Mentre  quella sopra fà capricci
                if (e.Button == System.Windows.Forms.MouseButtons.Left && penna.Checked)
                {
                    selection = true;
                    SelectionStart = new Point(e.X, e.Y);

                    //Disegno dello sprite

                    Graphics g = Graphics.FromImage(Layers[(int)numericUpDown1.Value]);


                    g.FillRectangle(Brushes.Magenta, new Rectangle(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height, CroppedTile.Width, CroppedTile.Height));
                    g.DrawImage(CroppedTile, new Point(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height));

                    Layers[(int)numericUpDown1.Value].MakeTransparent(Color.Magenta);


                    //Questa funzione serve solo la prima volta
                    //per far aggiornare la mappa al primo click
                    //impostando l'immagine come quella del layer di default
                    //successivamente, il CompositeMap farà il resto
                    if (!primo)
                    {
                        map.Image = empty;

                        map.Image = Layers[(int)numericUpDown1.Value];
                        CompositeMap();
                        primo = true;
                    }
                    else
                    {
                        CompositeMap();
                    }

                    mapDrawDow = true;

                    //Assegnazione Pezzo
                    AddPice(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height, CroppedTile.Width, CroppedTile.Height, (int)numericUpDown1.Value);

                }


}








Metodo Composite Map
ovvero la funzione che compone la mappa.


 //Composizione della mappa
        private void CompositeMap()
        {
            //La composizione della mappa prevede di
            //selezionare l'array completo delle mappe
            //e di sfumarle in trasparenza come background
            //in modo da poter lavorare pulito in primo piano
            //mentre gli altri layer sono in secondo piano

            Bitmap temp = new Bitmap(map.Width, map.Height);
            Graphics g = Graphics.FromImage(temp);

           


            //Disegno la griglia infine

            Pen p = new Pen(Brushes.Silver);
            p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

            for (int i = 0; i < map.Width; i += Block_Width)
            {
                g.DrawLine(p, new Point(i, 0), new Point(i, map.Height));
            }

            for (int i = 0; i < map.Height; i += Block_Height)
            {
                g.DrawLine(p, new Point(0, i), new Point(map.Width, i));
            }

                        



            if ((int)numericUpDown1.Value > 0)
            {
                for (int i = 0; i < Layers.Length; i++)
                {
                    g.DrawImage(Layers[i], new Point(0, 0));
                }
            }



            temp = (Bitmap)SetImageOpacity(temp, 0.4f);

            map.BackgroundImage = temp;

            
            //Se selezionato strumento ostacli
           
            if (_ostacoli.Checked)
            {
                for (int i = 0; i < Layers.Length; i++)
                {
                    g.DrawImage(Layers[i], new Point(0, 0));
                }

                g.DrawImage(LayerOstacoli, new Point(0, 0));
                map.Image = temp;
                map.BackgroundImage = temp;

                Graphics s = Graphics.FromImage(map.Image);
                s.DrawImage(LayerOstacoli, new Point(0, 0));
                numericUpDown1.Value = 1;
                map.Refresh();

            }


            //Se selezionato strumento evento
            if (eventi.Checked)
            {
                for (int i = 0; i < Layers.Length; i++)
                {
                    g.DrawImage(Layers[i], new Point(0, 0));
                }

                g.DrawImage(LayerEventi, new Point(0, 0));
                map.Image = temp;
                map.BackgroundImage = temp;

                Graphics s = Graphics.FromImage(map.Image);
                s.DrawImage(LayerEventi, new Point(0, 0));
                numericUpDown1.Value = 1;
                map.Refresh();

            }
            
            //Se selezionato strumento luci
            if (luci.Checked)
            {
                for (int i = 0; i < Layers.Length; i++)
                {
                    g.DrawImage(Layers[i], new Point(0, 0));
                }


                Graphics s = Graphics.FromImage(LayerLuci);
                s.Clear(Color.Transparent);

                for (int i = 0; i < Lights.Count; i++)
                {
                    SolidBrush sb2 = new SolidBrush(Color.FromArgb(55, (int)Lights[i].Color1, (int)Lights[i].Color2, (int)Lights[i].Color3));
                    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));
                    s.DrawImage(_2D_Mappy.Properties.Resources.Lamp_icon, Lights[i].x / Block_Width * Block_Width, Lights[i].y / Block_Height * Block_Height, 32, 32);
                }


                g.DrawImage(LayerLuci, new Point(0, 0));
                map.Image = temp;
                map.BackgroundImage = temp;

                Graphics ss = Graphics.FromImage(map.Image);
                ss.DrawImage(LayerLuci, new Point(0, 0));
                numericUpDown1.Value = 1;
                map.Refresh();

                
            }

        }




Riuscite a trovare il problema?
Il perché ho questo rallentamento solo per la parte Ostacoli?
Ultima modifica effettuata da Thejuster 07/03/16 7:53
mire.forumfree.it/ - Mire Engine
C# UI Designer
07/03/16 22:29
Roby94
Potresti spiegare meglio qual'è il risultato finale che cerchi?
Ultima modifica effettuata da Roby94 07/03/16 22:30
aaa
08/03/16 15:06
Thejuster
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.

mire.forumfree.it/ - Mire Engine
C# UI Designer
08/03/16 20:12
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.
aaa
08/03/16 22:28
Thejuster
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


if (e.Button == System.Windows.Forms.MouseButtons.Left && penna.Checked)
                {
                    selection = true;
                    SelectionStart = new Point(e.X, e.Y);
 
                    //Disegno dello sprite
 
                    Graphics g = Graphics.FromImage(Layers[(int)numericUpDown1.Value]);
 
 
                    g.FillRectangle(Brushes.Magenta, new Rectangle(e.X / Block_Width * Block_Width, e.Y / Block_Height * Block_Height, CroppedTile.Width, CroppedTile.Height));

}

mire.forumfree.it/ - Mire Engine
C# UI Designer
09/03/16 10:36
Snogar
Hai già provato a commentare il blocco "//Aggiungo un ostacolo" ? Giusto per eliminarlo dall'equazione.
Ultima modifica effettuata da Snogar 09/03/16 10:36
aaa
09/03/16 11:11
Thejuster
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


//Ostacoli  Qui è dove ho il problema
                if (_ostacoli.Checked)
                {
                    Graphics g = Graphics.FromImage(LayerOstacoli);
                    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
                   
           
                    /*-------------------------  Eliminato tutto questo -----
                  //Aggiungo un ostacolo
                    MappyLib.IOSystem._obstacle ob = new MappyLib.IOSystem._obstacle();
                    ob.x = e.X / Block_Width * Block_Width;
                    ob.y = e.Y / Block_Height * Block_Height;
                    ob.evento = false;
                    ob.name = "Obstacle";
                    Ostacoli.Add(ob);
                    //----
                     */
 
                    CompositeMap();  //Creo la composizione della mappa  Guarda sotto
                    
                }




che questo



if (_ostacoli.Checked)
            {
 
                g.DrawImage(LayerOstacoli, new Point(0, 0));
                map.Image = temp;
                map.BackgroundImage = temp;
 
                Graphics s = Graphics.FromImage(map.Image);
                s.DrawImage(LayerOstacoli, new Point(0, 0));
                numericUpDown1.Value = 1;
                map.Refresh();
 
            }




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.

mire.forumfree.it/ - Mire Engine
C# UI Designer
09/03/16 11:37
Snogar
Toglimi l'ultimo dubbio ....prova a mettere Graphics g = Graphics.FromImage(LayerOstacoli); all'esterno del mouse down.
aaa