Przyspieszenie Windows Forms Application.

0

Witam,
Mój problem dotyczy tym razem Windows Forms Application, a mianowicie jako projekt na koniec drugiego semestru tworzę prostą gierkę polegającą na omijaniu przeszkód, wszystko działało cacy, do czasu aż dodałem drugą przeszkodę oraz design. Wykorzystanie procesora przez aplikację wynosi około 20-25%, zapewne przez masę pętli znajdujących się w timer'ach, których aplikacja nie nadąży sprawdzać. Rozumiem że WFA nie służy do tworzenia gier, jednakże szkoda mi godzin spędzonych przed projektem, by zaczynać go od nowa. Czy jest możliwość aby tę aplikację jakoś przyspieszyć?

2

Pewnie i by się dało ale bez spojrzenia w kod ciężko powiedzieć co można by zmienić żeby przyśpieszyć twoją aplikację. A skoro to projekt na zaliczenie to pewnie nie chcesz go pokazać więc jedynym wyjściem jest przejrzenie jeszcze raz rozwiązań które stworzyłeś i spróbować co nie co po optymalizować.

0
DibbyDum napisał(a):

Pewnie i by się dało ale bez spojrzenia w kod ciężko powiedzieć co można by zmienić żeby przyśpieszyć twoją aplikację. A skoro to projekt na zaliczenie to pewnie nie chcesz go pokazać więc jedynym wyjściem jest przejrzenie jeszcze raz rozwiązań które stworzyłeś i spróbować co nie co po optymalizować.

Dzięki, na razie postaram się sam zoptymalizować kod, jeśli nie dam rady. Odświeżę temat.

0

Jeśli używasz wersji VS z uczelni, to możesz użyć profilera do znalezienia wąskich gardeł.

0

Hmm usunąłem Design i wykorzystanie procesora spadło z prawie 25% do 0%, Design ustawiłem był robiony w Photoshopie, format .gif i teraz nie rozumiem troszeczkę czemu on tak pożerał procesor..

Mianowicie chodzi o tą grafikę:
http://iv.pl/images/08710449618689213685.gif

0

Czy zapiszę tą grafikę w formacie ".gif" czy ".png", procesor jest obciążony tak samo. ( z grafiką ~ 25% +/- , bez grafiki 0% ).

0

Na prawdę 25% procka to jest tak strasznie dużo? :) Powinieneś się zacząć martwić jak podejdzie pod 90 albo gra zacznie ci "klatkować".

0

Problem w tym że jak jest 0% jest ok, ale gdy podchodzi pod te 25% gra klatkuje. Dzisiaj pytałem na laboratoriach swojego wykładowcę. Powiedział mi, że nie może mi odpowiedzieć na to pytanie ponieważ nie zna odpowiedzi. Sprawdziliśmy rozdzielczość która była idealnie dopasowana do okna programu. Dodatkowo polecił mi bym skorzystał z System.Drawing ( po prostu rysowanie obiektów) jednocześnie zaznaczając że nie wie czy to w czymś pomoże.

1

Na prawdę 25% procka to jest tak strasznie dużo?

25% to jest „strasznie dużo”, bo sugeruje że:

  • procesor ma cztery rdzenie (albo dwa i hyper-threading), oraz
  • jeden z tych czterech rdzeni jest zajęty na 100%

pokaż kod, inaczej niewiele można pomóc.

0

A może to kwestia samego kodu a nie żadnej grafiki, co to jest dokładnie za gra (zakładam że to sa jakieś obiekty które przesuwasz i one się klatkują bo jest za wolne odświeżanie)?

0

