2015-09-07 2 views
1

Я использую LWJGL для 3D-графики.Java - прием ввода в цикле

Вещь, которую я хочу сделать, - изменить тип рендеринга с «GL_TRIANGLES» на «GL_LINES» нажатием указанной клавиши (например, F1). Из-за высокой частоты кадров нормальной

if(Keyboard.isKeyDown(key)) 
     { 
      //Action 
     } 

будет включать и выключать до 200 раз в течение обычной кнопки. В целом, мне интересно, как эта проблема обычно решается, и как наилучшим образом справиться с ней.

Так, что я придумал это (наверное, очень неэффективно):

//Render class init 
Key F1 = new Key(Keyboard.KEY_F1); 

//Render method 
renderMode = F1.ifPressed(delta); 
if(renderMode) 
{ 
    //GL_LINES render 
} 
else 
{ 
    //GL_TRIANGLES render 
} 

//Key class 
public class Key 
{ 
    int DELAY_TIME = 20; 
    int delay = 0; 
    int key; 
    boolean isActive = false; 
    boolean state = false; 

public Key(int key) 
{ 
    this.key = key; 
} 

public boolean ifPressed(int delta) 
{ 
    if(!isActive) 
    { 
     if(Keyboard.isKeyDown(key)) 
     { 
      isActive = true; 
      state = !state; 
      return state; 
     } 
    } 
    else if(delay <= DELAY_TIME * delta) 
    { 
     delay++; 
    } 
    else if(delay > DELAY_TIME) 
    { 
     delay = 0; 
     isActive = false; 
    } 
    return state; 

ответ

2

Одно общее решение должно иметь список текущих активных действий/нажатых клавиш. Когда запускается событие ввода PRESSED (обычно это выполняется каркасом/ОС) для некоторого ключа, вы проверяете, находится ли этот ключ в списке.

if (list.contains(key)) { 
    // not first time, so fire held 
    onKeyHeld(key); 
} 
else { 
    list.add(key); 
    onKeyPressed(key); 
} 

Когда входное событие RELEASED обжигают, вы делаете следующее:

list.remove(key); 
onKeyReleased(key); 

события мыши сделаны подобным образом.

Лучше все же вы можете заменить эти методы некоторым классом UserAction, чтобы он мог быть привязан к событиям клавиш/мыши. Код изменился бы на что-то вроде:

bind(Key.SPACE, new UserAction("Jump") { 
    public void onActionStart() {} // on key pressed 
    public void onAction() {}  // on key held 
    public void onActionEnd() {} // on key released 
}); 

Я использовал это решение в игровой библиотеке и поэтому могу подтвердить, что оно работает.

+1

Я могу утверждать, что это лучший подход к работе с событиями кнопок. Это также работает для кнопки мыши или геймпада. – glethien

+0

Я до сих пор не могу понять, в чем смысл класса UserAction. Не могли бы вы обновить ответ с помощью некоторой его реализации? – DaSH

+1

Вам не обязательно иметь его, он просто делает код менее загроможденным и более OO. Это также помогает отделить одно действие от другого, поэтому оно может быть связано с событием с ключом или мышью. См. Реализацию здесь: https://github.com/AlmasB/FXGL/blob/master/src/com/almasb/fxgl/event/UserAction.java и https://github.com/AlmasB/FXGL/blob/master /src/com/almasb/fxgl/event/InputManager.java – AlmasB

Смежные вопросы