在项目中,使用as3内置事件框架必须通过自定义事件才可以实现值的传递,大量自定义事件、定义常量和整个事件派发的管理、添加侦听器、移除侦听器,或多或少都会带来大量的代码,而signals这个框架思想原来在C#中原本就有,作者整合了C#中的signals思想,实现起来比as3内置的事件更快捷,可以很轻松的实现多个强类型值的传递,的在一定程度上也会简化很多代码。有朋友测试,signals里面用内置的事件竟然是as3内置事件运行速度的4倍。

但是我想大家已经对Event事件机制已经非常熟悉了,那么我们就从Event框架机制开始吧。

var sprite:Sprite = new Sprite()
sprite.addEventListner(MouseEvent.CLICK, onEventHandler)
function onEventHandler(me:MouseEvent):void
{
//执行代码
}

  

稍微解释一下,以方便理解Signals框架,首先定义一个Sprite的实例,使用addEventListener()方法为sprite添加事件侦听,事件类型是MouseEvent.CLICK事件,事件响应函数为onEventHandler函数。如果想使用AS3.0 Event框架来自定义事件那绝对是个体力活,但使用Signals框架来自定义却非常简单。首先从最基本的开始。

Signal类

AlarmClock.as

这个类用来定义一个AlarmClock,同时使用Signals框架自定义事件以被AlarmClock的实例来捕获。

package insideria.basicSignal
{
import org.osflash.signals.Signal; public class AlarmClock
{
//定义一个alarm事件,设定为public属性以被访问,相当于Event框架中所使用的MousEvent.CLICK
public var alarm:Signal; public function AlarmClock()
{
//实例化alarm
alarm = new Signal();
} public function ring():void
{
//调用Signal类的实例的方法dispatch(),只要该方法被执行,Signal就会派发alarm事件,我们要做的就是捕获该事件,并作出相应
alarm.dispatch();
}
}
}

  

WakeUp.as

主函数类文档

package insideria.WakeUp
{
import flash.display.Sprite; public class WakeUp extends Sprite
{
//定义一个AlarmCLock类的变量
private var alarmClock:AlarmClock; public function WakeUp()
{
//实例化Alarmclock
alarmClock = new AlarmClock();
//使用signal的add()方法为该实例的alarm事件添加一个响应函数。类似于addEventListner()方法
alarmClock.alarm.add(onRing);
//调用ring()方法执行signal的dispatch()方法,派发事件
alarmClock.ring();
} //alarm事件的响应函数
private function onRing():void
{
trace("Wake up!");
}
}
}

  

执行文档在输出面板就会看到:

Wake Up!

如果想在使用Signal定义事件时想要派发参数也可以

AlarmClock.as

package insideria.basicSignalArguments
{
import org.osflash.signals.Signal; public class AlarmClock
{
public var alarm:Signal; public function AlarmClock()
{
alarm = new Signal(String);
} public function ring():void
{
alarm.dispatch("9 AM");
}
}
}

  当然多类型的参数也是可以的,只要在dispatch()方法里依次输入对用类型的数值即可

alarm = new Signal(String, Number, int, uint, Boolean);
alarm.dispatch("9 AM", 45.4, -10, 5, true);

  WakeUp.as

package insideria.basicSignalArguments
{
import flash.display.Sprite; public class WakeUp extends Sprite
{
private var alarmClock:AlarmClock; public function WakeUp()
{
alarmClock = new AlarmClock();
alarmClock.alarm.add(onRing);
alarmClock.ring();
} private function onRing(time:String):void
{
trace("Wake up! It's already " + time);
}
}
}

  

测试影片可以看到输出面板输出:

Wake Up! It's already 9 AM

还记得在as3.0 Event框架下,我们每次添加事件都要使用removeEventListner()方法来移除事件,Signal提供addOnce()方法仅添加一次事件而不需要我们再去添加额外代码去移除事件,在事件被派发一次后自动移除该事件。

alarmClock.alarm.addOnce(onRing);

  当然在更多情况下我们还是想要手动控制事件的移除,你可以使用remove()方法去移除事件,或者使用removeAll()方法一次性移除所有事件。

alarmClock.alarm.remove(onRing);
alarmClock.alarm.removeAll();

  

在as3.0 Event框架下,事件提供了currentTarget/Target用来通过事件来访问对象,Signlas框架也提供了类似的属性。

DeluxeSignal

DeluxeSignal类与GenericEvent类共同使用可以实现上述用法

AlarmClock.as