Klasy:

    abstract public class Obiekty
    {
        public int szybkosc;
        public int wysokosc;
        public int szerokosc;
        public int pozycja_x;
        public int pozycja_y;

        public Obiekty(int szybkosc, int wysokosc, int szerokosc, int pozycja_x, int pozycja_y)
        {
            this.szybkosc = szybkosc;
            this.wysokosc = wysokosc;
            this.szerokosc = szerokosc;
            this.pozycja_x = pozycja_x;
            this.pozycja_y = pozycja_y;
        }

        abstract public void Losuj();

        abstract public int Przyspiesz();
    }

    public class PrzeszkodaPierwsza : Obiekty
    {
        public PrzeszkodaPierwsza(int szybkosc, int wysokosc, int szerokosc, int pozycja_x, int pozycja_y)
            : base(szybkosc, wysokosc, szerokosc, pozycja_x, pozycja_y)
        {

        }

        public override void Losuj()
        {
            Random rld = new Random();
            wysokosc = rld.Next(25, 70);
            szerokosc = rld.Next(15, 45);
            pozycja_x = rld.Next(710, 735);
            pozycja_y = rld.Next(0, 296);
        }

        public override int Przyspiesz()
        {
            return szybkosc + 1;
        }
    }
    abstract public class Postac
    {
        public string imie;
        public int punkty;
        public int wysokosc;
        public int zycia;

        public Postac(string imie, int punkty, int wysokosc, int zycia)
        {
            this.imie = imie;
            this.punkty = punkty;
            this.wysokosc = wysokosc;
            this.zycia = zycia;
        }

        public abstract int PodniesPunkty();

        public abstract int StracZycie();

        public abstract int DodajZycie();
    }

    public class GraczPierwszy : Postac
    {

        public string Imie { get; set; }
        public int Punkty
        {
            get
            {
                return punkty;
            }

            set
            {
                if (punkty > 0)
                {
                    punkty = value;
                }
            }
        }
        public int Wysokosc { get; set; }

        public GraczPierwszy(string imie, int punkty, int wysokosc, int zycia)
            : base(imie,punkty,wysokosc, zycia)
        {

        }

        public override int PodniesPunkty()
        {
            return punkty + 1;
        }

        public override int StracZycie()
        {
            return zycia - 1;
        }

        public override int DodajZycie()
        {
            return zycia + 1;
        }
    }

