Effiziente If-Abfrage

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

Fluppe

Betreff: Effiziente If-Abfrage

BeitragDo, Jul 31, 2008 0:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen.

Für meinen Arkanoid-Klon arbeite ich zur Zeit an der Optimierung der Geschwindigkeit.

Es geht konkret um die Bedingung, den ImagesCollide-Befehl zu starten, wenn der Ball (b.x, b.y) in der Nähe des Blocks ist (bl.x,bl.y). Den Abstand beinhaltet die Variable 'abstand' (zu Testzwecklen global deklariert).

Der Ball hat die Geschwindigkeit b.xspeed und ein Field namens "check". Wenn dieses Feld 1 ist, soll auf mögliche Kollision mit dem Ball geprüft werden. Im Laufe der Funktion wird der Wert dann wieder auf 0 gesetzt. Logisch.

Eine Prüfung ist notwendig, da sie Anzahl der Blocks in einem Level relativ groß sein kann.

Meine Frage ist nun eigentlich ziemlich trivial:

Welches ist die effizienteste If-Schleife, die als Bedingung der Kollisionsprüfung verwendet werden kann?

Meine Lösung (zugegeben, das sieht irgendwie sehr unelegant aus):

Code: [AUSKLAPPEN]


      If b.xspeed => 0 And bl.x# => b.x# And bl.x# - b.x# <= abstand
            If bl.y# => b.y# And b.yspeed# => 0 And bl.y# - b.y# <= abstand bl.check=1   
           If b.y# => bl.y# And b.yspeed# <= 0 And b.y# - bl.y# <= abstand bl.check=1
              If bl.y# <= b.y# And b.yspeed# => 0 And b.y# - bl.y# <= abstand bl.check=1   
           If b.y# <= bl.y# And b.yspeed# <= 0 And bl.y# - b.y# <= abstand bl.check=1
        EndIf
      If b.xspeed => 0 And bl.x# <= b.x# And b.x# - bl.x# <= abstand
            If bl.y# => b.y# And b.yspeed# => 0 And bl.y# - b.y# <= abstand bl.check=1   
           If b.y# => bl.y# And b.yspeed# <= 0 And b.y# - bl.y# <= abstand bl.check=1
              If bl.y# <= b.y# And b.yspeed# => 0 And b.y# - bl.y# <= abstand bl.check=1   
           If b.y# <= bl.y# And b.yspeed# <= 0 And bl.y# - b.y# <= abstand bl.check=1
        EndIf
      If b.xspeed <= 0 And b.x# => bl.x# And b.x# - bl.x# <= abstand
            If bl.y# => b.y# And b.yspeed# => 0 And bl.y# - b.y# <= abstand bl.check=1   
           If b.y# => bl.y# And b.yspeed# <= 0 And b.y# - bl.y# <= abstand bl.check=1
              If bl.y# <= b.y# And b.yspeed# => 0 And b.y# - bl.y# <= abstand bl.check=1   
           If b.y# <= bl.y# And b.yspeed# <= 0 And bl.y# - b.y# <= abstand bl.check=1
        EndIf
      If b.xspeed <= 0 And bl.x# => b.x# And bl.x# - b.x# <= abstand
            If bl.y# => b.y# And b.yspeed# => 0 And bl.y# - b.y# <= abstand bl.check=1   
           If b.y# => bl.y# And b.yspeed# <= 0 And b.y# - bl.y# <= abstand bl.check=1
              If bl.y# <= b.y# And b.yspeed# => 0 And b.y# - bl.y# <= abstand bl.check=1   
           If b.y# <= bl.y# And b.yspeed# <= 0 And bl.y# - b.y# <= abstand bl.check=1
        EndIf




Lässt sich dieser If-Dschungel irgendwie lichten? Ich sehe schon vor lauter Bäumen den Wald nicht mehr. Wenn also jemand eine Idee hat: Immer her damit Smile Es läuft zwar auch so schon recht flott, aber da immer noch jeder Block durch den If-Wald gehen muss, raubt mir das Prozedere eine Menge FPS.

Cheers - Fluppe.
 

Dreamora

BeitragDo, Jul 31, 2008 0:40
Antworten mit Zitat
Benutzer-Profile anzeigen
da BM early drop hat ist das effizient genug. wenn die erste and bedingung false ist wird der rest garnimmer erst geprüft.

Einfacher geht das ganze nur wenn du das chaos das du da hast gescheit reformuliert in etwas funktional getrenntes.
Meine Empfehlung:
1. eine Formel die SquaredDistance berechnet ( das ist xAbstand^2 + yAbstand^2) und das vergleichen mit >= distance^2

2. das ganze in ne funktion packen. Warum? Weil du dann statt check=1 einfach return 1 machen kannst. damit wird der rest nimmer angesprungen wenn klar ist das check = 1

3. Dann überlegen wo sich die checks überlagern, welchen der checks man sinnvollerweise ganz am anfang macht. zB kann das ganze in 2 seperate IFs gelegt werden wenn du b.yspeed >= 0 und b.yspeed < 0 (<= macht keinen sinn denn dann ist der fall = 0 nicht eindeutig!) hast. Damit kannst du gleich mal extrem was rausstreichen. das geht mit dem rest und gescheiter funktionalen kapselug (a la 1 & 2) dann erheblich einfacher

am sinnvollsten schreibst du dir in text aus was es machen soll. das hilft häufig dabei sinnvolle intuitive ansätze direkt zu sehen und vor allem auch fehler in der implementation zu finden.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

Fluppe

BeitragDo, Jul 31, 2008 1:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die schnelle Antwort!

Werde ich morgen so umsetzen. Auf die Quadrierung bin ich gar nicht gekommen, sehr gute Idee.

Wenn noch eine andere Frage erlaubt ist: Ich verwende UPX als exe-Packer. Aber ich kann mich dunkel erinnern, ein Tool entdeckt zu haben, das nicht verwendete Libs gar nicht erst in die Exe integriert. Dadurch konnte man die Dateigröße noch einmal erheblich reduzieren. Leider finde ich das Tool nicht mehr. Hast Du da eine Idee?

Eine gute Nacht!
 

Dreamora

BeitragDo, Jul 31, 2008 1:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Tool brauchst du nur wenn du nicht selbst gedanken drüber machen willst, was du drin hast an Modulen.

Nennt sich Framework Assistant
Empfehle jedoch dringend die dev version damit noch nicht zu beharken weil du sonst immer wieder in wände rennst von wegen "Befehl XY nicht gefunden".
Wart mit Frameworks bis du fertig bist.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group