Cocos2d CCSprite Class get the name of the image file - iphone

I can initialize or create a new CCSprite object using the following code:
NSString *fileName = [[imagesPath objectAtIndex:i] lastPathComponent];
CCSprite *sprite = [CCSprite spriteWithFile:fileName];
Now, is there anyway to later find out the name of the image file used for the particular CCSprite object?
UPDATE 1:
userData property looks interesting!

No. CCSprite is not retaining the filename.
But like you noticed, you can hang whatever you want off the userData property -- make sure you manage its lifetime properly. Other options are to use subclassing or composition with CCSprite and your other game classes so that you can keep track of additional data.

If you just need filename, you can use this:
GameSprite *spriteLogo = [GameSprite spriteWithFile:#"Logo.png"];
[spriteLogo setUserObject:#"Logo.png"];
And when you want to retrieve the filename, use this:
NSLog(#"%#", sprite.userObject);

Related

AVAudioPlayer volume from variable

I'm trying to change the volume of a sound effect via a variable. I'm using AVAudioPlayer and calling the variable to set volume, however when I run the app I get no sound at all, regardless of the variable setting. (.1-1.0) However if I set the number from within the AvAudioPlayer block (player.volume = .5;) then it responds as it should. Any ideas what I'm doing wrong?
Example of my code:
#interface
#property (nonatomic) float setVolume;
#implementation
#synthesize setVolume;
float setVolume = .5;
-(void)countdown
{
//play sound
NSString *musicFilePath = [[NSBundle mainBundle] pathForResource:#"Countdown_beep" ofType:#"wav"];
NSURL *musicURL = [[NSURL alloc] initFileURLWithPath:musicFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:nil];
player.volume = setVolume;
[player play];
Thanks. :)
EDIT:
I fixed the problem by removing the declaration from the header file and creating the ivar within the implementation.
This line makes no sense and is irrelevant to your program:
float setVolume = .5;
You are already synthesizing a property/ivar called setVolume. This isn't it. So by default your property setVolume is zero and you are doing nothing to change that, so the volume is ending up as zero and no sound is happening.
To set the value of the property, set the value of the property. :) For example, you could say self.setVolume = .5. You could do that earlier in the countdown method, for example, or in some other method (one of the points of a property is that all methods of this object can see it).
Now, another issue with your code is that your property name begins with "set". This is probably a bad idea. If I were you, I'd pick another name. Names of the form "setX" are best used only as the name of a setter method for an instance variable / property X.

getting of a menuitemfont in cocos2d

i have a ccmenuitemfont and its contained inside a ccsprite. .
the touch event is assigned to menuitemfont.. i need to get the reference of the ccsprite which contains the menuitemfont on ccmenuitemfont click... that is i need to get the reference of the parent sprite.. how to implement? any ideas ? the code i used is as follows..
CCSprite *ballSprite=[CCSprite spriteWithFile:imageName];
[ballSprite setTag:randomNumber];
CCMenuItem *labelButton=[CCMenuItemFont itemFromString:[NSString stringWithFormat:#"%d",randomNumber]target:self selector:#selector(clickedBallLabel :)];
[labelButton setTag:randomNumber];
CCMenu *ball=[CCMenu menuWithItems:labelButton, nil];
[ball setPosition:ccp([ballSprite boundingBox].size.width/2, [ballSprite boundingBox].size.height/2)];
[ballSprite addChild:ball];
[self addChild:ballSprite];
[ballSprite setPosition:randomStartPoint];
id move = [CCMoveTo actionWithDuration:5 position:ccp(randomX, -30)];
[ballSprite runAction:move];
in my point of view , there is a logic problem in you program,you want your labelbutton have a recation right? when your touch it,so why you need a reference to parent with the button?but if there is a must for sure ,you need a spritesheet like this :
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:#"scene1atlas.plist"];
spriteBatchNode = [CCSpriteBatchNode batchNodeWithFile:#"scene1atlas.png"];
then you can add your obj into the batchnode,after that you can use [obj parent] get the parent reference
i'm not sure i know what your meaning,when the button been touched,the ballsprite should be changed?if so,you can just change the ballsprite directly for another new sprite,of course,the better way is the sprites should be into one batchnode as much as possible, otherwise,if your ballsprite is a spritesheet ,then use the method i've told before

How to point to specific CCSprite without passing it to the method?

This is pretty simple question, but I'm having really hard time with it.
I have made a method which takes int variable. With it, it would need to use it to do action with CCSprite.
For example I call it with this: [_hud hideThisActionLed:2]; and it should then hide CCSprite named actionLed2.
I can't pass the actual CCSprite to the method, because I call it from another class which don't have access to that particular sprite.
I can make the sprite name with this: [NSString stringWithFormat:#"actionLed%d", actionLedNumber], but can't come up with a way to use that to point to that specified CCSprite.
Here's how I declared the sprites in hud class:
actionLed1 = [CCSprite spriteWithFrameName:#"actionLed1.png" setScale:TRUE resetAnchor:TRUE];
[actionLed1 setOpacity:0];
[self addChild: actionLed1 z:11 tag:1];
That x4 for all 4 leds.
This depends on how can access the different leds.
If they are properties inside your class, then you can access them like this:
NSString *actionLedName = [NSString stringWithFormat:#"actionLed%d", actionLedNumber];
CCSprite *actionLed = [self valueForKey:actionLedName];
If they are stored in an array, then you can access them like this:
CCSprite *actionLed = [self.actionLeds objectAtIndex:actionLedNumber];
If you have set up a tag for each actionLed when adding it, then you can access them like this:
CCSprite *actionLed = [self getChildByTag:actionLedNumber];
When you add the CCSprite objects to your layer, use the withTag option. Then you can reference the sprites by the tag number which is the number you pass in to the hideThisActionLed method.
[_hud addChild:ledSprite withTag:1];
[_hud addChild:ledSprite2 withTag:2];
etc...
-(void)hideThisActionLed:(int)ledNum {
CCSprite *theSprite = [_hud getChildByTag:ledNum];
... hide the sprite ...

How to change sprite image with array of images cocos2d?

I am learning Cocos2d and building an application where i have sprite at one end and I need to through it on the other side and with the same I am removing the sprite from the screen and after some time, I am displaying the same.
Now I have a folder of images in my application and I need to load different images each time in random order from the same folder and maintain a log that these images do not repeat again and again. I am able to load images from the folder with :
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundleRoot error:nil];
NSArray *onlyJPGs = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self ENDSWITH '.jpg'"]];
Now how would I call this array and display different images each time and also maintain a log that images don't get repeat. I have already went through links like this and this but in vail. Any clue will be really very helpful. Thank you for the help in advance.
The best way to do this is by creating a spriteSheet. first of all you can get http://zwoptexapp.com/ , its free and you can create your spritesheet for using with cocos (on the exporter make sure you select cocos2d to create the proper plist)
You want to pack all your image in 1 big texture so you can add it to your project with the plist (zwoptex will create both for you)
then you can load your texture with
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"your_plist"];
switching textures is slow operation, so having all the images in the same texture will boost the openGL performance, after you've done that changing the texture for a sprite is very easy
[yourSprite setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"FRAME_NAME"]];
where FRAME_NAME is the name of the frame in the plist (you can see it by selecting the plist inside xcode.
to cycle in a random way without repeating images...
(i'll write some pseudocode directly in here, let me do inits inside class declaration and inline implementations :) )
//WARNING THIS IS PSEUDO CODE :)
#interface Randomizer {
//an array of NSStrings containing all you images names
NSMutableArray *allImagesFrameNames = [NSMutableArray arrayWithCapacity:NUM_FRAMES];
CCSprite *sprite = alloc init
}
-(void) resetAllFrames {
[allImagesFrameNames removeAllobjects];
[allImagesFrameName addObject:#"FIRST_IMAGE"];
[allImagesFrameName addObject:#"SECOND_IMAGE"]; //add all your images
}
#end
And to display a random frame:
-(void) display a randomImage {
//if the array is empty, all images are already been randomly displayed, so we reset the array
if([allImagesFrameName count] == 0)
[self resetAllFrames];
//we choose a random index
int randomIndex = arc4random %[allImagesFrameName count];
//we get the frame name at that index
NSString *imageFrameName = [allImagesFrameNames objectAtIndex:randomIndex];
//and we display the frame
[sprite setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:imageFrameName]];
[allImagesFrameNames removeObjectAtIndex:randomIndex];
}

problem while displaying image in imageview

i create a view based project named myclass.
and i add another UIviewcontroller subclass to it, named as webdata.
In the webdataviewcontroller.m i get image from the webserver.
I need to display this image on imageview in myclassViewController.m from webdataViewController.m
for this my code in webdataViewController.m is
docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
imagepath = [NSString stringWithFormat:#"%#/image.png",docDir];
logopath = [NSString stringWithFormat:#"%#/logo.png",docDir];
myclassViewController *obj = [[myclassViewController alloc]init];
obj.homeimage.image = [UIImage imageWithContentsOfFile:imagepath];
but image is not displayed,i try to print image in console
NSLog(#"image to display %#",obj.homeimage.image);
NSLog(#"image to display %#",[UIImage imageWithContentsOfFile:imagepath]);
but i get like this
image to display (null)
image to display <UIImage: 0x6f614b0>
why i get null for obj.homeimage.image,i did n't get can any one please help me.
Thank u in adavance.
(Let me add comment if question is not understandable)
Are you sure that obj.homeimage is not nil? If it is nil then obj.homeimage.image = ... will result to setting image property to nil object, that is "nothing".
Why don't you give us the code for myclassViewController ?
Also you have a lot of mistakes in capitalization, etc. It makes it hard to read your code and it's messy.
myClassViewController should be MyClassViewController
webdataViewController should be WebDataViewController
You should camel case variable names
homeimage should be homeImage
imagepath should be imagePath
You said you subclassed myclassViewController, I think by that you meant you added it as a subview. If so when you execute the code:
myclassViewController *obj = [[myclassViewController alloc]init];
you are creating a NEW myclassViewController, not referencing the parent view controller. You need a pointer to the the instance of the myclassViewController that added webdataViewController as a subview, and add the image to it's property. Also I'm guessing here lies your problem, you are creating a new empty instance of myclassViewController therefore you have not initialized your ivars. (Unless you did so in your -init method, but I would doubt that). So you alloc-ed and init-ed a new myclassViewController but none of it's variables are initialized so you are just messaging nil objects probably. Which is why your code isn't crashing yet still not responding. Once again this is a guess, but it probably is the problem.
I can edit with more information if you give the code for myclassViewController.