Metody:

 public void GraSieToczy()
        {
            if (KoniecGry == false)
            {
                FObiekt_1.Left -= PredkoscLotu();
                Odleglosc++;
                label2.Text = Odleglosc + " m.";
            }
        }        // Warunek.

        public void GraSieToczy2()
        {
            if (KoniecGry == false)     
            {
                FObiekt_2.Left -= PredkoscLotu();
            }
        }





        // ------------------------- Dla Postaci ---------------------
    
        public void OpiszPostac()
        {
            string imie = "Amadeusz";
            int wysokosc = 7;
            int punkty = 1;
            int zycia = 1;
            GraczPierwszy gracz_pierwszy = new GraczPierwszy(imie, punkty, wysokosc, zycia);
            ListaGraczy.Add(gracz_pierwszy);
        }



        public void Spadaj()
        {
            FPostac_1.Top += ListaGraczy[0].wysokosc;         // Wysokość komponentu "FPostac_1" się zwiększa o 7 jednostek symulując spadanie.
        }

        public void Lec()
        {
            FPostac_1.Top -= ListaGraczy[0].wysokosc;
        } 

        public void RuchPionowy()
        {
            if (gora)
            {
                Lec(); // Metoda odpowiedzialna za spadanie postaci.
            }
            else
            {
                Spadaj(); // Metoda odpowiedzialna za wznoszenie się postaci.
            }
        }     // Warunki dla leć i spadaj.

        public void ZderzenieZObiekt1()
        {
            int wysokosc_postaci = FPostac_1.Top + FPostac_1.Height;
            int wysokosc_obiektu = FObiekt_1.Top + FObiekt_1.Height + 3;
            int polozenie_postaci_y = FPostac_1.Top;
            int polozenie_obiektu_y = FObiekt_1.Top;
            int szerokosc_postaci = FPostac_1.Left + FPostac_1.Width;
            int szerokosc_obiektu = FObiekt_1.Left + FObiekt_1.Width + 3;
            int polozenie_postaci_x = FPostac_1.Left;
            int polozenie_obiektu_x = FObiekt_1.Left;

            if (((wysokosc_postaci <= wysokosc_obiektu) && (polozenie_postaci_y >= polozenie_obiektu_y)) && ((szerokosc_postaci <= szerokosc_obiektu) && (polozenie_postaci_x >= polozenie_obiektu_x)))
            {
                ListaGraczy[0].zycia = ListaGraczy[0].StracZycie();
                if (ListaGraczy[0].zycia < 1)
                {
                    GameOver();
                }
            }
        }

        public void ZderzenieZObiekt2()
        {
            if (((FPostac_1.Top + FPostac_1.Height <= FObiekt_2.Top + FObiekt_2.Height+3) && (FPostac_1.Top >= FObiekt_2.Top)) && ((FPostac_1.Left + FPostac_1.Width <= FObiekt_2.Left + FObiekt_2.Width+3) && (FPostac_1.Left >= FObiekt_2.Left)))
            {
                ListaGraczy[0].zycia = ListaGraczy[0].StracZycie();
                if (ListaGraczy[0].zycia < 1)
                {
                    GameOver();     
                }
            }
        }

        public void GameOver()           
        {                              // Kiedy postać zderzy się z obiektem.
            KoniecGry = true;
            FObiekt_1.Top = -793;
            FObiekt_2.Top = -799993;
            MessageBox.Show("Twoje punkty to: " + ListaGraczy[0].punkty, "Koniec Gry!");       // game over. 
            Close();
        }

        public void ObszarRozgrywki()
        {
            if (FPostac_1.Top <= 0)
            {
                FPostac_1.Top += ListaGraczy[0].wysokosc;                      // Blokada chroniąca przed wylotem postaci po za górny obszar świata gry.
            }

            if (FPostac_1.Top + FPostac_1.Height >= 323)
            {
                FPostac_1.Top -= ListaGraczy[0].wysokosc;                     // Blokada chroniąca przed wylotem postaci po za dolny obszar świata gry.
            }
        } 



        // -------------------- Dla drugiego obiektu -----------------


        public void ObiektDwaAktywuj()
        {
            if (ListaGraczy[0].punkty == 2) Obiekt2Akt = true;   // Jeśli punkty są równe 25 to obiekt2 się aktywuje.
            if (Obiekt2Akt == true) FObiekt2.Enabled = true;     
        }
       
        public void Obiekt2()
        {                    // Metoda opisuje Obiekt2 nadając mu randomową pozycję , wysokość i szerokość.
            ListaPrzeszkod[0].Losuj();
            FObiekt_2.Height = ListaPrzeszkod[0].wysokosc;
            FObiekt_2.Width = ListaPrzeszkod[0].szerokosc;
            FObiekt_2.Left = ListaPrzeszkod[0].pozycja_x;
            FObiekt_2.Top = ListaPrzeszkod[0].pozycja_y;
            ListaGraczy[0].punkty = ListaGraczy[0].PodniesPunkty();
        }

        public void Obiekt2_RuchGora()
        {
            int wysokosc = 7;   // Wysokość położenie na oknie się zmniejsza.
            FObiekt_2.Top -= wysokosc;
        }

        public void Obiekt2_RuchDol()
        {                                    // Jak się zwiększa o randomową jednostkę w skali od 1 do 10.
            int wysokosc = 7;
            FObiekt_2.Top += wysokosc;
        }

        public void RuchGoraiDol()
        {
            if (dol == false)
            {
                Obiekt2_RuchGora();
                if (FObiekt_2.Top <= FSwiat_1.Top)
                {
                    dol = true;
                }
            }

            if (dol == true)
            {
                Obiekt2_RuchDol();
                if (FObiekt_2.Top + FObiekt_2.Height >= FSwiat_1.Top + FSwiat_1.Height)
                {
                    dol = false;
                }
            }

        }

        public void OdNowaObiekt2()
        {
            if (FObiekt_2.Left <= -75)    
            {
                Obiekt2();
            } 

        }



        // ------------------- Dla Obiektu pierwszego ----------------

        public void OpiszPrzeszkode()
        {
            PrzeszkodaPierwsza przeszkoda_pierwsza = new PrzeszkodaPierwsza(szybkosc, wysokosc, szerokosc, pozycja_x, pozycja_y);
            ListaPrzeszkod.Add(przeszkoda_pierwsza);
        }

        public void Obiekt1()
        {
            ListaPrzeszkod[0].Losuj();
            FObiekt_1.Height = ListaPrzeszkod[0].wysokosc;
            FObiekt_1.Width = ListaPrzeszkod[0].szerokosc;
            FObiekt_1.Left = ListaPrzeszkod[0].pozycja_x;
            FObiekt_1.Top = ListaPrzeszkod[0].pozycja_y;
            ListaGraczy[0].punkty = ListaGraczy[0].PodniesPunkty();
        }

        public void OdNowaObiekt1()
        {                               //  Kiedy Obiekt wyleci po za świat gry.
            if (FObiekt_1.Left <= -75)
            {
                Obiekt1();
                ZmianaPredkosci();
            }
        }


        // ------------- Dla wszystkich Obiektów i Bonusów -----------

        public int PredkoscLotu()
        {
            return 2 + ListaPrzeszkod[0].szybkosc;
        }

        public void ZmianaPredkosci()    // Metoda odpowiedzialna za zmianę prędkości ruchu.
        {
            if (ListaGraczy[0].punkty == 3)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 6)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 10)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 14)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 18)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 22)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 26)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 30)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz(); 
            }

            if (ListaGraczy[0].punkty == 33)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 40)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 45)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 70)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 95)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 126)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }

            if (ListaGraczy[0].punkty == 150)
            {
                ListaPrzeszkod[0].szybkosc = ListaPrzeszkod[0].Przyspiesz();
            }
        }

        public void AktywujBonusZycie()
        {
            if (ListaGraczy[0].punkty == 50)
            {
                FBonusZycieTick.Enabled = true;
            }
        }


        // --------------------------Bonusy --------------------------
        public void BonusZycie()
        {
            int NowaPozycja = rld.Next(0, 296);
            FBonusZycie.Top = NowaPozycja;
            FBonusZycie.Left = 714;
        }

        // ----------------------- Dla Timer'ów ----------------------

        public void Postac_I_Przeszkoda_1()
        {
            RuchPionowy();
            GraSieToczy();
            OdNowaObiekt1();
            WyswietlStatystyki();
            ZderzenieZObiekt1();
            ObszarRozgrywki();
            ObiektDwaAktywuj();
        }

        public void Przeszkoda_2()
        {
            OdNowaObiekt2();
            GraSieToczy2();
            RuchGoraiDol();
            ZderzenieZObiekt2();
            AktywujBonusZycie();   
        }

        // ----------------------- Wyswietlanie ----------------------
        public void WyswietlStatystyki()
        {
            FPunkty.Text = ListaGraczy[0].punkty.ToString();
            FWyswitlZycie.Text = ListaGraczy[0].zycia.ToString();
        }

