Difference between BezierBy and BezierTo in Cocos2d? - cocos2d-iphone

I Want to know the difference between the BezierBy and BezierTo. What will happen in the below code if say this is the scenario
CCBezierConfig bezier = new CCBezierConfig();
// Bezier curve
bezier.controlPoint_1 = CGPoint.make(1002.0f,475.0f);
bezier.controlPoint_2 = CGPoint.make(454.0f, 281.0f);
bezier.endPosition = CGPoint.make(-20.0f,490.0f);
CCBezierBy by = CCBezierBy.action(100, bezier);
CCBezierTo to = CCBezierTo.action(2, bezier);
CCCallFuncN actionMoveDone = CCCallFuncN.action(this,"spriteMoveFinished");
CCSequence actions = CCSequence.actions(by, actionMoveDone);
obstacle1.runAction(actions);
Also have same issues in understand moveTo and moveBy
Please help me with the concepts.

CCMoveTo moves your node TO position. CCMoveBy moves your node for sone pixels. All ather actions are same.
Example:
CCNode *a = [[CCNode alloc] init];
[a setPosition:CGPointMake(100, 100)]; //our node starts at point (100, 100)
now, if you'll move it TO CGPointMake(200,200), his positions will be (200, 200). But if you'll move it from (100, 100) BY CGPointMake(200,200), it will be (300, 300).

Related

Positionning particle in node

Using cocos2d, I'm trying to replace a sprite (item in my code) with a particle system. This code is placed in my board class. This one works:
// Draw the particles
CCParticleSystem *particles = [[CCParticleSystem alloc] initWithDictionary:_popParticles];
particles.position = ccpSub(item.position,ccp(160,160));
particles.autoRemoveOnFinish = TRUE;
[self addChild:particles];
This one doesn't:
// Draw the particles
CCParticleSystem *particles = [[CCParticleSystem alloc] initWithDictionary:_popParticles];
particles.position = item.position;
particles.autoRemoveOnFinish = TRUE;
[self addChild:particles];
I tried player with this but without success:
particles.positionType = CCPositionTypeMake(CCPositionUnitUIPoints, CCPositionUnitUIPoints, CCPositionReferenceCornerBottomLeft);
My board is a 320x320 points CCSprite with anchor point set at 0.5, 0.5
When I log my item.position value, I get something relative to the bottom left corner of my board (from 30,30 to 290,290)
Is using ccpSub the correct way ?
When you destroy a node you also destroy all of it's children nodes, you said you add your particle to 'item' then you destroy that 'item', which means you have no particle anymore.

Sprite not drawing/appearing on screen, Cocos2d

