同时键盘输入(对角线游戏运动)

时间:2014-03-22 23:48:26

标签: javascript node.js input coffeescript 2d-games

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

我正在使用keypress库来读取用户输入,但我不知道如何一次捕获两个键以引起对角线移动(例如向下箭头和向右箭头)。这是我目前用于水平和垂直移动的代码:

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()
)

这是一款回合制游戏,目前游戏的运行循环是根据用户输入进行的。相反,我认为我需要做的是进行基于区间的游戏更新,并跟踪最近的两个按键事件以及它们之间的时间。

有更强大的方法吗?

3 个答案:

答案 0 :(得分:1)

以下是键盘管理器的个人实现:

这很容易理解。我有一个描述我的键盘状态的对象。如果有任何变化,我会发送一个活动。

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;

答案 1 :(得分:0)

我最终构建了一个键盘模块,用于报告何时按下同时键。它建立在keypress库之上。

每按一次键,键盘模块会检查过去100ms内按下的键,并将其作为单个键事件报告。它被限制为每40ms最多发出一次事件,以便有时间收集组合键。缺点是单键输入现在有40ms的延迟。这是输入在终端中如何工作的结果。

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()

答案 2 :(得分:0)

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