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];
}
Related
I am having trouble with my game, it was running fine until i tried to add the animation, now whenever i go to shoot it crashes my game and i cant work out what is wrong with my animation code. Below i will put in all the code that causes the ninja star to shoot but as i said i believe the error is in the animation.
ccsprite Projectile is what gets shoot and what im trying to animate
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (StrategyBullet > 0) {
//SOME IF STATEMENTS
if (Strategyscore == 47) {
StrategyBullet = StrategyBullet +5;
}
if (Strategyscore == 97) {
StrategyBullet = StrategyBullet +5;
}
if (Strategyscore == 197) {
StrategyBullet = StrategyBullet +10;
}
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace:touch];
// Set up initial location of projectile
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *projectile = [CCSprite spriteWithFile:#"ninja star 1.png"];
[self addChild:projectile z:2];
{
NSString *animationName = #"UNIQUE_ANIMATION_NAME";
CCAnimation* animation = nil;
animation = [[CCAnimationCache sharedAnimationCache] animationByName:animationName];
if(!animation)
{
NSMutableArray *animFrames = [NSMutableArray array];
for( int i=1;i<=5;i++)
{
NSString* path = [NSString stringWithFormat:#"ninja star %d.png", i];
CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:path];
CGSize texSize = tex.contentSize;
CGRect texRect = CGRectMake(0, 0, texSize.width, texSize.height);
CCSpriteFrame* frame = [CCSpriteFrame frameWithTexture:tex rect:texRect];
[animFrames addObject:frame];
}
animation = [CCAnimation animationWithSpriteFrames:animFrames];
animation.delayPerUnit = 0.175f;
animation.restoreOriginalFrame = YES;
[[CCAnimationCache sharedAnimationCache] addAnimation:animation name:animationName];
}
if(animation)
{
CCAnimate *animAction = [CCAnimate actionWithAnimation:animation];
[projectile runAction:animAction];
}
}
projectile.position = ccp(20, winSize.height/2);
// Determine offset of location to projectile
CGPoint offset = ccpSub(location, projectile.position);
// Bail out if you are shooting down or backwards
if (offset.x <= 0) return;
// Ok to add now - we've double checked position
[self addChild:projectile];
int realX = winSize.width + (projectile.contentSize.width/2);
float ratio = (float) offset.y / (float) offset.x;
int realY = (realX * ratio) + projectile.position.y;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far you'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;
// collison stuff
projectile.tag = 2;
[_projectiles addObject:projectile];
StrategyBullet --;
[StrategyBulletLabel setString:[NSString stringWithFormat:#"%d", StrategyBullet]];
// Move projectile to actual endpoint
[projectile runAction:
[CCSequence actions:
[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallBlockN actionWithBlock:^(CCNode *node) {
[node removeFromParentAndCleanup:YES];
// CCCallBlockN in ccTouchesEnded
[_projectiles removeObject:node];
}],
nil]];
}
}
The crash is because you addChild projectile twice (my best guess). The rest looks ok, although i tend to use sprite sheets for animations as opposed to file-based frames as you do.
I am a newbie to the world of cocos2d i am developing my first tutorial and facing one problem
my problem is i have an image (1024 X 320) and my orientation is landscape i need to move that image continuously from right to left for this purpose i have used space shooter tutorial by Ray(Thanks to him) but the image doesn't seem to be appearing again and again.
my code is..
-(id) init
{
if( (self=[super init])) {
CGSize screenSize = [CCDirector sharedDirector].winSize;
// 1) Create the CCParallaxNode
backgroundNode = [CCParallaxNode node];
[self addChild:backgroundNode z:-1];
// 2) Create the sprites we'll add to the CCParallaxNode
Back = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
//Back.position=ccp(screenSize.width/2, screenSize.height/2);
Back.rotation = -90;
Back1 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
Back1.rotation = -90;
// 3) Determine relative movement speeds for space dust and background
CGPoint dustSpeed = ccp(0.1, 0.1);
// 4) Add children to CCParallaxNode
[backgroundNode addChild:Back z:0 parallaxRatio:dustSpeed positionOffset:ccp(screenSize.width/2, screenSize.height/2)];
NSLog(#"back.content width is...%f",Back.contentSize.width);
[backgroundNode addChild:Back1 z:1 parallaxRatio:dustSpeed positionOffset:ccp(screenSize.width/2, screenSize.height*2)];
// 5) Enable updates
[self scheduleUpdate];
}
return self;
}
- (void)update:(ccTime)dt {
// 1) Update background position
CGPoint backgroundScrollVel = ccp(0,-1000);
backgroundNode.position = ccpAdd(backgroundNode.position, ccpMult(backgroundScrollVel, dt));
// 2) Check for background elements moving offscreen
NSArray *spaceDusts = [NSArray arrayWithObjects:Back, Back1, nil];
for (CCSprite *spaceDust in spaceDusts) {
if ([backgroundNode convertToWorldSpace:spaceDust.position].x < -spaceDust.contentSize.width) {
[backgroundNode incrementOffset:ccp(2*spaceDust.contentSize.width,0) forChild:spaceDust];
}
}
}
please help me out of this
Thanks in advance.
try this one
if (backgroundNode.position.y <-screenSize.height*2)
backgroundNode.position = ccp(0,0);
As init method is called only once the approach you are doing will be done only one time you need to again set the Position of the backgroundNode to 0 in your update method.
here the multiple may vary
Try this code it is creating a paralax moving from bottom to top change CGPointMake(0, 1.0) to this CGPointMake(1.0,0) in paraNode addChild line.
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) )
{
float yPos =0.0;
NSMutableString *fileNameString = [[NSMutableString alloc]initWithCapacity:0];
if (IS_IPHONE_5)
{
[fileNameString appendString:#"Background-568h.png"];
yPos= 560.0;
}
else
{
[fileNameString appendString:#"Background.png"];
yPos= 470.0;
}
background1 = [CCSprite spriteWithFile:fileNameString];
background1.tag = 1;
background1.anchorPoint = CGPointMake(0,0);
background2 = [CCSprite spriteWithFile:fileNameString];
background2.tag = 2;
background2.anchorPoint = CGPointMake(0,0);
background3 = [CCSprite spriteWithFile:fileNameString];
background3.tag = 3;
background3.anchorPoint = CGPointMake(0,0);
background4 = [CCSprite spriteWithFile:fileNameString];
background4.tag = 4;
background4.anchorPoint = CGPointMake(0,0);
paraNode = [CCParallaxNode node];
[paraNode addChild:background1 z:1 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, 0)];
[paraNode addChild:background2 z:2 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos)];
[paraNode addChild:background3 z:3 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos*2)];
[paraNode addChild:background4 z:4 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos*3)];
[self addChild:paraNode z:-1 tag:123];
[self updateFrameRate:0.7 andYposition:yPos];
[fileNameString release];
fileNameString = nil;
}
return self;
}
-(void)updateFrameRate:(float)speedValue andYposition:(float)yposToSet
{
move1 = [CCMoveBy actionWithDuration:speedValue position:CGPointMake(0, yposToSet)];
move2 = [CCMoveBy actionWithDuration:0.0 position:CGPointMake(0, -yposToSet)];
move3 = [CCMoveBy actionWithDuration:0.0 position:CGPointMake(0, 0)];
CCSequence* sequence = [CCSequence actions:move1,move2,move3, nil];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:sequence];
[paraNode runAction:repeat];
}
I want to add this game over scene to this game that I am trying to do for my homework, and I seem to not have it where if you kill the target the game over scene will pop up. I tried putting my code in every line and see if it will finally work but no it didn't. So now I have to ask for some help.
. m file
- (void)addTarget10 {
Boss *target10 = nil;
if ((arc4random() % 2) == 0) {{
target10 = [WeakAndFastBoss9 boss9];
}} else {
target10 = [WeakAndFastBoss9 boss9];
}
[[SimpleAudioEngine sharedEngine] playEffect:#"lastboss.mp3"];
// Determine where to spawn the target along the Y axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minY = target10.contentSize.height/2;
int maxY = winSize.height - target10.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
target10.position = ccp(winSize.width + (target10.contentSize.width/2), actualY);
[self addChild:target10 ];
// Determine speed of the target
int minDuration = target10.minMoveDuration;
int maxDuration = target10.maxMoveDuration;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(- target10.contentSize.width/2, actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(spriteMoveFinished9:)];
[target10 runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
target10.tag = 1;
[_targets addObject:target10];
}
-(void)gameLogicboss9:(ccTime)dt {
[self unschedule:_cmd];
[self addTarget10];
}
- (void)updateboss9:(ccTime)dt {
CGRect projectileRect = CGRectMake(projectile.position.x - (projectile.contentSize.width/2),
projectile.position.y - (projectile.contentSize.height/2),
projectile.contentSize.width,
projectile.contentSize.height);
BOOL bossHit = FALSE;
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];
for (CCSprite *target1 in _targets) {
CGRect target1Rect = CGRectMake(target1.position.x - (target1.contentSize.width/2),
target1.position.y - (target1.contentSize.height/2),
target1.contentSize.width,
target1.contentSize.height);
if (CGRectIntersectsRect(projectileRect, target1Rect)) {
[targetsToDelete addObject:target1];
bossHit = TRUE;
Boss *boss = (Boss *)target1;
boss.hp--;
if (boss.hp <= 0 ) {
[targetsToDelete addObject:target1];
}
break;
}
}
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
[self removeChild:target cleanup:YES];
_projectilesDestroyed++;
if (_projectilesDestroyed > 2) {
}
}
if (bossHit) {
//[projectilesToDelete addObject:projectile];
}
[targetsToDelete release];
}
-(void)spriteMoveFinishedboss9:(id)sender {
CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];
if (sprite.tag == 1) { // target
[_targets removeObject:sprite];
} else if (sprite.tag == 2) { // projectile
[_projectiles removeObject:sprite];
} }
This the game over scene I want to add when target 10/ boss 9 is killed
GameOverScene *gameOverScene = [GameOverScene node];
[gameOverScene.layer.label setString:#"You Lose"];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
Right now my other game over scene is when the sprite is moved passed screen.If you need me to answer any questions feel free to ask.
For scene replace you try this for your game code..
First Add this code to your GameOverScene class
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
GameOverScene *layer = [GameOverScene node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
Make your GameOverClass is subclass of CCLayer,
Than when You want to change scene do this
[[CCDirector sharedDirector] replaceScene:[GameOverScene scene]];
Ok, so you have to create a new scene. This can simple be done using File->New File and make it a subclass of NSObject. You then change the subclass to an CCLayer. As a test, you can just copy your code from the hello world layer. Next, just import the new class in your helloworld layer class and create a instance of it. Then in a method use [[CCDirector sharedDirector] replaceScene:sceneName];
You can use this site for more info, its very helpful, just read through it and you will find your answer:http://www.raywenderlich.com/352/how-to-make-a-simple-iphone-game-with-cocos2d-tutorial
I made my map to scroll automatically however I would like to know how can I slow down the scrolling before the map reaches the end and when it does I would like the map to stop scrolling. I want to know how to do this because my game is about the player trying to shoot the enemy before he reaches the end of the map where there is shelter for him to hide. I would like that before the enemy reaches the shelter have the scrolling slow down and when the enemy reaches the shelter I would like the map to stop scrolling.
Here is the code:
#implementation GameplayScrollingLayer
// Scrolling with TileMap Layers inside of a Parallax Node
-(void)addScrollingBackgroundWithTileMapInsideParallax {
CGSize screenSize = [[CCDirector sharedDirector] winSize];
CGSize levelSize = [[GameManager sharedGameManager]
getDimensionsOfCurrentScene];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
tileMapNode = [CCTMXTiledMap
tiledMapWithTMXFile:#"Level2TileMap.tmx"];
} else {
tileMapNode = [CCTMXTiledMap
tiledMapWithTMXFile:#"Level2TileMapiPhone.tmx"];
}
CCTMXLayer *groundLayer = [tileMapNode layerNamed:#"GroundLayer"];
CCTMXLayer *rockColumnsLayer = [tileMapNode
layerNamed:#"RockColumnsLayer"];
CCTMXLayer *rockBoulderLayer = [tileMapNode
layerNamed:#"RockBoulderLayer"];
parallaxNode = [CCParallaxNode node];
[parallaxNode setPosition:
ccp(levelSize.width/2,screenSize.height/2)];
float xOffset = 0.0f;
xOffset = (levelSize.width/2);
[groundLayer retain];
[groundLayer removeFromParentAndCleanup:NO];
[groundLayer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
[parallaxNode addChild:groundLayer z:30 parallaxRatio:ccp(1,1)
positionOffset:ccp(0,0)];
[groundLayer release];
xOffset = (levelSize.width/2) * 0.8f;
[rockColumnsLayer retain];
[rockColumnsLayer removeFromParentAndCleanup:NO];
[rockColumnsLayer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
[parallaxNode addChild:rockColumnsLayer z:20
parallaxRatio:ccp(0.2,1)
positionOffset:ccp(xOffset, 0.0f)];
[rockColumnsLayer release];
xOffset = (levelSize.width/2) * 0.3f;
[rockBoulderLayer retain];
[rockBoulderLayer removeFromParentAndCleanup:NO];
[rockBoulderLayer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
[parallaxNode addChild:rockBoulderLayer z:30
parallaxRatio:ccp(0.7,1)
positionOffset:ccp(xOffset, 0.0f)];
[rockBoulderLayer release];
[self addChild:parallaxNode z:1];
}
// Accelerometer
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { //new
shipSpeedY = 9.0 + acceleration.x*20;
shipSpeedX = -acceleration.y*20;
}
// Updating ship based on accelerometer
-(void)updateShip {
float maxY = winSize.height - ship.contentSize.height/2;
float minY = ship.contentSize.height/2;
float newY = ship.position.y + shipSpeedY;
newY = MIN(MAX(newY, minY), maxY);
float maxX = winSize.width - ship.contentSize.width/2;
float minX = ship.contentSize.width/2;
float newX = ship.position.x + shipSpeedX;
newX = MIN(MAX(newX, minX), maxX);
ship.position = ccp(newX, newY);
}
// Making background scroll automatically
-(void)update:(ccTime)dt {
[self updateShip];
CGPoint backgroundScrollVel = ccp(-100, 0);
parallaxNode.position = ccpAdd(parallaxNode.position, ccpMult(backgroundScrollVel, dt));
}
// Adding sprite ship
-(id)init {
self = [super init];
if (self != nil) {
winSize = [CCDirector sharedDirector].winSize;
ship=[CCSprite spriteWithFile:#"ship.png"];
ship.position=ccp(60,160);
[self addChild:ship z:100];
self.isAccelerometerEnabled = YES; //new
[self scheduleUpdate]; //new
[self addScrollingBackgroundWithTileMapInsideParallax];
}
return self;
}
- (void) dealloc
{
[super dealloc];
}
#end
i have a "mini map" that I am using to show a portion of the background.
How can I constrain the CCRenderTexure to the top right corner of the screen? I am also using CCCamera to follow a sprite.
in init()
CGSize s = [[CCDirector sharedDirector] winSize];
minimap = [[CCRenderTexture renderTextureWithWidth:s.width * 1.5 height:s.height * 1.5] retain];
[minimap setPosition:ccp( s.width - ( s.width * kMinimapScaleFactor ) - 5, s.height - ( s.height * kMinimapScaleFactor ) - 5)];
[minimap begin];
[self visit];
[minimap end];
CCSprite *mms = [minimap sprite];
[mms setScale:kMinimapScaleFactor];
mms.scaleY *= -1;
mms.anchorPoint = ccp(0, 0);
[self addChild:minimap z:1 tag:1];
[self schedule:#selector(updateMinimap:) interval:1.0f];
Above init()
#define kMinimapScaleFactor 0.2
-(void) updateMinimap: (ccTime) dt
{
[minimap begin];
[self visit];
[minimap end];
}
in .h
CCRenderTexture *minimap;
#property(nonatomic, retain) CCRenderTexture *minimap;
Here is how I use CCCamera
id cameraMove = [CCFollow actionWithTarget:_ball];
[self runAction:cameraMove];
Anyone know?
Thanks
All you have to do is add it to the scene id
+ (id)scene
{
CCScene *scene = [CCScene node];
GameScene *layer = [GameScene node];
[scene addChild:layer];
CGSize s = [[CCDirector sharedDirector] winSize];
layer.player = [CCRenderTexture renderTextureWithWidth:s.width height:s.height];
CCSprite *mms = [layer.player sprite];
[mms setScale:kMinimapScaleFactor];
mms.scaleY *= -1;
mms.position = ccp(300, 400);
[scene addChild:layer.player z:2 tag:1];
[layer schedule:#selector(updateMinimap:) interval:1/30.0f];
layer._mini = [CCSprite spriteWithFile:#"minimap.png"];
layer._mini.position = ccp(405, 255);
layer._mini.opacity = 150;
[scene addChild:layer._mini];
return scene;
}