Laden...

Main Loop / Device erstellen / ruckeln

Erstellt von Fab96 vor 19 Jahren Letzter Beitrag vor 19 Jahren 5.470 Views
F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren
Main Loop / Device erstellen / ruckeln

Moin

Momentan bin ich total am verzweifeln da ich egal was ich mache immer ein ruckeln und flackern habe.

Darum meine frage, wie erstellt ihr das grundgerüst damit dies nicht passiert?

Ich habs so versucht das 50mal pro sekunde die gamelogik durchlaufen wird und der rechner sooft das bild neu rendert wie er kann.

Bewegungen errechne ich indem ich die zeit seit dem letzen rendern nehme und sie zum beispiel mit 100 multipliziere und dann zeichne.

So komme ich beispielweise auf 3000frames nur es flackert und ruckelt teilweise.

So langsam verzweifel ich wirklich da ich langsam keine idee mehr hab woran es liegen könnte.


public void InitGFX(bool fullscreen)
   {
     try
     {
       PresentParameters pParam = new PresentParameters();
              
       Format current = Manager.Adapters[0].CurrentDisplayMode.Format;

        if (Manager.CheckDeviceType(0, DeviceType.Hardware, current, current, false) && fullscreen)
       {
         pParam.Windowed = false;
         pParam.BackBufferFormat = current;
         pParam.BackBufferCount = 1;
         pParam.BackBufferHeight = screenHeight;
         pParam.BackBufferWidth = screenWidth;
        }
        else
       {
   
         pParam.Windowed = true;

         }

                pParam.PresentationInterval = PresentInterval.Immediate;

                pParam.AutoDepthStencilFormat = DepthFormat.D16;

                pParam.EnableAutoDepthStencil = true;

                int adapterOrdinal = Manager.Adapters.Default.Adapter;
                pParam.SwapEffect = SwapEffect.Discard;

                device = new Device(adapterOrdinal, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, pParam);


                // Verschiedenes
                mMenu = new MainMenu(device);
                game = new Game(device);
                gameInfo = new Info(device);
            }
            catch
            {
                MessageBox.Show("Fehler beim Device inizialiesieren");
            }
        }


        private void RenderStart()
        {
     
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Black, 1.0f, 0);
            device.BeginScene();
         }

        private void RenderEnd(float eTime)
        {
            gameInfo.Draw(eTime);
            device.EndScene();

            device.Present();
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            gameInfo.startFPS();
            elapsedTime = Utility.Timer(DirectXTimer.GetElapsedTime) +timeSaver;
 
            switch (status)
                    {
                        case state.MainMenu: if (elapsedTime >= 0.02)
                                                {
                                                    mMenu.Update(elapsedTime);
                                                    timeSaver = 0;
                                                }
                                             else timeSaver = elapsedTime;

                                             this.RenderStart();
                            
                                                    mMenu.DrawMenu();
                                                
                                             this.RenderEnd(elapsedTime);
                                             break;


                       case state.Game:     if (elapsedTime >= 0.02)
                                               {
                                                    game.GameLogic(elapsedTime);
                                                    game.Update(elapsedTime);
                                                    timeSaver = 0;
                                                }
                                             else timeSaver = elapsedTime;

                                             this.RenderStart();
                                                
                                                    game.DrawGame();

                                             this.RenderEnd(elapsedTime);
                                                break;

                        case state.Option:      break;
                        case state.Info:        break;
                        case state.Highscore:   break;
                        case state.Credits:     break;
                    }


                    this.Invalidate();

                    gameInfo.endFPS();
                }

Da Bilder mehr sagen: Daswas ich bisjetzt habe: http://www.zikowsky.de/dk/Release.exe
nötige DX Dateien: http://www.zikowsky.de/dk/mdxredist.msi

mit M springt man ins "menu" und mit G wieder ins game pfeiltasten bewegen den raumer.

Ich hoffe das beispiel und der code helfen und irgendjemand hat eine idee, ich hab selber absolut keine mehr 🙁

PS: warum er das so komisch formatiert weiß ich auch nicht 😠 bei quote ist garkein tab etc. drin und hier viel zu viel 😠

H
704 Beiträge seit 2003
vor 19 Jahren

änder mal pParam.PresentationInterval = PresentInterval.Immediate; auf pParam.PresentationInterval = PresentInterval.Default;

Ansonsten habe ich kein Flimmern, das Schiff bewegt sich jedoch ein wenig ruckartig(es sind keine fließenden Bewegungen)

