zoukankan      html  css  js  c++  java
  • AS3 Signals

    在项目中,使用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+"
    ");
                     
                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+"
    ");
                     
            }
                 
        }
             
    }
    

      

  • 相关阅读:
    求多边形的面积
    Sequence operation3397
    Atlantis1542(线段树求矩形覆盖面积)
    hdu3033 分组背包(每组最少选一个)
    poj3468A Simple Problem with Integers(线段树延时更新)
    Picture 1828
    Minimum Inversion Number 1394(线段树法)
    hdu2955 Robberies 01背包
    C# 对MongoDB数据库进行增删该
    C#连接MongoDB数据库应用实战
  • 原文地址:https://www.cnblogs.com/zhepama/p/3359662.html
Copyright © 2011-2022 走看看