Reuse Cocos2d CocosNodes - iphone

I am trying to create a cool score counter in my iPhone game, where I created the digits 0 to 9 in photoshop and I want to update the score every second.
What I am doing now is the following:
In my init I load all the digit sprites into an array, so that the array has 10 items.
I created a method which breaks down the current score (eg. 2000) into single digits and gets the sprites from the array and after that adds them to a parent CocosNode* object.
Every second I get the parent CocosNode by it's tag and replace it with the new parent object.
Currently I am already running into problems with this, because the score 2000 uses the 0-digit three times and I cannot re-use sprites.
- (CocosNode*) createScoreString:(int) score
{
NSLog(#"Creating score string : %d", score);
NSString* scoreString = [NSString stringWithFormat:#"%d", score];
int xAxes = 0;
CocosNode* parentNode = [[Sprite alloc] init];
for (NSInteger index = 0; index < [scoreString length]; index++)
{
NSRange range;
range.length = 1;
range.location = index;
NSString* digit = [scoreString substringWithRange:range];
Sprite* digitSpriteOriginal = [self.digitArray objectAtIndex:[digit intValue]];
Sprite* digitSprite = [digitSpriteOriginal copy];
[digitSprite setPosition:cpv(xAxes, 0)];
xAxes += [digitSprite contentSize].width - 10;
[parentNode addChild:digitSprite];
}
return parentNode;
}
Am I handling this the right way within cocos2d or is there some standard functionality for this? Also, if this is correct, how can I 'reuse' the sprites?

I believe that you want to use the LabelAtlas class, you'll only need to provide a compatible bitmap (like one the fps counter uses).

Related

How can I increase numeric part of property name in for() loop?

I've 10 pan recognisers and want to assign to class property.
How can I increase numeric part of property name in for() loop?
for (int i=0; i < [_myArray count]; i++)
{
myClassInstance.recognizer = pangesture + i ?? // doesn't work of course. but how??
}
It's not fantastic form — definitely follow Caleb's comments wherever possible — but if you're really backed into a corner:
for(int i = 0; i < [_myArray count]; i++)
{
NSString *nameOfProperty = [NSString stringWithFormat:#"pangesture%d", i];
UIPanGestureRecognizer *recogniser = [self valueForKey:nameOfProperty];
}
That's using key-value coding; IBOutlets are necessarily KVC compliant or there'd be no way to load the NIB.
I've 10 pan recognisers and want to assign to class property. How can
I increase numeric part of property name in for() loop?
I'm not sure I understand your question fully, but assuming that you've got 10 gesture recognizers named g1 through g10 that you want to assign to 10 objects using a loop, a good approach would be to put those 10 gesture recognizers into an array and then make the assignment using the current index:
NSArray *recognizers = #[g1, g2, g3, g4, g5, g6, g7, g8, g9, g10];
if ([recognizers count < [_myArray count]) {
NSLog("Houston, we have a problem! Not enough gesture recognizers to go around.");
}
for (int i=0; i < [_myArray count]; i++)
{
myClassInstance.recognizer = recognizers[i]; // note the fancy "new" array access syntax!
}
If you're not allocating the gesture recognizers individually, then you can just create one each time though the loop:
for (MyClass *instance in _myArray) {
instance.recognizer = [[UIGestureRecognizer alloc] init...];
}

Appending UIButton with NSString

I have this code to show some text in a textview from SQLite DB..
NSMutableString *combined = [NSMutableString string];
for(NSUInteger idx = 0; idx < [delegate.allSelectedVerseEnglish count]; idx++) {
[combined appendFormat:#" %d %#", idx, [delegate.allSelectedVerseEnglish objectAtIndex:idx]];
}
self.multiPageView.text = combined;
self.multiPageView.font = [UIFont fontWithName:#"Georgia" size:self.fontSize];
delegate.allSelectedVerseEnglish is the NSArray
multiPageView is the UITextView
i put the above loop function to get the Numbers according to the text,for example 1 hello 2 iPhone 3 iPad 4 mac etc etc..i just want UIButton between the text instead of 1 2 3 4 ..for example i want unbutton hello unbutton iPhone etc etc.because i need to make some touch events from it.how to do this?
Thanks in advance.
If you want to place UIButtons between some text in textview, there is no other way but to place it as a separate view just above. So you'll need to add spaces beneath those buttons, the amount of those you should calculate yourself, based on the size of your buttons.
So, if you would like yo see something like this:
Press here [UIButton] or here [Another UIButton],
your text string should look like this
Press here or here ,
So when you add the buttons on those places, it would look just like you wish.
UPDATE
Seems like we need some more code here, so here it is:
First, you'll need to calculate the size of a letter. Let's assume that it is 10 pixels height and 8 pixels.No, let's just call that letterHeight and letterWidth.Let's also assume that you want 64x10 pixels buttons. So, we will need 64/8=8 +2 spaces to out behind that button(2 to make borders around that)
So, here we go
NSMutableString *combined = [NSMutableString string];
int letterHeight = 10;
int letterWidth = 8;
for(NSString *verse in delegate.allSelectedVerseEnglish) {
[combined appendFormat:#" %#",verse];//10 spaces there
//You have to experiment with this, but idea is that your x coordinate is just proportional to the length of the line you are inserting your button in, and y is proportional to number of lines
int xCoordinate = [combined length]*letterWidth%(int)(self.multiPageView.frame.size.width);
int yCoordinate = [combined length]*letterWidth/(int)(self.multiPageView.frame.size.width)*letterHeight;
UIButton *newButton = [[UIButton alloc]initWithFrame:CGRectMake(xCoordinate,yCoordinate,64,10)];
[self.multiPageView addSubview:newButton];
}
self.multiPageView.text = combined;

how can we create scoring in iphone game

I want to create score when a target is hit...
whenever a target is hit
int targetHit=0;
targerhit=targethit+1;
now I want to show that in label....
CCLabel* label2 = [CCLabel labelWithString:#"null" <-----i want to add score herer?and keep changing it ?how can i
fontName:#"Marker Felt"
fontSize:30];
label2.position = ccp(400, 295);
[self addChild:label2];
Suppose you have an integer score and String scoreString associated to a CCLabel scoreLabel. These thre elements must all be attributes of your class (maybe a CCLayer).
Now, if you just want to update the scoreLabel you have to:
//create a range object
NSRange range;
//it starts from the first character(0) and ends at the scoreString length
range.location=0;
range.length = [scoreString length];
//then delete the characters of the string which fall in the range (that means all)
[scoreString deleteCharactersInRange:range];
//then use appendFormat to update the scoreString with the latest score value
[scoreString appendFormat:#"%07d",score];
//therefore update the label
[scoreLabel setString:scoreString];
I didn't use cocos2d yet, but here is some info that i've found.
(void) setString: (NSString *) string
changes the string to render
Warning:
Changing the string is as expensive as creating a new CCLabel.

Determine the CTLine containg specific character

I am developing an Application in which I am using Core Text for layout purpose. I have used CTFrameSetter to draw the text.I have inserted a blank character '\ufffc' in my text. Now what i want is to determine the position of this blank character i.e. its x, y coordinates. I have not been able to find any function to determine the position of any specific character.
I tried using CTLineGetOffsetForStringIndex( CTLineRef line, CFIndex charIndex, CGFloat* secondaryOffset ); for finding the position, but I couldn't fully understand the working of this method.
Can anyone provide me some pointers on this issue?
you can loop all the CTLines of the current CTFrameRef, and for each ctline, get the CTRun and check if that CTRun is yours. simple code
NSArray *lines = (NSArray*)CTFrameGetLines(workFrame);
NSInteger count = [lines count];
CGPoint *origins = (CGPoint*)malloc(count * sizeof(CGPoint));
CTFrameGetLineOrigins(workFrame, CFRangeMake(0, count), origins);
for (int i = 0; i < lines.count; i++) {
CTLineRef line = (CTLineRef)[lines objectAtIndex:i];
CFRange cfRange = CTLineGetStringRange(line);//the string-range
NSArray * runArray = (NSArray *)CTLineGetGlyphRuns(line);
int runIndex = 0;
for (id runObj in runArray) {
CTRunRef run = (CTRunRef)runObj;
CFRange runRange = CTRunGetStringRange(run);
CGFloat xOffset = CTLineGetOffsetForStringIndex(line, runRange.location + runRange.length, NULL);
//checks if the crrun's text is your space
}
}

Loop through labels iPhone SDK

Ok I have 8 labels and I want to loop through them but am having no luck.
This is what I have tried.
for (int i; i = 0; i < 10; i++)
{
double va = [varible1.text doubleValue] + i;
int j = 0 + I
label(j).text= [[NSString alloc]initWithFormat:#"%2.1f", va];
}
This errors out. My labels are named like this label0, label1, label2
Any help would be appreciated.
label(j) is NOT equivalent to label0, label1, etc.
You should create an NSArray of labels, then you can access them with [arrayOfLabels objectAtIndex:j]. If you're not sure what this means, please read the documentation about NSArray...
You should maybe add all your labels to a C array, probably in -viewDidLoad
UILabel* labels[] = { label0, label1, label2, ... };
(not entirely sure about the syntax)
and then access them like
labels[i].text = ...
By the way, I think you're leaking memory here:
labels[i].text = [[NSString alloc]initWithFormat:#"%2.1f", va];
initWithFormat: will return a string with a retain count of 1. labels[i].text will retain that value again. You should release the string after setting the label's text. I'd probably just autorelease it here:
labels[i].text = [[[NSString alloc]initWithFormat:#"%2.1f", va] autorelease];
or use stringWithFormat (which returns an autoreleased string):
labels[i].text = [NSString stringWithFormat:#"%2.1f", va];
for (UILabel *lbl in self.view.subviews)
{
[lbl setFont:[UIFont fontWithName:#"AppleGothic" size:22]];
}
it will change all the labels in your ViewController by just giving tags to labels.
If you cannot or do not want to put your labels in an array, you could iterate through the UIViews using the tag field as an index. You store the index numbers in them (either through IB or programatically) and then get each label using: (UIView *)viewWithTag:(NSInteger)tag.
See below (set theView to the view your labels reside in):
for (int i; i = 0; i < 10; i++)
{
double va = [varible1.text doubleValue] + i;
UILabel * label = [theView viewWithTag: i];
label.text= [[NSString alloc]initWithFormat:#"%2.1f", va];
}