Home > Article > Web Front-end > HTML5 game framework cnGameJS development record - external input module
1. Why do we need external input modules?
We often use operations like this in games: click the mouse on a certain position, and the player object moves to that position, or press the mouse direction keys, and the player moves in different directions. ,etc. All of these operations involve dealing with external input devices. As game designers, we need to know the current position of the mouse, the click status of the keyboard, etc. at any time, so that we can control the game elements conveniently. Therefore, as a gameframework, external input modules are also essential.
#2. What functions are provided and how to use them?
The main function of the external input module is to dynamically record the position of the mouse relative to canvas, and record which keys on the keyboard are pressed and which The key has just been released and the corresponding callback function is triggered.
We can get the current position of the mouse on the canvas through the two fields saved by the frame:
var x=cnGame.input.mouseX; var y=cnGame.input.mouseY;
Since the game programming mode under canvas is Frame animation is realized through a game loop (for game loop, please see: HTML5 game framework cnGameJS development record (game loop)), Therefore, simply binding keyboard keyup and keydown often cannot achieve the desired effect, for example, if we want to make the element move to the left when the left button is pressed on the keyboard:
cnGame.input.onKeyDown("left",(){ player.move(-10); })
We will find that this method does not work well. Programming model for frame animation. Since when we press the left arrow key on the keyboard, its callback function will continue to trigger, so the triggering frequency cannot be consistent with the frequency of your frame animation (either too fast or too slow, depending on your frame frequency), so a better choice is to determine whether the left button is pressed every time the frame is updated. If it is pressed, move the game element to a certain position to the left, so that the game element becomes part of the frame animation. With each frame Updated:
/*每次帧更新调用的函数*/ var update=function(){ cnGame.input.isPressed("left",function(){player.move(-10);}) }
3. Code implementation
First look at how to keep the mouse on the canvas s position. The position of the mouse relative to the canvas is actually the difference between the position of the mouse relative to the page and the position of the canvas. As mentioned in the previous HTML5 game framework cnGameJS development record (core function module), in the initialization function of the framework, we have obtained the position of the canvas on the page through getCanvasPos, so the position of the mouse relative to the canvas can be calculated as follows:
/** *记录鼠标在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; }
Let’s look at how to record keyboard input later. We need an array to save the name-value pair of each key (key name and key code), and some objects to save the corresponding press of each key. and the release callback function, and the last object holds the key names that need to disable the default behavior. (Disabling keyboard default behaviors is necessary in game development to prevent players from triggering unnecessary browser default behaviors when manipulating game objects, such as scroll bar scrolling, etc.).
The first step is to create a dictionary of key names and key codes:
/** *键盘按键编码和键名 **/ 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] }
It’s a bit long, but it’s actually not very technical. It just makes it easier for us to know what the key name of a certain code is in the future. For example, if we press the left button, the process is: get the keyboard code of the left button -> get the key name in the dictionary -> get the handler that was also saved by the key name in the object through the key name, and execute it .
The code for the keyboard binding handler is as follows:
/** *记录键盘按下的键 **/ 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); } }
There can be multiple handlers for each key, so the object that saves the handler here saves an array. In addition, it should be noted that the pressed keys are saved through the pressed_keys array (pressed_keys[keyName]=true;), in order to facilitate the consistent parameter update in the frame update mentioned before (you can pass isPressed(keyName) in each update ) to determine whether a key is pressed).
Finally, attach all the source code of the input module:
/** * *输入记录模块 * **/ 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;iThe above is the detailed content of HTML5 game framework cnGameJS development record - external input module. For more information, please follow other related articles on the PHP Chinese website!