Scoring stops and resets game - ios

I'm making a game where you are supposed to move an image between other image without colliding. Everything worked fine until I added coins to the game. When the image hits a coin, it's supposed to make a sound (which it does) and add +1 to the coin label. The problem is, when I add the code to make the coinlabel get +1, the image that I'm moving will stop and go back to starting position. The same thing happened to me when I was using an NSTimer (because users playing the app had time on finish the level.) But everytime the label counted a number, the game stopped again and the ball was put back to the starting position.
Here is some code for the game.
-(IBAction)left {
goLeft = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(goLeft) userInfo:nil repeats:YES];
if (goLeft == nil) {
goLeft = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(goLeft) userInfo:nil repeats:YES];
}
}
-(IBAction)stopLeft {
[goLeft invalidate]; goLeft = nil;
}
-(void)goLeft {
image.center = CGPointMake(image.center.x -3.5, image.center.y);
{
//Coins
if (CGRectIntersectsRect(image.frame, coin1.frame)) {
coin1.hidden = YES;
[self getcoins];
}
-(void)getcoins{
//Here i have a avaudioplayer playing a noise (dont need to show that as that works fine)
//Then the +1 to label
coinlabel.text = [[NSNumber numberWithInt:([coinlabel.text intValue] + 1)] stringValue];
// And when i add this and the image hits the coin, the image goes back to the starting position. But i want it not to stop or anything, but continue.
}
The left action is connected to touch down. And stopleft is connected to touch up inside. Hope you understand and thanks for any help.

Related

UILabel updating incorrectly with NSTimer

I am showing a count down timer using UILabel and NSTimer -
-(void)a_Method
{
[coolTimeLbl setNeedsDisplay];
coolTime = 5; // it is an int
coolingTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(cooling) userInfo:nil repeats:YES]; // NSTimer
}
-(void)cooling
{
if (coolTime>0)
{
coolTime = coolTime-1;
NSLog(#" coolTime----%#",coolTime);
coolTimeLbl.text =[NSString stringWithFormat:#"%d",coolTime];
NSLog(#" coolTimeLbl----%#",coolTimeLbl.text);
}
else
{
[coolingTimer invalidate];
coolingTimer = nil;
}
}
The first time everything works fine and I am getting coolTimeLbl.text as - 4 3 2 1 0
But the second time when I call aMethod, coolTimeLbl is not getting updated properly - it is like 3 2 0 etc (some weird behavior)
However both NSLogs (coolTime & coolTimeLbl) print perfectly all the times and values.
Why does this happen? I tried many ways like NSNotification etc.
Please help me to fix this.
If you're calling a_Method more than once before coolingTimer invalidates itself, the timer will tick more than once.
You should add some boolean like ;
BOOL isTimerValid;
in a_Method,
if(!isTimerValid)
{
isTimerValid = YES;
coolingTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(cooling) userInfo:nil repeats:YES]; // NSTimer
}
in cooling,
else
{
isTimerValid = NO;
....
}
Had the same issue in one of my viewControllers and another one was working OK with same NSTimer code. Looked at about 20 SO threads to get it solved. No luck. In my case
myLabel.opaque = false
solved it.
Don't ask me why.

iOS blink flashlight with UISwitch, UISlider and NSTimer

I'm making a flashlight app and i'm in problem
how to blink the flashlight with uiswitch, uislder and nstimer.
i found something on web but I can't understand it.
I already done how to turn on the flashlight(LED)
but I can't find how to blink it.
Also, I can't use NSTimer well.
self.blinkTimer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:#selector(timerUpdate) userInfo:nil repeats:YES];
I found this code in Stack Overflow but #selector(timerUpdate) and scheduledTimerWithTimeInterval:0.3 is problem.
my plans are
uislider's value --> scheduledTimerWithTimeInterval:(uislder's value)
uiswitch --> start blinking the flashlight.
- (void)toggleFlashlight
{
}
- (IBAction)blink:(UISwitch *)sender {
}
- (IBAction)blinkspeed:(UISlider *)sender {
int progress = lroundf(sender.value);
self.blinksliderlabel.text = [NSString stringWithFormat:#"%dms", progress];
}
Sadly, I don't know.. how to insert the code there...
Please help :(

When a button passes through a specified Y value, all the other buttons falling also disappear with it

I'm trying to make multiple buttons fall down the screen all at once, at different speeds. But when I have my if statement check if it passed through the value, all the other buttons disappear with it. I'm also incrementing the score to go -1 each time a button passes through the Y value. Any help is appreciated, thanks.
- (void)b1Fall
{
b1.center = CGPointMake(b1.center.x, b1.center.y+6);
if (b1.center.y >= 506) {
[self updateScore];
b1.center = CGPointMake(44, 11);
}
}
- (void)b2Fall
{
b2.center = CGPointMake(b2.center.x, b2.center.y+7);
if (b2.center.y >= 506) {
[self updateScore];
b2.center = CGPointMake(160, 11);
}
}
- (void)b3Fall
{
b3.center = CGPointMake(b3.center.x, b3.center.y+8);
if (b3.center.y >= 506) {
[self updateScore];
b3.center = CGPointMake(276, 11);
}
}
- (void)updateScore
{
healthLabel.text = [NSString stringWithFormat:#"%d", [healthLabel.text intValue]-1];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// REMOVE AFTER TESTING
b1Timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(b1Fall) userInfo:nil repeats:true];
b2Timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(b2Fall) userInfo:nil repeats:true];
b2Timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(b3Fall) userInfo:nil repeats:true];
}
A few things:
1.) Put these animations in viewDidAppear instead of viewDidLoad - you want the animation to begin when the user is actually looking at the buttons, not when the view is loaded into memory, where the user may not be able to see it (viewDidLoad).
2.) Don't use NSTimer for animations, use this:
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
}
completion:^(BOOL finished){
// loop your animation here.
}];
3.) If you want to make a game, I don't recommend using this approach. All animations using UIKit are going to perform on the main thread and block the user flow. What you want is a framework like Cocos2D where the animations are doing in the GPU and ASYNC game logic is readily supported. UIKit isn't a good choice for game development in general.

