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);
        }
    }
}
相关推荐
SmalBox4 小时前
07-02-打包系统-压缩与加密策略
unity3d·游戏开发
Aman19845 小时前
Claude Code做Unity项目移植(一):从零散工具到团队式
unity·游戏开发·vibe coding·claude code·项目迁移
ZzT13 小时前
vibe coding 做小游戏·玩法篇:8 句试玩反馈,变成无限关卡、局外成长和援军登场
ai编程·游戏开发
ZzT2 天前
vibe coding 做小游戏·素材篇:Claude Code 操作网页版 ChatGPT,一个对话画完全套美术
ai编程·游戏开发
SmalBox2 天前
07-01-打包系统-资源分组策略
unity3d·游戏开发
ZzT2 天前
vibe coding 做小游戏·开工篇:5 天、8400 行代码一行没手写,先让 AI 能检查自己
ai编程·游戏开发·claude
Huanzhi_Lin2 天前
资源回收源码阅读参考-上
游戏开发·gc·laya·layaair·资源回收·laya3.4
SmalBox3 天前
06-04-源码-加密解密服务
unity3d·游戏开发
UWA3 天前
告别「好像还行」:制作人别再靠感觉做线上质量决策|GPM 小Q MCP 实战
性能优化·游戏开发·gpm
小杨互联网3 天前
Kenney Input Prompts 1.5(CC0)离线包说明
游戏开发