2

I'm coding the game "Simon", and I'm having some trouble figuring out how to use runnables and handlers. This is for the part of the game where the colors light up in a sequence pattern, right before the player has to press the buttons.

This is the code I have so far:

Handler handler = new Handler();
Runnable g = new Runnable() {
    @Override
    public void run() {
        setBtnBackGround(oldColors[0], 10, mButtons[0]);
    }
};
Runnable r = new Runnable() {
    @Override
    public void run() {
        setBtnBackGround(oldColors[1], 10, mButtons[1]);
    }
};
Runnable y = new Runnable() {
    @Override
    public void run() {
        setBtnBackGround(oldColors[2], 10, mButtons[2]);
    }
};
Runnable b = new Runnable() {
    @Override
    public void run() {
        setBtnBackGround(oldColors[3], 10, mButtons[3]);
    }
};

Also:

for (int i = 0; i < mGame.getLevel(); i++) {
    int color = colors.get(i);
    setBtnBackGround(newColors[color], 10, mButtons[color]);
    if (color == 0) {
        handler.postDelayed(g, 1000);
    } else if (color == 1) {
        handler.postDelayed(r, 1000);
    } else if (color == 2) {
        handler.postDelayed(b, 1000);
    } else {
        handler.postDelayed(y, 1000);   
    }
}

The buttons all light up at the same time, since, I guess, they're all placed one after another on the "message sequence"? How would I use runnables/handles to space apart the light-ups?

Thanks so much guys!

bluexmarker
  • 373
  • 1
  • 4
  • 13

2 Answers2

1

The reason all the buttons light up at the same time is because you for loop runs through all values of i without waiting at all in between.

So it effectively calls

//start loop
//i = 0
handler.postDelayed(g, 1000);
...
//i = 1
handler.postDelayed(r, 1000);
...
//i = mGame.getLevel()-1
handler.postDelayed(b, 1000);
//end loop

all at the same time.

There's no queue per-se, so you need to make it yourself by incrementing the delay depending on which i you're at. Try this:

int LIGHT_DURATION = 1000;

for (int i = 0; i < mGame.getLevel(); i++) {
    int color = colors.get(i);
    int delay = LIGHT_DURATION*i;
    setBtnBackGround(newColors[color], 10, mButtons[color]);
    if (color == 0) {
        handler.postDelayed(g, delay);
    } else if (color == 1) {
        handler.postDelayed(r, delay);
    } else if (color == 2) {
        handler.postDelayed(b, delay);
    } else {
        handler.postDelayed(y, delay);   
    }
}

I'm not sure what the parameters of setBtnBackGround(newColors[color], 10, mButtons[color]); mean/are but the way I'd do it, with the code I added above is as follows:

  1. Add all the delayed handlers with the above for loop, passing the colour
  2. In each handler set all buttons back to default and the selected colour button to the correct colour
roarster
  • 4,058
  • 2
  • 25
  • 38
0

I got it to work by creating a runnable for each unlit color and each lit color, so I had 8 runnables total with 1 handler. Then, as roarster suggested, I created a delay based on the iteration, like this:

for (int i = 0; i < mGame.getLevel(); i++) {
    int color = colors.get(i);


    if (color == 0) {
        handler.postDelayed(newG, (long) ((0.1+i)*1000));
        handler.postDelayed(oldG, (long) ((0.9+i)*1000));
    } else if (color == 1) {
        handler.postDelayed(newR, (long) ((0.1+i)*1000));
        handler.postDelayed(oldR, (long) ((0.9+i)*1000));
    } else if (color == 2) {
        handler.postDelayed(newY, (long) ((0.1+i)*1000));
        handler.postDelayed(oldY, (long) ((0.9+i)*1000));
    } else {
        handler.postDelayed(newB, (long) ((0.1+i)*1000));
        handler.postDelayed(oldB, (long) ((0.9+i)*1000));   
    }
}
bluexmarker
  • 373
  • 1
  • 4
  • 13