how to make a jerking in a sprite motion - iphone

all, I am making a game in which a sprite is move from one position to another through a jerk of 19 pixel, basically I want to make a game just like stacker online. in the app store, in this game the box is move through a jerk of 19 piexel , and the object is moving is in the grid , i have following code but I not give me the jerk motion
-(void)actionLayer
{
isRunning = 0;
addPixedlValue += 19;
id actionMove = [CCMoveTo actionWithDuration:6 position:ccp( 50,109)]; //300,100
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:#selector(LayerAction:)];
animateAction = [CCSequence actions:actionMove, actionMoveDone, nil];
NSLog(#"pixel value %d",addPixedlValue);
[boxSprite runAction:animateAction];
}
-(void)LayerAction:(id)sender
{
addPixedlValue +=19;
id actionMove = [CCMoveTo actionWithDuration:6 position:ccp( 270,109)]; //300,100
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:#selector(actionLayer)];
animateAction = [CCSequence actions:actionMove, actionMoveDone, nil];
[boxSprite runAction:animateAction];
}

I think your problem can be sort out By scheduling a selector for a time interval say 0.1 and you can update the position according to your self.
-(void)moveSprite
{
sprite.position = ccp ( sprite.position.x + 5 , sprite.position.y);
}
And unshedule the selector whenever needed to stop the sprite.
For Scheduling a selector
[self schedule : #selector ( moveSprite ) interval : 0.1];
For unscheduling
[self unschedule : #selector ( moveSprite )];
This help you in make jerking movement.

Related

How to stop runAction in cocos2d

How to stop all actions in game after some time?
in below code i am calling runaction on a sprite.
id actionMove = [CCMoveTo actionWithDuration:actualDuration*2.5 position:ccp(winSize.width + (target.contentSize.width/2), actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:#selector(spriteMoveFinished:)];
id sequece = [CCSequence actions:delayTime1, calFun1, delayTime2, calFun2,actionMove, actionMoveDone, nil];
id repeate = [CCRepeatForever actionWithAction:sequece];
[target runAction:repeate];
In this code a sprite is continuously moving. how to stop the above action after some time or after some condition ?
In runAction call Function and stop action for sprite.
[CCCallFuncN actionWithTarget:self selector:#selector(setInvisible:)];
- (void)setInvisiblestone:(CCNode *)node
{
[target stopAllActions];
}
All action stop in method.
-(void)gameover
{
[self unscheduleAllSelectors];
}

getting sender object in cocos2d

I am making a game using cocos2d. By using the following code,I have added an animation.How do I send the CCSprite reference?
if(sprite != monkey)
{
[self scheduleOnce:#selector(animate_sprite:) delay:0.1f];
}
-(void)animate_sprite:(ccTime) dt
{
id s2 = [CCScaleTo actionWithDuration:0.5 scaleX:2.0 scaleY:2.0];
id fun = [CCCallFuncN actionWithTarget:self selector:#selector(spriteDone:)];
[sprite runAction:[CCSequence actions:s2,fun,nil]];
}
How to get the sprite reference in animate_sprite method?
You can use performSelector:withObject:afterDelay this will do the same thing.
if(sprite != monkey)
{
[self performSelector:#selector(animate_sprite:) withObject:sprite afterDelay:0.1f];
}
-(void)animate_sprite:(CCSprite *)sprite
{
id s2 = [CCScaleTo actionWithDuration:0.5 scaleX:2.0 scaleY:2.0];
id fun = [CCCallFuncN actionWithTarget:self selector:#selector(spriteDone:)];
[sprite runAction:[CCSequence actions:s2,fun,nil]];
}
So just edit your method to use the sprite and not the ccTime object since you are not using it at all.

How to do this in Cocos2d?

Sorry about the poor question title, it's just that this seems to big for a title. So here's the dirt:
I am making a game (obviously) and I want the enemies to shoot (not necessarily at the player). I want the shoot method to be in the Enemies file, so as not to clutter up my HelloWorldLayer.m file even more. Here's what I'm using right now:
HelloWorldLayer.m
-(void)addEnemy:(BigAndStrongEnemy *)enemy {
enemy = nil;
if((arc4random() % 4) == 3) {
enemy = [BigAndStrongEnemy enemy];
} else {
enemy = [SmallAndFastEnemy enemy];
}
if(buffDude.position.y > character.position.y || buffDude.position.y < (character.position.y + 10)) {
}
int rand = arc4random() % 320;
if((arc4random() % 2 == 1)) {
[enemy setPosition:ccp(0,rand)];
}else{
[enemy setPosition:ccp(480,rand)];
}
[self animateEnemy:enemy];
[self addChild:enemy];
}
-(void)animateEnemy:(BigAndStrongEnemy *)enemy2 {
float randX = arc4random() % 480;
float randY = arc4random() % 320;
int rand = arc4random() % 320;
CGPoint moveToPoint = CGPointMake(randX, (randY - rand));
[enemies addObject:enemy2];
action = [CCSequence actions:
[CCMoveBy actionWithDuration:1 position:ccpMult(ccpNormalize(ccpSub(moveToPoint, enemy2.position)), 75)],
[CCMoveBy actionWithDuration:3 position:ccp(buffDude.position.x,buffDude.position.y)],
nil];
CCCallFuncO *a = [CCCallFuncO actionWithTarget:self selector:(#selector(shoot:)) object:enemy2];
CCSequence *s = [CCSequence actions:action,a, nil];
CCRepeatForever *repeat = [CCRepeatForever actionWithAction:s];
[enemy2 runAction:repeat];
}
And here's the Shoot info from the Enemies class:
Enemies.m:
-(void)shoot:(id)sender {
BigAndStrongEnemy *enemy = (BigAndStrongEnemy *)sender;
[enemy shoot];
}
-(void)spriteMoveFinished:(id)sender {
CCSprite *b = (CCSprite *)sender;
[self removeChild:b cleanup:YES];
}
-(void)shoot {
buffDude = [CCSprite spriteWithFile:#"bigAndStrongEnemy.gif"];
CCSprite *b = [CCSprite spriteWithFile:#"bullet.gif"];
b.position = ccp(self.position.x,self.position.y);
b.tag = 2;
[self addChild:b];
[bullets addObject:b];
CGSize winSize = [[CCDirector sharedDirector] winSize];
CGPoint point = CGPointMake((winSize.width - (winSize.width - self.position.x)),0);
[b runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:0.5 position:point],
[CCCallFuncN actionWithTarget:self selector:#selector(spriteMoveFinished:)],
nil]];
}
Every time the 3 seconds goes by, the app crashes, and goes to the breakpoint in the CCCallFuncO file. I haven't touched it, is the thing. I am completely confused. Any help is greatly appreciated. Sorry about the long question. Thanks!!
It looks like your CCCallFuncO is calling [self shoot:enemy2] where self is the HelloWorldLayer object, but shoot is defined in the Enemies class.
Edit:
buffDude should be released before assigning it and retain it afterwards, like this:
Change this:
buffDude = [CCSprite spriteWithFile:#"bigAndStrongEnemy.gif"];
to this:
[buffDude release];
buffDude = [CCSprite spriteWithFile:#"bigAndStrongEnemy.gif"];
[buffDude retain];
This assumes that this is the only place where buffDude is assigned. If it is also assigned elsewhere, make sure you properly retain and release it there as well.
Although, the more I think about it, I don't understand why you create a new buffDude every time shoot is called. I'm not sure what you're doing, so I won't say it's wrong, but it doesn't look right to me anyway.
from what i see (and the fact that i only worked with cocos2d-x) i can only tell you to test whether it steps inside your shoot funciton or not, but i guess you are somhow using CCCallFuncO bad, maybe you have to call it passing enemy2 also for the actionWithTarget parameter (i can tell that becouse that's how cocos2d-x works), also check if big and small enemy types can be converted together freely.

CCSequence Firing Actions in Cocos2d

I have three actions that are triggered in the CCSequence. The way I want it to be fired is that first the sprite should move in the center of the screen and then the scale action is fired. But for some reason the sprite moves to the center of the screen correctly but when the scale is fired it uses the old sprite position.
id actionRotate = [CCRotateBy actionWithDuration:0.6 angle:360];
id disappear = [CCFadeTo actionWithDuration:.5 opacity:0];
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:#selector(removeAlphabetToFindFromView:)];
id actionScale = [CCScaleBy actionWithDuration:0.6 scaleX:10 scaleY:10];
id moveTo = [CCMoveTo actionWithDuration:0.6 position:ccp(windowSize.width/2, windowSize.height/2)];
//[self removeAlphabetToFindFromView2:alphabetToFind];
[alphabetToFind runAction:[CCSequence actions:moveTo,actionScale,disappear,actionMoveDone, nil]];
UPDATE 1:
Maybe the startAnimation method has something to do with this. I have public x and y variables which is used as x and y positions for 4 different sprites:
-(void) startAnimation:(CCSprite *) sprite
{
[self generateRandomCoordinates];
id actionMove = [CCMoveTo actionWithDuration:3.0 position:ccp(x,y)];
id actionRotate = [CCRotateBy actionWithDuration:0.0 angle:rotateBy];
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:#selector(finishedMoving:)];
[sprite runAction:[CCSequence actions:actionMove,actionRotate, actionMoveDone, nil]];
}
-(void) finishedMoving:(id) sender
{
if(counter == randomAlphabets.count)
{
counter = 0;
}
CCSprite *sprite = [randomAlphabets objectAtIndex:counter];
[self generateRandomCoordinates];
[self startAnimation:sprite];
counter +=1;
}
UPDATE 2:
As expected the x and y used in the startAnimation method (getRandomCoordinates) were causing the problem. So, I removed all the actions before firing the sequence and now it works fine.

What is the best way to start Cocos2d Animation of Multiple Sprites?

I have an array randomAlphabets which contains CCSprite objects. I need to start animation on these objects. The randomAlphabets array (NSMutable) can contain max of 4 elements. I am running a loop and then starting the animation. Is this the correct way?
-(void) startAnimation:(CCSprite *) sprite
{
[self generateRandomCoordinates];
id actionMove = [CCMoveTo actionWithDuration:3.0 position:ccp(x,y)];
id actionRotate = [CCRotateBy actionWithDuration:0.0 angle:rotateBy];
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:#selector(finishedMoving:)];
[sprite runAction:[CCSequence actions:actionMove,actionRotate, actionMoveDone, nil]];
}
-(void) addAlphabetsOnScreen
{
for (int i=0; i<=randomAlphabets.count -1; i++) {
CCSprite *sprite = [randomAlphabets objectAtIndex:i];
[self generateRandomCoordinates];
sprite.position = ccp(x,y);
[self addChild:sprite];
[self startAnimation:sprite];
}
}
Sure, why not?
If have performance issues or sprites not starting their anims simultaneously, you might want to "prepare" the sequences for each sprite in one step (maybe after loading the level) and then just kick them all of in another step. 4 Sprites starting at the same time seems not too tough though.