Use of undeclared identifier winSize - objective-c

Not really sure why I am getting this error but I have looked in the .h file and I can't seem to come up with the reason xCode is throwing this error:
// on "init" you need to initialize your instance
-(id) init
{
if ((self=[super init])) {
_batchNode = [CCSpriteBatchNode batchNodeWithFile:#"Sprites.pvr.ccz"]; //1
[self addChild:_batchNode]; //2
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"Sprites.plist"]; //3
_ship = [CCSprite spriteWithSpriteFrameName:#"SpaceFlier_sm_1.png"]; //4
CGSize winSize = [CCDirector sharedDirector].winSize; //5
_ship.position = ccp(winSize.width * 0.1, winSize.height * 0.5); //6
[_batchNode addChild:_ship z:1]; //7
}
return self;
// 1) Create the CCParallaxNode
_backgroundNode = [CCParallaxNode node];
[self addChild:_backgroundNode z:-1];
// 2) Create the sprites we'll add to the CCParallaxNode
_spacedust1 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
_spacedust2 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
_planetsunrise = [CCSprite spriteWithFile:#"bg_planetsunrise.png"];
_galaxy = [CCSprite spriteWithFile:#"bg_galaxy.png"];
_spacialanomaly = [CCSprite spriteWithFile:#"bg_spacialanomaly.png"];
_spacialanomaly2 = [CCSprite spriteWithFile:#"bg_spacialanomaly2.png"];
// 3) Determine relative movement speeds for space dust and background
CGPoint dustSpeed = ccp(0.1, 0.1);
CGPoint bgSpeed = ccp(0.05, 0.05);
// 4) Add children to CCParallaxNode
[_backgroundNode addChild:_spacedust1 z:0 parallaxRatio:dustSpeed positionOffset:ccp(0,winSize.height/2)];
[_backgroundNode addChild:_spacedust2 z:0 parallaxRatio:dustSpeed positionOffset:ccp(_spacedust1.contentSize.width,winSize.height/2)];
[_backgroundNode addChild:_galaxy z:-1 parallaxRatio:bgSpeed positionOffset:ccp(0,winSize.height * 0.7)];
[_backgroundNode addChild:_planetsunrise z:-1 parallaxRatio:bgSpeed positionOffset:ccp(600,winSize.height * 0)];
[_backgroundNode addChild:_spacialanomaly z:-1 parallaxRatio:bgSpeed positionOffset:ccp(900,winSize.height * 0.3)];
[_backgroundNode addChild:_spacialanomaly2 z:-1 parallaxRatio:bgSpeed positionOffset:ccp(1500,winSize.height * 0.9)];
}

First off, unless C2D somehow magically changes the way return works, you proceed to do a lot of stuff after returning which can never be reached. You've just returned; you've exited the method. It's like telling the painter to leave the room he's working on and go home for the day... then screaming out to nothingness that he should paint the walls red. Actually, you wouldn't get to scream at all. Here's an example:
- (void) foo {
int x = 10;
return; //return control to caller
self->someValue = x; //never done; we've returned
}
x would be assigned ten and then you would return. Any lines afterwards are meaningless. Second of all, there's this line here.
CGSize winSize = [CCDirector sharedDirector].winSize;
It occurs within an if statement. The variable winSize can only be used within the constraints of the if statement you declared it in. It's "out of scope" of anything else. For example, the following will give the same warning.
- (void) bar {
if (0){
int x = 1;
}
int y = x;
}
Why not place all the stuff below return inside the if loop, right before it closes?

Related

If Else satement working but not updating cocos2d

i have tested my code by changing the starting lives vaule, the problem is it doesn't remove them as the statement becomes valid, How do i fix this? I have tried placing it in my .m file but it doesn't seem to work properly anywhere, any ideas on where it would go? I would post the .m but it is about 500 lines so it is a bit big so i just pasted the relevant bit of it. also i am a 15 year old, and i am fairly new to cocos2d development
The Code
- (void) addMonster {
CCSprite * monster = [CCSprite spriteWithFile:#"startH.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}
if (Strategyscore < 10) {
int minDuration = 5.0;
int maxDuration = 10.0;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
eate the actions
CCMoveTo * actionMove = [CCMoveTo actionWithDuration:actualDuration
position:ccp(-monster.contentSize.width/2, actualY)];
CCCallBlockN * actionMoveDone = [CCCallBlockN actionWithBlock:^(CCNode *node) {
[node removeFromParentAndCleanup:YES];
[_monsters removeObject:node];
Life--;
CCSprite *Life3 = [CCSprite spriteWithFile:#"heart.png"];
Life3.position = ccp(210,200);
CCSprite *Life2 = [CCSprite spriteWithFile:#"heart.png"];
Life2.position = ccp(220,200);
CCSprite *Life1 = [CCSprite spriteWithFile:#"heart.png"];
Life1.position = ccp(230,200);
[self addChild:Life3];
[self addChild:Life2];
[self addChild:Life1];
if(Life == 2) {
[self removeChild:Life3];
}
else if(Life == 1) {
[self removeChild:Life2];
[self removeChild:Life3];
}
else if(Life <= 0) {
[self removeChild:Life1];
[self removeChild:Life2];
[self removeChild:Life3];
// Cr [[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[MainMenu scene]]];
}
}];
[monster runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
//collision stuff
monster.tag = 1;
[_monsters addObject:monster];
}
Also the .h file
int StrategyBullet;
int Strategyscore;
int high;
int Life;
CCLabelTTF *highlabel;
CCLabelTTF *StrategyBulletLabel;
CCLabelTTF *StrategyscoreLabel;
#interface Strategy: CCLayer
{
NSMutableArray * _monsters;
NSMutableArray * _projectiles;
int _monstersDestroyed;
}
+(CCScene *) scene;
#end
Every time you add a new monster, you add a new set of sprites Life1,Life2, and Life3, superimposed on the previous ones. You probably want to have a single set of life hearts.
in .h
CCSprite *Life1,*Life2,*Life3;
in .m, init method
Life3 = [CCSprite spriteWithFile:#"heart.png"];
Life3.position = ccp(210,200);
Life2 = [CCSprite spriteWithFile:#"heart.png"];
Life2.position = ccp(220,200);
Life1 = [CCSprite spriteWithFile:#"heart.png"];
Life1.position = ccp(230,200);
[self addChild:Life1];
[self addChild:Life2];
[self addChild:Life3];
and in your actionMoveDone call block, dont remove them, just make them not visible
CCCallBlockN * actionMoveDone = [CCCallBlockN actionWithBlock:^(CCNode *node) {
[node removeFromParentAndCleanup:YES];
[_monsters removeObject:node];
Life--;
if(Life == 2) {
Life3.visible=NO;
}
else if(Life == 1) {
Life3.visible=NO;
Life2.visible=NO;
}
else if(Life <= 0) {
Life3.visible=NO;
Life2.visible=NO;
Life1.visible=NO;
}
}];
for starters. I just made this as 'like your coding style' as possible, but eventually you will find different patterns to do this as you game becomes more complex. Read about normal iOS code and naming conventions, it will help you and also make your code samples more palatable for the people trying to help you here.
Where are you montering the lives value ? In a tick method ?
if(Life == 2) {
[self removeChild:Life3];
}
else if(Life == 1) {
[self removeChild:Life2];
[self removeChild:Life3];
}
else if(Life <= 0) {
[self removeChild:Life1];
[self removeChild:Life2];
[self removeChild:Life3];
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[MainMenu scene]]];
}

adding CCPhysicsSprite to CCLayer cocos2d

I'm trying to reorganize HelloWorld project in cocos2d to our needs.
The thing I did - made a class, which is inherent from CCPhysicsSprite and wanted to add it to CCLayer (HelloWorldLayer). But something goes wrong. According to debugger my instance is created, but I can't see it in the iOS emulator. Need your help and explanations.
HelloWorldLayer.h
#interface HelloWorldLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate>
{
CCTexture2D *spriteTexture_; // weak ref
b2World* world_; // strong ref
GLESDebugDraw *m_debugDraw; // strong ref
}
HelloWorldLayer.mm (only changed by me functions:)
-(id) init
{
if( (self=[super init])) {
// enable events
self.touchEnabled = YES;
self.accelerometerEnabled = YES;
CGSize s = [CCDirector sharedDirector].winSize;
// init physics
[self initPhysics];
// create reset button
//[self createMenu];
//Set up sprite
//#if 1
// // Use batch node. Faster
// CCSpriteBatchNode *parent = [CCSpriteBatchNode batchNodeWithFile:#"blocks.png" capacity:100];
// spriteTexture_ = [parent texture];
//#else
// // doesn't use batch node. Slower
// spriteTexture_ = [[CCTextureCache sharedTextureCache] addImage:#"blocks.png"];
// CCNode *parent = [CCNode node];
//#endif
// [self addChild:parent z:0 tag:kTagParentNode];
//
//
// [self addNewSpriteAtPosition:ccp(s.width/2, s.height/2)];
CCLabelTTF *label = [CCLabelTTF labelWithString:#"Tap screen" fontName:#"Marker Felt" fontSize:32];
[self addChild:label z:0];
[label setColor:ccc3(0,0,255)];
label.position = ccp( s.width/2, s.height-50);
[self scheduleUpdate];
}
return self;
}
-(void) addNewSpriteAtPosition:(CGPoint)p
{
CCLOG(#"Add sprite %0.2f x %02.f",p.x,p.y);
if([self getChildByTag:kTagParentNode] == nil)
{
BloodRobotUnit *unit = [[BloodRobotUnit alloc] initWithOwner:world_ at:p];
[self addChild:unit z:0 tag:kTagParentNode];
}
}
And Creating unit: (header and mm file:)
#interface BloodRobotUnit : CCPhysicsSprite
{
b2Body *body_;
b2World *owner_;
}
-(id) initWithOwner:(b2World*)owner at:(CGPoint)pt;
mm:
-(id) initWithOwner:(b2World*)owner at:(CGPoint)pt
{
if(self = [super initWithFile:#"blocks.png" rect:CGRectMake(0, 0, 32, 32)])
{
owner_ = owner;
//create body at position
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(pt.x/PTM_RATIO, pt.y/PTM_RATIO);
body_ = owner->CreateBody(&bodyDef);
// Define another box shape for our dynamic body.
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m box
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body_->CreateFixture(&fixtureDef);
[self setB2Body: body_];
[self setPosition:pt];
return (self);
}
return nil;
}
Where is my mistake? Any help will be very appreciated
The trick was in setting position to self
Debugger showed that my texture was at position inf:inf
Code change to make everything work is the following:
in mm file of creating a CCPhysicsSprite iheriter do the following:
[self setB2Body: body_];
self.PTMRatio = PTM_RATIO;
//[self setPosition:CGPointMake(pt.x/PTM_RATIO, pt.y/PTM_RATIO)];
That is - you need to set only body position and set PTMRatio (thanx to #giorashc). Setting sprite texture is not necessary.

Infinite scrolling with more backgrounds

In my game I'm using infinite scrolling background.
This is my code:
- (void)setupBackground {
CGSize winSize = [CCDirector sharedDirector].winSize;
// 1) Create the CCParallaxNode
_backgroundNode = [CCParallaxNode node];
[self addChild:_backgroundNode z:-2];
// 2) Create the sprites you’ll add to the
// CCParallaxNode
_spacedust1 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
_spacedust2 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
_planetsunrise = [CCSprite spriteWithFile:#"bg_planetsunrise.png"];
_galaxy = [CCSprite spriteWithFile:#"bg_galaxy.png"];
_spacialanomaly = [CCSprite spriteWithFile:#"bg_spacialanomaly.png"];
_spacialanomaly2 = [CCSprite spriteWithFile:#"bg_spacialanomaly2.png"];
// 3) Determine relative movement speeds for space dust
// and background
CGPoint dustSpeed = ccp(0.1, 0.1);
CGPoint bgSpeed = ccp(0.05, 0.05);
// 4) Add children to CCParallaxNode
[_backgroundNode addChild:_spacedust1 z:0
parallaxRatio:dustSpeed
positionOffset:ccp(0,winSize.height/2)];
[_backgroundNode addChild:_spacedust2 z:0
parallaxRatio:dustSpeed
positionOffset:ccp(_spacedust1.contentSize.width*
_spacedust1.scale, winSize.height/2)];
[_backgroundNode addChild:_galaxy z:-1
parallaxRatio:bgSpeed
positionOffset:ccp(0,winSize.height * 0.7)];
[_backgroundNode addChild:_planetsunrise z:-1
parallaxRatio:bgSpeed
positionOffset:ccp(600,winSize.height * 0)];
[_backgroundNode addChild:_spacialanomaly z:-1
parallaxRatio:bgSpeed
positionOffset:ccp(900,winSize.height * 0.3)];
[_backgroundNode addChild:_spacialanomaly2 z:-1
parallaxRatio:bgSpeed
positionOffset:ccp(1500,winSize.height * 0.9)];
}
It works very well.
But I want change during the game this background image with another one, for example for LV 2.
How can I do this? I tried to create another function setupBackground2, with another image, but it doesn't work.
Change the texture of the existing sprite(s) using setTexture: after loading/getting the texture from CCTextureCache addImage: method.

Objective C - CCSprites scaling and displaying differently in different parts of my code

I'm building an app that has a main menu layer and a background layer (for gameplay). I am loading the exact same CCParallax node code in both places, using the same images to create an infinite scrolling background.
On the gameplay background layer, the background displays and scrolls appropriately. However, on the main menu layer, the backgrounds are scaled weird (they don't take up the entire screen), and also don't scroll appropriately (probably because the scale is off somehow, so the offset isn't working).
Here is a screenshot of what the background looks like on the main menu:
And here it is on the background layer (green lines are part of the gameplay):
It almost looks like the menu layer is adding the non-retina display version of the files, but if I load the simulator into the iPhone (non-retina) mode, the meny background is still way off:
The code that loads the two is pretty much identical.
Here is the main menu loader code:
-(id)init {
self = [super init];
if (self != nil) {
CGSize winSize = [CCDirector sharedDirector].winSize;
_backgroundNode = [CCParallaxNode node];
[self addChild:_backgroundNode z:-1];
_backgroundGrid1 = [CCSprite spriteWithFile:#"grid.png"];
_backgroundCircuits1 = [CCSprite spriteWithFile:#"bg-circuits.png"];
_backgroundGrid1.anchorPoint = CGPointMake(0,0);
_backgroundCircuits1.anchorPoint = CGPointMake(0,0);
CGPoint gridSpeed = ccp(0.05, 0.05);
CGPoint circuitSpeed = ccp(0.1, 0.1);
[_backgroundNode addChild:_backgroundGrid1 z:1 parallaxRatio:gridSpeed positionOffset:ccp(0,-winSize.height)];
[_backgroundNode addChild:_backgroundCircuits1 z:0 parallaxRatio:circuitSpeed positionOffset:ccp(0,-winSize.height)];
[self scheduleUpdate];
}
return self;
}
- (void)update:(ccTime)dt {
CGPoint backgroundScrollVel = ccp(0, 1000);
_backgroundNode.position = ccpAdd(_backgroundNode.position, ccpMult(backgroundScrollVel, dt));
NSArray *backgroundGrids = [NSArray arrayWithObjects:_backgroundGrid1, nil];
for (CCSprite *b in backgroundGrids) {
if ([_backgroundNode convertToWorldSpace:b.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(b.contentSize.height/3)) forChild:b];
}
}
NSArray *backgroundCircuits = [NSArray arrayWithObjects:_backgroundCircuits1, nil];
for (CCSprite *bc in backgroundCircuits) {
if ([_backgroundNode convertToWorldSpace:bc.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(bc.contentSize.height/3)) forChild:bc];
}
}
}
And here is the code for the background layer:
- (id)init
{
self = [super init];
if (self != nil) {
CGSize winSize = [CCDirector sharedDirector].winSize;
_backgroundNode = [CCParallaxNode node];
[self addChild:_backgroundNode z:-1];
_backgroundGrid1 = [CCSprite spriteWithFile:#"grid.png"];
_backgroundCircuits1 = [CCSprite spriteWithFile:#"bg-circuits.png"];
_backgroundGrid1.anchorPoint = CGPointMake(0,0);
_backgroundCircuits1.anchorPoint = CGPointMake(0,0);
CGPoint gridSpeed = ccp(0.05, 0.05);
CGPoint circuitSpeed = ccp(0.1, 0.1);
[_backgroundNode addChild:_backgroundGrid1 z:1 parallaxRatio:gridSpeed positionOffset:ccp(0,-winSize.height)];
[_backgroundNode addChild:_backgroundCircuits1 z:0 parallaxRatio:circuitSpeed positionOffset:ccp(0,-winSize.height)];
[self scheduleUpdate];
return self;
}
- (void)update:(ccTime)dt {
CGPoint backgroundScrollVel = ccp(0, 1000);
_backgroundNode.position = ccpAdd(_backgroundNode.position, ccpMult(backgroundScrollVel, dt));
NSArray *backgroundGrids = [NSArray arrayWithObjects:_backgroundGrid1, nil];
for (CCSprite *b in backgroundGrids) {
if ([_backgroundNode convertToWorldSpace:b.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(b.contentSize.height/3)) forChild:b];
}
}
NSArray *backgroundCircuits = [NSArray arrayWithObjects:_backgroundCircuits1, nil];
for (CCSprite *bc in backgroundCircuits) {
if ([_backgroundNode convertToWorldSpace:bc.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(bc.contentSize.height/3)) forChild:bc];
}
}
}

CCSprite not displayed when placed on CCNode or position is wrong

I have this code in my init:
-(id)init {
if ((self = [super init])) {
CGSize screenSize = [CCDirector sharedDirector].winSize;
mapSize = CGSizeMake(4000, 4000);
rotateWorld = [CCNode node];
[rotateWorld setContentSize:mapSize];
rotateWorld.position = CGPointMake(screenSize.width / 2, screenSize.height / 2);
positionWorld = [CCNode node];
[positionWorld setContentSize:mapSize];
positionWorld.position = CGPointMake(mapSize.width / 2, mapSize.height / 2);
[rotateWorld addChild:positionWorld z:0];
[self addChild:rotateWorld z:0];
// Test enemy
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"EnemiesSpritesheet.plist"];
spriteSheetNonPlayer = [[CCSpriteBatchNode alloc] initWithFile:#"EnemiesSpritesheet.png"capacity:10];
[positionWorld addChild:spriteSheetNonPlayer z:0];
enemy = [[Enemy_01 alloc] initWithSpriteFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"enemy_01_01.png"]];
enemy.position = CGPointMake(mapSize.width / 2, mapSize.height / 2);
[spriteSheetNonPlayer addChild:enemy];
}
return self;
}
Now I would expect my enemy sprite to show up in the middle of the screen, but it does not and I do not know if it is show at all. The funny thing is that if I change the positionWorld from a CCNode to a CCSprite containing a background image of 4000x4000 it works perfectly, but why not with a CCNode with its contetSize set? How do I get this to work with a CCNode?
Thank you
Søren
You need to set the anchorPoint to be ccp(0.5,0.5) for CCNode.
rotateWorld.anchorPoint = ccp(0.5f,0.5f);
positionWorld.anchorPoint = ccp(0.5f,0.5f);
CCSprite does the same thing internally in its init method (line 149 of CCSprite.m).