Einfache Gameoptimierung, kollisionsabfragen, Steps... je eigenen Objekt?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Einfache Gameoptimierung, kollisionsabfragen, Steps... je eigenen Objekt?

    Hallo,

    was ist eigendlich besser,
    wenn ich z.B. 5 Objekte habe, die jedes eine eigene Kollisionsabfage mit dem Player haben, den code in das jeweileige Objekt Stecken,
    oder alle abfragen in das Player Objekt?

    Genauso Code die in Stepevents stehen, lieber von den anderen Objekten auf die Variablen vom Player zugreifen oder im Stepevent vom Player
    auf alle anderen Object/Instance Variablen zugreifen?


    Was ist hier für den Gamespeed besser?

    Oder ist es völlig egal?

    Danke.
  • aus nem tollen Artikel zur Game maker SPiele Optimierung

    3. Do Fewer Collision ChecksObjects that have collision events are much slower than objects that don't. So place those events in the objects which will have the fewest instances. A good example is the player versus the 100 bullets. You obviously have to do a collision check between the two objects... make sure that event goes in the player object instead of the bullet.Collision functions (and trig calculations) in general are pretty heavy, so it's a good idea to have as few of them as possible. Make sure you're not doing the same collision check more than once in a single step. If you need to look up the return value of any slow function more than once, consider putting the value of the collision in a variable and check the variable instead.Whenever possible, turn off "Precise collision checking," which is a per-pixel collision detection method.

    zur Step Sache das sollte immer intern im Objekt ablaufen
  • Ah OK, wenn ich das richtig mit meinem Schulenglisch, was schon weit über 30 jahre her ist :) , übersetzt habe, ist es besser die Kollisionsabfragen die den Player betreffen in den Player zu schreiben.
    Eigendlich verständlich, schreibe ich sie in die anderen Objekten/Instancen wird sie ja pro Instance jedes mal aufgerufen/abgefragt.
    Da muss ich mich nicht wundern das ich hier mit ein paar bildchen nur auf 45 anstatt 60 fps komme.

    Ok, das hilft mir schonmal weiter, dann werde ich das ganze mal umschreiben.

    Darf ich da noch ne kleine zwischenfrage reinwerfen?

    Die Maps haben bei mir immer 2000*2000 pixel,
    der View wird auf die Screen grösse angepasst, so das wenn dieser kleiner ist das ganze scrollen kann. Das funktioniert auch,
    aber wie schaut es mit dem Cliping aus?
    Ich gehe jetzt davon aus das GM:S alles was nicht sichtbar ist auch nicht zeichnet, richtig?
    Aber die berechnungen finden ausserhalb vom Screen trotzdem statt,
    wenn ja, kann ich das auch unterbinden, gibt es da auch eine "Automatik" oder muss ich hier jede Instanceposition abfragen und wenn diese ausserhalb liegt aus den berechnungen ausschliesen?
    Ok, waren zwei Fragen :)
  • Fabbio schrieb:

    Ich gehe jetzt davon aus das GM:S alles was nicht sichtbar ist auch nicht zeichnet, richtig?

    Da wär ich nicht so sicher. Über die internen Mechanismen kann man da mangels Dokumentation oder Quellcode wenig sagen, aber erstell mal die Instanz eines Objekts mit einem show message oder play sound oder sowas im Draw Event und platzier diese Instanz außerhalb des Views. Wenn ich mich nicht irre, solltest du den entsprechenden Effekt auch im Spiel bekommen - also den Beweis, dass Draw-Events immer ausgeführt werden, so lang das Objekt die Variable "visible" auf true hat.
    Andererseits kanns auch sein, dass die GM-Engine clever genug ist, alle die draw_* Funktionen zu ignorieren, deren Zielbereich komplett außerhalb des Views liegt - aber wie gesagt, kann man nicht nachprüfen, ist auch nicht dokumentiert. Also im Zweifelsfall bist du besser beraten, wenn du einfach pauschal überprüfst, ob deine Instanz außerhalb des views liegt. Und wenn ja, führst du einfach das Draw-Event nicht aus.

    Ahja, und zu der Sache mit den Kollisonen: Ich hab selbst schon sowas programmiert, deswegen mach ich mal einen Educated Guess darüber, wie der GM intern seine Kollisionsabfragen macht.
    An und für sich ist es ja egal, ob ich frage "Kollidiert der Spieler mit einer Kugel?" oder "Kollidiert eine Kugel mit dem Spieler?". Wenn deine Engine clever genug ist, löst sie alle Kollisionen auf einmal auf - wenn sie noch cleverer ist, macht sie das auch nicht in jedem Frame, sondern nur, wenn ein Objekt mit Interesse an Kollisionen seine Position geändert hat.
    Wenn die Engine NICHT clever ist, macht sie für jedes Mal, wenn eine Instanz fragt "Kollidier ich mit einer Instanz von Objekt XYZ?" eine komplette Iteration über alle Spielobjekte, filtert die des Typs XYZ raus (am besten noch über Pointer-Casting, weil der Container nur ganz generell den Typ "Spielobjekt" kennt) und macht dann jeweils einen Kollisionscheck. Und dann ist es natürlich schneller, nur einmal über diesen ganzen Container voller Spielobjekte zu reiten, daraus 200 einzelne Kugeln zu pfriemeln und dann Kollisionen zu überprüfen, anstatt 200 Mal über den ganzen Container zu gehen, einen einzelnen Player rauszupfriemeln, und dann mit dem zu checken.
    Und ich behaupte jetzt einfach mal ganz frech, der GM ist nicht clever. :P
  • Hmmpf,
    da wartet noch viel einarbeit auf mich.
    Naja, da wird schon noch.

    In letzten Jahren habe ich mich mit GLBasic beschäftigt, hier habe ich eigendlich alles auf einer Tileengien aufgebaut.
    Da war es nicht so schwer "nur" was im Screen ist zu beachten, einfach Dynamisch die FOR NEXT schleife angepast.
    Genauso war es mit den Kollisionen, da die Objekte in einem Array gekenzeichtet sind, war es recht leicht die Kollisionsabfrage
    nur dann zu starten wenn etwas in der nähe war.

    Nur leider habe ich nicht immer Zeit dafür, und die Projektverwaltung von GM erlaubt es mir mich auch nach längeren Zeit recht schnell wieder zurecht zu finden.

    Hier in GM:S scheint es etwas anders zu laufen, die Standart Maps sind keine Arrays, sondern die objektpositionen werden gespeichert.
    Aber egal, ich werde mich schon durchwurschteln :)
    und die Comunity hier ist ja auch recht hilfsbereit :)
  • wird schon werden, wobei ich sagen muss das die GMS Engine an sich recht großzügig bei Fehlern ist wenns um kleine simple Projekte geht bzw man nicht auf HTML5 und Android möchte

    ich hatte selber oft das gefühl das meine Objekte irgendwie nicht tot sind weil mein HTML5 Projekt laggte obwohl alles schön zerstört wird, Instanzen beschränkt werden usw, im Endeffekt wars aber meine Dummheit bzw Leichtsinnigkeit einfach alles irgendwie unüberlegt zu bauen

    ich er wische mich oft im Step Event Dinge zu machen die natürlich mehrfach die Sekunde laufen werden, wobei man aber nicht daran denkt deswegen versuche ich alles zu killen wenn es fertig ist, setze Variablen im Step als Bedingung auf das ja alles zerstört wird wenn es seinen zweck erfüllt hat, keine Objekte mit ins nächste LV rüber nehmen , und Bedingungen nutzen wie path end oder out of view oder Screen

    wie gesagt WIndows verzieht da das ein oder andere bei HMTL% merkt man es am massivsten wenn man was nicht gut umgesetzt hat
  • fuexline schrieb:

    das weis ich sicher das Objekte außerhalb im DRAW und STEP weiter interagieren


    Das ist ein kleines Missverständnis, die Interaktion (solange die Instanz nich deaktiviert wurde) läuft freilich weiterhin. Irrenhaus ging es um das Drawevent, genauer die draw_* Funktionen. Es ist (mir) gänzlich unbekannt, ob draw_* und ähnliche Funktionen weiterhin ausgeführt werden.

    Aufjedenfall eine Möglichkeit das Zeichnen von Dingen zu beschleunigen ist, auf Surfaces zurückzugreifen. Surfaces scheinen direkt im VRAM gestored zu werden, d.h. sollten die Zugriffszeiten geringer sein. Mich würde interessieren, ob es sich lohnt ds_grids und ds_maps (z.B. anhand von Pixeln) in Surfaces zu speichern anstatt wie gehabt diese im RAM sitzen zu lassen.

    EDIT:
    "Kollidier ich mit einer Instanz von Objekt XYZ?" eine komplette Iteration über alle Spielobjekte, filtert die des Typs XYZ raus (am besten noch über Pointer-Casting, weil der Container nur ganz generell den Typ "Spielobjekt" kennt)

    Ich hatte bisher immer angenommen, dass Parents die Containerfunktion übernehmen und man dem GM da entgegenkommt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von domis4 ()

  • wieso nicht mal ausprobieren :thumbup:

    allerdings haben die geräte heute ausreichend ram ein alter Pc mit 512mb ram wird auch keine 512MB graka drin haben um das Problem auszulagern, ob das ganze an sich schneller ist müsste man mal antesten, wäre sicher interessant
  • Wenn man außerhalb des Sichtberreiches drawt, zeichnet er tatsächlich nichts. Das habe ich herausgefunden, wo diese Eigenschaft mir zum Verhängniss wurde. Ich wollte per Transformationen, die Spriteposition verändern. Und wenn man ursprünglich außerhalb des Views drawt und sich dann das Sprite per transformation wieder im View, so zeigte er es plötzlich nicht mehr an. Es ploppt dann einfach weg, wenn man den View bewegt. Ich persönlich mag diese Eigenschaft deswegen nicht.

  • Habe es selber gerade nochmal überprüft und es zeichnet tatsächlich weiter. Dann nehme ich meine Aussage zurück. Mich würde aber trotzdem interessieren, warum es damals nicht funktionierte. Das war halt damals die einzige logische Schlussfolgerung, weil nach dem Bewegen des Views, das Sprite plötzlich verschwand. Ich werde es wohl nie Erfahren...