Flashhilfe.de - Flash Community

Flash Spiele Performance Optimierung mit vielen Objekten / Animationen [Flash 11]

 


AntwortenRegistrieren Seite1  

Sebastian#1
Benutzerbild von SebastianFlashhilfe.de Moderator
Beiträge: 6981
Wohnort: München
Registriert: Jan 2002

31.08.2011, 12:16

Kurzes Vorwort wie es zu diesem Tutorial kam:

Lee Brimelow www.leebrimelow.com hat eine Interessante Diskussion gestartet als er Frage ob jemand seinen Code für ein Flash Spiel reviewen kann das er bei der Flash on the Beach Konferenz vorstellen möchte. Es geht darum unterschiedlichste Game Render-Techniken in Flash vorzustellen darunter vorallem das "Partial Blitting". Eine Technik mit der man für eine Animation nicht ein MovieClip mit mehreren Frames abspielt, sondern statt dessen aus einem großen Bild die verschiedenen Frame-Bereiche kopiert und ausgibt. Diese Technik ist performance schonender als die herkömliche Variante was besonders wichtig bei Spielen ist die viele animierte Objekte auf der Bühne zeigen. Klarer wird die Technik wenn man sich das Bild ansieht:




Neben dem Interessanten Code-Ansatz von Lee gab es dann noch unterschiedliche Kommentare zur Verbesserung des Codes. So richtig viel brachten die Sachen alle nicht, bis "?ukasz Gmaj" ein Beispiel gepostet hat bei dem die Darstellung der Animationen nicht mehr über das Hinzufügen von Bitmaps oder Sprite geschieht, sondern über ein Bitmap in denen alle Animationen enthalten sind.

Der Performance Unterschied ist gar nicht zu vergleichen. Ich konnte nach der Änderung so viele Animationen zur Bühne hinzufügen wie ich wollte ohne das ein Performance Verlust zu sehen war.

Bevor wir uns an den Code machen, schaut Euch die beiden swfs anbei an. "Partial Blitting.swf" ist die Version mit den einzelnen Sprites pro Animation, "Partial Blitting 2.swf" ist die Version mit nur einem Bitmap in denen alle enthalten sind. Nach öffnen mit der Maus auf die Bühne klicken um weitere Animationen hinzufügen.

Partial Blitting.swf (51.54 KB)
Partial Blitting 2.swf (51.53 KB)

In der ersten Variante "Partial Blitting.swf" wird für jede Animation ein Sprite angelegt in dem die einzelnen Frames im bitmapData des Sprites gezeichnet werden. Je mehr Animationen (Schlangen) auf die Bühne gelegt werden, desto mehr Sprites werden hinzugefügt. Pro Schlange also ein Sprite.

Bei der zweiten Variante wird in der Main Klasse ein Bitmap erzeugt mit der Größe der Bühne:
ActionScript:
1
2
private var stageBitmapData:BitmapData = new BitmapData(800, 600);
private var stageBitmap:Bitmap = new Bitmap(stageBitmapData);

das später per:
ActionScript:
1addChild(stageBitmap);

auf die Bühne gesetzt wird.

Die Animationen (Schlangen) selbst werden nun nicht mehr selbst auf die Bühne gesetzt. Statt dessen wird ihnen die Referenz "stageBitmap" als target übergeben.
ActionScript:
1var s:BlitSprite = new BlitSprite(stageBitmap, 130, 90, sheet, R.snake);


Die Referenz auf stageBitmap wird dann nur noch zum Rendern der Schlange benutzt:
ActionScript:
1
2
3
4
5
6
7
public function render():void
{
     stageBitmap.bitmapData.copyPixels(sheetBmd, frames[animIndex], p, null,null, true);
     
     // Determine what frame to show next
   animIndex = (animIndex == framesNum - 1) ? 0 : animIndex+1;
}

In der render() Methode wird also die Animation in das bereits bestehende stageBitmap hinzugezeichnet. Es ensteht damit ein großes Bild mit allen Animationen.

Die Render Methode wird per onEnterFrame bei jeder Animation einzelnt aufgerufen und zeigt jeweils den nächsten Frame an. Ohne das wechseln des Frames würden wir ansonsten nur ein Bild mit ein paar Schlangen sehen die aber nicht animiert wären.

