首页 web前端 H5教程 HTML5游戏框架cnGameJS开发实录-外部输入模块篇

HTML5游戏框架cnGameJS开发实录-外部输入模块篇

Mar 24, 2017 pm 04:13 PM

1.为什么我们需要外部输入模块?

  在游戏中我们常常用到类似这样的操作:鼠标点击某位置,玩家对象移动到该位置,或者按鼠标方向键,玩家向不同方向移动,等等。这些操作无一不用与外部输入设备打交道。作为游戏的设计者,我们很需要在任何时候知道鼠标目前的位置,键盘的点击状况等,从而方便我们对游戏元素加以控制。因此作为一个游戏框架,外部输入模块也是必不可少的。

2.提供哪些功能,怎样使用?

  外部输入模块主要实现的功能就是动态记录鼠标相对于canvas的位置,以及记录键盘上哪些键是按下的,哪些键刚刚松开,并触发相应的回调函数

  我们可以通过框架保存的两个字段获取鼠标当前在canvas的位置:

var x=cnGame.input.mouseX;
var y=cnGame.input.mouseY;
登录后复制

  由于canvas下的游戏编程模式是通过一个游戏循环来实现的帧动画(关于游戏循环请看:HTML5游戏框架cnGameJS开发实录(游戏循环篇)),因此单纯对键盘keyup与keydown的绑定,往往并不能达到期望效果,举个例子,我们如果想在键盘按下左键时使元素一直向左移动:

cnGame.input.onKeyDown("left",(){
    player.move(-10);
 })
登录后复制

  我们会发现这种方法并不能很好的运用在帧动画的编程模型。由于当我们按着键盘左方向键时,其回调函数会不断触发,因此触发频率并不能和你的帧动画的频率一致(要么太快要么太慢,取决于你的帧频率),所以更好的选择是每次帧更新时,判断左键是否按下,如果是按下游戏元素就向左移动一定位置,这样游戏元素就成为帧动画的一部分,随着每次帧的更新而更新:

/*每次帧更新调用的函数*/
var update=function(){
   cnGame.input.isPressed("left",function(){player.move(-10);})
}
登录后复制

3.代码实现

  首先看如何保持鼠标在canvas的位置。鼠标相对于canvas的位置,其实就是鼠标相对于页面的位置和canvas的位置之差。在之前的HTML5游戏框架cnGameJS开发实录(核心函数模块篇)里已经介绍过,在框架的初始化函数里,我们已经通过getCanvasPos获取到canvas在页面的位置,因此鼠标相对于canvas的位置可以如此计算: 

/**
     *记录鼠标在canvas内的位置
    **/    
    var recordMouseMove=function(eve){
        var pageX,pageY,x,y;
        eve=cg.core.getEventObj(eve);
        pageX = eve.pageX || eve.clientX + document.documentElement.scrollLeft - document.documentElement.clientLeft;
        pageY = eve.pageY || eve.clientY + document.documentElement.scrollTop - document.documentElement.clientTop;
        cg.input.mouseX=pageX-cg.x;
        cg.input.mouseY=pageY-cg.y;
            
    }
登录后复制

  之后再看看键盘输入的记录如何实现,我们需要一个数组,保存每个键的名值对(键名和键编码),以及一些对象,保存每个键对应的按下和松开的回调函数,还有最后一个对象,保存那些需要禁止默认行为的键名。(禁止键盘默认行为在游戏开发中很必要,可以防止玩家在操控时游戏对象时触发不必要的浏览器默认行为,例如滚动条滚动等)。

 首先是建立键名和键编码的字典:

/**
     *键盘按键编码和键名
    **/    
    var k=[];
    k[8] = "backspace"
    k[9] = "tab"
    k[13] = "enter"
    k[16] = "shift"
    k[17] = "ctrl"
    k[18] = "alt"
    k[19] = "pause"
    k[20] = "capslock"
    k[27] = "esc"
    k[32] = "space"
    k[33] = "pageup"
    k[34] = "pagedown"
    k[35] = "end"
    k[36] = "home"
    k[37] = "left"
    k[38] = "up"
    k[39] = "right"
    k[40] = "down" 
    k[45] = "insert"
    k[46] = "delete"
    
    k[91] = "leftwindowkey"
    k[92] = "rightwindowkey"
    k[93] = "selectkey"
    k[106] = "multiply"
    k[107] = "add"
    k[109] = "subtract"
    k[110] = "decimalpoint"
    k[111] = "divide"
    
    k[144] = "numlock"
    k[145] = "scrollock"
    k[186] = "semicolon"
    k[187] = "equalsign"
    k[188] = "comma"
    k[189] = "dash"
    k[190] = "period"
    k[191] = "forwardslash"
    k[192] = "graveaccent"
    k[219] = "openbracket"
    k[220] = "backslash"
    k[221] = "closebracket"
    k[222] = "singlequote"
    
    var numpadkeys = ["numpad1","numpad2","numpad3","numpad4","numpad5","numpad6","numpad7","numpad8","numpad9"]
    var fkeys = ["f1","f2","f3","f4","f5","f6","f7","f8","f9"]
    var numbers = ["0","1","2","3","4","5","6","7","8","9"]
    var letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    for(var i = 0; numbers[i]; i++)     { k[48+i] = numbers[i] }
    for(var i = 0; letters[i]; i++)     { k[65+i] = letters[i] }
    for(var i = 0; numpadkeys[i]; i++)  { k[96+i] = numpadkeys[i] }
    for(var i = 0; fkeys[i]; i++)       { k[112+i] = fkeys[i] }
登录后复制

  有点长,不过其实没啥技术含量,就是方便我们以后知道某个编码的键名是什么。例如我们按下左键,那么流程就是:获取到左键的键盘编码->在字典中得到键名->在对象中通过键名获取到之前同样通过键名保存的处理程序,并执行。

  为键盘绑定处理程序的代码如下:

/**
     *记录键盘按下的键
    **/    
    var recordPress=function(eve){
        eve=cg.core.getEventObj(eve);
        var keyName=k[eve.keyCode];
        pressed_keys[keyName]=true;    
        if(keydown_callbacks[keyName]){
            for(var i=0,len=keydown_callbacks[keyName].length;i<len;i++){
                keydown_callbacks[keyName][i]();
                
            }
        
        }
        if(keydown_callbacks["allKeys"]){
            for(var i=0,len=keydown_callbacks["allKeys"].length;i<len;i++){
                keydown_callbacks["allKeys"][i]();
                
            }
        }
        if(preventDefault_keys[keyName]){
            cg.core.preventDefault(eve);
        }
    }
登录后复制


  每个键的处理程序可以有多个,所以这里保存处理程序的对象保存的是一个数组。另外需要注意通过pressed_keys数组保存了按下的键(pressed_keys[keyName]=true;),就是为了方便实现之前说过的在帧更新中进行一致的参数更新(可以在每次update时通过isPressed(keyName)判断某个键是否按下)。

  最后附上该输入模块所有源代码:

/**
 *
 *输入记录模块
 *
**/
cnGame.register("cnGame.input",function(cg){
                                            
    this.mouseX=0;
    this.mouseY=0;
    /**
     *记录鼠标在canvas内的位置
    **/    
    var recordMouseMove=function(eve){
        var pageX,pageY,x,y;
        eve=cg.core.getEventObj(eve);
        pageX = eve.pageX || eve.clientX + document.documentElement.scrollLeft - document.documentElement.clientLeft;
        pageY = eve.pageY || eve.clientY + document.documentElement.scrollTop - document.documentElement.clientTop;
        cg.input.mouseX=pageX-cg.x;
        cg.input.mouseY=pageY-cg.y;
            
    }        
    
    cg.core.bindHandler(window,"mousemove",recordMouseMove);
    
    /**
     *被按下的键的集合
    **/    
    var pressed_keys={};
    /**
     *要求禁止默认行为的键的集合
    **/    
    var preventDefault_keys={};
    /**
     *键盘按下触发的处理函数
    **/    
    var keydown_callbacks={};
    /**
     *键盘弹起触发的处理函数
    **/    
    var keyup_callbacks={};

    
    /**
     *键盘按键编码和键名
    **/    
    var k=[];
    k[8] = "backspace"
    k[9] = "tab"
    k[13] = "enter"
    k[16] = "shift"
    k[17] = "ctrl"
    k[18] = "alt"
    k[19] = "pause"
    k[20] = "capslock"
    k[27] = "esc"
    k[32] = "space"
    k[33] = "pageup"
    k[34] = "pagedown"
    k[35] = "end"
    k[36] = "home"
    k[37] = "left"
    k[38] = "up"
    k[39] = "right"
    k[40] = "down" 
    k[45] = "insert"
    k[46] = "delete"
    
    k[91] = "leftwindowkey"
    k[92] = "rightwindowkey"
    k[93] = "selectkey"
    k[106] = "multiply"
    k[107] = "add"
    k[109] = "subtract"
    k[110] = "decimalpoint"
    k[111] = "divide"
    
    k[144] = "numlock"
    k[145] = "scrollock"
    k[186] = "semicolon"
    k[187] = "equalsign"
    k[188] = "comma"
    k[189] = "dash"
    k[190] = "period"
    k[191] = "forwardslash"
    k[192] = "graveaccent"
    k[219] = "openbracket"
    k[220] = "backslash"
    k[221] = "closebracket"
    k[222] = "singlequote"
    
    var numpadkeys = ["numpad1","numpad2","numpad3","numpad4","numpad5","numpad6","numpad7","numpad8","numpad9"]
    var fkeys = ["f1","f2","f3","f4","f5","f6","f7","f8","f9"]
    var numbers = ["0","1","2","3","4","5","6","7","8","9"]
    var letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    for(var i = 0; numbers[i]; i++)     { k[48+i] = numbers[i] }
    for(var i = 0; letters[i]; i++)     { k[65+i] = letters[i] }
    for(var i = 0; numpadkeys[i]; i++)  { k[96+i] = numpadkeys[i] }
    for(var i = 0; fkeys[i]; i++)       { k[112+i] = fkeys[i] }
    
    /**
     *记录键盘按下的键
    **/    
    var recordPress=function(eve){
        eve=cg.core.getEventObj(eve);
        var keyName=k[eve.keyCode];
        pressed_keys[keyName]=true;    
        if(keydown_callbacks[keyName]){
            for(var i=0,len=keydown_callbacks[keyName].length;i<len;i++){
                keydown_callbacks[keyName][i]();
                
            }
        
        }
        if(keydown_callbacks["allKeys"]){
            for(var i=0,len=keydown_callbacks["allKeys"].length;i<len;i++){
                keydown_callbacks["allKeys"][i]();
                
            }
        }
        if(preventDefault_keys[keyName]){
            cg.core.preventDefault(eve);
        }
    }
    /**
     *记录键盘松开的键
    **/    
    var recordUp=function(eve){
        eve=cg.core.getEventObj(eve);
        var keyName=k[eve.keyCode];
        pressed_keys[keyName]=false;
        if(keyup_callbacks[keyName]){
            for(var i=0,len=keyup_callbacks[keyName].length;i
登录后复制

以上是HTML5游戏框架cnGameJS开发实录-外部输入模块篇的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1674
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
HTML 中的表格边框 HTML 中的表格边框 Sep 04, 2024 pm 04:49 PM

HTML 表格边框指南。在这里,我们以 HTML 中的表格边框为例,讨论定义表格边框的多种方法。

HTML 中的嵌套表 HTML 中的嵌套表 Sep 04, 2024 pm 04:49 PM

这是 HTML 中嵌套表的指南。这里我们讨论如何在表中创建表以及相应的示例。

HTML 左边距 HTML 左边距 Sep 04, 2024 pm 04:48 PM

HTML 左边距指南。在这里,我们讨论 HTML margin-left 的简要概述及其示例及其代码实现。

HTML 表格布局 HTML 表格布局 Sep 04, 2024 pm 04:54 PM

HTML 表格布局指南。在这里,我们详细讨论 HTML 表格布局的值以及示例和输出。

HTML 输入占位符 HTML 输入占位符 Sep 04, 2024 pm 04:54 PM

HTML 输入占位符指南。在这里,我们讨论 HTML 输入占位符的示例以及代码和输出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在这里我们还分别讨论了 HTML 有序列表和类型的介绍以及它们的示例

HTML onclick 按钮 HTML onclick 按钮 Sep 04, 2024 pm 04:49 PM

HTML onclick 按钮指南。这里我们分别讨论它们的介绍、工作原理、示例以及各个事件中的onclick事件。

在 HTML 中移动文本 在 HTML 中移动文本 Sep 04, 2024 pm 04:45 PM

HTML 中的文本移动指南。在这里我们讨论一下marquee标签如何使用语法和实现示例。

See all articles