passing value from one scene to another - iphone

I've looked it up and most of the information is on making a singleton class. I just want to pass one value to my helloworldlayer.m from my menuscreen.m. What is the easy way to do this.
- (void) changeScenePlay
{
CCScene *testscene = [HelloWorldLayer scene];
testscene.number = 1;
[[CCDirector sharedDirector] replaceScene:testscene];
}
One of the methods i have tried is something like this, but this isnt working for me either.
how do i access a variable in a scene and change it.

Use variable member in HelloWorld layer class.
#interface HelloWorldLayer: CCLayer
{
int number;
}
#property(nonautomatic, assign) int number;
#end
#implementation HelloWorldLayer
#synthesize number;
+(CCScene *) sceneWithNumber:(int)inNumber
{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [[[HelloWorldLayer alloc] initWithId:inNumber] autorelease];
[scene addChild: layer z:Z_SCENE tag:TAG_SCENE];
return scene;
}
-(id) initWithId:(int)inNumber
{
if( (self=[super init])) {
self.number= inNumber;
}
return self;
}
#end
Call sceneWithNumber instead of scene
- (void) changeScenePlay
{
CCScene *testscene = [HelloWorldLayer sceneWithNumber:1];
[[CCDirector sharedDirector] replaceScene:testscene];
}

create extern variable for this and do as you are doing.

Related

COCOS 2D iPhone - Parsing variable between scenes and using in layer

