I am working with SpriteBuilder and Cocos2d to build a simple game, and I want to display an error message inside an if statement.
My problem is trying to initialize the CCNode I created in SpriteBuilder to show up on-screen.
I tried creating a CCNode layer and just creating all the objects via SpriteBuilder, but wasn't exactly sure how I was supposed to get that to show up on-screen as what I tried did not work correctly. I tried just using [self addChild:errorLayer] in the if statement and it crashed my app with the error message Argument must be non-nil, so I set up a breakpoint and errorLayer is nil, but I'm not sure how to make it non-nil.
I also tried creating a CCNode programmatically, but when the if-statement was run it didn't display anything on-screen. Here is the code I tried:
CCNode *errorLayer = [[CCNode alloc] init];
[errorLayer setContentSize:CGSizeMake(50, 100)];
[errorLayer setColor:[CCColor redColor]];
[self addChild:errorLayer];
Could anyone give me some tips on getting this to work? Thanks.
MainScene, which is the scene that the above code is called in, is initialized in AppController like this
- (CCScene*) startScene
{
return [CCBReader loadAsScene:#"MainScene"];
}
Related
I Have a very long view controller.m which I'm trying to split into separate files to keep it organised.
I know I can create separate .m .h files and separate them but in doing so I am ending up in loops (which I Understand since the MapController.m is initialising the viewcontroller again causing viewDidLoad to be triggered and repeat.
I have a Map I want to create in my MapController.m
-(void)setMapSettings{
NSLog(#"test");
viewController = [[ViewController alloc] init];
SKMapView *mapView = [[SKMapView alloc] initWithFrame:CGRectMake( 0.0f, 0.0f, CGRectGetWidth(viewController.view.frame), CGRectGetHeight(viewController.view.frame) )];
}
I want to add the above SKMapView to a UIView called mapViewContainer in my viewController.h
ViewController.m:
- (void)viewDidLoad {
mapsViewController = [[MapController alloc] init];
[mapsViewController setMapSettings];
}
Doing this creates a loop resulting in a crash. I know the answer is probably dead simple and I'm just being stupid, but I've spent hours finding a solution and I can't figure it out. Any idea's how I'm suppose to be able to do the above without looping, and without initialising the map views I require all in the ViewController.m?
You say that you are splitting the view controller by taking out code from it, but as far as I understand this has resulted in creating a second viewcontroller (either this, or "MapController" isn't the right naming).
Anyways, as you already mentioned the crash is definitely caused by that alloc/init loop: you should reengineer your code to have just one of the two objects instantiating the other.
(please bear in mind that if you are doing that to access one object from the other, you're doing it wrong: alloc/init creates a new instance of that class every time it is called, it does not give you a pointer to an existing one)
After my game ends I have a button called play again but when it runs it throws and error saying Attemped to add a SKNode which already has a parent. My question is can I reset or dealloc the SKScene so that it is like a fresh slate, like the app was never run?
Assuming the code is being executed in your scene I think what you want is this..
MyScene *newScene = [[MyScene alloc]initWithSize:self.size];
[self.view presentScene:newScene];
Where MyScene is SKScene subclass.
Hopefully that is what you were looking for.
You can use [self removeAllChildren]; in your SKScene to remove all children nodes.
Other objects like arrays, strings, etc... you will have to deal with on a one to one basis.
You can check if a node already has a parent before adding by doing this:
if(myNode.parent == nil)
[self addChild:myNode];
So in my project, I call an instance method called "-(void)fire" in the class "Survival.m":
-(void)fire {
NSLog(#"Firing");
CCSprite *sprite = [CCSprite spriteWithFile:#"bullet.png"];
sprite.position = player.position;
NSLog(#"%#",NSStringFromCGPoint(player.position));
[self addChild:sprite z:100];
}
When I do this, the sprite doesn't show on the screen.
The method is being called from another layer but since it logs "Firing" every time I tap the button, it's not the problem.
I am using a TMXTiledMap as well if that could cause any problems.
Please help, thanks!
EDIT---------
I can create sprites in the other layer, HUDLayer but not in the Survival layer which contains the player and the tiled map. If I create a sprite in the "init" method, it works correctly but If i do it in the method "fire" it doesn't work. The method "fire" is being called from the HUDLayer but I still now the method is being called since I see in the log that it says "Firing"
Could it be that:
1. The sprite is being created out of sight?
2. The sprite is not being created?
3. The sprite is not added to the correct parent?
Any suggestions?
to add a sprite in cocos2d do something like this
CCNode *parent = [self getChildByTag:kTagParentNode];
[parent addChild:sprite];
if that doesnt fix it, make sure the point where you are adding it is on the screen and try changing the z value to see if that helps
EDIT
add this under where you import files
enum {
kTagParentNode = 1,
};
Thanks Everybody, Solved it in some mysterious way. Thanks for the help anyway. I think I declared the layer in a wrong way.
Have a nice day!
I am creating a sprite like this in my init method (mySprite is declared in the .h):
mySprite = [CCSprite spriteWithFile:#"Image1.png"];
[mySprite setPosition:ccp(100, 300)];
[self addChild:mySprite z:1 tag:1];
Then in my other method, I try to animate it like so but it doesn't seem to animate at all, I also know that the method that this is in is getting called because I NSLogged it. Anyway here is how I try to animate mySprite:
CCSequence *moveSequence = [CCSequence actions:[CCMoveTo actionWithDuration:5 position:ccp(120, 400)],[CCMoveTo actionWithDuration:4 position:ccp(100, 300)], nil];
[mySprite runAction:[CCRepeatForever actionWithAction:moveSequence]];
Any ideas why this might be happening?
Thanks!
At first glance this part of the code seems right, so perhaps you would need to show more of your overall program so that we can examine what happens between your init function and your other method being called.
A couple things out of the blue:
make sure to call retain on your sprite so that it does not get removed summarily until you are done with it
what is "self" exactly here, is it a cocos layer? Is the layer added to the scene properly (ie, are you seeing the sprite being displayed, even if it does not move)?
I would also look to see if anything in the scene graph might happen between the "init" call and that second method of yours, in which you execute the animation code. Is there a StopAllActions somewhere? A removeFromParent or removeAllChildren, perhaps?
Cheers
I'm new to iPhone dev and need some help with adding subViews.
I have a reusable object that I made that is stored in a separate .h .m and xib file.
I would like to use this object in my main project's view controller. I have included the header and the assignment of the object generates no errors. I am able to load the object into my main project but can only do things with it inside my viewDidLoad method. I intend to have a few of these objects on my screen and am looking fora solution that is more robust then just hard wiring up multiple copies of the shape object.
As soon as I try to access the object outside of the viewDidLoad it produces a variable unknown error - first use in this function.
Here is my viewDidLoad method:
shapeViewController *shapeView = [[shapeViewController alloc] initWithNibName:#"shapeViewController" bundle:nil];
[self.view addSubview: shapeView.view];
// This is the problem line
// This code works changes the display on the shape object
[shapeView updateDisplay:#"123456"];
---- but the same code outside of the viewDidLoad generates the error.
So to sum up, everything works except when I try to access the shapeView object in the rest of the methods.
Thanks in advance
You need to declare the shapeView instance in your interface, not just inside one function. Then the code in the function becomes just an initialization.
So, in your .h file, inside the #interface you write the declaration:
shapeViewController *shapeView;
And in your viewDidLoad, you will initialize what you declared before:
shapeView = [[shapeViewController alloc] initWithNibName:#"shapeViewController" bundle:nil];
[self.view addSubview:shapeView.view];
Now you can use shapeView in your entire class.