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
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
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 ];
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.
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];
}
}
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);
}