im new to programming, i have been experimenting with cocos2d, heres the problem, i have made a simple game, device in portrait, it has falling sprites, and i want the sprite to disappear when the position of the top of the sprite < screen.height/2 how can this be done?
heres some code you may be interested in:
this is the falling sprite, it falls from the top of the screen to the bottom
-(void)addRock {
CCSprite *rock = [CCSprite spriteWithFile:#"rock.png"
rect:CGRectMake(0, 0, 27, 40)];
// Determine where to spawn the target along the X axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minX = rock.contentSize.width/2;
int maxX = winSize.width - rock.contentSize.width/2;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX) + minX;
// Create the target slightly off-screen along the right edge,
// and along a random position along the X axis as calculated above
rock.position = ccp(actualX, 500);
[self addChild:rock];
// Determine speed of the target
int actualDuration = spriteDuration;//speed of sprite
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(actualX,-winSize.height+ rock.contentSize.height)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:#selector(spriteMoveFinished:)];
[rock runAction:[CCSequence actions:actionMove, nil]];
}
when the sprite move has finished
-(void)spriteMoveFinished:(id)sender {
CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];
}
To fade your sprite out halfway of the Animation you can use CCSpawn to combine the falling animation with the fadeOut. But as you want it to fade out after a given time, you need to create a Sequence of CCDelayTime and CCFadeOut.
double fadeStart = 0.5;
id wait = [CCDelayTime actionWithDuration: actualDuration * fadeStart];
id fadeOut = [CCFadeOut actionWithDuration: actualDuration * (1.0 - fadeStart)];
id waitThenFade = [CCSequence actions: wait, fadeOut, nil];
id actionMove = ...;
id fullAnimation = [CCSpawn actions:actionMove, waitThenFade, nil];
[rock runAction:[CCSequence actions:fullAnimation, actionMoveDone, nil]];
In case you want the fading to start earlier or later you simply have to move the fadeStart value. 0 will start immediately, 1 will actually not fade, so better pick a value in between.
Maybe something like this?
CGSize size = [[CCDirector sharedDirector] winSize];
CCSprite* img = [[CCSprite alloc] initWithFile:#"yourSprite.png"];
img.position = ccp(size.width/2,size.height + img.boundingBox.size.height/2);
[img runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:3 position:ccp(img.position.x,size.height/2 - img.boundingBox.size.height/2)],
[CCFadeOut actionWithDuration:1],
[CCCallFuncN actionWithTarget:nil selector:#selector(spriteMoveFinished:)],
nil]];
Related
I have around 10 sprite of same image and these are moving, i want to change the image(2 images) of all sprite alternatively by using timer.
I am using following code but its not working for me
CCSprite *target = [CCSprite spriteWithFile:#"images1.png" rect:CGRectMake(0, 0, 120, 140)];
// Determine where to spawn the target along the Y axis
winSize = [[CCDirector sharedDirector] winSize];
int minY = target.contentSize.height/2;
int maxY = (winSize.height/2) - target.contentSize.height/2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) ;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
target.position = ccp(winSize.width + (target.contentSize.width/2), actualY);
[self addChild:target];
// Determine speed of the target
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
id delayTime1 = [CCDelayTime actionWithDuration:1.0f];
id calFun1 = [CCCallBlock actionWithBlock:^{
//HERE SET BLUE TEXTURE..
[target setTexture:[[CCSprite spriteWithFile:#"image1.png"]texture]];
}];
id delayTime2 = [CCDelayTime actionWithDuration:1.0f];
id calFun2 = [CCCallBlock actionWithBlock:^{
//HERE SET RED TEXTURE..
[target setTexture:[[CCSprite spriteWithFile:#"image2.png"]texture]];
}];
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration*2.5 position:ccp(-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];
But by using this code only one image is continuously showing on sprite. The image is not changing.
Try this
-(CCSpriteFrame *)getImageWithName:(NSString *)image{
CCSprite *sprite=[CCSprite spriteWithFile:image];
CCSpriteFrame *frame=[CCSpriteFrame frameWithTexture:sprite.texture rect:CGRectMake(0, 0, sprite.contentSize.width, sprite.contentSize.height)];
return frame;
}
Then
[target setDisplayFrame:[self getImageWithName:#"image1"]];
[target setDisplayFrame:[self getImageWithName:#"image2"]];
I want to integrate cocos2d in one of my view. So, I have a normal view controller(MapEditorViewController) and a view, in my view controller, (I created a IBOutlet UIView *openGLView) in which I want cocos2d to be in. In my view controller, I have a method setupCocos2D :
- (void)setupCocos2D {
CCGLView *glView = [CCGLView viewWithFrame:self.openGLView.bounds
pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8
depthFormat:0 // GL_DEPTH_COMPONENT16_OES
];
glView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.openGLView insertSubview:glView atIndex:0];
[[CCDirector sharedDirector] setOpenGLView:glView];
CCScene *scene = [HelloWorldLayer scene];
[[CCDirector sharedDirector] runWithScene:scene];
}
setupCocos2D is called in viewDidLoad of the class MapEditorViewController.
I have a layer (HelloWorldLayer), which is basically the code in the tutorial of http://www.raywenderlich.com/25736/how-to-make-a-simple-iphone-game-with-cocos2d-2-x-tutorial
// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(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];
// return the scene
return scene;
}
- (void) addMonster {
CCSprite * monster = [CCSprite spriteWithFile:#"backbutton.png"];
// Determine where to spawn the monster along the Y axis
CGSize winSize = [CCDirector sharedDirector].winSize;
int minY = monster.contentSize.height / 2;
int maxY = winSize.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(winSize.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
CCMoveTo * actionMove = [CCMoveTo actionWithDuration:actualDuration
position:ccp(-monster.contentSize.width/2, actualY)];
CCCallBlockN * actionMoveDone = [CCCallBlockN actionWithBlock:^(CCNode *node) {
[node removeFromParentAndCleanup:YES];
}];
[monster runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super initWithColor:ccc4(255,0,255,255)]) ) {
CGSize winSize = [CCDirector sharedDirector].winSize;
CCSprite *player = [CCSprite spriteWithFile:#"carteIntrouvable.png"];
player.position = ccp(player.contentSize.width/2, winSize.height/2);
[self addChild:player];
[self setIsTouchEnabled:YES];
[self schedule:#selector(gameLogic:) interval:1.0];
}
return self;
}
-(void)gameLogic:(ccTime)dt {
[self addMonster];
}
Now, I don't know what I'm doing wrong, the layer appears but it is black, even though I change the line initWithColor in -(id) init.
How can I change the layer's background color, because the code works if I don't integrate cocos2d with UIKit... ?
Alternative Solution: Add CCLayerColor to base layer.
-(void) onEnter
{
[super onEnter];
ccColor4B color = {255,255,0,255};
CCLayerColor *colorLayer = [CCLayerColor layerWithColor:color];
[self addChild:colorLayer z:LAST_LAYER_PLUS_1];
}
I am developing 'Paper Toss' for iphone using cocos2d & I would like to know that how to implement 3D perspective view into this,because while we are throwing the paper ball to the bin,we have to get the 3D feel.I'am attaching the code which i have done,using this i have got a straight line motion.Please help me..
*- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
// Set up initial location of projectile
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *projectile = [CCSprite spriteWithFile:#"ball.png"
rect:CGRectMake(0, 0, 40, 40)];
projectile.position = ccp(winSize.width/2,20);
// Determine offset of location to projectile
int offX = location.x - projectile.position.x;
int offY = location.y - projectile.position.y;
// Bail out if we are shooting down or backwards
if (offY <= 0) return;
// Ok to add now - we've double checked position
[self addChild:projectile];
// Determine where we wish to shoot the projectile to
int realY = winSize.height + (projectile.contentSize.width/2);
float ratio = (float) offX / (float) offY;
int realX = (realY * ratio) + projectile.position.x;
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
[projectile runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallFuncN actionWithTarget:self selector:#selector(spriteMoveFinished:)],
nil]];
//add to the projectiles array
projectile.tag = 2;
[_projectiles addObject:projectile];
}*
Finally I have completed paper toss using cocos2d.I implemented bezier curve and here it is,
// Bezier curve control points
bezier.controlPoint_1 = ccp(location.x-CONTROL_POINT1_X, CONTROL_POINT1_Y);
bezier.controlPoint_2 = ccp(location.x-CONTROL_POINT2_X, CONTROL_POINT2_Y);
bezier.endPosition = ccp(location.x-CONTROL_POINT1_X,distance);
// Motion along bezier curve and finally call a function
[projectile runAction:[CCSequence actions:
[CCAutoBezier actionWithDuration:DEFAULT_ACTION_DURATION bezier:bezier],
[CCCallFuncN actionWithTarget:self selector:#selector(collisionCheck:)], nil]];
Just scale your sprite image so it gets smaller the "further away" it is.
Hey you can use bezier curve for 3d perspective view in cocos2d.
bezier.controlPoint_1 = ccp(location.x-CONTROL_POINT1_X, CONTROL_POINT1_Y);
bezier.controlPoint_2 = ccp(location.x-CONTROL_POINT2_X, CONTROL_POINT2_Y);
I am trying to simulate a modal view in cocos2d by displaying a few sprites over my scene and showing a menuitemsprite as a continue button. In the code below, i show my game over modal and have the menu set up with a CCMenuItemSprite; which does not respond to touches, and a CCMenuItemImage; which does work.
-(void) gameOver {
CGSize size = [[CCDirector sharedDirector] winSize];
self.menu.isTouchEnabled = NO;
CCLayer *modalLayer = [[CCLayer alloc] init];
[self addChild:modalLayer z:20];
CCSprite *spriteGameOver = [CCSprite spriteWithFile:#"game_over.png"];
spriteGameOver.position = ccp( size.width/2,size.height/2);
CCLabelTTF *lblGameOver = [CCLabelTTF labelWithString:[NSString stringWithFormat:#"Game Over!\nScore %d/%d",numCorrect,questionIdx] dimensions:CGSizeMake(380, 300) alignment:CCTextAlignmentCenter fontName:#"Trebuchet MS" fontSize:50.0f];
// position the label on the center of the screen
lblGameOver.position = ccp(size.width/2-200, size.height/2-100);
lblGameOver.color = ccc3(20, 20, 20);
lblGameOver.opacity = 0;
// add the label as a child to this Layer
[spriteGameOver addChild: lblGameOver];
spriteGameOver.opacity = 0;
[modalLayer addChild:spriteGameOver];
CCSprite *spriteGameOverBtn = [CCSprite spriteWithFile:#"mainButton.png" rect:CGRectMake(0,0,300,60)];
spriteGameOverBtn.position = ccp( size.width/2,size.height/2-100);
CCLabelTTF *lblGameOverBtn = [CCLabelTTF labelWithString:#"Continue" dimensions:CGSizeMake(300, 60) alignment:CCTextAlignmentCenter fontName:#"Trebuchet MS" fontSize:40.0f];
//lblGameOverBtn.position = ccp(size.width/2-200, size.height/2-300);
[lblGameOverBtn setAnchorPoint:ccp(0.0f,0.1f)];
lblGameOverBtn.color = ccc3(20, 20, 20);
lblGameOverBtn.opacity = 0;
// add the label as a child to this Layer
[spriteGameOverBtn addChild: lblGameOverBtn];
spriteGameOverBtn.opacity = 0;
CCMenuItemImage *itemH = [CCMenuItemImage itemFromNormalImage:#"backArrow.png" selectedImage:#"backArrowS.png" target:self selector:#selector(goToMain:)];
itemH.position = ccp( size.width/2,size.height/2-100);
CCMenuItemSprite *mGameOverBtn = [CCMenuItemSprite itemFromNormalSprite:spriteGameOverBtn selectedSprite:nil disabledSprite:nil target:self selector:#selector(goToMain:)];
CCMenu *menuGO = [CCMenu menuWithItems: itemH,mGameOverBtn, nil];
menuGO.position = ccp( 0, 0);
[modalLayer addChild:menuGO z:21];
[lblGameOverBtn runAction:[CCSequence actions:[CCDelayTime actionWithDuration: 1.75f],[CCFadeIn actionWithDuration: 1.75f],nil]];
[spriteGameOverBtn runAction:[CCSequence actions:[CCDelayTime actionWithDuration: 1.75f],[CCFadeIn actionWithDuration: 1.75f],[CCDelayTime actionWithDuration: 3.75f],nil]];
[lblGameOver runAction:[CCSequence actions:[CCDelayTime actionWithDuration: 1.75f],[CCFadeIn actionWithDuration: 1.75f],[CCDelayTime actionWithDuration: 3.75f],nil]];
[spriteGameOver runAction:[CCSequence actions:[CCDelayTime actionWithDuration: 1.75f],[CCFadeIn actionWithDuration: 1.75f],[CCDelayTime actionWithDuration: 3.75f],nil]];
//[self runAction:[CCSequence actions:[CCDelayTime actionWithDuration: 2.75f],[CCCallFunc actionWithTarget:self selector:#selector(goToMain:)], nil]];
}
I'm having the same problem with CCMenuItemSprite too. It looks like the CCMenuItemSprite-class is a bit buggy. In my case it doesn't respond to touches. But I found out it has something to do with multi-layered Sprites inside the CCMenuItemSprite. So when I use a single-layered Sprite it works, but when I use a Sprite which contains multiple embedded sprites it doesn't.
My 'not-ready-yet' solution right now is setting the contentSize to the appropriate size of the CCMenuItemSprite right after it has been initialized:
CCMenuItemSprite * menuItem = [CCMenuItemSprite itemWithNormalSprite:multiLayeredSprite selectedSprite:nil target:self selector:#selector(clickHandler:)];
[s setContentSize:backgroundSprite.contentSize];
CCMenu * menu = [CCMenu menuWithItems:
menuItem,
nil];
It's receiving touch-events now. The only problem I now have is the positioning of the Rectangle... it's still in the upper-right corner. I'll try to found out how to fix this now.
Hopefully this is clarifying a bit of the problem.
Have you have registered your scene with the touch dispatcher and your selectors actually do something?
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:NO]
I am making a game in Cocos2d. I want enemies to spawn on the right and left sides of the screen, and move to a random point on the screen, then repeat. Despite my efforts, I cannot figure it out. This should be relatively easy to answer, it should look like something out of one of Ray Wenderlich's tutorials. Some code would be nice. Thanks!
This is the code from ray Wanderlich tutorial..
[self schedule:#selector(addTarget) interval:2.0];
-(void)addTarget {
CCSprite *target = [CCSprite spriteWithFile:#"Target.jpg"
rect:CGRectMake(0, 0, 27, 40)]; //Creating Sprite and setting rect
// Determine where to spawn the target along the Y axis
CGSize winSize = [[CCDirector sharedDirector] winSize]; //Get the screensize
int minY = target.contentSize.height/2;
int maxY = winSize.height - target.contentSize.height/2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
target.position = ccp(winSize.width + (target.contentSize.width/2), actualY);
[self addChild:target];
// Determine speed of the target
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration
position:ccp(-target.contentSize.width/2, actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(spriteMoveFinished:)];
[target runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
}
minY-->position at the bottom of the screen
maxY--->position at the top of the screen.
rangeY ---> the height of the screen.
actualY--->calculate the random point between bottom of the screen and top of the screen.
target.position --> setting random position for the sprite to move.
actualDuration --> getting random duration.so that the sprite moves in various time delay.
actionMove --> creating Move action.
actionMoveDone ---> After completing move action,calling spriteMoveFinished to remove sprites.