package insideria.deluxeSignal
{
import org.osflash.signals.DeluxeSignal;
import org.osflash.signals.events.GenericEvent; public class AlarmClock
{
//定义alarm事件
public var alarm:DeluxeSignal;
//定义一个字符串
public var message:String; public function AlarmClock()
{
//实例化DeluxeSignal
alarm = new DeluxeSignal(this);
//为字符串赋值
message = "This is a message from our AlarmClock";
} public function ring():void
{
//绑定派发事件
alarm.dispatch(new GenericEvent());
}
}
}

  WakeUp.as

package insideria.deluxeSignal
{
import org.osflash.signals.events.GenericEvent;
import flash.display.Sprite; public class WakeUp extends Sprite
{
private var alarmClock:AlarmClock; public function WakeUp()
{
alarmClock = new AlarmClock();
alarmClock.alarm.add(onRing);
alarmClock.ring();
} private function onRing(event:GenericEvent):void
{
trace(event.target);
trace(event.signal);
trace(event.target.message);
}
}
}

  

测试影片,输出面板输出:

alarmClock

DeluxeSignal

This is a message from our AlarmClock

NativeSignal

最后Signals框架提供NativeSignal类用来代替Event框架事件,以MouseEvent为例

//自定义事件clicked
private var clicked:NativeSignal;
private var box:Sprite;
box = new Sprite();
box.graphics.beginFill(0xCCCCCC);
box.graphics.drawRect(0, 0, 100, 100);
box.graphics.endFill();
addChild(box);
//通过Event机制下的MouseEvent.CLICK,为box添加clicked事件
clicked = new NativeSignal(box, MouseEvent.CLICK, MouseEvent);
//添加响应函数
clicked.add(onClicked); private function onClicked(event:MouseEvent):void
{
trace("clicked");
}

  

再来个例子:

package com.pleribus.as3signalsdemo {

    import org.osflash.signals.natives.NativeSignal;
import org.osflash.signals.Signal;
import flash.display.Sprite;
import flash.events.MouseEvent; /**
* @author Clint Hannaford
*/
public class Player extends Sprite { public var playerKilled:Signal;
public var playerHit:Signal;
public var click : NativeSignal;
private var health: Number; public function Player(){ } public function init() : void {
//为health变量赋值
health = 10;
//实例化自定义事件playerKilled
playerKilled = new Signal();
//实例化自定义事件playerHit
playerHit = new Signal();
//实例化自定义事件click
click = new NativeSignal(this, MouseEvent.CLICK, MouseEvent);
//为此类画上图形按钮
with (this.graphics){ beginFill(0x000000);
drawRect(0, 0, 50, 50);
endFill(); beginFill(0xFFFFFF);
drawRect(10, 10, 10, 10);
drawRect(30, 10, 10, 10);
drawRect(10, 30, 30, 10); } } //自定义一个公有方法hit
public function hit():void{
//health变量自减
health--;
//为此类的实例绑定并派发playerHit事件
playerHit.dispatch("Player Hit", health);
//判断health变量值,当小于等于0时执行kill()函数
if (health <= 0){
kill();
} } //私有方法kill,执行此函数为此类的实例绑定并派发playerKilled事件
private function kill():void{ playerKilled.dispatch("Player Killed"); } } }

  

package com.pleribus.as3signalsdemo {

    import flash.events.MouseEvent;
import flash.text.TextField;
import flash.display.Sprite; /**
* @author Clint Hannaford
*/
public class SignalsDemo extends Sprite { public var player:Player;
public var textOutput:TextField; public function SignalsDemo() {
//执行addPlayer()方法
addPlayer();
//执行addTextField()方法
addTextField(); //为自定义事件添加响应函数
player.playerHit.add(onPlayerHit);
player.playerKilled.add(onPlayerKilled);
player.click.add(onClickPlayer); } //实例化Player类
private function addPlayer():void{ player = new Player();
player.init(); player.x = 30;
player.y = 30; player.buttonMode = true; addChild(player); } //实例化TextField
private function addTextField():void{ textOutput = new TextField(); textOutput.x = 10;
textOutput.y = 100;
textOutput.width = 350;
textOutput.height = 200; textOutput.border = true; addChild(textOutput); } //事件响应函数
private function onClickPlayer(event:MouseEvent) : void { // 每当按钮被点击时执行Play()类中定义的hit()方法
player.hit(); } private function onPlayerKilled(message:String) : void { textOutput.appendText(message+"\n"); player.playerHit.remove(onPlayerHit);
player.playerKilled.remove(onPlayerKilled);
player.click.remove(onClickPlayer); this.removeChild(player); } private function onPlayerHit(message:String, health:Number) : void { textOutput.appendText(message+" - health now: "+health+"\n"); } } }

  

