I am trying to make a timer for my game that counts down from a number, let's call it 100. I am following the cocos2d best practices, and therefore I am not using a NSTimer. What I am looking to do is that every second, I want to numbers of this timer to change. I could probably find a way to do it using a spritesheet with all of the numbers from 100-0, but I know there is a way to do it using just the numbers 0-9 and their pictures.
This is the code that I am using, with the corresponding -(void)
[self schedule: #selector(tick:)];
[self schedule: #selector(tick2:) interval:1];
All in all, I would like to know how to make it count down from 100, but also to know how to make those ticks decrease the value by 1 every second.
Initialize an integer variable that will keep your countdown value:
int count = 100;
You will want to keep a label (CCLabelBMFont etc) to display this count value. I recommend Glyph Designer (or Hierro if you want something free) to generate the 0 to 9 cocos2D-compatible font bitmaps, which you can then use in your CCLabelBMFont:
CCLabelBMFont* countLabel = [CCLabelBMFont labelWithString:#"0" fntFile:#"myFont.fnt"];
Next, schedule a single tick function that will fire every second:
[self schedule: #selector(tick:) interval:1];
This tick function decrements count by 1 each time it is called. Also, add the condition that if count has reached 0, it will unschedule itself:
-void tick:(ccTime) dt
{
count --; // decrement count by 1 each time this function is called
if (count == 0)
[self unschedule: #selector(tick:)];
}
And finally, in your main update loop (or even in the tick function itself after you decrement your count), you can update and redraw this label with the latest value each time:
[countLabel setString:[NSString stringWithFormat:#"%i", count]];
All the best.
Related
I have a project in Sprite Kit and I am trying to make it so that a timer gradually decreases. For example if the timer float variable is set at 3.0, this would gradually decrease and be at 0, 3 seconds later. With the way that updates work in sprite kit its a horrible mess trying to get an integer to gradually decrease.
For example:
time+=1;
If I was to put this in an update void, it would increment extremely quickly and differently depending on frames and so forth. Is there a way I can Increment or Decrement a value at a steady rate no despite the fps in Sprite Kit?
You'd be better off getting the current time with each update and comparing it to some initial time to determine when 3 seconds pass.
Declare an ivar in your SKScene subclass:
#implementation MyScene {
NSDate* _timestamp;
}
When your timer starts:
_timestamp = [NSDate timeIntervalSinceReferenceDate];
Check your timer in your update pass:
- (void)update:(NSTimeInterval)currentTime {
if(_timestamp != nil && currentTime - _timestamp.timeIntervalSinceReferenceDate >= 3.0) {
// Perform your timer event
}
// Other updates
}
I have a game where you bounce on platforms. I want the score to increase by 1 every time you bounce on a platform. However, it keeps increasing by some random number every time (like 10).
In Game.h I have:
int ScoreNumber;
IBOutlet UILabel *ScoreLabel;
-(void)Score;
...
In Game.m I have:
-(void)Score {
ScoreNumber = ScoreNumber +1.0;
ScoreLabel.text = [NSString stringWithFormat:#"%i", ScoreNumber];
}
-(void)PlatformMoving {
if (CGRectIntersectsRect(Bird.frame, Platform1.frame)) {
[self Score];
}
}
...
This should count by 1 every time but it counts by more than 1
If you place a breakpoint in your (void)Score method you'll probably see that its being called multiple times per bounce because the rectangles probably overlap for multiple frames. You could place a check inside the (void)PlatformMoving method to see if the last test failed before calling Score again. This would ensure that Score is never called on 2 consecutive frames and should prevent scoring any more than one point per bounce.
I create six (6) UIImageView's and add them to the view. I then create a timer running at 0.01 second intervals and incrementing the number by a set amount. Every so often the numbers just stop changing. Below is a sample of the code I'm running to better show what I'm doing.
NSTimer *newTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(numberTimerFired:) userInfo:nil repeats:YES]];
[newTimer fire];
// Assume that I've created six (6) UIImageView's and stored them in an array called digitImageViewArray (the right most UIImageView would be index 5)
- (void)numberTimerFired:(NSTimer *)newTimer
{
// self.currentNumber is the NSInteger property that is incremented each repetition
int tempScore = self.currentNumber;
int currentDigit = 5;
do {
int digit = tempScore % 10;
tempScore /= 10;
[[self.digitImageViewArray objectAtIndex:currentDigit] setImage:[self.numberImageArray objectAtIndex:digit]];
currentDigit--;
} while (tempScore !=0);
self.currentNumber += 133; // 133 can be any number to increment by
}
I have other conditions setup to stop the timer when the number reaches the final number. As I said, as this number goes up, whether the final number is 999,999 or 50,000 it just freezes intermittently as it rises. Any help would be greatly appreciated!
I also checked the Profile and watch CPU / memory usage. It's not even breaking 35% CPU and the memory usage is very insignificant. I've tried several fixes, such as adjusting the time interval the NSTimer runs at. However, if I leave the screen after it runs and come backā¦ it runs smoothly with no glitching.
I'm using a custom UISlider. I save the value after user input using slider.value. After a while, I need to restore the position of the slide to its saved value using [slider setValue:savedValue].
But I noticed some discrepancies between the position at save time and the position after restoration.
After a while I found out that if the user moves the thumb very quickly, it goes further than the actual value (Some kind of momentum/inertia effect). How can I make sure that one value corresponds to one thumb position?
Assuming you're catching UIControlEventTouchUpInside to dictate 'finished', use UIControlEventEditingDidEnd instead.
Failing that, you could key-value observe value, at each change cancelling future saves and, if tracking is false, scheduling a new for 0.5 seconds from now. E.g.
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(storeValue) object:nil];
if(!slider.tracking)
{
[self performSelector:#selector(storeValue) withObject:nil afterDelay:0.5];
}
(or explicitly store whether a save is scheduled if you find any performance problem with that, I guess, but don't overcomplicate it unless you have to)
Are you treating the value as an integer?
Because it (the UISlider object) stores a float, treating it as an integer can cause this behaviour..
Perhaps re-set it in the action where you process the change, I've found this necessary before once or twice..
Eg (this hooked up to the sliders (value changed) controlEvent....
-(IBAction) sliderMoved:(id)sender{
UISlider *sld = (UISlider *)sender;
CGFloat val = sld.value;
val += 0.49; /// rounder...
int result = (int) val;
[sld setValue:(CGFLoat)result animated:YES];
///// etc process entry...
}
This kind of treatment turns the slider into a multi-position "switch", it snaps to whole number values.. You could be doing it with fabsf(...) function if you want to remain in the float territory too...
Little explication: I have an app with 5 textfields, i already got the code to make the avaerage of them. Using floates and giving a variable to each textfield.so, the adding of the value of all the textfield /5 (divided per 5)
My problem is that when a textfield is leaved emptty, its not goona be /5, if user fill in only 4 cells it will be/4 and so on.
Question: how to divide the adding of cells depending in how many cells have content?
I was tryng with textfield.text.length > 0 in an if. But i dont get it
Thanks, hope i was clear.
You could check each textfield and see if the text is NULL or blank (#"")
Use an int to keep track of the number of textfields that have a value.
For example:
int counter = 0;
float total = 0.0;
if([textfield1.text length] > 0)
{
counter++;
float thisValue = [textfield1.text floatValue];
total = total + thisValue;
}
repeat this for all 5 textfields and then divide your total by the counter variable.
You could include the if statement in a loop if you are going to vary the number of text fields or to reduce the amount of coding you do.
EDIT I have changed my answer based on the good suggestions of other to use text.length
try to count the number of used textfields by increasing a number every time you read out a textfield that has valid text in it and divide the result by that number. (logically the "number" should be initialized as 0)