Wichtig ist das stageBitmap vor dem bearbeiten zu sperren lock() und nach Beendung der Änderungen wieder freizugeben unlock(). Dies verhindert das der FlashPlayer bei jeder Änderung des stageBitmaps die Bühne neu zeichnet. Die Bühne wird also erst nach unlock(); neu gezeichnet anstatt bei jeder Änderung des Bitmaps.
ActionScript:
1
2
3
4
5
6
7
8
9
10
11
protected function loop(event:Event):void
{
     stageBitmapData.lock();
     stageBitmapData.fillRect(r, 0xffffff);
     // Loop through snakes and render them
   for(i=0; i<numSnakes; i++)
     {
        snakes[i].render();
     }
     stageBitmapData.unlock();
}



Nachteile:
Wie so vieles hat auch diese Technik ein paar Nachteile. In der ersten Variante haben wir pro Schlange ein einzelnes Sprite das problemlos per z.B. snake.rotation += 2 rotiert werden kann. Bei der zweiten Variante bedarf dies einer erweiterte Methode die uns das rotieren einzelner Animationen über den Mittelpunkt der jeweiligen Animation erlaubt. Dies gilt auch beim skalieren etc. das man früher einfach über den jeweiligen Sprite anpassen konnte.

Ihr könnt Euch das Problem ansehen wenn ihr in der ersten Version "Partial Blitting" die Zeile:
ActionScript:
1//snakes[i].rotation += 2;

in der loop Methode einkommentiert.


Anbei die beiden Projekte "Partial Blitting" und "Partial Blitting 2" als Flash Builder 4.5 Projekt.

Vielen Dank an Lee Brimelow und an "?ukasz Gmaj" für das Teilen der Performance Optimierung.

Viele Grüße,
Sebastian
JavaScript & JavaFX Freelancer || Flashhilfe @ Twitter || XING Profil

Angehängte Dateien:
Komprimierte Datei Partial Blitting.zip81.65 KB
Komprimierte Datei Partial Blitting2.zip98.09 KB
Geändert von Sebastian am 31.08.11 um 12:57 Uhr
Werbung
Beiträge: 0
Registriert: Feb 2016


ashitaka#2
Benutzerbild von ashitaka
Beiträge: 161
Registriert: Apr 2010

04.11.2011, 16:32

Guter Rat,
wundert mich nur ein bisschen dass der Flashgott Lee Brimelow das nicht schon vorher wusste.
Immerhin funktioniert z.b. die kostenlose Game Engine Flixel schon lange auf diesem Prinzip.

Mit dem FP 11 muss man dann allerdings wieder überdenken, ob das die beste Methode ist, weil hier dank 2D/3D-Hardwarebeschleunigung sowieso viel mehr möglich sein wird.
Zeitleisten-Programmierung ist böse! löst euch von der Zeitleiste -> benutzt Flashdevelop!
Antworten auf Flash AS3 Fragen.
Flash Programmierer
tadaaa#3
Benutzerbild von tadaaa
Beiträge: 5
Wohnort: berlin
Registriert: Oct 2012

18.10.2012, 18:54

Ich habe mich da einmal rangewagt, aber bin ziemlich gescheitert...
Alle Menschen werden als Unikat geboren, doch die meisten sterben als Kopie.
Joker80#4
Benutzerbild von Joker80
Beiträge: 7
Registriert: Dec 2012

11.12.2012, 09:44

Ja, für mich ist das leider auch ein bisschen zu krass....
Homer: Können die sich keinen Pfahl für das Schild leisten?
Bart: Das ist ein Anhalter, Dad!
Werbung
Beiträge: 0
Registriert: Feb 2016


skoda#5
Benutzerbild von skoda
Beiträge: 1189
Wohnort: Boston MA
Registriert: Feb 2006

13.12.2012, 21:47

was der performance unterscheid zu object pooling ?
no one died when clinton lied
MilliVanilli#6
Benutzerbild von MilliVanilli
Beiträge: 5
Registriert: Mar 2014

05.03.2014, 13:20

Guter Tip, aber vielleicht etwas unüberschaubar ... vielleicht wage ich mich eines Tages daran.

AntwortenRegistrieren Seite1  

Schnellantwort

Du musst registriert sein, um diese Funktion nutzen zu können.

 
Ähnliche Beiträge zum Thema
Online-Spiel Crossover [Flash 11] 05.06.2019 - Indy_Crossover
Partner Webseiten: art-and-law.de  Mediengestalter.info   php-resource.de   phpforum.de   phpwelt.de   Pixelio.de   Scubacube.de  
Haftungsausschluss   Datenschutzerklärung   Hier Werben   Impressum
© 1999-2019 Sebastian Wichmann - Flashhilfe.de