同时键盘input(对angular线游戏移动)

我正在Node上angular色需要对angular移动的2D游戏。 这是一个纯粹在Node环境中自上而下的基于文本的游戏(没有浏览器,所以我没有很好的keydown / keyup事件)。

我正在使用按键库来读取用户input,但是我不知道如何一次捕获两个键来引起对angular线移动(例如向下箭头和向右箭头)。 这里是我现在的水平和垂直运动的代码:

game = new Game() game.print() keypress(process.stdin) process.stdin.setRawMode(true) process.stdin.resume() process.stdin.on('keypress', (ch, key) -> return unless key return process.stdin.pause() if key.ctrl and key.name is 'c' player = game.player switch key.name when 'up' if key.shift then player.turnUp() else player.moveUp() when 'right' if key.shift then player.turnRight() else player.moveRight() when 'down' if key.shift then player.turnDown() else player.moveDown() when 'left' if key.shift then player.turnLeft() else player.moveLeft() when 'enter' player.repeatMove() when 'b' player.placeBlock() game.update() game.print() ) 

这是一个基于回合的游戏,目前游戏的运行循环是在用户input上进行的。 相反,我认为我需要做的是基于间隔的游戏更新,并跟踪两个最近的按键事件和它们之间的时间。

有没有更强大的方法?

这里是我个人的键盘pipe理器实现:

这很容易理解。 我有一个对象,它描述了我的键盘状态。 任何改变我发送一个事件。

 tools.KeyboardController.keyPressed = function(e) { var evtobj = window.event? event : e; var key = evtobj.keyCode; //don't need to change anything if it's already pressed if(tools.KeyboardController.keyStatus[key] === true) return; //we store the key in an object which describe the keyboard status tools.KeyboardController.keyStatus[key] = true; //send an event to signal the touch is pressed EventManager.fire("tools.KeyboardController.keyPressed."+key); } tools.KeyboardController.keyReleased = function(e) { var evtobj = window.event? event : e; var key = evtobj.keyCode; //if key is not already realese, noting to do if(tools.KeyboardController.keyStatus[key] === false) return; //set the key as not pushed tools.KeyboardController.keyStatus[key] = false; //send an event to signal the touch is released EventManager.fire("tools.KeyboardController.keyReleased."+key); } tools.KeyboardController.keyStatus = {}; document.onkeydown = tools.KeyboardController.keyPressed; document.onkeyup = tools.KeyboardController.keyReleased; 

我结束了build立一个键盘模块,报告何时按下同时按键。 它build立在按键库之上。

每按一次键,键盘模块就会检查过去100ms内按下的键,并将其报告为单个键事件。 每40毫秒最多发一次事件,以节省时间收集组合键。 缺点是单键input现在有40ms的延迟。 这是input如何在terminal中工作的结果。

 EventEmitter = require('events').EventEmitter keypress = require('keypress') _ = require('underscore') # This module allows for reading simultaneous key events in the terminal. module.exports = class Keyboard extends EventEmitter _keyTimes: {} constructor: -> keypress(process.stdin) process.stdin.setRawMode(true) process.stdin.resume() @_emitKeyStatus = _.throttle(@_emitKeyStatus, 40, leading: false) process.stdin.on('keypress', (ch, key) => @_processKey(key)) # Batch-emits any keys recently pressed. _emitKeyStatus: -> currentTime = @_tuple2time(process.hrtime()) millisecond = 1000000 keys = {} for own keyName, time of @_keyTimes if currentTime - time < 100 * millisecond keys[keyName] = true @emit('keypress', keys) _tuple2time: (tuple) -> (tuple[0] * 1e9) + tuple[1] _processKey: (key) -> return unless key return @emit('quit') if key.ctrl and key.name is 'c' time = @_tuple2time(process.hrtime()) # Treat ctrl, shift and meta as distinct keys. @_keyTimes.shift = time if key.shift @_keyTimes.ctrl = time if key.ctrl @_keyTimes.meta = time if key.meta @_keyTimes[key.name] = time @_emitKeyStatus() 
 checkInput: function(){ if (this.isPlayerOne == false) { if (myInput.isKeyDown(Input.KEY_UP)) { if (this.y > 0) { this.y = this.y - 10; } } else if (myInput.isKeyDown(Input.KEY_DOWN)) { // x,y are taken from the left corner if (this.y < game_height - this.height) this.y = this.y + 10; } } else { if (myInput.isKeyDown(65)) { // 'A' if (this.y > 0) { this.y = this.y - 10; } } else if (myInput.isKeyDown(90)) { // 'Z' // x,y are taken from the left corner if (this.y < game_height - this.height) this.y = this.y + 10; } } }