-1

I am working on a memory based matching puzzle game. For that I need to glow buttons randomly from sequence. I have been googling sample puzzles,games & code snippets since a week or so, yet I was unable to trace out an appropriate sample project or some source to get started.

I am glowing the lights(buttons) by changing its background images(imitation), I have already set the default images for buttons(coloured bulb when in stable state) in story board. I have used NSMutableArray of IBOutletCollection i.e. tapLightButtons. Here is what I tried to get the sequence of lights glowing in a random mode to get the game experience.

-(void)startGlowingLights
{
    [self shuffleValuesInArray:_tapLightButtons];
    [self shuffleValuesInArray:lightArray];
    [self shuffleValuesInArray:_initialButtonImages];
    [self performSelector:@selector(animateButtonSequence) withObject:self afterDelay:0.2];
}

- (void) animateButtonSequence
{
    __block UIButton *tapLight;

    [UIView animateWithDuration:0.15
                          delay:0.0
                        options:UIViewAnimationOptionCurveLinear
                     animations:^{

                         // button flash animation
                     } completion:^(BOOL finished) {
                         if (finished) {
                             if (i < _tapLightButtons.count) {
                                 i++;
                                 [self performSelector:@selector(animateButtonSequence) withObject:self afterDelay:1.0];
                                 tapLight = [self.tapLightButtons objectAtIndex:i-1];
                                 UIImage *glownLight = [UIImage imageNamed:[lightArray objectAtIndex:i-1]];
                                 [tapLight setBackgroundImage:glownLight forState:UIControlStateNormal];
                                 [[TTLMusicPlayer sharedInstance] playGlowLightSound:[[NSBundle mainBundle] pathForResource:@"beep" ofType: @"mp3"]];

                         //Reset the completed glowed button to previous state(off mode)
                                     double delayInSeconds = 1.0;
                                     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
                                     dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                                         if (i != 0 && i < _initialButtonImages.count) {
                                            [tapLight setBackgroundImage:[self.initialButtonImages objectAtIndex:i-1] forState:UIControlStateNormal];
                                         }
                                     });

                             }
                             else {
                                 i = 0;
                             }
                             NSLog(@"i value is %d",i);
                         }
                     }];
}

-(NSMutableArray *)shuffleValuesInArray:(NSMutableArray *)shuffledArray
{
    for (NSInteger x=0;x<[shuffledArray count];x++)
    {
        NSInteger randomNumber = (arc4random() % ([shuffledArray count] - x)) + x;
        [shuffledArray exchangeObjectAtIndex:x withObjectAtIndex:randomNumber];
    }
    return shuffledArray;
}

tapLightButtons is the array which holds puzzled buttons(lights) which glows automatically one after another in random fashion.

lightArray is an array holding all the appropriate colour images(flash to produce glowed affect)

initialButtonImages contains array of all default(initial) images of buttons(off mode lights)

Some how I could partially achieve what I wanted to, surprisingly even after shuffling all arrays, still I see variations in the order because the glowed image should be the corresponding of stable(off mode coloured light) and then after resetting, the stable image should match the one before the light was actually glowed.

Posted the question on game dev site from Stack Exchange as well!!

Game Screen for better understanding

enter image description here

After flashing of coloured light

enter image description here

How to properly glow the buttons randomly from sequence?

Community
  • 1
  • 1
Eshwar Chaitanya
  • 942
  • 2
  • 13
  • 34
  • At times i wonder how come people put whole idea on public forum and since most of them are making it for some client i fail to see breach of NDA – amar May 14 '14 at 05:53
  • @amar "Please provide us with more info so that we can help you better", "What are you trying to do", "Why are you doing this" etc. are the often comments I receive from experts and moderators out here. Any how tq for your comment, I have modified my question in more specific manner, please check now :) – Eshwar Chaitanya May 14 '14 at 06:00
  • I dont think i can give specific solution in short time but a pointer subclass UIButton to hold extra state relevant to your algo and look into reactive cocoa it will help – amar May 14 '14 at 06:05
  • Isn't this just a matter of periodically picking a random number within a range (say, 1-n where n is the number of buttons) and "glowing" the corresponding button? There are about a million questions on SO related to selecting random numbers. – Caleb May 14 '14 at 06:10
  • *randomly from sequence* what does this mean? – Caleb May 14 '14 at 06:15
  • @Caleb From a sequence of available buttons, we have to glow the button one after another, in a random manner – Eshwar Chaitanya May 14 '14 at 06:21

1 Answers1

2

I would do this a different way that leads to simpler code. I created an array of 9 custom buttons in IB and added them to an outlet collection. I subclassed the buttons, and added a flashWithOnTime: method, so the button itself would take care of switching between the normal and highlighted states.

This is the method in the button subclass,

