Cocos2D - iPhone - Sprite won't show when created in an instance method - ios

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!

Related

Clearing a SKScene to start a new game

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];

How to check if two moving objects collide each other IOS

I have a problem in UIDynamicBehavior. I am using UIPushBehavior for moving two objects in different directions.
I want to print "Collide" when they get collide.
Which method gets called when two moving objects collide?
UIDynamicAnimator
UICollisionBehavior
UIPushBehavior
First, you have to make the class you want to handle the collision implement UICollisionBehaviorDelegate, so in your header file you would change your interface line to #interface MyClassHere : MySuperclass <UICollisionBehaviorDelegate>. For your collision behavior, when you are initializing it use collisionBehavior.delegate = self; then add the method - (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item1 withItem:(id<UIDynamicItem>)item2 atPoint:(CGPoint)p which will be called every time a collision happens between two items that are part of UICollisionBehavior.
So your method would look like:
- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item1 withItem:(id<UIDynamicItem>)item2 atPoint:(CGPoint)p{
NSLog(#"Collide");
}
Hope it helps :)

Initializing a child CCNode onto a parent CCNode

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"];
}

SpriteKit SKAction doesn't work after removing and readding a node

Been banging my head against this for a day now, and I really have no idea what's going on.
I have a very simple setup: an SKNode (let's call it base) which contains another SKNode (sub-base), as well as several SKShapeNode objects. At some time, I move one of the SKShapeNode objects (using removeFromParent) from the base node to the sub-base node. Then I apply an SKAction, which moves the node to some arbitrary position.
Except, that SKAction does not work when the SKShapeNode has been removed and added to the sub-base object. If I remove it from the sub-base, and put it back in the base, SKActions once again work.
I am completely stumped. Is there some property that gets set on a node when it's added to another node, which isn't getting properly reset when I remove it...? I can't imagine this is something that should be happening.
Any ideas would be so very welcome.
Update:
Here's some code that I can produce it with. This function is inside a subclass of SKNode. The class adds a bunch of SKShapeNodes, and it also has this other SKNode called testNode, so, without further ado:
-(void) removeThenAdd
{
[someNode removeFromParent];
[self.testNode addChild:someNode];
SKAction* action = [SKAction moveTo:CGPointMake(200, 200) duration:1];
SKNode* thatSameNodeJustAdded = [self.testNode.children objectAtIndex:0];
[thatSameNodeJustAdded runAction:action];
}
Another update!
I just found that, if I add an SKAction to the node whilst it is sitting inside the testNode, then after that remove it from the testNode and add it back to its original parent, the action is then activated. Like, what am I missing here? This must be some kind of designed behaviour I'm just not using right..
This seems to be a bug in the SDK. I had this issue because I wanted to make advanced sprites (sprites with children, emitters, etc) in their own scene files so that I could selectively load and then add them to my scenes. I came up with a work around using NSKeyedArchiver and NSKeyedUnarchiver -- Convert the node (or parent node) to data, and then back again, and the new object is ready to be added to a scene, if it's an emitter, or has child nodes that are emitters they will all be copied through and properly re-added. Here is the extension I made for swift, works like a charm:
extension SKNode {
// Pulling a node from one scene and putting it into another causes some problems with broken emitters :(
// Fix here is to archive and then unarchive the node before returning
class func nodeFromScene(nodeName : String, sceneFileName : String) -> SKNode? {
if let scene = SKScene(fileNamed: sceneFileName), node = scene.childNodeWithName(nodeName) {
let archive = NSKeyedArchiver.archivedDataWithRootObject(node)
return NSKeyedUnarchiver.unarchiveObjectWithData(archive) as? SKNode
}
return nil
}
}
I was also seeing this issue occur in my SpriteKit project. In my case I was removing a node from an SKScene file I'd created in the Scene Editor and adding it to my current scene.
Following some debugging it showed that the actions weren't being run at all. And upon further investigation I discovered why... it seems that when you add a node to the scene in this manner the isPaused property is set to true. Whether this is intentional or a bug I can't find out for sure.
From the docs:
https://developer.apple.com/documentation/spritekit/sknode/1483113-ispaused
isPaused
If the value is true, the node (and all of its descendants) are skipped when a scene processes actions.
So in order to "fix" this issue, before running any SKActions on the node, unpause the node:
node.isPaused = false

Animating CCSprite not working?

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

Resources