6-15 游戏键盘输入机制

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);
        }

 

 

posted @ 2012-06-15 13:12  向恺然  阅读(618)  评论(0编辑  收藏  举报

我必须说的是:我崇尚开源,但鄙视剽窃。本博客所有引用的图片,文章,和代码,均只作为研究学习使用,不作为商业应用。如果我无意中冒犯了您,请发消息留言,我将立即删除。