• 615 游戏键盘输入机制


    6-15  晴

    一、键盘输入机制

          关键字:消息处理   消息分发  消息注册  逻辑集中  解耦

          键盘输入起始总是从键盘事件开始的,这是一个源头。

           在特定的UI元素上面(这个和你采取的具体平台相关,但一般情况下都是一个UIElement),注册键盘输入事件和处理函数。

          这里的秘密就在于这个处理函数,当然,你可以在处理函数中直接调用很键盘输入相关的游戏逻辑处理,比如UpKey Down ,Y 坐标增加,这就是一个按向上箭头,物体向上移动的效果。但这么做是不够好的。有几点原因:

    其一,这种做法会让游戏的动画受限于了键盘输入的频率,难以控制,会很卡。这个我们后面会详细讲解。

    其二,这种做法属于一种“硬编码”,键盘按下,物体移动,直接把一个游戏逻辑和一个硬输入连接在了一起,它们之间其实没有什么联系,这很不科学,也不柔和。

    解决这个问题,有很多做法,下面我来讲讲在LLGame的机制下,是怎么样处理的。LLGame本身是一种基于消息的处理机制。

    看一下图:

                           

            其实键盘处理的消息机制和游戏中其他的消息处理本质上说一样的,这也是消息处理的好处,统一的机制,不会让你陷入到不同复杂逻辑中,不断变换思维而穷于应付。

    Step1:

          首先你要准备好一个实体,这个实体能够接收带有键盘信息的消息,至于这个实体是作为键盘输入管理器,还是作为场景管理器,并没有一定之规,视乎游戏具体逻辑和个人思路而定。总之,需要有个地方集中收集键盘消息。

    Step2:

          根据具体游戏平台进行键盘处理事件注册,一般都是选择一个UIElement进行注册,例如在Flash平台上面,选择了一个DisplayObject进行键盘事件注册。在事件处理函数中,向刚才已经做好准备的实体(这个实体已经能够处理键盘消息)发送带有键盘信息的消息。

          这个键盘管理器(或者场景管理器),收到消息后,进一步和游戏逻辑联系起来。比如这时候你仍然喜欢让精灵坐标向上,那么也恭喜你,你把这个事情和一条消息联系了起来,而不是一个硬输入。更合理的做法,是在键盘管理器收到消息后,进行初步的处理,然后根据具体情况,再一次进行消息分发,在更具体的实体哪里处理逻辑。(这时候那个实体应该已经注册好了消息处理函数)。

     

     1 private static function InitKeyMouse():void
     2         {
     3             IME.enabled = false;  //中文输入控制
     4             AcceptStage.addEventListener(KeyboardEvent.KEY_DOWN, function (e:KeyboardEvent):void
     5             {
     6                 MsgManager.SendMessage(new MsgId("KeyDownMsg", 0, SceneID,DataSource.MsgMins["KeyDown"], e.keyCode));
     7             });
     8             AcceptStage.addEventListener(KeyboardEvent.KEY_UP, function (e:KeyboardEvent):void
     9             {
    10                 MsgManager.SendMessage(new MsgId("KeyUpMsg", 0, SceneID,DataSource.MsgMins["KeyUp"], e.keyCode));
    11             });
    12         }

     在下面,我们谈谈鼠标输入。

    二、鼠标输入机制

         对于鼠标输入和键盘输入非常类似,但也有不同点:键盘输入的全局性更强,鼠标输入会针对某一个精灵(或者其他具体的东西)。根据这个特点,可以采取不同的做法。我在使用GPU的情况下使用Silverlight技术做2D游戏,因为整个画面都是贴图渲染,所以仍然采取的是将鼠标输入作为了一个整体,只有根UIElement注册,然后根据位置算出来鼠标在哪个精灵上面,再向此精灵发送消息,这样做,性能更高,结构简单;但在Flash平台下面,采取的是向每个精灵注册鼠标事件,这样实现起来更方便,不过在删除精灵实体的时候,需要把注册的事件也要清除,否则不断累积,造成性能低下。

            /**
             * 根据实体ID,为VisualEnt实体的ImgContainer添加事件处理函数
             * 所以请注意,这个方法限制在VisualEnt实体上面
             */
            public static function AddHandler(_id:int, _event:String, _handler:Function):void
            {
                var data:VisualEntData = DataCenter.GetData(_id);
                data.ImgContainer.addEventListener(_event, _handler);
                data.AddHandler(_event, _handler);
            }
  • 相关阅读:
    SQL Cookbook:二、查询结果排序(4)对字母数字混合的数据排序
    (转).net框架读书笔记引用参数(ref/out)
    (转).net面试问答(大汇总)
    SQL Cookbook:一、检索记录(9)限制返回的行数
    C# 3.0 Cookbook:一、字符与字符串处理(5):把一个字符串与另一个字符串的头部或尾部作比较
    (转)sql海量数据优化
    (转)C# 中的委托和事件(二)
    (转)我看微软.NET各技术应用前景
    在sql server数据库中快速删除记录,清空表
    SQL Cookbook:二、查询结果排序(3)按子串排序
  • 原文地址:https://www.cnblogs.com/GameCode/p/2550539.html
Copyright © 2020-2023  润新知