NSTimer not firing when it should

I have a table view that is broken up into alphabetic sections. I am displaying an animated banner in a UIImage View in the footer of each section, and need to determine which image is displayed when the UIImage View is clicked. I set a timer right before I make the call to startAnimating. The timer is to fire every 5 seconds, at the same rate that the animation changes, but the timer is firing much faster. Sometimes it will fire 2 or 3 times within that 5 second period. Here is the code where I start the timer and the animation:
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger) section {
...
imgAdBar = [[bannerView alloc]initWithFrame:CGRectMake(footer.frame.origin.x,footer.frame.origin.y,footer.frame.size.width,footer.frame.size.height)];
imgAdBar.image=[UIImage imageNamed:[NSString stringWithFormat:#"%#", [animationArray objectAtIndex:0]]];
[imgAdBar saveBannerArray:animationArray];
[imgAdBar setUserInteractionEnabled:YES];
imgAdBar.animationImages = images;
imgAdBar.animationDuration=[images count]*5;
imgAdBar.animationRepeatCount=0;
timerCount=0;
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(timerRunning:) userInfo:nil repeats:YES];
[imgAdBar startAnimating];
[footer addSubview:imgAdBar];
footer.backgroundColor = [UIColor clearColor];
}
return footer;
}
And here is the selector:
-(void)timerRunning:(NSTimer*)theTimer
{
NSLog(#"timerCount=%d",timerCount);
imgAdBar.timerCount=timerCount;
if (timerCount==numAnimationImages) {
timerCount=0;
}
NSLog(#"currentImage=%#",[animationArray objectAtIndex:timerCount]);
timerCount++;
}
I plan to use that timer to index into my image array so that I can tell which is displayed. Anyone have any idea why it's not firing when it should? Thanks for any assistance!
You have to use NSTimer as an property ...
Since viewForFooterInSection is called several times for many sections you have to invalidate before you reinitialize it or you have to check for null following is the code..
Invalidate:
NSTimer *timer; // declare in ViewDidLoad
// code in viewForFooterInSection
[timer invalidate];
timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
target: self
selector: #selector(handleTimer:)
userInfo: nil
repeats: YES];
Check for nil
if (timer == nil) {
timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
target: self
selector: #selector(handleTimer:)
userInfo: nil
repeats: YES];
}
Hope it should help..
Declare an NSTimer as property in your header file
#propterty (nonatomic, retain) NSTimer *someTimer;
In the line where you fire the timer
someTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(timerRunning:) userInfo:nil repeats:YES];
Don't forget to release it in -(void)viewDidUnload
[someTimer release];
Since you do not use the value of timerCount unless there is a click, you do not need to update it on timer: it is sufficient to store the time at the moment when you start animation. Knowing that each image is shown for five seconds, you can calculate the index of the image being displayed by taking the difference, in seconds, between the time of the click and the time when you started the animation, dividing it by five, and taking the remainder of the division by the total number of images.
Say you have ten images, each displaying for five seconds in a loop. Let's also say that the animation has started at 08:15:51. Now let's say there's a click at 08:19:23, or 212 seconds after the animation has started. After dividing by five you get 42; taking the remainder of the division by ten, you get 2. Therefore, you know that the user has clicked on the third image in the animation loop (as usual, indexes start from zero).

