Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

19.04.2011, 15:37

Binzublödfür: einfache Kollisionserkennung

Hallo,


(Link)


(Link)


Zwei Bilder, eine Situation: Der Ball bewegt sich von der Spielerleiste weg (auch wenn der Ball beim ersten schon zu weit ist) und prallt dann ab. Funktioniert auch, allerdings wird die Kollisionsberechnung scheinbar ungenau mit der Entfehrung, vielleicht ist dies auch nur eine optische Täuschung. So berechne ich dies:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
                for(vector<Object*>::iterator i = blocks.begin(); i != blocks.end(); i++){
            Vector3 blockPos = (*i)->getPosition(); 
            
            if(pos.x < blockPos.x+0.045 &&
               pos.x > blockPos.x-0.045 &&
               pos.z < blockPos.z+0.02 &&
               pos.z > blockPos.z-0.02){
                
                           moveBall.z *= -1;

               break;
            }
        }


Dabei werden alle Blöcke auf dem Feld durchlaufen (also nur der eine). Wenn ich mir die Koordinaten bei der Kollision ausgeben lasse stimmen diese auch soweit (also z.B. Block (0|0.7), Ball (0|0.68)). Bei der aller letzten Reihe kollidiert der Ball gar nicht mehr mit den Blöcken. Außerdem kommt es vor das der Ball "durchfährt" und in den Blöcken ein paar mal hin und her fährt.

MfG DK

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

2

19.04.2011, 16:10

Eventuell bewegt sich Dein Ball zu schnell in die z-Richtung? Du nimmst ja gerade mal 0.04 als Breite. Vielleicht tunnelt der Ball einfach durch den Block,
heißt ist in einem Frame kurz davor und im nächsten schon dahinter.

Dann reicht es nicht aus, bei einer Kollision die Geschwindigkeit zu ändern. Du solltest die Geschwindigkeit ändern UND dann mit der neuen nochmals die Position des Balles bestimmen. Damit setzt Du ihn quasi bei einer Kollision etwas zurück.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

19.04.2011, 17:53

Die kleinen Werte kommen durch die Weltkoordinaten zustande (hab nicht so groß skaliert). Würde es was bringen die Ballposition+Vektor auf Kollision zu prüfen? Ich probier das jetzt mal mit dem zurücksetzen.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

4

19.04.2011, 19:12

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(vector<Object*>::iterator i = blocks.begin(); i != blocks.end(); i++){
            Vector3 blockPos = (*i)->getPosition(); 
            float dif = 0.02+blockPos.z/6;

            if(pos.x < blockPos.x+0.045 &&
               pos.x > blockPos.x-0.045 &&
               pos.z < blockPos.z+dif &&
               pos.z > blockPos.z-dif){
                moveBall.z *= -1;
                score++;
                blocks.erase(i);

                break;
            }
        }


Superhässlich aber es funktioniert...
Was genau zieht an einem Spiel jetzt eigentlich die FPS runter? Ich bekomme nur 100 FPS, und diese werden mit jedem zerstörten Block mehr (so ja 4 mehr pro Block). Hätte ich eine schnellere Ausgabe mit weniger VBOs (im Moment eins pro Model, die können allerdings mehrfach verwendet werden und so sinds für alles nur 4)? Oder ziehen die Vektordurchläufe so viel? Ich weiß nicht was ich stark verbessern könnte...

Und noch was: Wie baue ich es jetzt am besten ein das der Ball sich an der Spielerleiste je nach Aufschlagpunkt stärker oder schwächer auf der X-Achse bewegt?

Hab glaub ich etwas komisch geschrieben ^^ naja.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

19.04.2011, 19:35

Ich seh nicht wo bei 100 FPS das Problem liegt!?

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

19.04.2011, 22:12

100 FPS sind eigentlich schonmal ok. Du musst ein bisschen drauf achten was in deinem Code so passiert. Der Rechenaufwand von deinen Funktionen kann deinen Code langsam machen. Wurzelfunktionen sind zum Beispiel Funktionen die relativ langsam sind. Wenn du diese vermeiden kannst dann ist das schonmal nicht schlecht. Weiterhin können unnötige Schleifendurchläufe deinen Code verlangsamen. Unnötige If's sind auch schonmal ein Performancekiller. Das sind jetzt nur ein paar Beispiele auf was man so alles achten kann. Je nachdem bringt auch die Wahl deiner Container mehr Performance. Auf den Inhalt eines Arrays kannst du normal schneller zugreifen als auf den Inhalt einer Liste. Das hängt einfach mit dem Aufbau des Containers zusammen. Wenn du Code schreibst, dann versuch dir einfach mal vorzustellen, was da so genau abläuft und was wann gemacht wird. Das hilft schonmal für den Anfang weiter;) Der Rest kommt dann irgendwann mit wachsender Erfahrung.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

7

19.04.2011, 23:35

Zitat

Ich seh nicht wo bei 100 FPS das Problem liegt!?


