<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【CSON原創】HTML5游戲框架cnGameJS開發實錄(外部輸入模塊篇)

      返回目錄

      1.為什么我們需要外部輸入模塊?

        在游戲中我們常常用到類似這樣的操作:鼠標點擊某位置,玩家對象移動到該位置,或者按鼠標方向鍵,玩家向不同方向移動,等等。這些操作無一不用與外部輸入設備打交道。作為游戲的設計者,我們很需要在任何時候知道鼠標目前的位置,鍵盤的點擊狀況等,從而方便我們對游戲元素加以控制。因此作為一個游戲框架,外部輸入模塊也是必不可少的。

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

        外部輸入模塊主要實現的功能就是動態記錄鼠標相對于canvas的位置,以及記錄鍵盤上哪些鍵是按下的,哪些鍵剛剛松開,并觸發相應的回調函數。

        我們可以通過框架保存的兩個字段獲取鼠標當前在canvas的位置:

       

      var x=cnGame.input.mouseX;
      var y=cnGame.input.mouseY;


        由于canvas下的游戲編程模式是通過一個游戲循環來實現的幀動畫(關于游戲循環請看:HTML5游戲框架cnGameJS開發實錄(游戲循環篇)),因此單純對鍵盤keyup與keydown的綁定,往往并不能達到期望效果,舉個例子,我們如果想在鍵盤按下左鍵時使元素一直向左移動:

       

      cnGame.input.onKeyDown("left",function(){
      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<len;i++){
      keyup_callbacks[keyName][i]();

      }
      }
      if(keyup_callbacks["allKeys"]){
      for(var i=0,len=keyup_callbacks["allKeys"].length;i<len;i++){
      keyup_callbacks["allKeys"][i]();

      }
      }
      if(preventDefault_keys[keyName]){
      cg.core.preventDefault(eve);
      }
      }
      cg.core.bindHandler(window,"keydown",recordPress);
      cg.core.bindHandler(window,"keyup",recordUp);

      /**
      *判斷某個鍵是否按下
      *
      */
      this.isPressed=function(keyName){
      return !!pressed_keys[keyName];
      };
      /**
      *禁止某個鍵按下的默認行為
      *
      */
      this.preventDefault=function(keyName){
      if(cg.core.isArray(keyName)){
      for(var i=0,len=keyName.length;i<len;i++){
      arguments.callee.call(this,keyName[i]);
      }
      }
      else{
      preventDefault_keys[keyName]=true;
      }
      }
      /**
      *綁定鍵盤按下事件
      *
      */
      this.onKeyDown=function(keyName,handler){
      keyName=keyName||"allKeys";
      if(cg.core.isUndefined(keydown_callbacks[keyName])){
      keydown_callbacks[keyName]=[];
      }
      keydown_callbacks[keyName].push(handler);

      }
      /**
      *綁定鍵盤彈起事件
      *
      */
      this.onKeyUp=function(keyName,handler){
      keyName=keyName||"allKeys";
      if(cg.core.isUndefined(keyup_callbacks[keyName])){
      keyup_callbacks[keyName]=[];
      }
      keyup_callbacks[keyName].push(handler);

      }
      /**
      *清除鍵盤按下事件處理程序
      *
      */
      this.clearDownCallbacks=function(keyName){
      if(keyName){
      keydown_callbacks[keyName]=[];
      }
      else{
      keydown_callbacks={};
      }

      }
      /**
      *清除鍵盤彈起事件處理程序
      *
      */
      this.clearUpCallbacks=function(keyName){
      if(keyName){
      keyup_callbacks[keyName]=[];
      }
      else{
      keyup_callbacks={};
      }

      }
      });
      posted @ 2012-02-14 12:42  Cson  閱讀(1820)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产成人无码免费视频在线| 在线精品自拍亚洲第一区| 久久久久久久久18禁秘| 在线国产精品中文字幕| 国产视频一区二区| 国产精品尤物乱码一区二区| 亚洲欧洲日产国码AV天堂偷窥| 亚洲精品麻豆一区二区| 国产AV大陆精品一区二区三区| 国产精品视频一区二区亚瑟| 四虎影视一区二区精品| 色熟妇人妻久久中文字幕| 激情综合五月网| 欧美日韩一线| 国产精品尤物午夜福利| 熟女一区二区中文在线| 国产日女人视频在线观看| 日韩一区在线中文字幕| 国产麻豆成人精品av| 国产mv在线天堂mv免费观看| 亚洲欧美综合精品成人导航| 国产欧美精品一区二区三区-老狼 真实单亲乱l仑对白视频 | 放荡的少妇2欧美版| 一区二区三区四区五区自拍| 日韩精品亚洲专在线电影| 濮阳县| 欧美综合区自拍亚洲综合绿色| 久久乐国产精品亚洲综合| 亚洲成人四虎在线播放| 日本熟妇人妻一区二区三区| 在线成人精品国产区免费| 综合欧美视频一区二区三区| 菠萝菠萝蜜午夜视频在线播放观看| 精品中文人妻在线不卡| 下面一进一出好爽视频| 亚洲人成电影在线天堂色| 日本丰满护士bbw| 亚洲国产av剧一区二区三区| 久久精品av国产一区二区| 日本一本无道码日韩精品| 精品夜恋影院亚洲欧洲|