Flash: Maske mit Verlauf

Lange Zeit war es in Flash so, dass eine Maske nur harte Kanten aufweisen konnte. Entweder maskiert oder nicht. Aus gestalterischer Sicht ein klares Manko. Lösen ließ sich dieses Problem beschränkt mit Hilfe von PNGs mit Verläufen auf Transparent. Dies funktioniert jedoch nicht immer und bringt je nach Größe des PNGs auch eine größere Ladezeiten mit sich.

Seit Flash 8 gibt es, wie in einem früheren Blogeintrag beschrieben, die cacheAsBitmap-Funktion. Damit lassen sich alle Vektordaten eine MovieClips, der noch keine zwischengespeicherte Bitmap besitzt, in eine Bitmap zeichnen. Diese wird dann anschließend auf die Hauptbühne gezeichnet. Führt man nun dieses cacheAsBitmap = true; auf die Maske, sowie auf den zu maskierenden MovieClip aus, erhält man zwei MovieClips mit Bitmap-Daten. Maskiert man nun den MovieClip, werden alle Verläufe auf Transparent als Maske mit unterschiedlicher Intensität umgesetzt. Damit lassen sich nun innerhalb von Flash Masken mit Verläufen erstellen, was die oben beschrieben Probleme mit der gestalterischen Freiheit, sowie der Dateigröße löst.

Jedoch ist diese Funktion mit Vorsicht zu genießen. In bestimmten Fällen kann es zu unschönen Fragmenten oder Flimmereffekten an den halb-transparenten Bereichen kommen. So zum Beispiel wenn der maskierte MovieClip animiert oder mit neuen Objekten gefüllt wird, also dieser MovieClip Änderungen erfährt. Hier hat Flash Probleme mit der cacheAsBitmap-Funktionalität. Die erforderlichen Umrechnungen und Maskierungen werden nicht richtig ausgeführt.

Flash: ColorTransform of Pictures

Bilder in Flash nachzubearbeiten ist in gewissen Grenzen möglich. Eine Anwendung dessen wird zum Beispiel bei Konfiguratoren verwendet. Will man etwa einem 3D-Modell eines Autos eine andere Farbe geben, ist es nicht nötig das Bild mit anderer Farbe neu zu laden, sondern man kommt mit den Flash-Internen Funktionen aus.

Das Färben von Flächen ist mittels 3D-Bildern relativ einfach. Dazu werden die 3D-Bilder als MultiPass herausgerendert und in Photoshop für Flash aufbereitet. In Flash CS3 können diese Bilder dann importiert werden und behalten dabei ihre Ebenensets und Mischmodi. Eine Ebene dieses Bildes ist dann die Farbebene des 3D-Objektes. Diese wird in Flash dann als Bitmap umgerechnet, da der hier verwendete ColorTransform nur für Bitmaps verwendbar ist. Das Bitmap wird dann im einem Movieclip gekapselt, um es per Script ansprechen zu können.

Für die eigentliche Farbgebung sind die beiden Klassen ColorTransform und Transform in Flash zu importieren. Zunächst wird dann ein neues Objekt von Typ ColorTransform erzeugt und mit der rgb-Zielfarbe gefüllt. Ein weiteres Objekt ist das Transform Objekt. Diesem wird der Ziel-MovieClip mitgegeben, welcher das Bitmap zum Färben enthält. Durch die schlichte Zeile "transformObject.colorTransform = colorTransformObject;“ wird dann das eigentliche Färben ausgelöst. Damit bekommt das 3D-Objekt eine neue Füllfarbe, behält aber durch das Beibehalten der entsprechenden Ebenen aus dem MultiPass-Rendering seine Form und sein ursprüngliches Aussehen. Vorteile dieses Verfahren liegen vor allem bei der geringeren Dateimenge, bzw dem geringerem Traffic, so wie der Möglichkeit für den User seine Änderungen in Echtzeit zu sehen.

Flash & AS2: Punktgenauer hitTest

Beim normalen hitTest kann es passieren, dass die Funktion true zurückliefert obwohl visuell eigentlich noch hit stattgefunden hat. Dies liegt daran, dass Flash nicht mittles der grafischen Objekte prüft, sondern eine BoundingBox verwendet. Diese Vereinfachung erfolgt aus Performance-Gründen. In den meisten Fällen ist der hitTest mit einer BoundingBox vollkommen ausreichend.

Jedoch gibt es spezielle Fälle, bei denen ein punktgenauer hitTest nötig ist. Zur Veranschaulichung ist an diesen Beitrag ein Beispielfile angehängt. Für diesen speziellen hitTest werden die zu testenden Objekte zunächst in ein BitmapData-Objekt umgewandelt. Dazu wird ein BitmapData-Objekt erstellt mit den Abmaßungen des Zielbildes und mittles .draw(mc) mit dem MovieClip gefüllt. Die eigentliche hitTest-Abfrage erfolgt mit der klassischen hitTest-Funktionalität. Jedoch erfolgt die Parameterübergabe etwas verändert:

