Das Erstellen einer Schaltfläche aus einer Bitmap kann lästig sein. Wenn Sie die Flash-IDE verwenden, können Sie eine Maske erstellen, um zu bestimmen, welche Pixel Teil der Schaltfläche sind und welche nicht. In jedem anderen Workflow kann das gesamte Rechteck, das die Bitmap enthält, einschließlich aller transparenten Pixel, angeklickt werden . In diesem Lernprogramm erfahren Sie, wie Sie mit wenigen Zeilen Code automatisch alle transparenten Pixel anklickbar machen.
Werfen wir einen Blick auf das Endergebnis, auf das wir hinarbeiten:
Beachten Sie, dass der Handcursor nur angezeigt wird, wenn Sie über das aktuelle Bild fahren. Selbst die Lücken im Haar lassen es nicht erscheinen. Und das nicht nur für die Show: Die Knopfdrucke registrieren sich nur, wenn Sie auf diese Bereiche klicken.
Auf den ersten Blick erscheint die obige SWF-Datei extrem einfach. Aber schau genauer hin! Beachten Sie, dass in der obigen Demo ein Tastendruck nur gezählt wird, wenn Sie auf das eigentliche Bild klicken. Dies würde normalerweise nicht passieren. Da ein Bitmap-Bild immer ein Rechteck ist, würde das Klicken auf eine beliebige Stelle innerhalb des Rechtecks normalerweise als Tastendruck gelten. Schauen Sie sich das Beispiel unten an, wo ich das Begrenzungsrechteck unseres Bildes umrissen habe. Hier können Sie auf eine beliebige Stelle innerhalb des Rechtecks klicken, einschließlich der transparenten Bereiche.
Wie Sie sehen, wollen wir das nicht! Für den Anfang könnte ein Benutzer versehentlich auf die Schaltfläche klicken, wenn er dies nicht beabsichtigt. Es sieht außerdem seltsam aus, wenn ein Handcursor über einem leeren Feld angezeigt wird. In diesem Lernprogramm erfahren Sie, wie Sie diese Probleme problemlos beheben können.
Wenn Sie mit objektorientierter Programmierung oder FlashDevelop noch nicht vertraut sind, empfiehlt es sich, die bereitgestellten Links zu überprüfen, bevor Sie dieses Lernprogramm starten.
Öffnen Sie FlashDevelop und erstellen Sie ein neues AS3-Projekt (Projekt> Neues Projekt) und nennen es so etwas BitmapButtonProj
. Auf der rechten Seite öffnen Sie die src Ordner und Doppelklick Main.as
um es zu öffnen. Fügen Sie Ihrem Projekt eine neue Klasse hinzu (Klicken Sie mit der rechten Maustaste auf / src /> Hinzufügen> Neue Klasse) namens BitmapButton
Wir brauchen jetzt ein Bild, um damit zu arbeiten. Hier ist der, den ich benutze:
Um ein Bitmap-Bild (z. B. eine .jpeg-Datei oder eine .png-Datei) in Actionscript 3 zu verwenden, müssen Sie es einbetten. FlashDevelop macht das einfach. Nachdem Sie das obige Bild irgendwo gespeichert haben, klicken Sie mit der rechten Maustaste auf lib Ordner rechts, Maus über Hinzufügen, und wähle das aus Bibliotheksbestände Möglichkeit.
Wenn Sie Ihr eigenes Bild verwenden möchten, Stellen Sie sicher, dass Sie eine mit Transparenz auswählen.
Das von Ihnen ausgewählte Bild erscheint jetzt im lib Ordner in FlashDevelop. Klicken Sie mit der rechten Maustaste auf das Bild und wählen Sie aus Einbetten-Code generieren.
public class Main erweitert Sprite [Embed (source = "… /lib/face.png")] private var ButtonImg: Class;
Dieser Code bettet ein
das Bild in unserem Projekt. Wenn Sie ein Bild einbetten, müssen Sie in der nächsten Zeile eine Klasse definieren, die das eingebettete Bild darstellt. In diesem Fall wird unsere Klasse aufgerufen ButtonImg.
Als nächstes fügen wir ein Textfeld
um anzuzeigen, wie oft wir auf die Schaltfläche geklickt haben (die als nächstes hinzugefügt wird). Fügen Sie dies zu Main()
:
clicksTextField = new TextField (); clicksTextField.width = stage.stageWidth; clicksTextField.defaultTextFormat = new TextFormat (null, 14, 0, true, false, false, null, null, TextFormatAlign.CENTER); clicksTextField.text = "Button Presses:" + numClicks; clicksTextField.mouseEnabled = false; addChild (clicksTextField);
Der obige Code formatiert einfach den Text, der in der oberen Mitte unseres Projekts angezeigt wird. Verpassen Sie nicht, wie wir unser erklärt haben Textfeld
in Zeile 15.
Dieser Code sollte auch eingehen Main()
:
var button: BitmapButton = neues BitmapButton (ButtonImg); button.x = stage.stageWidth / 2 - button.width / 2; button.y = stage.stageHeight / 2 - button.height / 2; addChild (Schaltfläche); button.addEventListener (MouseEvent.CLICK, onButtonClick);
Wenn wir unser instanziieren BitmapButton
In Zeile 36 übergeben wir unsere eingebettete Bildklasse als Parameter. Dies wird von der verwendet BitmapButton
Klasse. Danach können wir einfach unsere behandeln BitmapButton
Instanz wie jede andere DisplayObject
: wir können es positionieren und eine hinzufügen MouseEvent.CLICK
Zuhörer, wie wir es normalerweise tun würden.
Fügen Sie diese Ereignisbehandlungsfunktion zu hinzu Main.as
:
private Funktion onButtonClick (e: MouseEvent): void numClicks ++; clicksTextField.text = "Button Presses:" + numClicks;
Das letzte Stück Code in unserem Main
class ist der Ereignis-Listener für Schaltflächenklicks. Darin fügen wir einfach die Anzahl der Klicks hinzu, numClicks,
und aktualisieren Sie den Text in clicksTextField.
Umblättern zu BitmapButton.as
. Importieren Sie zuerst diese Klassen:
import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.MouseEvent;
Dann erkläre diese:
private var bitmapData: BitmapData; private const THRESHOLD: Anzahl = 0;
Sie müssen sicherstellen, dass die BitmapButton
Klasse erweitert Sprite
, seit einem Bitmap
allein kann keine Mausinteraktivität haben. (Das Bitmap
Klasse erweitert InteractiveObject nicht.)
öffentliche Funktion BitmapButton (ImageData: Class) var image: Bitmap = new ImageData (); addChild (Bild); bitmapData = image.bitmapData; addEventListener (MouseEvent.MOUSE_MOVE, onMouseMove); addEventListener (MouseEvent.CLICK, onClick);
In unserer BitmapButton
Konstruktor, wir erreichen ein paar wichtige Dinge.
Bitmap
, namens Bild
, von der Image-Klasse, die dem Konstruktor als Parameter übergeben wird.Bitmap
als Kind von uns Sprite
.BitmapData
gleich der BitmapData
unseres Bildes.KLICKEN
und MOUSE_MOVE
Ereignis-Hörer.private Funktion onMouseMove (e: MouseEvent): void var pixel: uint = bitmapData.getPixel32 (mouseX, mouseY); useHandCursor = buttonMode = ((pixel >>> 24)> THRESHOLD);
Unser einfaches Schauen MOUSE_MOVE
Event Listener ist der wahre Kopf unserer Klasse. Sein Hauptzweck besteht darin, zu bestimmen, ob sich der Mauszeiger über einem transparenten Pixel befindet oder nicht. Schauen wir uns an, wie das geht.
Die erste Zeile zeigt die Farbe und Transparenz des Pixels, über dem sich der Cursor gerade befindet. Dazu verwenden wir die getPixel32 ()
Methode der Variablen BitmapData
(was ist die Bitmap-Datendarstellung unseres Bildes).
Wir müssen eine x- und y-Koordinate an übergeben getPixel32 ()
, natürlich verwenden wir die Position der Maus.
Der Anruf kehrt dann zurück uint
Darstellung der Farbe und Transparenz des Pixels an der von uns angegebenen Stelle.
Farben in Flash werden normalerweise als Hexadezimalzahlen behandelt uint
im Format RRGGBB. Die ersten beiden Ziffern stehen für den Rotanteil in der Farbe, die nächsten zwei für Grün und die letzten beiden für Blau. jedoch, getPixel32 ()
bietet uns ein besonderes uint
unser Pixel im Format AARRGGBB darstellt. Hier stehen die ersten beiden Ziffern für die Alpha, oder die Menge an Transparenz von 00 (klar) bis FF (undurchsichtig).
Also zum Beispiel, FF980000
würde eine völlig undurchsichtige rote Farbe darstellen, während 00980000
würde eine vollständig transparente rote Farbe darstellen. Normalerweise werden diese als dargestellt 0xFF980000
oder 0x0098000
: Das "0x" lässt Sie (und Flash!) wissen, dass die Zahl hexadezimal (0-f) und nicht dezimal (0-9) ist..
An diesem Punkt haben wir eine uint
namens Pixel
Dies hält die Farbe und das Alpha des Pixels im AARRGGBB-Format unter unserer Maus. Leider sind dies zu viele Informationen. Alles, was uns interessiert, ist die Transparenz dieses Pixels oder des AA-Teils.
Sie könnten einen mathematischen Ausdruck schreiben, um diesen Abschnitt zu erhalten - in der Tat, int (pixel / Math.pow (16,6))
würde funktionieren. Dies ist jedoch eine etwas umständliche Aussage, und die Leistung ist langsamer als eine andere Option, die wir haben: der bitweise unsignierte Rechtsverschiebungsoperator, >>>
.
Unsere Variable Pixel
ist nur eine binäre Zahl für Flash. Normalerweise schreiben wir es hexadezimal, um es lesbarer zu machen. Ohne zu sehr ins Detail zu gehen, kann jede Ziffer einer Hexadezimalzahl durch eine Folge von vier Binärziffern dargestellt werden, von denen jede entweder eine 0 oder eine 1 ist Binär verwendet 0-1.)
Angenommen, wir haben eine Hexadezimalzahl, D4. Im Binärformat würde dies als 11010100 dargestellt werden. Beachten Sie, wie wir acht Binärziffern für die Binärdarstellung verwenden: viermal so viele wie in Hexadezimalzahlen.
Mit diesem Verstand wollen wir untersuchen, was das ist >>>
Operator tut tatsächlich. Verwenden wir unser vorheriges Beispiel, die Hexadezimalzahl D4 oder 0xD4
zur Klarheit. Jetzt lass uns benutzen >>>
wie so:
0xD4 >>> 4
Beachten Sie, dass 4 eine normale Dezimaldarstellung einer Zahl ist (am Anfang gibt es kein "0x"). Dieser Ausdruck verschiebt sich im Wesentlichen alle binär Ziffer in D4 vier Stellen nach rechts und vergisst jede Ziffer, die sich am Ende der Zahl befinden würde.
0xD4 ist im Binärformat 11010100. Wenden Sie vier Schichten an, und es wird 1101. Im Hexadezimalwert ist dies 0xD.
Wenn Sie Probleme haben, dies zu verstehen, stellen Sie sich die Binärziffern als Blöcke auf der rechten Seite eines Tisches vor. Das >>>
Der Operator ist so, als würde er die Blöcke nach rechts schieben. Hier ist unsere ursprüngliche Binärzahl:
Nun, hier ist unsere neue Nummer, nachdem wir es getan haben 0xD4 >>> 4
:
Beachten Sie, wie wir, nachdem wir 0xD4 um 4 Bits verschoben hatten, nur noch 0xD hatten. Das ist kein Zufall. Wie bereits erwähnt, besteht jede hexadezimale Ziffer aus 4 Binärziffern - jedes Mal, wenn wir sie um 4 nach rechts verschieben, klopfen wir im Wesentlichen eine hexadezimale Ziffer vom Ende. Sie können wahrscheinlich sehen, wohin wir damit gehen!
Zurück zu unserem Pixel im 0xAARRGGBB-Format. Wenn wir es um 24 verschieben, verschieben wir uns tatsächlich um 6 hexadezimale Ziffern. Dies bedeutet, dass der RRGGBB-Teil abgeschlagen wird und am Ende nur noch der 0xAA-Teil übrig bleibt, der unsere Alphakomponente ist.
Ein schnelles Zahlenbeispiel: Angenommen, unser Pixel entspricht FF980000. Binär ist dies 1111 1111 1001 1000 0000 0000 0000 0000. (Jede Gruppe von 4 Ziffern stellt eine Hexadezimalziffer dar.) Wenn wir diese Zahl um 24 verschieben, erhalten wir einfach die beiden Transparenzzeichen 1111 1111 oder FF.
Schau es dir noch einmal an:
useHandCursor = buttonMode = ((pixel >>> 24)> THRESHOLD);
Okay, das (pixel >>> 24)
Teil macht jetzt Sinn, aber was ist mit dem Rest?
Es ist einfach. Wir prüfen, ob unsere Alphakomponente (das Ergebnis von pixel >>> 24
) ist größer als der Wert von SCHWELLE
(der momentan auf 0 gesetzt ist). Wenn es so ist, useHandCursor
und buttonMode
werden auf true gesetzt, wodurch der Cursor in eine Hand geändert wird. Dadurch erscheint unser Bild wie eine Schaltfläche.
Wenn unsere Alphakomponente kleiner oder gleich ist SCHWELLE
, Der Cursor bleibt normal, da sich der Mauszeiger über einem (halb-) transparenten Pixel befindet. Da wir den Wert 0 festgelegt haben, werden nur vollständig transparente Pixel nicht als Teil unserer Schaltfläche eingebunden. Sie können dies jedoch beispielsweise auf 0x80 setzen. Dann würde der Handcursor für alles angezeigt, das mehr als halb transparent ist.
private Funktion onClick (e: MouseEvent): void if (! useHandCursor) e.stopImmediatePropagation ();
Der letzte Teil unseres BitmapButton
Klasse ist die MouseEvent.CLICK
Ereignis-Listener Diese Funktion wird bei jedem Klick auf unser Bild aufgerufen, unabhängig davon, ob das Pixel transparent ist oder nicht. (Wenn Sie den Mauszeiger wie zuvor ändern, wirkt sich dies nicht auf die tatsächliche Position aus MouseEvent
.)
Bei jedem Klick prüfen wir also die useHandCursor
Eigentum. Wenn es so ist wahr
, Dies bedeutet, dass sich die Maus über einem normalen Pixel in unserem Bild befindet, und wir müssen nichts tun. Das macht Sinn - das Ereignis wird dann mit dem Ereignis-Listener fortgesetzt, den wir hinzugefügt haben Main.as
. jedoch, wenn useHandCursor
ist falsch, wir müssen etwas unternehmen, um zu verhindern, dass das Ereignis mit anderen Ereignis-Listenern fortfährt.
Dafür verwenden wir die stopImmediatePropagation ()
Methode, die alle Veranstaltung
Objekte haben. Einfach gesagt, damit wird der Fluss des Ereignisses gestoppt und es werden keine weiteren Ereignis-Listener empfangen. So funktioniert unser Event Listener in Main.as
wird nie gerufen werden.
Warnung: Dies könnte einen unangenehmen Nebeneffekt haben - jeder globale Ereignis-Listener wird das Ereignis ebenfalls nicht erhalten. Wenn Sie sich darüber Sorgen machen, können Sie die Zeile hinzufügen parent.dispatchEvent (e.clone ());
nach dem e.stopImmediatePropogation ()
. Obwohl dies den Rahmen des Tutorials sprengt, empfehle ich hier mehr über das Ereignissystem zu lesen.
Dies beendet unser Tutorial! Danke fürs Lesen, und ich hoffe, Sie haben etwas Neues gelernt.
Ein Hinweis zur Vorsicht bei der Verwendung unserer BitmapButton
Klasse - andere MouseEvents
wird immer noch normal funktionieren, da wir uns nur damit befasst haben MouseEvent.CLICK
. Wenn Sie möchten, können Sie dieselbe Technik verwenden, für die Sie verwendet wurden MouseEvent.CLICK
und wenden Sie es auf andere Ereignisse an, wie z MouseEvent.MOUSE_DOWN
.
Unsere BitmapButton
class ermöglicht es uns, aus Bitmap-Bildern schnell und einfach große Schaltflächen mit Transparenz zu erstellen, wie in dieser Demo. Wenn Sie Fragen haben, beantworte ich diese gerne. Hinterlassen Sie einfach einen Kommentar.