Spritebuilder physics - cocos2d-iphone

ive run into some trouble with my spritebuilder project and i cant find a workaround. Im using the flappyfly tutorial to create a game.
In the tutorial there is an Obstacle.ccb in spritebuilder and obstacle.h/m in xcode. The obstacles get spawned into the main scene with this code
- (void)spawnNewObstacle {
CCNode *previousObstacle = [_obstacles lastObject];
CGFloat previousObstacleXPosition = previousObstacle.position.x;
if (!previousObstacle) {
// this is the first obstacle
previousObstacleXPosition = firstObstaclePosition;
}
Obstacle *obstacle = (Obstacle *)[CCBReader load:#"Obstacle"];
obstacle.position = ccp(previousObstacleXPosition + distanceBetweenObstacles, 0);
[obstacle setupRandomPosition];
obstacle.zOrder = DrawingOrderPipes;
[_physicsNode addChild:obstacle];
[_obstacles addObject:obstacle];
}
What i want to accomplish is to have these obstacles still spawning randomly. I dont want my hero to collide with the obstacles, instead i want the obstacles to act as a physics body, so you can jump on it, the problem is that when i disable hero and obstacle collision, the mainscene still imports the obstacles.m but no physics is being applied, even though physics is on in the obstacles.ccb, and the hero is able to go through the obstacles. The only way i can make it an actual physics body is to add the obstacles.ccb to the mainscene.ccb under the physics node. This works but then of course obstacles dont spawn randomly. Any workaround?

If you want them to keep spawning and for your hero to be able to jump on them without having to go to game over, i suggest setting a collision group for them

Related

cocos2D: Adding delay after rendering a scene

I am trying to launch a physics object after loading a game scene, something similar to https://www.makegameswith.us/tutorials/getting-started-with-spritebuilder/creating-two-levels/
The code I have is something like this
- (void)didLoadFromCCB {
// tell this scene to accept touches
self.userInteractionEnabled = TRUE;
[self launchObject];
}
- (void) launchObject {
CCNode* object = [CCBReader load:#"Object"];
// Apply force to it
}
The problem is if I add a sleep method in didLoadFromCCB before launching the object or the first line in the launchObject, the game scene itself is loading only after that many seconds (say after clicking play) and immediately launches, but I want the game scene to load and after n seconds the physics object is launched.
I can easily solve this problem by using
- (void)update:(CCTime)delta
by setting some conditions for launch, but the question is, is that the right approach. I don't want to complicate update method to hold multiple if/else stuff and use it beyond what it's intended for, especially if there is another best way to do it.
I tried different solutions posted in this forum but didn't help my case.

How to access b2body of CCPhysicsSprite using its tag

i`m working on a platformer game , i have A character who jumps on different platforms , until he reaches the end of the level.
one type of platform is a tree log floating on water. the log slowly moves up and down along the tide of water .
each platform is actually a b2body. here is how i define a platform :
b2Body *platformbody;
b2BodyDef platforbodydef;
b2FixtureDef platformfixdef;
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(0.5f, 0.5f);
platforbodydef.type=b2_staticBody;
platforbodydef.position.Set(BlockPlatX[i][j], BlockPlatY[i][j]);
platformbody= world->CreateBody(&platforbodydef);
platformfixdef.shape=&dynamicBox;
platformsprite=[CCPhysicsSprite spriteWithFile:#"TreeLog.png"];
dynamicBox.SetAsBox(platformsprite.texture.contentSize.width/PTM_RATIO/2,platformsprite.texture.contentSize.height/PTM_RATIO/2);
platformfixdef.friction=1;
platformfixdef.density=1;
platformfixdef.restitution=0;
platformbody->CreateFixture(&platformfixdef);
if(platforbodydef.position.y < watersprite.contentSize.height/2)
{
platforbodydef.position.Set(prevPlatX + 300, watersprite.contentSize.height/2 + 10);
CGPoint point=CGPointMake(platforbodydef.position.x,watersprite.contentSize.height/2);
CCMoveTo *waterMove=[CCMoveTo actionWithDuration:3 position:point];
point=CGPointMake(platforbodydef.position.x,watersprite.contentSize.height/2+ 10);
CCMoveTo *waterMoveBack=[CCMoveTo actionWithDuration:3 position:point];
CCSequence* sequence = [CCSequence actions:waterMove,waterMoveBack, nil];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:sequence];
[platformsprite runAction:repeat];
}
[platformsprite setPTMRatio:PTM_RATIO];
[platformsprite setB2Body:platformbody];
[platformsprite setPosition:CGPointMake(platforbodydef.position.x, platforbodydef.position.y)];
[self addChild:platformsprite z:4 tag: 10000 + i*100 + j];
i am using a loop ,so i create more than one of these platforms .
but the problem is that when the sprite runs the action sequence , the position of the b2body associated with it does`nt change and this obviously causes lots of problems.
is there anyway i can access the b2body of the sprite using its tag and change the position of the body instead?
First thing is that the sprite follows the body and not the other way round. When you are repositioning the b2Body via setTransform you have to be very careful as you can find some really odd behaviours. The collision is not being performed in the proper fashion, so if the moved body will intersect with something else some crazy stuff can happen.
Why are you using sequence to move the body on the water. You are much better off using a prismatic joint to push it along and at the end of the track place a sensor which will revert the motor of the joint to move it in the other direction. Let the physics engine deal with the movement. This way you allow the system to work in the way it was intended and the sprite will updates its position to the body automatically.
Edit: I would also advised using a visual box2d editor. You are using Cocos2d as an engine, so there is quite few to choose from. I would personally recommend "Really Useful Box2D Editor" or "R.U.B.E." in short.

Understanding cocos2d scenes, how they works really?

I'm stuck on something about the scenes creation and replacement in cocos2d, so I'm going to ask precisely what seems to be misunderstood by me. I have a game (fully working except for scene swapping, sadly) with some little-games, now, if I had to do this starting with a cocos2d scene as menu I wouldn't have any problem, but since I did it starting with UIKit I truly need to know better how the scenes are working to fix it.
Firstly, is it required to start a scene in the appDelegate? since I'm starting with UIkit and the scene must be shown after you choice the game (say, out of 3 choices), which scene should I put in the appDelegate? and where exactly? I'm putting the scene in this method:
-(void) directorDidReshapeProjection:(CCDirector*)director
{
if(director.runningScene == nil)
//start scene
}
If I put the FIRST scene, the UIKit part works good and when I start the "game number TWO" as first choice (say we play this game for first) I got the Open GL 0x0506 error, then the scene start.
If I put the first scene, I choice the first game, and then quit and choice the second game, the scene is replaced properly without that error.
If I put the first scene, and I start the "game number 1" it works (obviously) because he has the scene loaded, but I cannot know which game will start as first the user.
I tried with an "intro scene" loaded at the appDelegate but I got the same problem. the problem basically is "how to start scene if you have more than one scene and don't know which will be called as first"...
The 'getting started with iOS' documentation will really clear up a lot of these questions. You can find it at developer.apple.com - https://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007072
It explains just what an AppDelegate actually is, as well as how to use one properly. It is not immediately clear how to mix UIKit and cocos2d, but the above link cleared a lot up for me. Another very helpful resource is a tutorial by Ray Wenderlich -
http://www.raywenderlich.com/4817/how-to-integrate-cocos2d-and-uikit
From a bird's eye view, the CCDirector inherits from a UIWindow. Mixing UIKit and cocos2d is as simple as building your interface with UIKit, then at some point opening a UIWindow and allowing the CCDirector to start cocos2d. In a sense, the components act as almost two entirely separate entities.

Cocos2D - Particles follow the emitter instead of staying at the position they were released

In cocos2D I currently have a very simple particle emitter initialized like this:
turnEmitter = [[CCParticleFlower alloc] init];
turnEmitter.texture = [[CCTextureCache sharedTextureCache] addImage:#"Pocket.png"];
[self addChild:turnEmitter z:1];
turnEmitter.scale = 0.7f;
turnEmitter.positionType = kCCPositionTypeFree;
It is simply added directly to the gameplay layer.
This emitter follows a sprite around the screen in this way (happens in the update method):
turnEmitter.position = turnEmblem.position;
Now the problem is that the tail of particles left behind the emitter moves with the emitter, instead of released particles simply staying in the position they were released, which gives a really weird and stupid looking effect.
What I want to do is have the particles not follow the emitter at all after they have been spawned, unfortunately I have been unable to find any way of doing so.
As you can see from the code above I have already searched around, and found people which suggests changing the positionType property of the emitter, although I have tried all the possibilities and it does not solve the problem.
Does anyone have any ideas as to what this might be?
You may want to try changing the "emitterMode" as well to "kCCPositionTypeFree". I had a similar issue where i had the emitter as a child of a CCNode. The CCNode was being rotated, but the particles and emitter wasn't. In the same way it looked stupid because the illusion of rotation was ruined. I need to set the following on my emitter:
emitter.emitterMode = kCCPositionTypeRelative;
emitter.positionType = kCCPositionTypeRelative;

endless runner game like dino rush object placement in cocos2d

My game is mostly already completed, but I need some changes related to the placement of objects. I have the same objects like the dinorush game. Like (fruit, block, missile, ball etc). I need proper placement of all objects like in the dino rush game. Currenly I am using random positions and movement of objects. I have not used any physics in my game. Also if I design placement using a tile map, then can we have magnet effects when my player stands near to the banana object? (I mean all banana automatically are attracted by the player)
Please help me. I am newbie in cocosd. This is my first game in cocos2d.
You can add a new class inherited the ccNode named magnet(banana) then add it to your game.Calculate the distance between the player and the banana.If the distance is less than the number you want, then move it to the player.
-(void)update:(ccTime)delta
{
float distance = ccpDistance(self.position, player.position);
if(distance < d){
CCAction *action = [CCMoveTo actionWithDuration:1.0f position:player.position];
[self addChild:action];
}
}