actBmp.hitTest (new flash.geom.Point (this._x, this._y), 0xFF, hitBmp, new flash.geom.Point (mc._x, mc._y))

Mittles dieser Notation kann nun punktgenau ein hitTest durchgeführt werden, was besonders bei Spielen oder ähnlichen Anwendungen mit dieser speziellen Anforderung hilfreich sein kann.

This movie requires Flash Player 9

ASDoc mit Ant in FlexBuilder / Eclipse

Das Flex SDK stellt das Kommandozeilentool ASDoc zum automatischen Erstellen von Dokumentationen bereit. Mit ASDoc können einfach HTML-Dokumentationen zu einem bestehenden Flex Projekt erstellt werden, vorausgesetzt die ActionScript und MXML Files wurden nach den Standards kommentiert.

Um asdoc aufzurufen muss mit der Kommandozeile in den Flex SDK Ordner navigiert werden, und hier in den Ordner bin. Dann kann über die Zeile aufgerufen werden:

asdoc -source-path . -doc-classes comps.GraphingWdt comps.GraphingWtgTwo

Mehr Beispiele siehe Adobe Livedocs

Über ein kleines Ant Script das im FlexBuilder bzw. in Eclipse ausgeführt wird, kann dieser Prozess vereinfacht werden. Bei diesem Skript müssen lediglich die Variablen im oberen Bereich angepasst werden und ein Symlink zum flex sdk erstellt werden. Der Symlink ist nötig, da ASDoc nicht mit eventuellen Leerzeichen umgehen kann.

<?xml version="1.0"?>
<project name="ASDoc" default="asdocs">

	<!--
	Note that /flex_sdk/ is a symlink I setup to point to the actual
	Flex sdk install since there are issues with spaces in the
	command line arguments.
	-->

	<property name="PROJECT_DIR" value="path to project"/>
	<property name="FLEX" value="/flex_sdk"/>
	<property name="TEMPLATES" value="${FLEX}/asdoc/templates"/>
	<property name="DOC_SOURCE" value="${PROJECT_DIR}/src/de"/>
	<property name="LIB" value="${PROJECT_DIR}/libs"/>
	<property name="OUTPUT" value="${PROJECT_DIR}/docs"/>

	<!-- Creates the ASDoc and saves it in the specified
	Folder in the Project -->
	<target name="asdocs">

		<!-- Clean out the contents of the doc directory,
		without deleting "docs" -->
		<delete includeemptydirs="true">
			<fileset dir="${OUTPUT}" includes="**/*" />
		</delete>

		<exec executable='${FLEX}/bin/asdoc'>
			<arg line='-library-path ${FLEX}/frameworks/libs'/>
			<arg line='-library-path ${LIB}'/>
			<arg line='-doc-sources ${DOC_SOURCE}'/>
			<arg line='-output ${OUTPUT}'/>
			<arg line='-templates-path ${TEMPLATES}'/>
			<arg line='-source-path ${PROJECT_DIR}/src/'/>
		<arg line='-footer squareFACTOR'/>
		</exec>
	</target>
</project>

Nun müssen noch die folgenden Schritte ausgeführt werden:

  1. Neues Projekt erstellen (So kann das Skript für mehrere Projekte verwendet werden)
  2. build.xml einfügen (siehe Code oben) und Variablen anpassen
  3. build.xml als Ant Build ausführen

Um ein Ant Script ausführen zu können muss im Flex Builder ein zusätzliches Apache Ant Support Plugin installiert werden, in Eclipse ist dieses schon standardmäßig vorhanden. Eine Anleitung zur Installation von Apache Ant gibt Peter Elst in seinem Blog.

Bildskalierung per ActionScript (AS2)

Sobald ein Bild per Skript skaliert wird hat Flash ein großes Problem dieses Bild sauber darzustellen. Es entstehen Fragmente und unsaubere Bildstörungen. Ein Variante wäre das Bild in zwei Zuständen (groß, klein) zu laden und am Ende des Tweenvorganges per ActionScript auszutauschen. Jedoch ergeben sich hieraus die Probleme, dass zum einen zwei Bilder geladen werden müssen und zum anderen das Bild während des Tweens unansehnlich wird. Diese beiden Probleme lassen sich mit einer Scriptvariante lösen.