[last.fm](http://www.last.fm/user/hauptmanAlpha/)
F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

Die ruckartigen bewegungen sind beim Menü sowie im "spiel oder?

genau dasist ja das problem, ich hab keineahnung wie ich es webekommen könnte, es muss also irgendwo ein kleinerfehler sein in derlogik.

EDIT: habs mit default getestet, ist logischreweise dann bei mir bei ~80FPS nur es ruckelt meinr meinung nach deutlich mehr

1.373 Beiträge seit 2004
vor 19 Jahren

Der Gesteinsbrocken im Menü ruckelt bei mir nicht.

Dass das Raumschiff ruckelt liegt daran, wie du die Eingabe abfragst. Du solltest dem Raumschiff einen Geschwindigkeitsvektor verpassen. Zu Beginn ist dieser Vektor (0,0). Sobald eine Taste gedrückt wird (KeyDown event), wird dieser auf die entsprechende Richtung/Geschwindigkeit gesetzt. Bei z.B. Pfeil-Nach-Rechts auf (50, 0). Welche Einheit das ist, musst du selbst wissen, beispielsweise Pixel pro Sekunde.

Pro Logik-Frame berechnest du die neue Position des Raumschiffes so:

neuePosition = altePosition + ( richtungsVektor * zeitSeitLetztemFrameInSekunden )

Übrigens ist es vollkommen unsinnig, mehr frames zu rendern als Logik-Frames zu berechnen. Wozu sollte man mehrfach das gleiche Bild rendern wollen? Andersherum wäre es sinnvoller: möglichst oft den Spielstatus aktualisieren, und das Rendern ( = sehr rechenintensiv ) begrenzen. Wobei auch das kritisch werden kann: eine zu hohe Logik-Framerate kann dazu führen, dass Berechnungen sehr ungenau werden, da sich kleine Rundungsfehler schnell aufaddieren.

MfG VizOne

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

        public void Update(float elapsedTime)
        {
            if (elapsedTime <= 1000)
            {
                float movePlayer = playerSpeed * elapsedTime;
  
                if (movingUp)
                {
                    playerPosition.Y -= movePlayer;
                    player.Y = playerPosition.Y;
                    movingUp = false;
                }

                if (movingDown)
                {
                    playerPosition.Y += movePlayer;
                    player.Y = playerPosition.Y;

                    movingDown = false;
                }
                if (movingLeft)
                {
                    playerPosition.X -= movePlayer;
                    player.X = playerPosition.X;

                    movingLeft = false;
                }

                if (movingRight)
                {
                    playerPosition.X += movePlayer;
                    player.X = playerPosition.X;
                    movingRight = false;
                }
            }
        }
[/SHARP]

mach ich schon so, im menü auch, nur ruckelts trozdem, in nem beispiels ollte playerspeed 450 sein.

Wenn ich 450 etwa in 45 ändere ist s im grunde flüssig, nur sehr sehr langsam da wohl nichtmal 50pixel die sekunde, auserdem hab ich dann irgendwie ein unscharfes bild.

im "Menu" springt bei mir der Asteroid machnaml ganz leicht und hab das gefühl das es einfach nciht wirklich rund läuft.

[URL]www.zikowsky.de/IceWarsShooter.exe[/URL]
hier mal source und co
1.373 Beiträge seit 2004
vor 19 Jahren

Wie fragst du die Tasten ab?

MfG VizOne

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

So :


        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape) // Quit
                this.Close();

            if (e.KeyCode == Keys.M)
                status = state.MainMenu;
            if (e.KeyCode == Keys.G)
                status = state.Game;

            base.OnKeyUp(e);
        }


        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
            {
                game.IsMovingUp = true;
            }
            if (e.KeyCode == Keys.Down)
            {
                game.IsMovingDown = true;
            }

            if (e.KeyCode == Keys.Left)
            {
                game.IsMovingLeft = true;
            }

            if (e.KeyCode == Keys.Right)
            {
                game.IsMovingRight = true;
            }
 
        }

1.373 Beiträge seit 2004
vor 19 Jahren

Ersetz es mal durch


protected override void OnKeyUp(KeyEventArgs e)
{
	switch(e.KeyCode)
	{
		case Keys.Escape:
			this.Close();
			break;

		case Keys.M:
			status = state.MainMenu;
			break;

		case Keys.G:
			status = state.Game;
			break;

		case Keys.Up:
			game.IsMovingUp = false;
			break;

		case Keys.Down:
			game.IsMovingDown = false;
			break;

		case Keys.Left:
			game.IsMovingLeft = false;
			break;

		case Keys.Right:
			game.IsMovingRight = false;
			break;
	}
	base.OnKeyUp(e);
}


