tags:

views:

148

answers:

3
+2  Q: 

Time delay problem

+2  A: 

i think you are using the wrong design pattern here.

you should use an Observer pattern for this type of thing.

A polling loop not very efficient, and as you've noticed doesn't really yield the desired results.

I'm not sure what you are using inside your objects to detect if a key is pressed, but if it's a GUI architecture such as Swing or AWT it will be based on the Observer pattern via the use of EventListeners etc.

pstanton
The truth is, I have NO clue about design patterns. I'm still in high school, and decided to embark on an adventure here. But thank you, for the insight...
Brendan
A: 

Please post more information about the GamePadController class that you are using.

More than likely, that same library will offer an "event" API, where a "callback" that you register with a game pad object will be called as soon as the user presses a button. With this kind of setup, the "polling" loop is in the framework, not your application, and it can be much more efficient, because it uses signals from the hardware rather than a busy-wait polling loop.


Okay, I looked at the JInput API, and it is not really event-driven; you have to poll it as you are doing. Does the sound stop looping when you release the button? If so, is your goal to have the sound play just once, and not again until the button is release and pressed again? In that case, you'll need to track the previous button state each time through the loop.

Human response time is about 250 ms (for an old guy like me, anyway). If you are polling every 50 ms, I'd expect the controller to report the button depressed for several iterations of the loop. Can you try something like this:

boolean played = false;
while (true) {
  String sound = null;
  if (controller.isButtonPressed(1)) 
    sound = "hiHat.wav";
  if (controller.isButtonPressed(2)) 
    sound = "crash.wav";
  if (sound != null) {
    if (!played) {
      drum.playSound(sound);
      played = true;
    }
  } else {
    played = false;
  }
  Thread.sleep(50);
}
erickson
Done, i used the Jinput API, so maybe you're correct.
Brendan
i heard a talk recently that stated the human response time was more like 80 ms
pstanton
@pstanton there are numerous applets on the web that allow you to test your reaction time. Because they are more like a video game than a lab experiment, they should be relevant to this topic. The 1/4 second number is also used a lot in traffic safety and accident investigation.
erickson
Ok, thanks for the update. The problem isn't that the sound cuts off, it's that sometimes it plays multiple times (overlapping) and other times, it doesn't play at all...
Brendan
brendan, that's primarily because it's bad design! you should move to the observer pattern or write something that bridges the api you are using to the observer pattern.
pstanton
That's what I'm working on, thank you for your help
Brendan
A: 

Here is a (slightly simplified) Observer-pattern applied to your situation.

The advantage of this design is that when a button is pressed and hold, method 'buttonChanged' will still only be called once, instead of start 'repeating' every 50 ms.

  public static final int BUTTON_01 = 0x00000001;
  public static final int BUTTON_02 = 0x00000002;
  public static final int BUTTON_03 = 0x00000004;
  public static final int BUTTON_04 = 0x00000008; // hex 8  == dec 8  
  public static final int BUTTON_05 = 0x00000010; // hex 10 == dec 16
  public static final int BUTTON_06 = 0x00000020; // hex 20 == dec 32
  public static final int BUTTON_07 = 0x00000040; // hex 40 == dec 64
  public static final int BUTTON_08 = 0x00000080; // etc.
  public static final int BUTTON_09 = 0x00000100;
  public static final int BUTTON_10 = 0x00000200;
  public static final int BUTTON_11 = 0x00000400;
  public static final int BUTTON_12 = 0x00000800;

  private int previousButtons = 0;

  void poll()
  {         
    rockbandDrum.poll();
    handleButtons();
  }

  private void handleButtons()
  {
    boolean[] buttons  = getButtons();
    int pressedButtons = getPressedButtons(buttons);    
    if (pressedButtons != previousButtons)
    {         
      buttonChanged(pressedButtons); // Notify 'listener'.
      previousButtons = pressedButtons;
    }   
  }

  public boolean[] getButtons()
  {   
    // Return all the buttons in a single array. Each button-value is a boolean.

    boolean[] buttons = new boolean[MAX_NUMBER_OF_BUTTONS];
    float value;
    for (int i = 0; i < MAX_NUMBER_OF_BUTTONS-1; i++)
    {
      int index = buttonsIndex[i];
      if (index < 0) { continue; }

      value = comps[index].getPollData();
      buttons[i] = ((value == 0.0f) ? false : true);
    }
    return buttons;
  }

  private int getPressedButtons(boolean[] array)
  {      
    // Mold all pressed buttons into a single number by OR-ing their values.

    int pressedButtons = 0;    
    int i = 1;
    for (boolean isBbuttonPressed : array)
    {
      if (isBbuttonPressed) { pressedButtons |= getOrValue(i); }
      i++;
    }    
    return pressedButtons;    
  }

  private int getOrValue(int btnNumber) // Get a value to 'OR' with.
  {
    int btnValue = 0;    
    switch (btnNumber)
    {
      case 1  : btnValue = BUTTON_01; break;
      case 2  : btnValue = BUTTON_02; break;
      case 3  : btnValue = BUTTON_03; break;
      case 4  : btnValue = BUTTON_04; break;
      case 5  : btnValue = BUTTON_05; break;
      case 6  : btnValue = BUTTON_06; break;
      case 7  : btnValue = BUTTON_07; break;
      case 8  : btnValue = BUTTON_08; break;
      case 9  : btnValue = BUTTON_09; break;
      case 10 : btnValue = BUTTON_10; break;
      case 11 : btnValue = BUTTON_11; break;
      case 12 : btnValue = BUTTON_12; break;
      default : assert false : "Invalid button-number";
    }
    return btnValue;
  }

  public static boolean checkButton(int pressedButtons, int buttonToCheckFor)
  {
    return (pressedButtons & buttonToCheckFor) == buttonToCheckFor;
  }   

  public void buttonChanged(int buttons)
  {
    if (checkButton(buttons, BUTTON_01)
    {
      drum.playSound("hiHat.wav");
    }

    if (checkButton(buttons, BUTTON_02)
    {
      drum.playSound("crash.wav");
    }
  }
John
Thanks for your answer! When I get home I'll try this and tell you if it works. Thanks alot for the effort!
Brendan