Framerate stürzt ein (Endless Runner)

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

  • Framerate stürzt ein (Endless Runner)

    Hallo Zusammen
    Aktuell arbeite ich an meinem ersten kleinen Spiel im Game Maker. Faireshalber muss ich erwähnen, das der meiste Code aus diversen Examples und Tutorials "zusammengeschnitten" ist, da ich noch nicht wirklich Ahnung von GML habe. Learning by doing...hoffe ich zumindest :)

    Nun zu meinem Problem:
    Mein Spiel soll ein sogenannter "Endless Runner" werden. Ich habe also einen Room, in dem der Spieler nur springen kann (y-achse), aber sich entlang der x-achse nicht bewegt. was sich bewegt, sind in zufälliger Reihenfolge enstehende Blöcke(32x32), die bei room_width+64 enstehen, sich mit movex=-4 nach links bewegen und bei x<-32 zerstört werden. Das ganze funktionierte bei einem Room Speed von 60 ganz gut. Ganz seltene leichte FPS Einstürze, was ich aber darauf zurückführe, das ich auf einem Netbook programmiere :)

    Als nächstes wollte ich ein Script einbauen, welches prüft, wo, welcher Block mit anderen Blöcken kontakt hat, und dementsprechend den Sprite des Objektes auf die Frame setzen, die einen grafischen übergang zwischen den Blöcken erzeugt. Dadurch würde es dann stimmiger aussehen. Ich weiß nicht, wie ich das besser erklären kann, Aber wenn ihr das Script seht, weiß der eine oder andere bestimmt, was genau es macht.

    Das funktioniert alles soweit ganz gut
    ABER
    seit ich dieses Script benutze, fällt die Framerate wärend des spielens nach einer gewissen Zeit kontinuierlich.
    60...55...52.....48.....44.....34...usw.
    Ich könnte ja verstehen, das mein Netbook für das script nicht stark genug ist. Aber das müsste doch die Framerate sofort im Keller sein oder nicht? und nicht erst nach ner gewissen Zeit.

    Hoffentlich kann mir bei diesem Problem jemand helfen :)


    Hier mal das Script:

    GML-Quellcode

    1. dist=argument0
    2. left=place_meeting(x-dist,y,object_index)
    3. right=place_meeting(x+dist,y,object_index)
    4. up=place_meeting(x,y-dist,object_index)
    5. down=place_meeting(x,y+dist,object_index)
    6. image_single=image_number;
    7. if left{image_single=15}
    8. if right{image_single=13}
    9. if up{image_single=12}
    10. if down{image_single=14}
    11. if up and down{image_single=2}
    12. if left and right{image_single=3}
    13. if left and up {image_single=4}
    14. if left and down {image_single=7}
    15. if left and up and down{image_single=8}
    16. if right and up{image_single=5}
    17. if right and down{image_single=6}
    18. if right and up and down{image_single=10}
    19. if right and left and up{image_single=9}
    20. if right and left and down{image_single=11}
    21. if left and right and up and down {image_single=1}
    22. if !left and !right and !up and !down {image_single=0}
    Alles anzeigen


    Das Object obj_wall:
    Create:

    GML-Quellcode

    1. movex=-2;
    2. if instance_place(x,y,obj_wall)
    3. {
    4. instance_destroy();
    5. }
    6. scr_autotile(1);


    Step:

    GML-Quellcode

    1. with instance_place(x+movex,y,obj_player) x+=other.movex
    2. x+=movex


    Outside Room:

    GML-Quellcode

    1. if x<-32 instance_destroy()

    Das Controller Object, welches die Blöcke spawned:
    Create:

    GML-Quellcode

    1. movex=-4
    2. spawnx=room_width+64
    3. spawny=room_height-32
    4. spawnTime=32/2
    5. alarm[0]=1
    6. distance=0
    7. score=distance;
    Alles anzeigen

    Alarm0:

    GML-Quellcode

    1. var i;
    2. i=spawny
    3. repeat choose(1,1,2)
    4. {
    5. instance_create(spawnx,i,obj_wall)
    6. i-=32
    7. with (obj_wall) {
    8. scr_autotile(1);
    9. }
    10. }
    11. alarm[0]=spawnTime*choose(1,1,1,1,1,1,1,1,1,1,1,1,1,2)
    Alles anzeigen


    Wie gesagt, habe ich noch nicht so viel Ahnung von GML, habe aber versucht, das Problem selber zu lösen, da ich den Code weitesgehend verstehe. Aber da obj_wall ja nach dem durchlaufen des Rooms bei x-32 zerstört wird, kann es doch nicht zu einer überlastung der Objekte kommen oder?
    Ich verstehe es nicht...

    Ich hoffe jemand kann mir bei diesem Problem helfen und bitte daher um eure Hilfe :)
    Danke im vorraus



    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von GeneticZ ()

  • was genau macht image_single?
    laut diesem thread
    gmc.yoyogames.com/index.php?showtopic=360368
    sollte es nicht mehr benutzt werden. Ich finde es auch nicht im Manual - liegts vielleicht daran?

    Weiters kannst du
    if x<-32 instance_destroy() in das step event setzen, muss nicht unbedingt im outside_room event sein
  • Gregor schrieb:

    was genau macht image_single?
    laut diesem thread
    gmc.yoyogames.com/index.php?showtopic=360368
    sollte es nicht mehr benutzt werden. Ich finde es auch nicht im Manual - liegts vielleicht daran?

    Weiters kannst du
    if x<-32 instance_destroy() in das step event setzen, muss nicht unbedingt im outside_room event sein


    image_single soll den frame des Sprites von obj_wall zu einem passenden ändern. Sprite_index hätte den selben effekt oder?

    Und danke für den Hinweis mit instance_destroy() :)

  • Für mich hört sich das so an,... als ob deine objekte eben nicht zerstört werden, sondern sich immernoch für den PC im Spiel befinden,... das würde zumindest die Framerateinbrüche erklären,... du erstellst immer neue Blöcke die die Rechenleistung natürlich erhöhen,... werden diese nicht zerstört, steigt diese Kontinuierlich....

    Warum du den Roomspeed außerdem unbedingt auf 60 Frames/per second laufen lassen willst, verstehe ich nicht,... 30 Frames reichen im normalfall locker für eine flüssige Wiedergabe aus,... bei 60 Frames erhöht sich nur die Rechenleistung, was gerade bei kleinen PC wie deinem zu problemen führt....

    An deinem Code konnte ich jetzt auf die schnelle leider keinen Fehler erkennen, der das ganze erklärt hätte


    Weiters kannst du
    if x<-32 instance_destroy() in das step event setzen, muss nicht unbedingt im outside_room event sein

    Im Outside Room macht es aber deutlich mehr sinn
    da dieses Event nur aufgerufen wird, wenn der Block den raum wirklich verlassen hat,... step event wird immer abgefragt, was die rechenleistung weiter beeinträchtigt
  • Blayde schrieb:

    Für mich hört sich das so an,... als ob deine objekte eben nicht zerstört werden, sondern sich immernoch für den PC im Spiel befinden,... das würde zumindest die Framerateinbrüche erklären,... du erstellst immer neue Blöcke die die Rechenleistung natürlich erhöhen,... werden diese nicht zerstört, steigt diese Kontinuierlich....

    Warum du den Roomspeed außerdem unbedingt auf 60 Frames/per second laufen lassen willst, verstehe ich nicht,... 30 Frames reichen im normalfall locker für eine flüssige Wiedergabe aus,... bei 60 Frames erhöht sich nur die Rechenleistung, was gerade bei kleinen PC wie deinem zu problemen führt....

    An deinem Code konnte ich jetzt auf die schnelle leider keinen Fehler erkennen, der das ganze erklärt hätte


    Jap, ganz genau. Aber instance_destroy() zerstört doch die objekte oder nicht? Der Meinung bin ich ja auch. Als würden die Objekte NICHT zerstört werden, und einfach immer neue enstehen. Das geht natürlich auf die Framerate.

    Zu Speed 60 und 30:
    bei speed 60 habe ich die "x-" geschwindigkeit der Blöcke auf -2, bei 30 dementsprechend auf -4. Aber bei dem 30er Speed sieht die Bewegung eben deutlich "abgehakter" aus. Bevor ich das Script eingebaut habe, lief es auf 60 aber auch tadellos.

  • GeneticZ schrieb:

    image_single soll den frame des Sprites von obj_wall zu einem passenden ändern. Sprite_index hätte den selben effekt oder?


    image_single macht quasi nichts anderes, als image_speed auf 0 zu setzen und image_index auf den entsprechenden Wert.
    sprite_index jedoch ändert nicht den image_index (also quasi das sub-image des sprites) sondern das gesamte sprite.

    Kurz:

    GML-Quellcode

    1. //Das hier...
    2. image_single = 5;
    3. //...ist das selbe wie das:
    4. image_speed = 0;
    5. image_index = 5;


    Und der Code hier:
    Spoiler anzeigen

    GML-Quellcode

    1. dist=argument0
    2. left=place_meeting(x-dist,y,object_index)
    3. right=place_meeting(x+dist,y,object_index)
    4. up=place_meeting(x,y-dist,object_index)
    5. down=place_meeting(x,y+dist,object_index)
    6. image_single=image_number;
    7. if left{image_single=15}
    8. if right{image_single=13}
    9. if up{image_single=12}
    10. if down{image_single=14}
    11. if up and down{image_single=2}
    12. if left and right{image_single=3}
    13. if left and up {image_single=4}
    14. if left and down {image_single=7}
    15. if left and up and down{image_single=8}
    16. if right and up{image_single=5}
    17. if right and down{image_single=6}
    18. if right and up and down{image_single=10}
    19. if right and left and up{image_single=9}
    20. if right and left and down{image_single=11}
    21. if left and right and up and down {image_single=1}
    22. if !left and !right and !up and !down {image_single=0}
    Alles anzeigen



    Ist weder schön noch performant. (Keine anschuldigung, nur eine Anmerkung)
    Hier wäre mein Binärer Lösungsansatz:

    GML-Quellcode

    1. a = 0;
    2. if (place_meeting(x+dist,y,object_index)) {
    3. a+=1;
    4. }
    5. if (place_meeting(x,y-dist,object_index)) {
    6. a+=2;
    7. }
    8. if (place_meeting(x-dist,y,object_index)) {
    9. a+=4;
    10. }
    11. if (place_meeting(x,y+dist,object_index)) {
    12. a+=8;
    13. }
    14. image_index = a;
    Alles anzeigen


    Das würde bereits deinen gesamten ersten Block im Code ersetzen.
    Hierbei ist jedoch zu bedenken, dass Du die Bilder im Sprite entsprechend anpassen musst.
    Beispiel: 0: Kein, 1: Rechts, 2: Oben, 3: Oben&Rechts, 4: Links, usw...

    Ich weiß jetzt nicht wie das Sprite genau aussieht, aber ich benutz das gerne für Mauern oder Straßen die sich automatisch verbinden
    Dieser Beitrag wurde bereits 8.675.628 mal editiert, zuletzt von »levarris07« (Heute, 11:33)

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

  • Jap, sorry mein Fehler. Ich meinte natürlich image_index und nicht Sprite_index. Vielen dank für die Erklärung.

    Ok, zurück zu meinem Problem:

    GML-Quellcode

    1. if x<-32 instance_destroy()

    zerstört doch die Objekte, welche den Room verlassen haben bei x -32, oder nicht?

    Edit:
    Omg, ich glaube fast,

    GML-Quellcode

    1. if x<-32 instance_destroy();

    in einem Step Event auszuführen, anstatt in einem Outside Room Event hat mein Problem gelöst. Bei ersten tests scheint es jetzt tatsächlich flüssig zu laufen.

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

  • Das Outside-Room Event wird nur einmal ausgeführt, in dem Frame, in dem das Sprite den Raum komplett verlassen hat. Ist von deinem Sprite-Origin zum rechten Rand des Sprites weniger als 32 Pixel Platz, dann wird nichts passieren. Ein Check auf x<0 sollte ausreichen, um zu verhindern, dass das Objekt schon beim Spawnen auf der anderen Seite des Screens zerstört wird. Dann muss es auch nicht ins Step-Event.
    Einige meiner Spiele:
  • Hi.
    ich hab jetzt ehrlich gesagt nicht alle Beiträge gelesen. Aber mir ist in deinem code was aufgefallen. Im Alarm schreibst du with (obj_wall)... das führt den code ALLE obj_wall Instanzen aus. Wie ich das sehe ist das unnötig. Du solltest die neu erstellt Instanz von obj_wall in einer Variable speichern und dann dein Script nur für genau diese Instanz ausführen. Also
    inst = instance_create (x, y obj_wall)
    with (inst){
    //dein script
    }

    LG