I have the code of calling a new scene with the variable:
[[CCDirector sharedDirector] replaceScene:[GameScene sceneWithParam:item.tag]];
In GameScene.h
#interface GameScene : CCLayer {
}
+(id) sceneWithParam:(int)nvl;
#end
GameScene.m
+(id) sceneWithParam:(int)nvl
{
CCScene *scene = [CCScene node];
GameScene *layer = [GameScene node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if( (self=[super init] )) {
}
return self;
}
I can't use the variable nil inside if( (self=[super init] )) {
I have already tried to set a property test, and to test = nvl; inside +(id) sceneWithParam:(int)nvl; but it is not possible.
Yes, it's not possible to use dynamic parameters in static methods. If you want to create your object with parameters, you have to create an init method, receiving parameters you need. E.g.:
-(id) initWithYourParam:(id)param
{
if ( (self=[self init]) ) {
self.propertyParam = param;
}
return self;
}

how push scene in cocos2d and pass parameters

i want know if there is a way to push a scene in cocos2d 2.0 and pass some parameter to this pushed scene, for example, i know that to push a scene i use this:
[[CCDirector sharedDirector] pushScene:[HelloWorldLayer scene]];
and this push the helloworldlayer, that is a simple layer:
// HelloWorldLayer
#interface HelloWorldLayer : CCLayer
{
}
// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;
#end
but i want pass to this layer some parameter, so when the layer is pushed i can use the parameter i passed.
how i can do it?
you can do something like +(CCScene *) sceneWithParameter:(ParameterType)parameter; instead of +(CCScene *) scene;
First you will have to create a method to call with the parameter like so
HelloWorldLayer.h
#interface HelloWorldLayer : CCLayer
{
}
+(CCScene *)sceneWithParam:(id)parameter;
#end
HelloWorldLayer.m
#implementation HelloWorldLayer
+(CCScene *)sceneWithParam:(id)parameter
{
[[parameter retain]doSomething];
CCScene * scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if(self = [super init])
{
}
return [super init];
}
// All your methods goes here as usual
#end
Then you push it by calling
[[CCDirector sharedDirector] pushScene:[HelloWorldLayer sceneWithParam:obj]];
Now this might still not be enough, if you need the parameter inside your layer you will need to do the same thing for the layer. Create the initmethod with the method and then pass it further to the layer in the sceneWithParam: method.
Do it through global variable or external object (which is accessible from "pusher" and HelloWorldLayer. Or even you can pass the parameter through userData property of HelloWorldLayer.
Johnathan's and Kreiri's answers work well, but couldn't you also just add properties to your pushed scene and set them? So the code would look something like this (typed in browser, you may have to tweak):
HelloLayer *hello = [HelloLayer scene];
hello.param1 = someValue;
hello.param2 = someOtherValue;
hello.param3 = yetAnotherValue;
[[CCDirector sharedDirector] pushScene: hello];
Of course, in HelloLayer.h, you'd define something like:
#property (strong, nonatomic) NSString *param1;
#property (readwrite) BOOL *param2;
#property (strong, nonatomic) NSNumber *param3;

How to access sprites from a different class

I'm trying to make an app and I am currently trying to separate data into different files.
I will give some code from the main class (ArcherClass) and the player class.
This is the player class:
Player.h______________________
#interface Player:CCLayer{
CCSprite *_head;
}
#property (nonatomic, retain) CCSprite *head;
-(void)setHead:(CCSprite *)head;
+(id)player;
#end
Player.m______________________
#implementation Player
#synthesize head = _head;
+(id)player{
Player *playerSprite = nil;
return playerSprite;
}
-(void)setHead:(CCSprite *)head{
_head = [CCSprite spriteWithFile:#"head.png"];
}
#end
ArcherClass.m______________________
#import "ArcherClass.h"
#import "cocos2d.h"
#import "Player.h"
#implementation ArcherClass
//skip some stuff...
+(id) scene{
CCScene *scene = [CCscene node];
CCLayer* layer = [ArcherClass node];
[scene addChild:layer];
return scene;
}
-(id) init{
if(self = [super init]{
self.isTouchEnabled = YES;
}
Player *player = [[Player alloc]init];
CCSprite *bob = player.head;
bob.position = ccp(250,250);
//There are layers in this class, so this may be a problem
}
I had the app up and working, everything worked previously because everything was local to the ArcherClass. There were no other classes. Now I am trying to make seperate classes for everything, but I am running into problems. How can I fix this?

Pass level time to Congratulations scene cocos2d

Just wondered if someone could quickly give me a hand. Im building a simple puzzle slider game, ive added a timer to the game now and all i want to do is pass the time it took to complete the puzzle over to the congrats scene. Could anyone just have a look at my code see where im going wrong please?
play.h
#import "cocos2d.h"
#import "Box.h"
#interface PlayLayer : CCLayer
{
int timeInt;
int secs;
int mins;
CCLabel *timeLabel;
NSString *TotalTimeString;
}
#property (nonatomic, assign) int timeInt;
#property (nonatomic, assign) int secs;
#property (nonatomic, assign) int mins;
#property (nonatomic, retain) NSString *TotalTimeString;
#end
Play.m
#import "PlayLayer.h"
#import "Congrats.h"
#implementation PlayLayer
#synthesize timeInt;
#synthesize secs;
#synthesize mins;
#synthesize TotalTimeString;
-(id) init{
self = [super init];
TotalTimeString = [NSString stringWithFormat:#"Time: %02d:%02d", mins, secs];
timeLabel = [[CCLabel labelWithString:TotalTimeString dimensions: CGSizeMake(130,27) alignment: UITextAlignmentCenter fontName:#"Marker Felt" fontSize:25.0] retain];
timeLabel.position = ccp(155,430);
[self addChild:timeLabel];
[self schedule: #selector(tick2:) interval:1.0];
return self;
}
-(void) tick2: (id) sender{
timeInt++;
secs = timeInt % 60;
mins = timeInt / 60;
[timeLabel setString: TotalTimeString];
}
-(void) check: (id) sender data: (id) data{
int valueToCheck = 0;
bool breakOut = false;
for (int y=0; y < box.size.height && !breakOut; y++) {
for (int x=0; x < box.size.width && !breakOut; x++) {
Tile *tile = [box objectAtX:x Y:y];
if (tile.check != [box hashOfXY:x y:y]) breakOut = true;
valueToCheck++;
}
}
int totalTiles = box.size.width * box.size.height;
if (valueToCheck == totalTiles){
[[CCDirector sharedDirector] replaceScene:[CCFadeTransition transitionWithDuration:1 scene:[Congrats node]]];
CCScene *scene = [Congrats scene];
scene.TotalTimeTakenWhenDiedString = TotalTimeString;
[[CCDirector sharedDirector] replaceScene:scene];
}
}
#end
Congrats.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "PlayLayer.h"
#interface Congrats : CCLayer {
CCLabel *timeLabel;
NSString *TotalTimeTakenWhenDiedString;
}
#property (nonatomic, assign) NSString *TotalTimeTakenWhenDiedString;
+(id) scene;
#end
Congrats.m
#import "Congrats.h"
#import "DifficultyLevel.h"
#import "PlayLayer.h"
#import "PlayLayerMedium.h"
#import "PlayLayerHard.h"
#import "MainMenu.h"
#implementation Congrats
#synthesize TotalTimeTakenWhenDiedString;
+(id) scene {
// ‘scene’ is an autorelease object.
CCScene *scene = [CCScene node];
// ‘layer’ is an autorelease object.
Congrats *layer = [Congrats node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
// on “init” you need to initialize your instance
-(id) init {
// always call “super” init
// Apple recommends to re-assign “self” with the “super” return value
if( (self=[super init] )) {
timeLabel = [[CCLabel labelWithString: TotalTimeTakenWhenDiedString dimensions: CGSizeMake(130,27) alignment: UITextAlignmentCenter fontName:#"Marker Felt" fontSize:25.0] retain];
timeLabel.position = ccp(155,430);
}
return self;
}
-(void) goToGameplay: (id) sender {
[[CCDirector sharedDirector] replaceScene:[CCFadeTransition transitionWithDuration:1 scene:[MainMenu node]]];
}
}
#end
I was kind of hoping that, that would work. But i keep getting this error "error: request for member 'TotalTimeTakenWhenDiedString' in something not a structure or union"
Anyone help at all?
Cheers
Your problem is here:
CCScene *scene = [Congrats scene];
scene.TotalTimeTakenWhenDiedString = TotalTimeString;
The object scene is of type CCScene and you are trying to access TotalTimeTakenWhenDiedString on it. But that is a property of Congrats, not of CCScene.
Here's a suggestion which might work, by getting the Congrats object out from scene. (Caveat: I'm not familiar with cocos2d, and I only looked it up quickly here. This may be a terrible way to be doing it!)
Change here:
// add layer as a child to scene
[scene addChild:layer z:0 tag:1]; // tag it with 1
and here:
CCScene *scene = [Congrats scene];
Congrats *congrats = (Congrats *)[scene getChildByTag:1]; // get the congrats child object, which we tagged 1
congrats.TotalTimeTakenWhenDiedString = TotalTimeString;
[[CCDirector sharedDirector] replaceScene:scene];
... Why dont you just create a singleton class which you can use as a global object? and access/update it anywhere in the game?

Coco2d - using CCBitmapFontAtlas

i'm trying to create a simple game with COCO2d but no luck so far...
when i'm trying to create a CCBitmapFontAtlas i get a error saying :
"_OBJC_CLASS_$_CCBitmapFontAtlas", referenced from:"
and also :
"'CCBitmapFontAtlas' is deprecated "
here is my header file:
#interface MainMenuScene : CCLayer
{
CCBitmapFontAtlas* startNewGameLabel;
}
(id) scene;
#end
and here is my implementation file :
#import "MainMenuScene.h"
#implementation MainMenuScene
(id) scene
{
CCScene scene = [CCScene node];
CCLayer layer = [MainMenuScene node];
[scene addChild:layer];
return scene;
}
-(id) init
{
if ((self = [super init]))
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
[self setVisible:YES];
startNewGameLabel = [CCBitmapFontAtlas
bitmapFontAtlasWithString:#"New Game"
fntFile:#"bitmapfont.fnt"];
//[CCLabelTTF labelWithString:#"New Game"
// fontName:#"AppleGothic"
// fontSize:48];
CGSize size = [[CCDirector sharedDirector] winSize];
startNewGameLabel.position = CGPointMake(size.width / 2, size.height / 2);
[self addChild:startNewGameLabel];
}
return self;
}
(void) dealloc
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
[super dealloc];
}
#end
I created both .FNT file and .PNG file with heir
You want CCLabelBMFont instead of CCBitmapFontAtlas.
startNewGameLabel = [CCLabelBMFont
labelWithString:#"New Game"
fntFile:#"bitmapfont.fnt"];
Use CCLabelBMFont instead. Will be removed 1.0.1