protected override void OnKeyDown(KeyEventArgs e)
{
	switch(e.KeyCode)
	{
		case Keys.Up:
			game.IsMovingUp = true;
			break;

		case Keys.Down:
			game.IsMovingDown = true;
			break;

		case Keys.Left:
			game.IsMovingLeft = true;
			break;

		case Keys.Right:
			game.IsMovingRight = true;
			break;
	}
	base.OnKeyDown(e);
}

Und schmeiß die folgenden Zeilen aus Update raus:


 movingUp = false;
 movingDown = false;
 movingLeft = false;
 movingRight = false;

Dann sollte es schön "flutschen". Oder noch besser: benutz DirectInput

MfG VizOne

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

Stimmt läuft besser, danke 🙂

aber dafür hab ich immer noch dies leichte ruckeln/flackern

etwa wie bei nem ego-shooter bei schnellen bewegungen ohne vsync.

1.373 Beiträge seit 2004
vor 19 Jahren

Dann wird es wohl am fehlenden VSync liegen, oder? 😁 Schalt ihn doch ein (wie hier bereits erwählt: PresentInterval.One bzw. Default)

MfG VizOne

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

hm dasist auch vsync ? gut was gelernt, nur wenn ich auf default stelle ruckelt und stottert es wieder 😠

1.373 Beiträge seit 2004
vor 19 Jahren

Lad mal das (neue) Programm und am besten den Source hoch. Ich würd wohl mal durchschauen, ob ich was sehe.

MfG VizOne

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren
F
124 Beiträge seit 2004
vor 19 Jahren

dein proggi stürzt bei mir beim starten direkt mit einer ausnahme ab. eine messagebox bei dir meint auch "fehler beim dewvice erstellen" ... ich habe selbst mit mdx9 etwas probiert und wollte was machen. ich weiß, dass mein notebook nur softwarevertexprocessing kann, daran wird es liegen. vielleicht baust du ne kleine prüfroutine ein ?

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

hmdanke fürs testen, werds auf jedenfall einbauen,hat ich nur momentan nochnciht dran gedacht da ich eigentlich garnix online stellen wollte bis ich nicht was anschaubares habe.

Werd ichaber einbauen sobald der fehler hier koorigiert ist. auch wenn das wohl dauert 😠

A
41 Beiträge seit 2003
vor 19 Jahren

hiergibts ein komplettes Tutorial zu DirectX 9 mit C#

vielleicht hilft dir das:
http://www.kuhnstall.de/tutorials/dx9sharp1.html

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

JO kenn ich, nur ist das DirectDraw, icharbeite abermit DIrect3D da in DX9 DDraw nicht mehr verwendet werden soll und ich wenn gleichdas lernen will was ich später brauche.

ich hoffe das vizOne nocheine idee hat da er bis jetzt ja schon sehr gut geholfen hat.

1.373 Beiträge seit 2004
vor 19 Jahren

Mögliche Faktoren wären auch noch Debug vs. Release build, Debug vs. Release DX Runtime

MfG VizOne

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

hm du meinst das ich es mit den Debug dll's compiliere ? oderwas genau ?

habs eben nochmal als release build versucht, sieht da auchnciht besser aus.

Hab nochmal was anderes getestet, hab auf:
pParam.PresentationInterval = PresentInterval.Immediate;

gestellt und habs so eingestellt das er die positionen wirklich jeden OnPaint durchgang berechnet, da verginern sich die ruckler/springer beträchtlich, nur sobald ich auf default stelle ruckelts trozdem genauso wie vorhher.

Ich denke dadurch könnts eventuell an der positionsberechnung liegen ?

EDIT 2: hab was getestet, damit scheints absolut flüssig zu laufen soalnge Immerdiate an ist, nur flackert es dafür absolut unerträglich.

habe
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

und habe nun
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | ControlStyles.OptimizedDoubleBuffer, true);

dadurch scheints auf Immerdiate flüssigzusein nur halt verdammt am ruckeln.

Edit 3: ich habe mir mal alle bewgungswerte des asteroiiden in ein string gespeichert und den dann aufder console nach einem durchlauf ausgegen:

3,887952
4,536666
2,363149
2,366781
2,41947
3,461697
2,499396
2,254169
2,249364
2,359825
2,378347
2,396031
2,324485
3,671668
2,152787
2,376112
2,474281
2,271378
3,660661
2,349908
2,219947
2,42623
2,329039
2,696851
3,086286
4,933141
2,124879
2,702187
6,540943
11,12088
3,373418
3,179734
2,517638
2,307612
2,519678
2,3496
2,190251
2,352059
2,580132
2,268473
2,328061
2,283503
3,477341
2,549067
2,530349
3,229349
2,597341
2,078532
2,307416
2,345242
2,678637
3,336402
2,226652
2,36625
2,476097
2,212907
2,524874
2,181395
3,177583
3,892031
2,35217
2,561974
3,573806
2,096942
2,349544
2,376056
13,43925
3,00284
3,52109
2,348148
2,357003
2,346555
2,399635
2,353176
2,319904
2,33999
3,574672
2,345717
2,315043
2,607594
2,213214
2,62673
3,136712
2,417961
2,287386
2,450675
3,45773
2,390751
2,514482
2,553816
2,027744
3,442086
2,348762
2,740572
2,827371
2,664361
4,088984
2,550743
3,078855
2,043584
2,350243
4,822233
4,611564
2,434527
2,304231
3,122464
3,445801
6,039315
5,205662
4,554405
2,266405
2,361166
7,754338
2,92973
3,547294
3,399734
2,354713
2,803904
2,238385
2,065989
2,320826
2,329374
2,38061
3,559978
2,582647
2,13935
3,454545
2,560465
2,341164
2,295851
2,246962
2,368262
2,759066
3,109725
2,311607
4,658078
7,308387
6,653723
3,90491
2,52317
2,064788
4,666766
2,450256
5,06394
3,542321
3,947318
3,084387
3,061283
2,383236
2,509118
2,26512
2,252996
2,530545
2,339739
2,22126
2,317557
2,387482
2,530573
2,251431
2,397902
2,280681
2,374631
2,239084
2,359406
2,78337
2,251012
2,187541
2,413407
4,035233
2,833712
2,640978
3,210995
5,364648
2,95694
2,288224
2,31806
2,367228
2,433969
2,352952
2,717496
2,163096
3,377356
2,25213
3,554558
2,326357
2,327391
2,498278
2,220869
2,348483
2,343426
2,666428
2,128846
2,306327
2,304986
2,369323
2,381392
2,707774
3,315142
2,299231
2,396087
2,190949
6,99357
2,470426
2,287134
2,345521
2,618797
2,215784
2,264953
2,509202
2,161923
2,348232
2,4904
2,293085
2,326385
2,30236
2,350857
2,3515
2,62363
2,303729
2,133316
3,020831
2,952638
3,434822
2,643967
2,214415
2,441819
4,551221
3,812104
3,168391
2,42271
3,069692
5,065923
3,244323
2,663188
2,351249
2,395472
3,348945
3,670104
4,263978
5,56649
3,509413
2,00193
4,69339
4,697692
3,829146
4,199947
2,959175
5,018375
2,865979
3,724356
5,337243
2,60061
2,348483
4,160725
3,068323
2,628714
2,249476
2,05311
2,338202
2,361362
2,435058
2,426705
2,381811
2,308087
2,507693
2,294062
3,301761
2,348567
2,563203
2,349768
2,213913
2,248275
3,529974
2,886819
4,522586
2,04241
3,482174
2,342867
2,383934
2,371531
2,297638
2,361669
3,657728
2,217489
2,351723
2,354601
2,618126
2,331972
2,346639
2,265176
2,269702
2,32619
2,330631
2,330883
2,345857
2,376475
2,410614
2,280345
2,408909
2,292358
2,613768
2,217153
2,222908
2,374408
2,334766
2,40335
2,302472
2,35921
2,360384
2,391421
2,499871
4,982505
2,144407
2,129824
2,41025
2,482159
2,113816
2,350802
2,397372
2,326692
2,334207
2,426985
3,507764
2,293923
2,370385
2,907046
4,19883
2,288867
2,617959
2,559711
3,1561

etwas viel text, aber wie mansieht sind da teilweise enorme sprünge, was ein starkes ruckeln natprlich erzeugt.

Werte sind default werte, bei Immerdiate sind die größten sprünge maximal von 2,0x zu 3,5x

F
Fab96 Themenstarter:in
66 Beiträge seit 2004
vor 19 Jahren

Hab nun weiter rumgetestet und hoffentlich auch verbessert, nur nun hab ich irgendwie so ein ruckelnalle paar sekunden, es läuft kurz flüssig 1/2 sekunde dann ruckeln dann wiederflüssig usw.

Hat daeventuell wer eine idee ? es muss im grunde am device erstellen liegen, alles andere hab ich rausgenommen, ich lsse nur nochein sprite von linsnach rechts laufen, mehr nicht.

Oderkönnt eventuelll wer beispiel geben insachen device erstellen ? alles was ich bis jetzt getestet hab klappte nicht wirklich. 😠

@VizOne: hast du dir esschon angeschautevnetuell ?