I got some obstacles falling from the sky my sprites collide with the obstacles. When the obstacles are done falling I unify the obstacles so it becomes one big rectangle. My sprites collide properly against it. But when a sprite comes near the obstacles and you try to drag the sprite away from it it sometimes gets stuck so you can't drag the sprite anymore.
Spawning obstacles like this :
Code: Select all
//*************************************************************************************************************
- (void) spawnObstacle:(id) sender :(int) redOrBlue
{
CCSprite *obstacle = [CCSprite spriteWithSpriteFrameName:[self getObstacleName]];
CGPoint point;
int i;
if(redOrBlue)
{
for(i = 0 ; i < [redObstacles count] ; i++)
{
point = CGPointFromString([redObstacles objectAtIndex:i]);
if(point.x != 0 && point.y != 0)
{
[redObstacles replaceObjectAtIndex:i withObject:NSStringFromCGPoint(ccp(0,0))];
break;
}
}
}
else
{
for(i = 0 ; i < [blueObstacles count] ; i++)
{
point = CGPointFromString([blueObstacles objectAtIndex:i]);
if(point.x != 0 && point.y != 0)
{
[blueObstacles replaceObjectAtIndex:i withObject:NSStringFromCGPoint(ccp(0,0))];
break;
}
}
}
if(i >= [blueObstacles count])
{
return; //no free spots left. Do not spawn
}
obstacle.position = point;
obstacle.tag = i;
CCScaleTo *scaleAction = [CCScaleTo actionWithDuration:1.5 scale:scaleObstacleDownTo];
CCCallFuncN *callback = [CCCallFuncN actionWithTarget:self selector:@selector(addObstacle:)];
CCSequence *seq = [CCSequence actions:scaleAction , callback, nil];
[obstacle runAction:seq];
[self addChild:obstacle z:-2];
}
//*************************************************************************************************************
- (NSString *) getObstacleName
{
switch (SCENE)
{
case kMineScene: return @"obstacleIceBlock.png";
case kChinaScene: return @"obstacleCrate.png";
case kNinjaScene: return @"obstacleIceBlock.png";
case kMummyScene: return @"obstacleCrate.png";
default:
case kEskimoScene: return @"obstacleCrate.png";
}
}
//*************************************************************************************************************
- (void) addObstacle:(CCSprite*) sender
{
if(isPaused)
return;
//cpSpaceAddPostStepCallback(space, newObstacle, nil, sender);
[obstacleBuffer addObject:sender];
[soundEngine playEffect:@"obstacleDrop.mp3"];
}
//********************************************
- (void) compress
{
cpSpaceAddPostStepCallback(space, unifyObstacles, nil, nil);
}
//********************************************
void newObstacle(cpSpace *space, void *obj, void *data)
{
CCSprite *sender = (CCSprite *) data;
float width = sender.contentSizeInPixels.width * scaleObstacleDownTo;
float height = sender.contentSizeInPixels.height * scaleObstacleDownTo;
float x = sender.positionInPixels.x;
float y = sender.positionInPixels.y;
if(sender.tag < base_width * base_height) //if it's an level 0 obstacle
{
// CCLOG(@"new base obstacle : %@" , NSStringFromCGRect(CGRectMake(x-width/2,y+height/2,width,height)));
CGRect aux;
CGRect new = CGRectMake(x-width/2,y+height/2,width,height);
CGRect united;
for(int i = 0 ; i < [allBaseObstacles count] ; i++)
{
aux = CGRectFromString([allBaseObstacles objectAtIndex:i]);
united = CGRectUnion(aux, new);
if(abs(united.size.width * united.size.height - new.size.height*new.size.width - aux.size.height *aux.size.width) < 5 *factor)
{
// CCLOG(@"join");
[allBaseObstacles removeObjectAtIndex:i];
new = CGRectUnion(aux, new);
}
}
[allBaseObstacles addObject:NSStringFromCGRect(new)];
}
}
//********************************************
void unifyObstacles(cpSpace *space, void *obj, void *data)
{
CGPoint centerBlue = ccp(centerOfTheBlueObstacles.x * factor,centerOfTheBlueObstacles.y*factor);
CGPoint centerRed = ccp(centerOfTheRedObstacles.x * factor,centerOfTheRedObstacles.y*factor);
float Width = ObstacleWidth * scaleObstacleDownTo * factor;
float Height = ObstacleHeight * scaleObstacleDownTo * factor;
cpVect verts[] =
{
cpv(centerBlue.x - (Width * base_width/2) , centerBlue.y + (Height * base_height/2)),
cpv(centerBlue.x + (Width * base_width/2) , centerBlue.y + (Height * base_height/2)),
cpv(centerBlue.x + (Width * base_width/2) , centerBlue.y - (Height * base_height/2)),
cpv(centerBlue.x - (Width * base_width/2) , centerBlue.y - (Height * base_height/2)),
};
cpPolyShape *newShape = cpPolyShapeInit(cpPolyShapeAlloc(),staticBody, 4, verts, cpv(0,0));
newShape->shape.collision_type = kCollisionType_Obstacle;
cpSpaceAddStaticShape(space, &newShape->shape);
cpVect verts2[] =
{
cpv(centerRed.x - (Width * base_width/2) , centerRed.y + (Height * base_height/2)),
cpv(centerRed.x + (Width * base_width/2) , centerRed.y + (Height * base_height/2)),
cpv(centerRed.x + (Width * base_width/2) , centerRed.y - (Height * base_height/2)),
cpv(centerRed.x - (Width * base_width/2) , centerRed.y - (Height * base_height/2)),
};
cpPolyShape *newShape2 = cpPolyShapeInit(cpPolyShapeAlloc(),staticBody, 4, verts2, cpv(0,0));
newShape2->shape.collision_type = kCollisionType_Obstacle;
cpSpaceAddStaticShape(space, &newShape2->shape);
// cpSpaceRehashStatic(space);
}
Here's how I drag the sprites.
Code: Select all
- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
// NSLog(@"touch began");
if(isPaused || !canBeDragged || LOST)
return NO;
//take the coordinates of the touch and transform them into the OpenGL system.
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
CGRect frame = CGRectMake(self.position.x - self.contentSize.width/2, self.position.y - self.contentSize.height/2,
self.contentSize.width, self.contentSize.height);
if(!CGRectContainsPoint(frame, location))
return NO;
if(self.scale != 1)
[self setScale:1];
CCScaleBy *scale = [CCScaleBy actionWithDuration:0.2 scale:1.25];
[self runAction:scale];
location.x *= factor;
location.y *= factor;
if(BombShape)
{
offsetX = BombBody->p.x - location.x;
offsetY = BombBody->p.y - location.y;
velVal = BombBody->v;
BombBody->v = cpvzero;
BombShape->collision_type++; //make it 'Dragged'. For example RedNinja++ is DraggedRedNinja
}
return YES;
}
//****************************************************************************************
- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
if(isPaused || !canBeDragged)
return;
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
CGPoint prevLocation = [touch previousLocationInView: [touch view]];
prevLocation = [[CCDirector sharedDirector] convertToGL: prevLocation];
location.x *= factor;
location.y *= factor;
prevLocation.x *= factor;
prevLocation.y *= factor;
if(BombBody)
{
//during the dragging, the bomb must not have velocity. Otherwise, it will "run" beneath your finger.
//so we are constantly calculating the velocity and ,when you end the draging, assign that value to the velocity of the bomb.
velocity = cpv((location.x - prevLocation.x) * 30 , (location.y - prevLocation.y)*30);
CGPoint newPosition = cpv(location.x + offsetX, location.y + offsetY);
//test per X
canMoveOnX = CheckOnX(BombBody->p , newPosition,radius);
canMoveOnY = CheckOnY(BombBody->p , newPosition,radius);
if(canMoveOnX)
BombBody->p.x = newPosition.x;
if(canMoveOnY)
BombBody->p.y = newPosition.y;
}
}