How to record sound in iOS?

I am currently wondering how you can record audio in iOS. I know many people comprehend this as recording from a microphone and playing it back, but this is not the case. I am making a sound recording application for the iPad. In the GarageBand application that Apple has on the iOS App store, you can record your own sounds and play them back from within the application. If this doesn't make sense, think of it as this:
All I am trying to do is make a button that plays a sound. I need to know how to record that button sound and be able to play the sound sequence back. So if I pressed "record" then buttons "A, F, J" and then "stop" then press "play" it would playback what it recorded (sounds A F and J).
I am trying to make it so that you can record and make your own music within this app. Sorry if this is confusing, please help me to the best of your abilities. Thanks!
You could create two NSMutableArrays and empty them when you hit record. You would also need an NSTimer and an int. So in header:
NSTimer *recordTimer;
NSTimer *playTimer;
int incrementation;
NSMutableArray *timeHit;
NSMutableArray *noteHit;
Include in your header all of the voids and IBActions and such below.
Make your sound buttons all have different, unique tags.
and then in your main file:
-(void)viewDidLoad {
timeHit = [[NSMutableArray alloc] init];
noteHit = [[NSMutableArray alloc] init];
}
-(IBAction)record {
recordTimer = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:#selector(timerSelector) userInfo:nil repeats:YES];
[timeHit removeAllObjects];
[noteHit removeAllObjects];
incrementation = 0;
}
-(void)timerSelector {
incrementation += 1;
}
-(IBAction)hitSoundButton:(id)sender {
int note = [sender tag];
int time = incrementation;
[timeHit addObject:[NSNumber numberWithInt:time]];
[noteHit addObject:[NSNumber numberWithInt:note]];
[self playNote:note];
}
-(IBAction)stop {
if ([recordTimer isRunning]) {
[recordTimer invalidate];
} else if ([playTimer isRunning]) {
[playTimer invalidate];
}
}
-(IBAction)playSounds {
playTimer = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:#selector(playback) userInfo:nil repeats:YES];
incrementation = 0;
}
-(void)playback {
incrementation += 1;
if ([timeHit containsObject:[NSNumber numberWithInt:incrementation]]) {
int index = [timeHit indexOfObject:[NSNumber numberWithInt:incrementation]];
int note = [[noteHit objectAtIndex:index] intValue];
[self playNote:note];
}
}
-(void)playNote:(int)note {
//These notes would correspond to the tags of the buttons they are played by.
if (note == 1) {
//Play your first note
} else if (note == 2) {
//Play second note
} else if (note == 3) {
//And so on
} else if (note == 4) {
//etc.
}
}
With a little bit of fiddling (I doubt this code is perfect), you might get this to work. Like you will probably want the play/record buttons to be disabled once you hit one of them. Good luck!

Resources