Findest du nicht bei einer Radeon HD 5870? Find ich allerdings schon wenn man bedenkt das ich ohne Blöcke auf dem Spielfeld immerhin 800fps habe und bei anderen Testprogrammen mit dem 100 fachen an Vertices und Texturen über 1500fps.
Also ich denke der Killer ist die Kollisionserkennung (durchläuft einen vector mit allen Blöcken) und mehreren if Abfragen. Ich kann mir aber auch nicht vorstellen die wegzubekommen, aber wie macht man das dann in Spielen wie Crysis die ja deutlich komplexer sind und viel mehr Kollisionen, von Grafik mal abgesehen, haben?
Für mein erstes Spiel ist mir das erstmal aber egal. Für die Zukunft find ich bestimmt noch gute Lektüre...

Wie löse ich das mit der Richtungsänderung am Spielerbalken am elegantesten?

8

20.04.2011, 08:54

DrawCalls sind ein großes Problem, also jeder Aufruf an die Grafikkarte irgendwas zu zeichnen. Die genannten Wurzeln/Abfragen/Schleifen benötigen natürlich auch Rechenzeit aber nur wenn es davon wirklich sehr viele gibt.

Ich vermute, deine Blöcke sind sehr simple Modelle, die Zeit zum eigentlichen darstellen ist daher verschwindend gering. Allerdings muss sich die Grafikkarte auf jeden DrawCall erstmal einstellen, du solltest also versuchen, möglichst wenig Aufrufe zu haben, also z.B. slle Blöcke in einen großen VertexBuffer packen und auf einen Schlag rendern. Wenn dir das gelingt (ist natürlich bei unterschiedlichen Modellen mit unterschiedlichen Texturen nicht immer einfach/möglich) solltest du auch so 800 statt 100 FPS haben. Siehe dazu auch:
http://www.mvps.org/directx/articles/fps…_frame_time.htm

Kollisionserkennung ist natürlich auch immer ein beleibter Performancekiller, aber da du ja vermutlich nur einen Ball hast, wächst das nur linear mit der Anzahl der Blöcke, das dürftest du also kaum merken.
Lieber dumm fragen, als dumm bleiben!

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

9

20.04.2011, 09:04

Also 100 FPS sind ja noch kein Problem. Es gibt unendliche viele Möglichkeiten, was Dein Programm so langsam macht.
Ich denke mal das Testprogramm wird diese 1000den Vertices in einem Batch als ein Drawcall absetzen. Du machst das (ich rate mal)
wahrscheinlich pro Block. Dann setzt Du wahrscheinlich (wieder geraten) jedes mal die Texture usw. usw. Da sammelt sich dann
sooo dermaßen viel an Ineffizienz an, dass es halt langsam wird.
Am besten nimmst Du dir mal einen Profiler und schaust mal, wo denn die Zeit verloren geht. So kannst Du nur raten und ich vermute mal,
dass Du hier wohl auch mit Deiner Vermutung falsch liegst. Die Kollisionsabfrage sollte nicht das Problem sein. Obwohl man auch hier
einiges drehen kann.

Es gibt eigentlich nur eine Lösung für die Richtungsänderung. Ich mach das mal etwas grob:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
void updateBall(float time) {
  Vec3 ballPos = m_Ball->getPosition();
  ballPos += m_Velocity * time;
  if ( collides(ballPos) ) {
    m_Velocity.z *= -1.0f;
   ballPos += m_Velocity * time;
  }
  m_Ball->setPosition(ballPos);
}

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

10

20.04.2011, 12:01

Zitat

Ich vermute, deine Blöcke sind sehr simple Modelle, die Zeit zum eigentlichen darstellen ist daher verschwindend gering. Allerdings muss sich die Grafikkarte auf jeden DrawCall erstmal einstellen, du solltest also versuchen, möglichst wenig Aufrufe zu haben, also z.B. slle Blöcke in einen großen VertexBuffer packen und auf einen Schlag rendern.


Stimmt, daran liegts... Aber das änder ich später da es mir so erstmal einfacher ist und ich schließlich erstmal die Kollision usw. hinbekommen muss.
Momentan ist die FPS ja sowieso nicht das Problem.

Zitat


Es gibt eigentlich nur eine Lösung für die Richtungsänderung. Ich mach das mal etwas grob:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
void updateBall(float time) {
  Vec3 ballPos = m_Ball->getPosition();
  ballPos += m_Velocity * time;
  if ( collides(ballPos) ) {
    m_Velocity.z *= -1.0f;
   ballPos += m_Velocity * time;
  }
  m_Ball->setPosition(ballPos);
}



Das du nach der Kollision die Position neu bestimmst versteh ich, allerdings weiß ich nicht genau wie ich z.B. bestimmen kann ob der Ball nun von vorne/hinten bzw. von der Seite getroffen hat und dementsprechend z oder x ändern muss...





Hier mal das ganze zum Download, wenn ihr ein wenig "gespielt" habt merkt ihr was ich an der Kollision sch**** finde:

http://marvinblum.de/media/download/Citus_2.zip

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (20.04.2011, 12:29)


Werbeanzeige