-(void)flashWithOnTime:(CGFloat)onTime {
    [self setHighlighted:YES];
    [self performSelector:@selector(setHighlighted:) withObject:@NO afterDelay:onTime];
}

This is the code in the view controller that starts the sequence (from a button tap). Rather than shuffling, I pick a random index out of an array, and then delete that entry so it can't be picked again. The methods offImageWithSolidColor and onImageWithSolidColor, are just methods I used to create the images.

@interface ViewController ()
@property (strong, nonatomic) IBOutletCollection(RDFlashingButton) NSArray *buttons;
@property (strong,nonatomic) NSArray *indexes;
@property (strong,nonatomic) NSMutableArray *mutableIndexes;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.indexes = @[@0,@1,@2,@3,@4,@5,@6,@7,@8];
    for (RDFlashingButton *aButton in self.buttons) {
        [aButton setBackgroundImage:[self offImageWithSolidColor] forState:UIControlStateNormal];;
        [aButton setBackgroundImage:[self onImageWithSolidColor] forState:UIControlStateHighlighted];
    }
}

-(void)flashRandomly {
    if (self.mutableIndexes.count > 0) {
        int index = arc4random_uniform(self.mutableIndexes.count);
        int value = [self.mutableIndexes[index] intValue];
        RDFlashingButton *aButton = self.buttons[value];
        [aButton flashWithOnTime:0.4];
        [self.mutableIndexes removeObjectAtIndex:index];
        [self performSelector:@selector(flashRandomly) withObject:nil afterDelay:.4];
    }
}

-(IBAction)startFlashing:(id)sender {
    self.mutableIndexes = [self.indexes mutableCopy];
    [self flashRandomly];
}
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • I was able to understand every bit of your answer, thank you so much, but I am unable to understand the reason for crash :"-[UIButton flashWithOnTime:]: unrecognised selector sent to instance 0x97a2bd0" ....also kindly check and confirm whether my implementation [code](http://pastebin.com/rFMamu1m) is right or not, thanks again :) – Eshwar Chaitanya May 15 '14 at 10:22
  • @EshwarChaitanya, You're getting that error because you didn't change the class of some or all of your buttons in IB to TTLFlashingButtons. The error is saying that the flashWithOnTime: message is being sent to a UIButton, not your subclass. Your code implementation looks ok. – rdelmar May 15 '14 at 14:19
  • Thanks a ton, it helped, but the thing is buttons are glowing , but only one time....then it stops, not continuously, although we are removing index for reuse and more over we are adding delay to action :) – Eshwar Chaitanya May 16 '14 at 13:18
  • @EshwarChaitanya, how do you want the glowing to behave? Do you want more than one at a time? Do you want it to be continuous? You didn't give much detail about that in your question. – rdelmar May 16 '14 at 15:11
  • If we are not removing objectAtIndex, then the sequence is continuous and that's what I wanted, thank you so much for the help. But I need to disable the corner lights for 4 lights and 5 lights mode, how to do this. Also my guess is if we place a tag and if the user taps the light of same tag, then he progresses, is that the way? Sorry to trouble you again,thanks :) – Eshwar Chaitanya May 19 '14 at 07:56
  • @EshwarChaitanya, yes tags would be a good way to differentiate among the different buttons. – rdelmar May 19 '14 at 15:10
  • How to glow 4 buttons at a time in sequence and random fashion, thanks and sorry for the trouble :) – Eshwar Chaitanya May 21 '14 at 11:27
  • @EshwarChaitanya, well, if you want to flash 4 at once, you need to pick 4 random numbers and call flashWithOnTime: on each of the buttons at those 4 indexes. – rdelmar May 21 '14 at 15:14
  • Tq, I tried to follow this [link](http://stackoverflow.com/questions/5839881/get-n-random-objects-for-example-4-from-nsarray) ,but the thing is out of 4/5 lights which were picked, I see the glow repetition, also crash saying index 1 out of bounds. But I want the lights to glow at random out of 4/5, and in random fashion as usual. Here is my implementation [code](http://pastebin.com/EEMd050V) ,please help me, thanks :) – Eshwar Chaitanya May 22 '14 at 12:51
  • @EshwarChaitanya, I don't know what you mean by "I want the lights to glow at random out of 4/5". Do you want either 4 or 5 lights (chosen at random) to blink at the same time? When those go off, you want another random group of 4 (or 5) to glow? Do you want this to repeat indefinitely? – rdelmar May 22 '14 at 15:39
  • I solved it, np, but I need a small suggestion from you. I am trying to validate the tap of user through tag, I have been successful. But the problem is 'The sequence should be tracked(stored)' and even if the user delays touch, the validation should be the sequence, but not the current glowed light and the appropriate button tap. Also in pattern mode, the sequence should be stored and if the user misses a bit in tapping the same, then it should be over. How to go about this, thanks :) – Eshwar Chaitanya May 27 '14 at 12:34