Surface um Speicher zu entlasten

  • Surface um Speicher zu entlasten

    Also bei meinem projekt "die entgrater" soll blut bei angriff auf gegner auf den Boden fallen und dort liegen bleiben. Ich würde jetzt gerne diese Bluttropfen (die mit image_(x/y)scale verändert sind) auf eine surface zeichnen (also alle 200 Steps oder so) und die dann wiederum auf den bildschirm zeichnen. Anschließend werden natürlich alle alten Bluttropfen-Objekte gelöscht.
    Meine Probleme:
    1.Wie kann ich das mit dem gleichen Scale Wert tun, und nicht mit einem neuem Zufalls Wert, also das sich das Bild nicht verändert, nur eben die Objekte weg sind und Speicher sparen.
    2.Als was sollte ich den surface einsetzen (background wird ja nicht funken, da da schon was drauf ist, genauso bei einem draw element des objektes.Könnt mich aber auch irren.
    3. Wie mach ich das mit dem with also, ich würd im step event für das objekt, dass die surface "bezeichnet" with (Bluttropfen) usw.. schreiben. Nur wie können die auf eine surface eines anderen Objektes zeichnen?

    Also ein paar Fragen, würd mich auf Antworten freuen, da das ohne nicht so ausieht. Hätt halt gern vieeel Blut und nicht nur so ein paar Tröpfchen. Außerdem könnt ich so den ganzen Raum gespeichert lassen und würde und wirklich alles was entstanden ist im level bleibt.

    Achja, hab mit surfaces noch nicht viel gemacht, wenn es geht hätt ich gern den allgemeinen code. Sonst brauch ich nur allgemeine (schriftliche, nicht gecodete) tipps, aber so als surface noob...

    danke im Voraus
    PULSE

    Zweispieler [||||||||||]
    Einspieler [||||||||||]

    [Die Entgrater ist auf Eis gelegt]
  • 1. Geht es denn nicht, wenn du es mit draw_sprite_ext drawst und dann halt für x/yscale eben image_x/yscale nimmst?
    2. Nicht verstanden, was du meinst 8|
    3. Du erstellst eine Surface ja so:

    GML-Quellcode

    1. sur = surface_create(320,240); //Beispiel
    Willst du jetzt darauf von einem anderen Objekt was drauf drawen (nicht im Draw Event, das gibt Probleme :P ):

    GML-Quellcode

    1. surface_set_target(surface_objekt.sur); // Leitet Zeichnen auf die Surface
    2. draw_sprite_ext(sprite_index,-1,x,y,image_xscale,image_yscale,0,-1,1);
    3. surface_reset_target(); // Setzt das Zeichnen wieder zurück zu normal


    Surface sind allgemein ein kleines Problem. Alpha + Surface ist schrecklich, also immer schön mit einem bestimmten Wert arbeiten. Zum Anfang ist in der Surface ne Menge Grafikmüll - den musst du erstmal löschen ^^ und und und...

    Wie wärs denn eigentlich mit Partikeln? Wenn du nicht grade 200 000 Blutflecken hast, die eventuell mit der Zeit ganz langsam (!) verschwinden sollen, wäre das die perfekte Lösung ;)

    Gruß, dein kopierjunge
  • Partikel? Hab ich auch schon überlegt, krieg ich aber mit der korekten Gravitation (=Flugbahn) nich hin. Außerdem entstehen wirklich überall 10-15 Pixel hohe Blutschichten, und zwar überall auf dem Boden, auf Wänden, ....das schaffen ´nicht mal die Partikel, außerdem müssten die das gesamte Level dort bleiben.
    Das mit 2. mein ich so: Ich hab ein Objekt der das mit der surface macht. Nun liegen überall schon Blut Objekte rum. Nun will ich das die alle in ihren Zustand (=also Position und Scale) auf die Surface zeichnen sollen. Das würd ich mit with (zb Blutobjekt) und dann das auf die surface drawn. Kann ich das dann einfach mit der richtigen id machen? Vielleicht funkt das sowieso, hab mir das etwas komplizierter vorgestellt.

    Das mit dem Background oder so, hab ich mir nochmal durch den Kopf gehen lassen. Müsste halt nur den vorherigen Background zusätzlich auf die Surface drawn und dann die Blutobjekte, dann würd das nichts machen.

    Edit: Thank you for the code! Hätt ewig in der Hilfe nach schaun müssen...

    Edit die 2.: ups, das mit von anderen objekt drawn hab ich irgendwie überlesen, dann wär die frage geklärt. Probier das ganze mal aus, dann sehn wir ja ob noch Fragen entstehen...

    und die 3.: Der zeigt bei sur=surface_create[...] einen Synthax Error bei = an, komisch....
    Das hab ich im alarm[0] event für das objekt das die surface erstellt

    GML-Quellcode

    1. globalvar surface,background
    2. var surface, background
    3. surface=surface_create(room_width,room_height)
    4. with (blut_platzhalter)
    5. {
    6. surface_set_target(surface_objekt.surface); // Leitet Zeichnen auf die Surface
    7. draw_sprite_ext(sprite_index,-1,x,y,image_xscale,image_yscale,0,-1,1);
    8. surface_reset_target(); // Setzt das Zeichnen wieder zurück zu normal
    9. }
    10. background=background_create_from_surface(surface,0,0,room_width,room_height,true,false,true)
    11. background_index[0]=background
    12. alarm[0]=200
    Alles anzeigen


    ich hoffe das letzte mal editiert, das erstellen muss in ein create event. Fehler macht man(n) da, die sind schon zum lachen :headtouch:



    ES FUNKT, JUHU (DAs hätt ich jetzt wirklich nicht gedacht. Unendlich Blut ich komme) Großes Danke an Copy Boy!!!! :D :D :thumbsup:


    Falls jemand in einem Spiel unendlich But benutzen will, und das das ganze level erhalten will, dann funkt der code perfekt:

    Das ins create event vom surface controller

    GML-Quellcode

    1. alarm[0]=200
    2. surface = surface_create(room_width,room_height)


    Und das ins Step Event

    GML-Quellcode

    1. if instance_number(blut_platzhalter)>2000
    2. {
    3. with (blut_platzhalter) {if speed=0 {global.unbewegtes_blut+=1}}
    4. if global.unbewegtes_blut>1000
    5. {
    6. with (blut_platzhalter)
    7. {
    8. if speed=0
    9. {
    10. surface_set_target(blut_controller.surface); // Leitet Zeichnen auf die Surface
    11. draw_sprite_ext(sprite_index,-1,x,y,image_xscale,image_yscale,0,-1,1);
    12. surface_reset_target(); // Setzt das Zeichnen wieder zurück zu normal
    13. instance_destroy()
    14. }}
    15. if background!=0{
    16. if (variable_local_exists("background")) {background_delete(background);}}
    17. background=background_create_from_surface(surface,0,0,room_width,room_height,true,false,true)
    18. background_index[0]=background
    19. global.unbewegtes_blut=0
    20. }
    21. else {global.unbewegtes_blut=0}
    22. }
    Alles anzeigen


    Ruckelt eigentlich überhaupt nicht. Man muss nur bedenken, dass nicht zu viele Bluttropfen in der Luft sind, denn wenn sie zu boden fallen (und sich keins mehr bewegt) ist die Sache wieder wie ohne But.

    Kann geclosed werden!!
    PULSE

    Zweispieler [||||||||||]
    Einspieler [||||||||||]

    [Die Entgrater ist auf Eis gelegt]

    Dieser Beitrag wurde bereits 13 mal editiert, zuletzt von Trompadon ()

  • Du würdest mir einen großen Gefallen tun, wenn du die den Speicher für den Background wieder freigibst (sonst wird der immer voller und irgendwann beendet es dein Spiel mit einem Error - das denk ich zumindest ^^ ). Also ins Step Event nach if alarm[0]=0 {:

    GML-Quellcode

    1. if (variable_local_exists("background")) {background_delete(background);}
  • eh, ok. meiner meinung nach dürfte das immer weiter überschrieben werden, also nicht gespeichert. Hab schon lange Tests gemacht, noch nie ein error.
    Fängt nur bei 4000 und mehr Bluttropfen zu ruckeln an, aber sobald alle am Boden sind ist das wieder Geschichte. Machen kann ichs ja trotzdem, schadet ja nichts... 8)

    Edit: oh, ja du hast recht, da wird ja immer ein neuer erstellt und abgespeichert. mach ich gleich mal.

    Edit die 2. Dein Code is nicht ganz richtig, da muss ich noch ne zusätzliche background variable einfügen, da die ja immer erhalten bleibt, also->background _previous. Bin am Werken...

    und die 3. Das funzt nicht ich teste jetzt mal das ganze ne halbe Stunde oder so, mit simuliertem Tastendruck, mal schaun...
    (Hab Vista, eigentlich sollte ja gleich ne Fehlermeldung kommen, so aus erfahrung 0

    nur so ne frage dauert das bei 2gb länger bis der grafik speicher voll ist, noch passiert nichts

    hab den code abgändert und er funzt, bei vista kann der grafik speicher praktisch nicht voll werden (hab ich ja ganz vergessen) der volltrottel=vista lädt das ja in den arbeitspeicher, also wird das bei 2gb ewig dauern, is aber bei spielen wie gothic III nicht grad lustig, da das game solange kartenmaterial in den arbeitspeicher müllt bis der zugemüllt ist und er pc abstürzt!!
    PULSE

    Zweispieler [||||||||||]
    Einspieler [||||||||||]

    [Die Entgrater ist auf Eis gelegt]

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von Trompadon ()

  • Ich weiß, is ein Doppel post, den lösch ich wieder, falls ne antwort kommt.
    Also
    Der obige Code wurde nochmal optimiert, wenn jemand weiß wie man der grafik karte mehrere steps zeit lassen kann um die surface zu drawn und den background zu laden, möge seiner meinung kund tun!
    Ist nicht so schlimm mit dem Ruckeln, es Ruckelt halt kurz wenn mehr als 2000 Bluttropfen am Feld sind, die noch nicht als Hintergrund gespeichert sind. Das stört bei normaler "Blutführung" wahrscheinlich kein bisschen, da ich mit einer Waffe teste die jeden Step einmal schießt und zwar auf mehrere Gegner die nicht sterben können und bei jedem Bullettreffer 20 Bluttropfen verlieren.
    Is halt nur so ne frage zur optimierung.
    Hab außerdem einen neuen Thread aufgemacht zu einer Gelände-Zerstörungs Engine, wenn ihr wollt könnt ihr mal ein paar tips geben... ^^
    PULSE

    Zweispieler [||||||||||]
    Einspieler [||||||||||]

    [Die Entgrater ist auf Eis gelegt]