AS3 Signals的更多相关文章

  1. [Repost]Events and Signals in PyQt4

    Reference:http://zetcode.com/gui/pyqt4/eventsandsignals/ Events and Signals in PyQt4 In this part of ...

  2. [转]关于AS3 Socket和TCP不得不说的三两事

    磨刀不误砍柴工,让我们从概念入手,逐步深入. 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络 ...

  3. as3正则表达式

    1.新建正则表达式,有两种方式var exp1:RegExp = new RegExp("ABCD","g");var exp2 = /ABCD/g;//g g ...

  4. [转]AS3 int uint Number

    转自:http://luhantu.iteye.com/blog/1910301 AS3 int uint Number 博客分类: AS3 flex number 类型  1) int 类可使用表示 ...

  5. AS3和js相互通信要点分析

    目标:在html页面里可以使用事件来影响到swf文件的内容,swf文件也可以影响html里js代码的内容 一.新建flash文件,用Flash CC试用版新建一个TextArea.fla的源文件,不添 ...

  6. 关于as3调用js报“null为空或不是对象”错误

    主要原因是:flash插件的object对象无ID属性. 顺便说下as3调用js的方法. as3引用: import flash.external.ExternalInterface; as3中调用 ...

  7. 在as3中使用protobuf

    在最近参与开发的adobe air项目中,前后端的通信协议从XML.JSON再到protobuf,最后选择protobuf原因,主要是前后端维护protobuf协议就行了,同时还可以利用IDE做一些编 ...

  8. [AS3.0] HTMLLoader与js交互

    HtmlLoader 的属性window是加载到 HTML 控件中的内容的全局 JavaScript 对象,通过这个对象能够方便的和页面js通讯. AS代码: import flash.html.HT ...

  9. [ActionScript 3.0] AS3.0和AS2.0的相互通信

    AS3和AS2之间的通信,最好的方式可能就是LocalConnection了. AS2向AS3发送数据,即AS2调用AS3的函数: as2.0代码(按钮上写的发送信息代码): on (release) ...

随机推荐

  1. Android:实现一种浮动选择菜单的效果

    总结如何实现Android浮动层,主要是dialog的使用. 自定义一个类继承自Dialog类,然后在构造方法中,定义这个dialog的布局和一些初始化信息. 案例1: public class Me ...

  2. [Web API] 如何让 Web API 统一回传格式以及例外处理

    [Web API] 如何让 Web API 统一回传格式以及例外处理 前言 当我们在开发 Web API 时,一般的情况下每个 API 回传的数据型态或格式都不尽相同,如果你的项目从头到尾都是由你一个 ...

  3. DateTime.IsLeapYear 方法判断是否是闰年,DaysInMonth判断一个月有几天,Addday取得前一天的日期GetYesterDay

    一:DateTime.IsLeapYear 方法判断是否是闰年 二:代码 using System; using System.Collections.Generic; using System.Co ...

  4. <Chapter 2>2-1-2.安装Java SDK

    Java运行时环境的App Engine SDK运行在任何运行了Java SE开发工具(JDK)的电脑上.Java SDK App Engine 支持JDK 6,并且当运行App Engine的时候, ...

  5. leetcode@ [310] Minimum Height Trees

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  6. Web Service 与 EJB 的分布式的区别

    EJB的分布式:一个业务逻辑可能会调用分布在多台服务器上的 EJB 组件,但是这么多的组件调用必须纳入一个事务范围之中.也就是说如果需要调用三个 EJB 组件,第一个调用成功,第二个调用成功,但第三个 ...

  7. JDBC学习笔记(7)——事务的隔离级别&批量处理

    数据库事务的隔离级别 对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 ...

  8. TTL电平、CMOS电平、RS232电平的区别

    工作中遇到一个关于电平选择的问题,居然给忘记RS232电平的定义了,当时无法反应上来,回来之后查找资料才了解两者之间的区别,视乎两年多的时间,之前非常熟悉的一些常识也开始淡忘,这个可不是一个好的现象. ...

  9. Chrome的Postman的使用

    Chrome提供了一个很好的Web App 名为 Postman 使用这个web app,你可以输入一个url,然后可以很清楚的看到返回的各种结果 直接在Google中输入Postman, 找到它   ...

  10. C#中垃圾回收与内存管理机制

    今天抽空来讨论一下.Net的垃圾回收与内存管理机制,也算是完成上个<WCF分布式开发必备知识>系列后的一次休息吧.以前被别人面试的时候问过我GC工作原理的问题,我现在面试新人的时候偶尔也会 ...