Reputation:
I am creating a quiz game and I can't figure out the best way to implement UIButtons that disappear one by one at 3 second intervals. I can get the first UIButton to disappear after 3 seconds, but the subsequent UIButtons take considerably longer.
I believe the problem is that my code becomes more inefficient with each UIButton I make disappear. The following method is what I call with a repeating NSInterval to make each subsequent UIButton disappear:
-(void)hideButton { int buttonNum;
while(buttonNum != -1)
{
buttonNum = rand() % 5;
if(buttonNum != [quiz correctNumber])
{
if(buttonNum == 0 && [buttonOne isEnabled] == YES)
{
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[buttonOne setEnabled:NO];
[buttonOne setAlpha:0.0];
[UIView commitAnimations];
}
else if(buttonNum == 1 && [buttonTwo isEnabled] == YES)
{
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[buttonTwo setEnabled:NO];
[buttonTwo setAlpha:0.0];
[UIView commitAnimations];
}
else if(buttonNum == 2 && [buttonThree isEnabled] == YES)
{
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[buttonThree setEnabled:NO];
[buttonThree setAlpha:0.0];
[UIView commitAnimations];
}
else if(buttonNum == 3 && [buttonFour isEnabled] == YES)
{
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[buttonFour setEnabled:NO];
[buttonFour setAlpha:0.0];
[UIView commitAnimations];
}
else if(buttonNum == 4 && [buttonFive isEnabled] == YES)
{
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[buttonFive setEnabled:NO];
[buttonFive setAlpha:0.0];
[UIView commitAnimations];
}
buttonNum = -1;
}
}
}
Upvotes: 1
Views: 2613
Reputation: 6373
Good answer from Alex Martelli. Another possibility would be to replace the separate objects buttonOne, buttonTwo, etc. with a single array of buttons, button[5] and replace your big loop with this:
do {
buttonNum = rand() % 5;
} while (buttonNum == [quiz correctNumber] || ![buttons[buttonNum] isEnabled]);
[buttons[buttonNum] setEnabled:NO]; // Doesn't need to be in animation block
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[buttons[buttonNum] setAlpha:0.0];
[UIView commitAnimations];
*** Dan, below: Something to randomize the order of the button hiding and make sure the correct answer was not hidden would still be needed, but otherwise that's a great solution too.
Upvotes: 1
Reputation: 5394
Another way of making the buttons disappear at set intervals is to use the
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
method. To use this, you would define a function to make a button disappear when it is called:
-(void)hideButton:(UIButton *)button{
button.enabled = NO;
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[button setAlpha:0.0];
[UIView commitAnimations];
}
Then you would spit out those delayed selectors in a loop like this:
for(int i=0; i<numButtons; i++){
[self performSelector:@selector(mySelector:) withObject:buttons[i] afterDelay:3*i+3]
}
Upvotes: 1
Reputation: 882103
When you have only, say, 2 buttons left, since you still generate a random number between 0 and 4, you only have a 20% chance of actually making one more button disappear -- 20% of the time you'll do nothing because the random number matches the correct one, and 60% of the time under those conditions you'll do nothing because it matches an already-disappeared button.
I suggest you keep an array initially populated with references the 4 buttons that may actually disappear (don't bother putting the correct-number one there as you'll never disappear it anyway). In your function, generate a random number that's between 0 and N-1 when you have N buttons left in that array, so you can disappear the appropriate button with effective and concise code -- then (if the button that disappeared was not the last one in the array) swap it with the last one and decrement N by one. Of course when N is 1 there's no need for the random number either.
Upvotes: 3