Laya 1.x AS3 游戏开发 以玩家死亡为例子 了解如何通过事件调用函数

记录 碰到的两种事件监听的解决方案

先明确方案的目的:

使得类当中的函数,在事件分发的时候被调用

比如:希望当玩家死亡的时候,玩家的角色倒下

我们希望的是 当玩家死亡的时候,系统"告诉"死亡处理函数:"玩家现在死亡了,倒下了",即当玩家死亡的时候调用Player类中的onPlayerDead函数

js 复制代码
/*系统提示类*/
public class Player
{
    ...
    /*
    玩家死亡的时候调用
    @param data 附带的数据
    */
    public function onPlayerDead(data:*):void
    {
        console.log("玩家死亡!死因:{1}",parseToString(data));
        fall(data);//玩家的角色倒下
    }
    ...
}

方案一:要求类实现接口

我们编写一个"关心数据"接口,并将实现这个接口的类被注册到控制中心的"关心数据的类"的集合当中。

控制中心可将事件以及附带的数据向集合中的每个类发送。

类根据收到的事件类型,以及相应的数据做相应的处理。 如图1所示,其中A和B都是"关心数据的类"。

可以在基类中添加判断,继承了该类的子类是否实现"关心数据"接口,如果事件了,则注册到控制中心中的集合当中。

注意:当对象的生命周期结束的时候应该从"关心数据"集合当中注销掉

简化代码如下:

关心数据的接口,要求类实现 对派发的事件的类型以及数据做出相应处理

js 复制代码
public interface ICareAboutData
{
    function updateData(type:String,param:Object):void
}

控制中心需要负责存储注册的物体,以及分发事件

js 复制代码
/*控制中心*/
public class Class Control
{
    //因为该集合是全局唯一的 所以使用static
    private static var dic:Object = new Object();
    ...
    /*注意 调用static方法的时候 不需要实例化类,就可以调用*/
    /*注册Object*/
    public static function registerObject(object:ICareAboutData):void
    {
        //使用自带的内部成员属性(带有$)的
        dic[object["$_GID"] = object;
    }   
    ...
    /*注销Object*/
    public static function unregisterObject(object:ICareAboutData):void
    {
        delete dic[view["$_GID"]];
    }
    
    /*广播事件*/
    public static function dispatch(type:*,param:Object):void
    {
        for(var key:* in dic)
        {
        var object:ICareAboutData = dic[key];
        object.updateData(type,param);
        }
    }
}

基类,这里主要是想说明,可以通过在基类编写判断是否为"关心数据"的逻辑,来避免为每个物体(每种角色,比如:如果敌人也要求死亡就倒下,那么继承基类就好了)都单独写逻辑。

js 复制代码
/*自定义的基类,生命周期根据使用的游戏引擎有区别,这里以Laya 1.x为例*/
public class BaseCharacter extends Object
{
    ...
    protected function onAdded()
    {
        ...
        if(this is ICareAboutData)
        {
            Control.registerObject(this);
        }
        ...
    }
    ...
    /*当然地,在生命周期结束的时候应该注销*/
    protected function onRemoved():void
    {
        ...
        if(this is ICareAboutData)
        {
            Control.unregisterObject(this);
        }
        ...
    }
    
}

这时,可以使玩家的角色类Player 继承这个基类,并实现接口,如下所示:

适配之后的Player类:

js 复制代码
/*系统提示类*/
public class Player extends BaseCharacter implements ICareAboutData
{
    ...
   
    //玩家死亡的时候调用
    //@param data 附带的数据
    public function onPlayerDead(data:*):void
    {
        console.log("玩家死亡!死因:{1}",parseToString(data));
        fall(data);//玩家的角色倒下
    }
    ...
    
    /*为到来的事件以及数据做处理*/
    /*不同的事件类型 以及不同的数据 可以做不同的处理的 也可以不做处理*/
    public function updateData(type:String,param:Object = null):void
    {
            swich(type)
            {
                case EventType.PLAYERED:
                    onPlayerDead(param);
                    break;
                case EventType.SOMEEVENT:;
                    break;//不做处理,当然不写也行,这里是为了表现差异化
                defalut:
                    break;
            }
            
    }
    
}

这时候 可以假设,有以下通信协议类,收到服务器的信息之后可以发事件,通报玩家死亡:

js 复制代码
public class PlayerCtr
{
    public function onReceive(playerData:*):void
    {
        if(playerData.hp <= 0 )
        {
            Control.dispatchAll(EventType.PLAYERED);
        }
    }
}
相关推荐
SmalBox7 小时前
03-05-架构篇-操作异步体系(OperationSystem)
unity3d·游戏开发
SmalBox1 天前
03-04-架构篇-文件系统架构(IFileSystem)
unity3d·游戏开发
甲维斯9 天前
Opus5.5大考!做一个赛车游戏"秋名山车神"
人工智能·游戏开发
鑫鑫哥adam11 天前
一个 1x1 贴图,是怎么炸掉整个热更包的?
unity3d·游戏开发
Behavior12 天前
Unity 手游动态更换 App 图标 — Android 与 iOS 双端技术方案
c#·unity3d·游戏开发
SmalBox13 天前
03-03-架构篇-Runtime加载系统架构
unity3d·游戏开发
SmalBox13 天前
03-02-架构篇-Editor打包系统架构
unity3d·游戏开发
Yeah12713 天前
当 LLM 进入游戏玩法:从收权到放权
游戏开发
Behavior13 天前
Unity 手游 iOS Deep Link 唤醒全流程:从 URL Scheme / Universal Links 到 C# 层参数投递
c#·unity3d·游戏开发