Metody Postac_I_Przeszkoda_1(), Przeszkoda_2() umieszczone w timerach, których Interval przyjmuję wartość 1.

0

timerach, których Interval przyjmuję wartość 1.

No to masz już odpowiedź, chcesz mieć 1000 klatek na sekundę to się nie dziw że procek nie wyrabia.

0

Faktycznie, zmieniłem interval wszystkich timerów i wykorzystanie procesora gwałtownie spadło, ale tak czy siak klatkuje, i gra która polega na unikaniu nadlatujących obiektów nie ma totalnie sensu. Jakieś proponowane rozwiązania widzicie po za przejściem na .XNA lub WPF?

1
wojas666 napisał(a):

Rozumiem że WFA nie służy do tworzenia gier, jednakże szkoda mi godzin spędzonych przed projektem, by zaczynać go od nowa

super! masz okazję się czegoś nauczyć
przy przepisywaniu gry na coś normalnego zwrócisz uwagę na to że logika gry (czyli większość kodu) nie powinna być zależna od warstwy prezentacji. Portując grę zwrócisz uwagę gdzie można było się ustrzec wzajemnych zależności i w przyszłości będziesz prawdopodobnie tworzył mniej sztywny kod

wojas666 napisał(a):

Faktycznie, zmieniłem interval wszystkich timerów

"wszystkich"? To ile ich masz? Wystarczy w zupełności jeden
Lagi przy tle powstają przez ciągłe odrysowanie tła - tło musi się odrysować gdy obiekt przestaje go zasłaniać. Skup się na innej metodzie rysowania tła

1 użytkowników online, w tym zalogowanych: 0, gości: 1