Dazu wird das Bild zunächst einmal geladen und in einem MovieClip zwischengelagert. Dieses Bild wird als Parameter an eine Funktion übergeben, die zunächst in leeres Rechteck, in der Größe des Bildes, erzeugt. Des weiteren wird das Bild als BitmapData umgerechnet. Diese Daten lässen sich über die draw-Methode in das erzeugte Rechteck legen. Somit dient das BitmapData als Füllung für das Rechteck und verhält sich somit wie zum Beispiel ein gezeichnetes Bild mit einem Verlauf. Der MovieClip mit geladenen Bild kann nun gelöscht werden, da diese Daten nicht mehr nötigt werden. Das entstandene BitmapData-Bild lässt sich nun sauber per Script skalieren und die oben beschiebenen Fragmente sind nicht mehr vorhanden.

Flash CS3 Skin Template

Wie in meinem letzten Artikel erwähnt, waren Jürgen und Ich bei der Adobe onAIR tour in München. Dort habe ich Lee (einem der Referenten von Adobe) das Problem mit dem Illustrator CS3 Skin Template geschildert. Es scheint nichts neues zu sein dass die Templates nicht richtig funktionieren.

Auf sein Anraten hin habe ich nun das Flex Extension Kit für Flash CS3 installiert und das mitgelieferte Template genutzt. Leider muss ich sagen das es keinen tick besser funktioniert als das Illustrator Template. Im Gegenteil, hier kommt noch hinzu das der PopUpButton nicht richtig dargestellt wird. Ein weiterer Versuch war, einzelne Komponenten anstatt des gesamten Templates zu verwenden. Aber auch hier ein Bild des jammers, das Panel versagt leider komplett und dadurch verhagelt es die gesamte Testanwendung.

Ich werde also weiterhin mit dem Illustrator Template arbeiten und auf schöne Tweens und Effekte leider verzichten müssen. Der Bug-Report an Adobe wird von mir die nächsten Tage noch rausgehen mit der Hoffnung das bald Besserung eintritt.

AIR Applikationen Updaten

Das Szenario ist bekannt, eine Anwendung wurde fertiggestellt, natürlich wurde alles ausreichend getestet und doch stellt sich nach einem erfolgreichen Launch heraus, es gibt doch noch den ein oder anderen Bug. Oder ein bestimmtes Feature wird noch nachgeschoben. Das ist bei einer Webapplikation kein Problem, die entsprechenden Files werden geändert und auf dem Server erneuert. Doch eine AIR Applikation ist auf den Systemen der Benutzer installiert und kann nicht von einem zentralen Ort upgedatet werden. Außer man hat beim Entwickeln daran gedacht eine Updatefunktion einzubauen. Genau für diesen Zweck gibt es in Adobe AIR eine spezielle Updater Klasse. Mithilfe dieser Klasse können AIR Anwendungen einfach und unkompliziert upgedatet werden.

Update Klasse
Die Updater Klasse enthält folgende Funktion update
public function update(airFile:File, version:String):void

Wird diese Funktion aufgerufen, wird die laufende Applikation beendet (wie wenn NativeApplication.exit() aufgerufen würde), die Applikation auf die die Variable airFile verweist wird installiert und gestartet. Aus Sicherheitsgründen muss die Variable version die korrekte Version der zu installierenden Anwendung enthalten.
Diese Versionsnummer kann aber nicht fest in die Applikation codiert werden, ansonsten wäre immer nur ein Update von einer bestimmten zu einer bestimmten Version möglich. Eine Möglichkeit ist nun eine XML-Datei auf einen Update-Server zu legen in der die Versionsnummer der aktuellen Version und der Pfad zum .air File gespeichert wird. Diese wird dann heruntergeladen, geparst und die Version wird mit der aktuell installierten Version verglichen. Ist die Version auf in der XML-Datei neuer als die aktuell installierte Software wird der Benutzer benachrichtigt und das Update kann durchgeführt werden.

AIRRemoteUpdater
Mit dem AIRRemotUpdater von „cotedazur brazil“ wird das Updaten erheblich vereinfacht. Das erstellen, updaten und parsen der XML-Datei fällt hier komplett weg, denn Der AIRRemoteUpdater vergleicht die momentan installierte Version der Anwendung mit der neusten verfügbaren Version auf einem Webserver (ohne das .air File herunterzuladen). Handelt es ich um eine andere Version kann die neue Version heruntergeladen und über die Updater.update Funktion (siehe oben) installiert werden.

Dieser ganze Prozess kann nun automatisiert werden, so dass zum Beispiel bei jedem Start der Anwendung abgefragt wird ob eine neue Version verfügbar ist. Somit bleiben die Benutzer der Anwendung immer auf dem neusten Stand. Wichtig ist jedoch die Update Funktionalität von Anfang an einzubauen, ansonsten können die Benutzer der ersten Stunde nicht über Updates informiert werden.