This might sound pretty straightforward. I have populated an array with PhysicsSprites in a class (Sprites.mm) that returns itself (which I initialize in the init method HelloWorldLayer.mm class). How can access the array (from Sprites.mm) in the update method of HelloWorldLayer.mm? I want to put some restrictions on sprites in the update method. Please Help.
Asked
Active
Viewed 339 times
2 Answers
1
First of all you need to share the same b2World in both the classes and then you can access the Sprites.mm world.
For more understanding I've created a demo which would work. I am adding the code of the Sprites.mm code which I called as Spritese.h & Spritese.mm
The below is the Spritese.h code
@interface Spritese : CCLayer {
NSMutableArray *arrSprite;
b2World* world;
}
@property (nonatomic,retain) NSMutableArray *arrSprite;
-(id)initWithArrayOfSprites : (b2World *)_world;
@end
The Below one for the .mm
@implementation Spritese
@synthesize arrSprite;
#define PTM_RATIO 32
#define kTagBatchNode 1
-(id)initWithArrayOfSprites :(b2World *)_world{
if((self = [super init])){
CGSize screenSize = [CCDirector sharedDirector].winSize;
world = _world;
//Set up sprite
CCSpriteBatchNode *batch = [CCSpriteBatchNode batchNodeWithFile:@"blocks.png" capacity:150];
[self addChild:batch z:0 tag:kTagBatchNode];
for(int i=0; i<3; i++)//creating 3 objects
[self addNewSpriteWithCoords:ccp(screenSize.width/2, screenSize.height/2)];
}
return self;
}
-(void) addNewSpriteWithCoords:(CGPoint)p
{
CCLOG(@"Add sprite %0.2f x %02.f",p.x,p.y);
CCSpriteBatchNode *batch = (CCSpriteBatchNode*) [self getChildByTag:kTagBatchNode];
//We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is
//just randomly picking one of the images
int idx = (CCRANDOM_0_1() > .5 ? 0:1);
int idy = (CCRANDOM_0_1() > .5 ? 0:1);
CCSprite *sprite = [CCSprite spriteWithBatchNode:batch rect:CGRectMake(32 * idx,32 * idy,32,32)];
[batch addChild:sprite];
sprite.position = ccp( p.x, p.y);
// Define the dynamic body.
//Set up a 1m squared box in the physics world
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
bodyDef.userData = sprite;
b2Body *body = world->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);
[arrSprite addObject:sprite];
}
@end
In the HelloWorld.h file import the Class Spritese and add
@property(nonatomic,retain) Spritese *sprit;
and synthesize it in .mm file
Now in the init method of the HelloWorld add this code
sprit = [[Spritese alloc] initWithArrayOfSprites:world];
[self addChild:sprit];
And finally in the tick OR update method you need to add
-(void) tick: (ccTime) dt
{
int32 velocityIterations = 8;
int32 positionIterations = 1;
world->Step(dt, velocityIterations, positionIterations);
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
CCSprite *myActor = (CCSprite*)b->GetUserData();
myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
Spritese *s = (Spritese *)b->GetUserData();
for(int i=0; i < [sprit.arrSprite count]; i++){
if(s == [sprit.arrSprite objectAtIndex:i]){
s.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
s.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
NSLog(@"Process Sprite Here");
}
}
}
}
}
I hope the code example would work at your side.

Marine
- 1,097
- 7
- 19
-
It guess it worked, but I am having an issue which I guess is from the update method. For now I want to impose gravity (higher than the world) on the sprites in say `arrSprite` but they're still responding to the world gravity. See the update method below. `-(void)update:(ccTime)dt { int32 velocityIterations = 8; int32 positionIterations = 1; world->Step(dt, velocityIterations, positionIterations); for (PhysicsSprite* spr in sprit.arrSprite) { b2Body* bBody = [spr getPhysicsBody]; bBody->ApplyForce(b2Vec2(0,20*bBody->GetMass()), bBody->GetWorldCenter()); } }` – wilM Jun 05 '12 at 16:31
-
As you share the same world in both the layer. You would not be able to differentiate both the worlds. I guess any layer cannot have more than 1 world. – Marine Jun 06 '12 at 07:45
-
Please could you explain this a bit further for me, I don't fully understand it. Thank you – wilM Jun 06 '12 at 16:31
-
Sorry I would be unable to explain more as I only know the Reason why its happening and came to conclusion that it gives the conflict because of sharing the same world. – Marine Jun 07 '12 at 07:58
0
create property in your Sprites.h file
@property (nonatomic, readonly) NSArray* physicSprites;
then in your .mm file
@synthesize physicSprites = m_physicSprites;
if your array instance is called m_physicSprites;
then you will be able to get access to it smth like
[spritesInstance physicSprites];
or
spriteInstance.physicSprites

Morion
- 10,495
- 1
- 24
- 33