I'v got trouble getting my sprite to appear on screen using my current method. I got multiple sprites on the screen already, but I'v added this new one in a different manner as I'm going to manipulate it later on (handling different interactions and such). But I don't see why it doesn't appear on the screen when I run the program. I'v tried changing the z order without luck, but that might be because the sprite wasn't added in the init method like the others so the z order doesn't affect it in comparison to the background and such created in the init method. Anyways, got any clue for why it won't draw on screen?
- (void) addMonster {
CCSprite * monster = [CCSprite spriteWithImageNamed:#"Ghost.png"];
// Determine where to spawn the monster along the Y axis
CGSize viewSize = [CCDirector sharedDirector].viewSize;
int minY = monster.contentSize.height / 2;
int maxY = viewSize.height - monster.contentSize.height/2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the monster slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
monster.position = ccp(viewSize.width + monster.contentSize.width/2, actualY);
[self addChild:monster];
// Determine speed of the monster
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
CCActionMoveTo * actionMove = [CCActionMoveTo actionWithDuration:actualDuration
position:ccp(-monster.contentSize.width/2, actualY)];
CCActionCallBlock * actionMoveDone = [CCActionCallBlock actionWithBlock:^(CCNode *node) {
[monster removeFromParentAndCleanup:YES];
}];
[monster runAction:[CCActionSequence actions:actionMove, actionMoveDone, nil]];
}
//The call back function
-(void)gameLogic:(CCTime)dt {
[self addMonster];
}
- (id)init{
// Apple recommend assigning self with supers return value
self = [super init];
if (!self) return(nil);
if( (self = [super init]) ) {
self.userInteractionEnabled = YES;
//How often a new ghost gets produced
[self schedule:#selector(gameLogic:) interval:1.0];
//And some more code none relevant to this keeps going...
I am having the same problem.
The sprites i add do appear, but when i leave the scene and come back, they won't appear. As far as i know sprites needs to be added in the init method. When you add them at a later stage (in my case) they appear only once.
I am still looking for a solution to add the sprites at a later stage than the init method and appears more than once.
Maybe this answer helps you finding a solution.

CCSprite Direction Cococs2d 3.0

How can i shoot the sprite "ink" straight up? The player Squiddy moves across the screen and i would like it to shoot the ink up, straight up, everytime. The code i have so far shoots the ink but it shoots it to a certain point on the screen
The code
CGPoint targetPosition = ccp(self.contentSize.width/2, self.contentSize.height/2 + self.contentSize.height);
ink = [CCSprite spriteWithImageNamed:#"MarioTube_Body_Rev.png"];
ink.position = Squiddy.position;
ink.physicsBody = [CCPhysicsBody bodyWithCircleOfRadius:ink.contentSize.width/2.0f andCenter:ink.anchorPointInPoints];
ink.physicsBody.collisionGroup = #"playerG roup";
ink.physicsBody.collisionType = #"projectileCollision";
CCActionRotateBy *actionSpin = [CCActionRotateBy actionWithDuration:.5f angle:360];
[ink runAction:[CCActionRepeatForever actionWithAction:actionSpin]];
[_physicsWorld addChild:ink];
CCActionMoveTo *actionMove = [CCActionMoveTo actionWithDuration:.75f position:targetPosition];
CCActionRemove *actionRemove = [CCActionRemove action];
[ink runAction:[CCActionSequence actionWithArray:#[actionMove,actionRemove]]];
As I said before, try to apply a force or impulse to ink.physicsBody:
CGPoint force = ccpMult(ccp(0,90), 600); //x=0, y=90, force=600
[ink.physicsBody applyForce:force];
With a value of x=0, the force will go up. Just play with the values.
Hope this helps

Cocos2d Kobold2d reorderChildren doesn't order CCSprites properly

I am having an issue in Kobold2d-Cocos2d regarding the layering of CCSprite objects.
All of my code works fine, except that a certain tile (a CCSprite), held in an array, is supposed to always be on top. The code has an array of references to CCSprites (Tile) and goes along all the tiles swapping them with each other. So element 0 and 1 switch (in the array and on screen using a moveTo), then the new element 1 and 2 switch, then the new element 2 and 3 switch etc...
The idea is the Tile at the start of the chain leapfrogs to the front of the line!
I always want that first tile to stay on top, but it isn't. It only does sometimes (when it's above the other Tile it's switching places with on the screen, implying it was added later)
Here's the CCScene code in question:
//reference first CCSprite in array -works
Tile *firstTile = [tileArray objectAtIndex:(int)[[[selTracker oldSelectionArray] objectAtIndex:0]element]];
//How much time should be spend leapfrogging each two tiles broken up over 1 second.
float intervalTime = .75/(float)[[selTracker oldSelectionArray] count];
//Will use this to count each tile set we leapfrog
float currentPass = 0;
//TODO: destroy this wrapper class that holds number, use NSNumber. Fine for now.
SimpCoord *lastCord;
//Make moving sprite higher than all others. DOESN'T WORK?
[self reorderChild:firstTile z:100];
//Loop through all the tiles that were selected
for (SimpCoord *coord in [selTracker oldSelectionArray])
{
if (lastCord)
{
//Queue each tile to leapfrog with our moving tile
if ([self respondsToSelector:#selector(switchTilesFuncWrapper:)])
{
NSArray *argArray = [NSArray arrayWithObjects:
[NSNumber numberWithInt:[lastCord element]],
[NSNumber numberWithInt:[coord element]],
[NSNumber numberWithFloat:(intervalTime)], nil];
[self performSelector:#selector(switchTilesFuncWrapper:) withObject:argArray afterDelay:((currentPass) * intervalTime)];
}
currentPass++;
}
lastCord = coord;
}
`
That calls the following code by the way that actually swaps the two Tiles (I excluded the function wrapper middleman I needed for multiple arguments):
(In case it makes it easier to understand, rather than use a 2d array to hold all my tiles I just only draw 10 per line, hence the tileCoordsByElement method - but that shouldn't be important)
//
// Switch two tiles on the screen and in the holder array
// onlySwitchArray pass in true to only swap tiles in organization array
// but provide no animation.
- (void) switchTiles:(NSNumber*)elePosVal secPos:(NSNumber*)elePos2Val timeToSwitch:(NSNumber*)time
{
float switchTime = [time floatValue];
int elePos = [elePosVal intValue];
int elePos2 = [elePos2Val intValue];
Tile *tmpTile = [tileArray objectAtIndex:elePos];
Tile *tmpTile2 = [tileArray objectAtIndex:elePos2];
//Move actual tiles on screen
//Move Tile is elePos (1) to elePos2
int curCol = 0;
int curRow = 0;
[self tileCoordsByElement:elePos2 x:&curRow y:&curCol];
CCSequence *tmpTile1_Seq = [CCSequence actions:
[CCMoveTo actionWithDuration:switchTime position:ccp((curRow-1)*tmpTile.width + tmpTile.width/2,
(curCol-1)*tmpTile.height + tmpTile.height/2)], nil];
[tmpTile runAction:[CCRepeat actionWithAction:tmpTile1_Seq times:1]];
//Move Tile that is elePos2 to elePos(1)
[self tileCoordsByElement:elePos x:&curRow y:&curCol];
CCSequence *tmpTile1_Seq2 = [CCSequence actions:
[CCMoveTo actionWithDuration:switchTime position:ccp((curRow-1)*tmpTile.width + tmpTile.width/2,
(curCol-1)*tmpTile.height + tmpTile.height/2)], nil];
[tmpTile2 runAction:[CCRepeat actionWithAction:tmpTile1_Seq2 times:1]];
//Swap tiles in array second
[tileArray replaceObjectAtIndex:elePos withObject:tmpTile2];
[tileArray replaceObjectAtIndex:elePos2 withObject:tmpTile];
}
Alright.
I'm aware some things I'm doing aren't exactly efficient and if it's not relevant I don't really want to focus to heavily on them. This is just a learning exercise for me - I just honestly don't understand why the origional Tile won't stay on top.
I've tried every resource or example I possibly can find for answers (sample included code, tutorials online, terrible book I bought, random somewhat related stackoverflow articles) and I'm getting nothing :\
In case it matters this is how I origionally added my sprites to the scene:
//Set up A CCSpriteBatchNode to load in pList/pngs of images
[[CCSpriteFrameCache sharedSpriteFrameCache]
addSpriteFramesWithFile:#"zAtl_BasicImages_64.plist"];
nodeBasicImages = [CCSpriteBatchNode batchNodeWithFile:#"zAtl_BasicImages_64.png" capacity:100];
//Initialize array used to track tiles in scene
tileArray = [[NSMutableArray alloc] init];
for (int i = 0; i<100; i++)
{
Tile *tmpTile = [[Tile alloc] init];
[tileArray addObject:tmpTile];
[self reorderChild:tmpTile z:-1];
}
Note: I checked and the zOrder on both Tiles is correct on the line before the MoveTo animation begins.
I added my sprites not to my layer, but to an image node because I was using a Sprite Atlas. So I was trying to access sprites that weren't even there. - I'm a new user so going to have to wait 8 hours until I can close. Peace. Why it didn't throw an error I'll never know.

cocos2d: Why can't I change a scaled node's position?

I think I'm just understanding scaling/positioning nodes/layers incorrectly. I'm setting up my node like this (node class is derived from CCNode):
-(id) init
{
if ((self = [super init]))
{
// Create parallax background node.
background = [BackgroundNode node];
[self addChild:background z:0];
// Create foreground node.
foreground = [ForegroundLayer node];
[self addChild:foreground z:0];
self.position.y = 500.0f;
self.scaleX = 1.5f;
self.scaleY = 1.5f;
}
return self;
}
It doesn't seem to matter what I set the self.position.y to - the scaled node is always displayed as though it was positioned in the bottom-left of the screen. I've tried playing around with anchorPoint as well, but it doesn't really seem to change anything.
The reason I'm asking is because I'd like to be able to pan vertically when I'm zoomed in - this doesn't seem to really be the right way to accomplish it, though. Any ideas?
self.position.y = 500.0f;
doesn't work. It should be
self.position = ccp(self.position.x, 500.0f);
Please refer to "Cocoa Objective-c Property C structure assign fails".