how to remove sprite object when we create touch in cocos2d? - ios

I am new in cocos2d. I have a problem when we create new sprite object. It's not remove onto the display. Sprite object are not delete when we add new lives.(add heart sprite).
//Here I create a live which in heart shape.
-(id) init {
if( (self=[super init]) ) {
hearthArray = [[NSMutableArray alloc] init];
lives = 4;
for(NSInteger ilive = 0; ilive<lives; ilive++){
CCSprite *hearth = [CCSprite spriteWithFile:#"hearth.png"];
hearth.position = ccp( ((ilive+1)*50), winSize.height - 50);
[hearthArray insertObject:hearth atIndex:ilive];
[self addChild:hearth];
}
return self;
}
//Below code into remove the heart.(decrease lives).
- (void) addMonster:(ccTime)dt {
//select a random monster from the _monsters Array
int selectedMonster = arc4random() % [_monsters count];
Monster *monster = [_monsters objectAtIndex:selectedMonster];
int m = [monster movement];
CCSprite *spriteMonster = [[CCSprite alloc] initWithFile:[monster monsterSprite]];
spriteMonster.tag = [monster tag];
CGSize winSize = [CCDirector sharedDirector].winSize;
int minX = spriteMonster.contentSize.width / 2;
int maxX = winSize.width - spriteMonster.contentSize.width/2;
int rangeX = maxX - minX;
int actualY = (arc4random() % rangeX) + minX;
//BLOCK 2 - Determine speed of the monster
int minDuration = [monster minVelocity];
int maxDuration = [monster maxVelocity];
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
if(m == 1){
spriteMonster.position = ccp( actualY,winSize.height + spriteMonster.contentSize.height/2);
[self addChild:spriteMonster];
//BLOCK 4 - Create the actions
CCMoveTo * actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp( actualY,-spriteMonster.contentSize.height/2)];
CCCallBlockN * actionMoveDone = [CCCallBlockN actionWithBlock:^(CCNode *node) {
[_monstersOnScreen removeObject:node];
[node removeFromParentAndCleanup:YES];
// Remove lifes
lives--;
// [[hearthArray lastObject] removeFromParentAndCleanup:YES];
[self removeChild:[hearthArray lastObject] cleanup:YES];
[hearthArray removeLastObject];
NSLog(#"m=1 when array : %#",hearthArray);
if(lives == 0)
[[CCDirector sharedDirector] replaceScene:[HelloWorldLayer scene]];
}];
[spriteMonster runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
[_monstersOnScreen addObject:spriteMonster];
}
}
//Below into Add new lives using for loop.when touch particular object.
-(void)increaseLivesWhentouchCoin{
NSLog(#"lives is get when add live : %i",lives);
NSLog(#"hearthArray when toch coin: %#",hearthArray);
lives = lives+1;
NSLog(#"lives+1 : %i",lives);
for(NSInteger i = 0; i<lives; i++){
hearth = [CCSprite spriteWithFile:#"hearth.png"];
CGSize winSize = [CCDirector sharedDirector].winSize;
hearth.position = ccp( ((i+1)*50), winSize.height-50);
[hearthArray insertObject:hearth atIndex:i];
[self addChild:hearth];
}
NSLog(#"hearthArray out for loop: %#",hearthArray);
}
Please help me.Thanks in advance.

Your increaseliveswhentouch coin method should be like this..
-(void)increaseLivesWhentouchCoin{
CCSprite *hearth = [CCSprite spriteWithFile:#"hearth.png"];
CGSize winSize = [CCDirector sharedDirector].winSize;
hearth.position = ccp( ((lives+1)*50), winSize.height-50);
[hearthArray insertObject:hearth atIndex:lives];
[self addChild:hearth];
lives++;
}
You have to add just one heart object .There is no need to create all objects again,if you want to create remove all the objects first..

Related

how can we set tag for a CCSprite in cocos2D

I am new to cocos2D . I want to set Tag for CCSprite but this show me error in cococs2D version 3 while i have seen Answer on Stackoverflow [set tag] property but it does not work form me in cocos2d Version 3 .
What I requried is I have created two different Monster and I want to find out in Collision delegate which monster has collided .
Let me show you how I am creating Monster.
CCSprite *monster = [CCSprite spriteWithImageNamed:#"xyz.png"];
int minY = monster.contentSize.height / 2;
int maxY = self.contentSize.height - monster.contentSize.height / 2;
int rangeY = maxY - minY;
int randomY = (arc4random() % rangeY) + minY;
// 2
monster.position = CGPointMake(self.contentSize.width + monster.contentSize.width/2, randomY);
monster.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect){CGPointZero, monster.contentSize} cornerRadius:0];
monster.physicsBody.collisionGroup = #"monsterGroup";
monster.physicsBody.collisionType = #"monsterCollision";
[_physicsWorld addChild:monster z:1];
// 3
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration - minDuration;
int randomDuration = (arc4random() % rangeDuration) + minDuration;
// 4
CCAction *actionMove = [CCActionMoveTo actionWithDuration:randomDuration position:CGPointMake(-monster.contentSize.width/2, randomY)];
CCAction *actionRemove = [CCActionRemove action];
[monster runAction:[CCActionSequence actionWithArray:#[actionMove,actionRemove]]];
- (BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair monsterCollision:(CCNode *)monster projectileCollision:(CCNode *)projectile
{
[monster removeFromParent];
[projectile removeFromParent];
score=score+1;
return YES;
}
here I want to fetch CCsprite by Tag or by image i am not sure how can i recognize CCsprite in collision delegate.
I'm not sure but I think you can set name property for a sprite when adding it like:
[self addChild:(CCNode *) z:(NSInteger) name:(NSString *)]
and then later get it by
getChildByName

code crashes when sprite go to the position

I use following code to show cloud randomly
- (void) cloudFly
{
int whichcloud = (arc4random() % 2) + 1;
CCSprite *target = [CCSprite spriteWithImageNamed:[NSString stringWithFormat:#"cloud%d.png",whichcloud]];
target.opacity = 0.3;
int minY = target.contentSize.height / 2;
int maxY = winSize.height - target.contentSize.height / 2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
target.position = ccp(winSize.width + (target.contentSize.width/2), actualY);
[self addChild:target];
int minDuration = 1.0;
int maxDuration = 3.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
id actionMove = [CCActionMoveTo actionWithDuration:actualDuration position:ccp(-target.contentSize.width / 2, actualY)];
id actionMoveDone = [CCActionCallFunc actionWithTarget:self selector:#selector(cloudFinished:)];
[target runAction:[CCActionSequence actions:actionMove, actionMoveDone, nil]];
[_clouds addObject:target];
}
- (void)cloudFinished:(id)sender
{
CCSprite *sprite = (CCSprite *)sender;
[sprite stopAllActions];
[self removeChild:sprite cleanup:YES];
}
but when the cloud flys to the position, this code will crash at line
- (void)cloudFinished:(id)sender
I use cocos2d-iphone v3.x, I try to comment/remove all codes in
- (void)cloudFinished:(id)sender
but it still crash. BWT, does ccsprite remove tag?
CCActionCallFunc is expecting a selector with no arguments, you should use CCActionCallBlock instead. There is an example in this answer.
try this:
[ _clouds addChild: target ];

Sprite wont spawn [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
This code spawns a monster, but no enemy.
I expect an enemy to be spawned, why doesn't it?
#import "MyScene.h"
#import "GameOverScene.h"
static const uint32_t projectileCategory = 0x1 << 0;
static const uint32_t monsterCategory = 0x1 << 1;
static const uint32_t enemyCategory = 0x1 << 1;
// 1
#interface MyScene () <SKPhysicsContactDelegate>
#property (nonatomic) SKSpriteNode * player;
#property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
#property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
#property (nonatomic) int monstersDestroyed;
#property (nonatomic) int enemysDestroyed;
#end
static inline CGPoint rwAdd(CGPoint a, CGPoint b) {
return CGPointMake(a.x + b.x, a.y + b.y);
}
static inline CGPoint rwSub(CGPoint a, CGPoint b) {
return CGPointMake(a.x - b.x, a.y - b.y);
}
static inline CGPoint rwMult(CGPoint a, float b) {
return CGPointMake(a.x * b, a.y * b);
}
static inline float rwLength(CGPoint a) {
return sqrtf(a.x * a.x + a.y * a.y);
}
// Makes a vector have a length of 1
static inline CGPoint rwNormalize(CGPoint a) {
float length = rwLength(a);
return CGPointMake(a.x / length, a.y / length);
}
#implementation MyScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
// 2
NSLog(#"Size: %#", NSStringFromCGSize(size));
// 3
self.backgroundColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
// 4
self.player = [SKSpriteNode spriteNodeWithImageNamed:#"player"];
self.player.position = CGPointMake(self.player.size.width/2, self.frame.size.height/2);
[self addChild:self.player];
self.physicsWorld.gravity = CGVectorMake(0,0);
self.physicsWorld.contactDelegate = self;
}
return self;
}
-(void)addMonster {
// Create sprite
SKSpriteNode * monster = [SKSpriteNode spriteNodeWithImageNamed:#"monster"];
monster.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:monster.size]; // 1
monster.physicsBody.dynamic = YES; // 2
monster.physicsBody.categoryBitMask = monsterCategory; // 3
monster.physicsBody.contactTestBitMask = projectileCategory; // 4
monster.physicsBody.collisionBitMask = 0; // 5
// Determine where to spawn the monster along the Y axis
int minY = monster.size.height / 2;
int maxY = self.frame.size.height - monster.size.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 = CGPointMake(self.frame.size.width + monster.size.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
SKAction * actionMove = [SKAction moveTo:CGPointMake(-monster.size.width/2, actualY) duration:actualDuration];
SKAction * actionMoveDone = [SKAction removeFromParent];
SKAction * loseAction = [SKAction runBlock:^{
SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:NO];
[self.view presentScene:gameOverScene transition: reveal];
}];
[monster runAction:[SKAction sequence:#[actionMove, loseAction, actionMoveDone]]];
}
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > 1) {
self.lastSpawnTimeInterval = 0;
[self addMonster];
}
}
- (void)update:(NSTimeInterval)currentTime {
// Handle time delta.
// If we drop below 60fps, we still want everything to move the same distance.
CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLast > 1) { // more than a second since last update
timeSinceLast = 1.0 / 60.0;
self.lastUpdateTimeInterval = currentTime;
}
[self updateWithTimeSinceLastUpdate:timeSinceLast];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self runAction:[SKAction playSoundFileNamed:#"pew-pew-lei.caf" waitForCompletion:NO]];
// 1 - Choose one of the touches to work with
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
// 2 - Set up initial location of projectile
SKSpriteNode * projectile = [SKSpriteNode spriteNodeWithImageNamed:#"projectile"];
projectile.position = self.player.position;
projectile.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:projectile.size.width/2];
projectile.physicsBody.dynamic = YES;
projectile.physicsBody.categoryBitMask = projectileCategory;
projectile.physicsBody.contactTestBitMask = monsterCategory;
projectile.physicsBody.contactTestBitMask = enemyCategory;
projectile.physicsBody.collisionBitMask = 0;
projectile.physicsBody.usesPreciseCollisionDetection = YES;
// 3- Determine offset of location to projectile
CGPoint offset = rwSub(location, projectile.position);
// 4 - Bail out if you are shooting down or backwards
if (offset.x <= 0) return;
// 5 - OK to add now - we've double checked position
[self addChild:projectile];
// 6 - Get the direction of where to shoot
CGPoint direction = rwNormalize(offset);
// 7 - Make it shoot far enough to be guaranteed off screen
CGPoint shootAmount = rwMult(direction, 1000);
// 8 - Add the shoot amount to the current position
CGPoint realDest = rwAdd(shootAmount, projectile.position);
// 9 - Create the actions
float velocity = 480.0/1.0;
float realMoveDuration = self.size.width / velocity;
SKAction * actionMove = [SKAction moveTo:realDest duration:realMoveDuration];
SKAction * actionMoveDone = [SKAction removeFromParent];
[projectile runAction:[SKAction sequence:#[actionMove, actionMoveDone]]];
}
- (void)projectile:(SKSpriteNode *)projectile didCollideWithMonster:(SKSpriteNode *)monster {
NSLog(#"Hit");
[projectile removeFromParent];
[monster removeFromParent];
self.monstersDestroyed++;
if (self.monstersDestroyed > 80) {
SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:YES];
[self.view presentScene:gameOverScene transition: reveal];
}
}
- (void)didBeginContact:(SKPhysicsContact *)contact
{
// 1
SKPhysicsBody *firstBody, *secondBody, *thirdBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
thirdBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
thirdBody = contact.bodyA;
}
// 2
if ((firstBody.categoryBitMask & projectileCategory) != 0 &&
(secondBody.categoryBitMask & enemyCategory) != 0 &&
(thirdBody.categoryBitMask & monsterCategory) != 0)
{
[self projectile:(SKSpriteNode *) firstBody.node didCollideWithMonster:(SKSpriteNode *) secondBody.node];
[self projectile:(SKSpriteNode *) firstBody.node didCollideWithEnemy: (SKSpriteNode *) secondBody.node];
}
}
- (void)addEnemy {
// Create sprite
SKSpriteNode * enemy = [SKSpriteNode spriteNodeWithImageNamed:#"enemy"];
enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:enemy.size]; // 1
enemy.physicsBody.dynamic = YES; // 2
enemy.physicsBody.categoryBitMask = enemyCategory; // 3
enemy.physicsBody.contactTestBitMask = projectileCategory; // 4
enemy.physicsBody.collisionBitMask = 0; // 5
// Determine where to spawn the monster along the Y axis
int minY = enemy.size.height / 2;
int maxY = self.frame.size.height - enemy.size.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
enemy.position = CGPointMake(self.frame.size.width + enemy.size.width/2, actualY);
[self addChild:enemy];
// Determine speed of the monster
int minDuration = 1.0;
int maxDuration = 6.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
SKAction * actionMove = [SKAction moveTo:CGPointMake(-enemy.size.width/2, actualY) duration:actualDuration];
SKAction * actionMoveDone = [SKAction removeFromParent];
SKAction * loseAction = [SKAction runBlock:^{
SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:NO];
[self.view presentScene:gameOverScene transition: reveal];
}];
[enemy runAction:[SKAction sequence:#[actionMove, loseAction, actionMoveDone]]];
}
- (void)projectile:(SKSpriteNode *)projectile didCollideWithEnemy:(SKSpriteNode *)enemy {
NSLog(#"Hit");
[projectile removeFromParent];
[enemy removeFromParent];
self.enemysDestroyed++;
if (self.enemysDestroyed > 80) {
SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:YES];
[self.view presentScene:gameOverScene transition: reveal];
}
}
#end
I am not sure if you realize this, but you never actually call addEnemy. Look through the code. You will find a call to addMonster but never addEnemy. Implementing the method is one thing- without calling the method, whatever is inside will never run.

Delegate not working between HudLayer and GameLayer

I have created a HudLayer class which defines a protocol for when button presses happen.
-(id) init
{
if( (self=[super initWithColor:ccc4(255, 255, 0, 128)])) {
self.position=ccp(0,0);
self.contentSize=CGSizeMake(480, 40);
scoreLabel=[CCLabelTTF labelWithString:#"0" fontName:#"Marker Felt" fontSize:24];
scoreLabel.position=ccp(62,20);
scoreLabel.anchorPoint=ccp(0,0.5);
[self addChild:scoreLabel];
CCLabelTTF *textLabel=[CCLabelTTF labelWithString:#"Score:" fontName:#"Marker Felt" fontSize:24];
textLabel.position=ccp(5,20);
textLabel.anchorPoint=ccp(0,0.5);
[self addChild:textLabel];
CCMenuItemImage * item = [CCMenuItemImage itemWithNormalImage:#"fire.png" selectedImage:#"fire.png" target:self selector:#selector(projectileButtonTapped:)];
CCMenu *menu = [CCMenu menuWithItems:item, nil];
menu.position = ccp(150, 20);
[self addChild:menu];
}
return self;
}
- (void)projectileButtonTapped:(id)sender
{
NSLog(#"projectileButtonTapped HudLayer");
[self.delegate respondsToSelector:#selector(projectileButtonTapped:)];
}
Then in my HelloWorldLayer class I implement the protocol and set myself as the delegate.
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
//add another layer to the scene
// HudLayer *anotherLayer = [HudLayer node];
// anotherLayer.delegate = self;
// [scene addChild: anotherLayer];
// layer.hud=anotherLayer;
// return the scene
return scene;
}
-(id) init
{
if( (self=[super init]) ) {
_tileMap = [CCTMXTiledMap tiledMapWithTMXFile:#"GridWars#medium.tmx"];
_background = [_tileMap layerNamed:#"Background"];
_foreground = [_tileMap layerNamed:#"Foreground"];
_meta = [_tileMap layerNamed:#"Meta"];
_meta.visible = NO;
CCTMXObjectGroup *objectGroup = [_tileMap objectGroupNamed:#"Objects"];
NSAssert(objectGroup != nil, #"tile map has no objects object layer");
NSDictionary *spawnPoint = [objectGroup objectNamed:#"SpawnPoint"];
int x = [spawnPoint[#"x"] integerValue];
int y = [spawnPoint[#"y"] integerValue];
_wizardHero = [[WizardHero alloc]init];
_redEnemy = [[RedEnemy alloc]init];
_wizardHero.position = ccp(x,y);
[self addChild:_wizardHero];
[self setViewPointCenter:_wizardHero.position];
[self addChild:_tileMap z:-1];
self.touchEnabled = YES;
self.enemies = [[NSMutableArray alloc] init];
self.projectiles = [[NSMutableArray alloc] init];
[self schedule:#selector(testCollisions:)];
for (spawnPoint in [objectGroup objects]) {
if ([[spawnPoint valueForKey:#"Enemy"] intValue] == 1){
x = [[spawnPoint valueForKey:#"x"] intValue];
y = [[spawnPoint valueForKey:#"y"] intValue];
[self addEnemyAtX:x y:y];
}
}
_hud = [HudLayer node];
_hud.delegate = self;
[self addChild:_hud];
}
return self;
}
- (void)projectileButtonTapped:(id)sender
{
// Find where the touch is
// CGPoint touchLocation = [touch locationInView: [touch view]];
// touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
// touchLocation = [self convertToNodeSpace:touchLocation];
if (self.wizardHero.selectedTargets.count > 0) {
// Create a projectile and put it at the player's location
CCSprite *projectile = [CCSprite spriteWithFile:#"Projectile.png"];
projectile.position = _wizardHero.position;
[self addChild:projectile];
// Determine where we wish to shoot the projectile to
int realX;
// Are we shooting to the left or right?
CGPoint diff = ccpSub(self.redEnemy.position, self.wizardHero.position);
if (diff.x > 0)
{
realX = (_tileMap.mapSize.width * _tileMap.tileSize.width) +
(projectile.contentSize.width/2);
} else {
realX = -(_tileMap.mapSize.width * _tileMap.tileSize.width) -
(projectile.contentSize.width/2);
}
float ratio = (float) diff.y / (float) diff.x;
int realY = ((realX - projectile.position.x) * ratio) + projectile.position.y;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far we're shooting
int offRealX = realX - projectile.position.x;
int offRealY = realY - projectile.position.y;
float length = sqrtf((offRealX*offRealX) + (offRealY*offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length/velocity;
// Move projectile to actual endpoint
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(projectileMoveFinished:)];
[projectile runAction:
[CCSequence actionOne:
[CCMoveTo actionWithDuration: realMoveDuration
position: realDest]
two: actionMoveDone]];
[self.projectiles addObject:projectile];
}
}
The problem is that only the projectileButtonTapped: in the HudLayer is called (ie. the delegate's method never gets called).
P.S.
To save space I left out both .h files. But I assure you they are correct, with the #protocol used in HudLayer and that same protocol name put in <> within the HelloWorldLayer.
I think :
- (void)projectileButtonTapped:(id)sender
{
NSLog(#"projectileButtonTapped HudLayer");
if ([self.delegate respondsToSelector:#selector(projectileButtonTapped:)]) {
[self.delegate performSelector:#selector(projectileButtonTapped:) withObject:sender];
}
}

how to run actions on multiple sprites at the same time

I'm new to cocos2d. I'm writing my first app. But I have a problem I can't solve it. The problem is that when I move multiple sprites, the others are OK except the last one. I want my sprites will run actions at the same time. But I don't know how to fix it. Any ideas or advice about promoting my code. Thanks.
Here's my code.
-(void) setHeadFace:(Face *)headFace moveFrom:(CGPoint)startPosition moveTo:(CGPoint)endPosition`
{
CCMoveTo *moveOut = [CCMoveTo actionWithDuration:0.2f position:startPosition];
CCScaleTo *scaleTo = [CCScaleTo actionWithDuration:0.2f scale:0.0f];
CCSpawn *moveFrom = [CCSpawn actions:moveOut,scaleTo,nil];
CCMoveTo *moveTo = [CCMoveTo actionWithDuration:0.0f position:endPosition];
CCSequence *headAction = [CCSequence actions:moveFrom,moveTo,nil];
[headFace.faceSprite runAction:headAction];
}
-(void) setMidlFace:(Face *)curtFace moveTo:(CGPoint)movePosition nextFace:(Face *)nextFace
{
CCMoveTo *moveTo = [CCMoveTo actionWithDuration:0.2f position:movePosition];
CCSequence *moveAction = [CCSequence actions:moveTo,nil];
[curtFace.faceSprite runAction:moveAction];
nextFace.faceSprite = curtFace.faceSprite;
nextFace.faceType = curtFace.faceType;
[nextFace.faceSprite setPosition:movePosition];
}
-(void) setTailFace:(Face *)tailFace moveTo:(CGPoint)movePosition
byGuardSprite:(CCSprite *)guardSprite`
{
CCDelayTime *delay = [CCDelayTime actionWithDuration:0.2f];
CCMoveTo *moveIn = [CCMoveTo actionWithDuration:0.2f position:movePosition];
CCScaleTo *scaleTo = [CCScaleTo actionWithDuration:0.2f scale:1.0f];
CCSpawn *moveTo = [CCSpawn actions:moveIn,scaleTo,nil];
CCCallBlock *touchBlock =[CCCallBlock actionWithBlock:^{
tailFace.faceSprite = guardSprite;
tailFace.faceType = guardSprite.tag;
tailFace.faceSprite.tag = -1;
isTouch = YES;
}];
CCSequence *tailAction=[CCSequence actions:delay,moveTo,touchBlock,nil];
[guardSprite runAction:tailAction];
}
-(void) moveFaces:(Face *)face direction:(int)direction`
{
CCSprite *guardSprite = nil;
CGPoint movePosition;
CGPoint curtPosition;
CGPoint startPosition;
CGPoint endPosition;
int x = face.cdX;
int y = face.cdY;
CGFloat width = faceGrid[x][0].position.x;
CGFloat height = faceGrid[0][y].position.y;
switch (direction) {
case MOVE_DOWN:
CCLOG(#"move down:direction %d", direction);
movePosition = CGPointMake(width,faceGrid[x][0].position.y);
//move the first face out of the grid
startPosition = CGPointMake(width,faceGrid[x][0].position.y-GRID_OFFSET.y/2);
endPosition = CGPointMake(width,faceGrid[x][GRID_HEIGHT-1].position.y+GRID_OFFSET.y/2);
[self setHeadFace:faceGrid[x][0] moveFrom:startPosition moveTo:endPosition];
guardSprite = faceGrid[x][0].faceSprite;
guardSprite.tag = faceGrid[x][0].faceType;
for (int j=1; j<GRID_HEIGHT; j++)
{
curtPosition=CGPointMake(width,faceGrid[x][j].position.y);
//move the middle face to the next face
[self setMidlFace:faceGrid[x][j] moveTo:movePosition nextFace:faceGrid[x][j-1]];
movePosition = curtPosition;
}
//use the guard face to set the last face's move action
[self setTailFace:faceGrid[x][GRID_HEIGHT-1] moveTo:movePosition byGuardSprite:guardSprite];
break;
......
}
I used tick function for same purpose.
-(void)onEnter
{
[super onEnter];
self.isTouchEnabled = true;
[self schedule: #selector(tick:)];
}
-(void) tick: (ccTime) dt
{
CGPoint pos = head.position ;
head.position = ccp(pos.x+gameSpeed, pos.y);
pos = tail.position ;
tail.position = ccp(pos.x+gameSpeed, pos.y);
}

Resources