Destroying Sprites in and around the Collided Sprite - iphone

I need help in destroying the sprites which are in and around the collided sprites ie in a radius of 2.5 cms all sprites should be destroyed. Idea here is i will be shooting a projectile from bottom to the objects falling from the top. Once collision happens all the sprites around that radius also should be destroyed. Like a Bomb Effect. I have used box2d for collision ie contact listener. How to go about doing that?
Please Suggest:-)
Regards,
Karthik

Hold an array of your sprites, or if you are using a batchNode you can do that.
When the collision happens, go through your sprites. Check the distance with their position and the explosion center and kill them if they are in range.
e.g.
CCSprite *sprite;
for (sprite in [batchNode descendants]) {
if ([sprite isInRangeOf:[explosionSprite position]]) {
[sprite yourRemovalMethod];
}
}
the method 'isInRangeOf:' would be within your sprite subclass
Something like..
-(BOOL) isInRangeOf:(CGPoint)explosionCenter {
//Use pythagoras theorem to work out the distance between [sprite position] and [explosionCenter]
CGFloat dx = explosionCenter.x - [self position].x;
CGFloat dy = explosionCenter.y - [self position].y;
float distance = sqrt(dx*dx + dy*dy );
// If your distance is less than or equal to your 'death radius' return YES, else No.
if (distance <= 25) {
return TRUE;
} else {
return FALSE;
}
}
Hope that helps.

Related

Making a SKSpriteNode platform that recognize when a SKSprite is outside of it

I'm trying to make a random type platform (based on the shape of the sprite that I put) in where the main character of my game would be situated; if an enemy passes the platform shape, it will be removed (like it was fallen). Here is an image of what I want to say:
The blue dot will be the hero character, the red ones the bad guys; the one that is inside a purple circle is the one that should be removed when falling out of the circular platform
So basically, I don't know how to detect properly when a charater is falling, I have something now, but they fall when all the body is fallen:
- (void) boundsCheck:(SKSpriteNode*)sprite{
CGPoint newPosition = self.position;
CGPoint newVelocity = self.velocity;
CGPoint bottomLeft = CGPointMake(sprite.frame.origin.x, sprite.frame.origin.y);
CGPoint topRight = CGPointMake(sprite.frame.origin.x + sprite.size.width,
sprite.frame.origin.y + sprite.size.height);
if (newPosition.x <= bottomLeft.x) {
[self removeCharacterWithPosition:newPosition];
}
if (newPosition.x >= topRight.x) {
[self removeCharacterWithPosition:newPosition];
}
if (newPosition.y <= bottomLeft.y) {
[self removeCharacterWithPosition:newPosition];
}
if (newPosition.y >= topRight.y) {
[self removeCharacterWithPosition:newPosition];
}
self.position = newPosition;
self.velocity = newVelocity;
}
Can you tell me some tips? Thanks
If the platform is exactly circular you could check the distance of the red dots from the platform center. If their distance is bigger than the platform radius you can consider them out of the platform. To check the distance between two CGPoints (which are used to store the position property of nodes) you can use a function like this:
- (float)distanceBetween : (CGPoint) centerOfPlatform and: (CGPoint)enemy
{
return sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p1.y,2));
}
The answer was simple, there is a method called: containsPoint with that I could detect if the CGPont of the enemy is inside or not of the platform :) so I made it:
if ([bezierPath containsPoint:newPosition]) {
self.position = newPosition;
self.velocity = newVelocity;
return;
}
thanks for the answers!

Collision of Sprites in CCSpriteBatchNode and CCParallaxNode

I have two sprites one is added as the child of CCSpriteBatchNode and the other as the child of CCParallaxNode. Is there any method to detect their collision? I have used the following code.
-(void)CheckCollition:(CCSprite *)Opp_Obs Opponent:(CCSprite *) H_man
{
// NSLog(#"inside check collision");
CGRect b_rect=[Opp_Obs boundingBox];
CGPoint p_position=[H_man position];
if (CGRectContainsPoint(b_rect,p_position))
{
NSLog(#"collision with opponent");
// Zoom Animation with Points
CCScaleBy *zzomscal=[CCScaleTo actionWithDuration:.2 scale:.12];
CCRotateTo * rotLeft = [CCRotateBy actionWithDuration:0.2 angle:360];
CCCallFunc *ccfun=[CCCallFunc actionWithTarget:self selector:#selector(zoomComplete)];
CCSequence * zzomseq = [CCSequence actions:zzomscal,rotLeft,ccfun, nil];
[H_man runAction:zzomseq];
}
else
{
NSLog(#"no collision");
}
}
But here the control never enters into the loop. Is there any other solution? Anyone please help me.
Set a breakpoint and compare the values of rect and position. One of them may be zero, or way off.
In the latter case you may need to convert the bbox origin and position to world coordinates first in order to compare them. This is the case when the sprites' parents are moving too (parent position != 0,0).

Moving a sprite with touches began, casting and parameters in obj - c?

I've been reading a book on the cocos2d framework for ios5 for a few days and have developed a small game that the book walks you through. To control the sprite in this game you use the accelerometer:
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
float deceleration = 0.4f;
float sensitivity = 6.0f;
float maxVelocity = 100;
// adjust velocity based on current accelerometer acceleration
playerVelocity.x = playerVelocity.x * deceleration + acceleration.x * sensitivity;
// we must limit the maximum velocity of the player sprite, in both directions (positive & negative values)
if (playerVelocity.x > maxVelocity)
{
playerVelocity.x = maxVelocity;
}
else if (playerVelocity.x < -maxVelocity)
{
playerVelocity.x = -maxVelocity;
}
// Alternatively, the above if/else if block can be rewritten using fminf and fmaxf more neatly like so:
// playerVelocity.x = fmaxf(fminf(playerVelocity.x, maxVelocity), -maxVelocity);
}
Now I'm wondering if I can change this code to allow the sprite to still accelerate/decelerate along the x axis, but to use touch input rather than the accelerometer, and to go faster the longer the touch is held down for? So a touch to the right would move the sprite to that spot slowly, if the touch is released, it stops moving to that spot. The longer a touch is held down, the faster the sprite moves.
is there anything in the framework to allow me to implement a rotation mechanism that allows my sprite to rotate to the position that the touch was in, so it looks like its facing the point thats been touched?
Well, afaik theres no method that will determine the angle to the touch and then rotate the sprite accordingly, but if you have the x and y coordinates of the sprite and the touch you can calculate it yourself fairly easily.
CGPoint spriteCenter; // this should represent the center position of the sprite
CGPoint touchPoint; //location of touch
float distanceX = touchPoint.x - spriteCenter.x;
float distanceY = touchPoint.y - spriteCenter.y;
float angle = atan2f(distanceY,distanceX); // returns angle in radians
// do whatever you need to with the angle
Once you have the angle you can set the rotation of the sprite.

CCMoveTo doesn't get the updated player postition.....(iphone,cocos2d)

I'm adding an enemy like this:
-(void)addEnemy {
if ([spawnedEnemies count] < 25) {
CCSprite* sprite = [CCSprite spriteWithFile:#"white.png"];
float randomX = arc4random() % 480;
float randomY = arc4random() % 320;
sprite.position = ccp(randomX,randomY);
[spawnedEnemies addObject:sprite];
[self addChild:sprite];
[sprite runAction:[CCMoveTo actionWithDuration:5 position:player.position]];
} }
but if my player moves the sprite still moves to the last player position...
because of that i tried this in my tick:
-(void)tick:(ccTime)delta {
for (CCSprite *sp in spawnedEnemies) {
[sp stopAllActions];
[sp runAction:[CCMoveTo actionWithDuration:5
position:player.position]];
} }
but the enemies will only move if i stop moving (there just moving reallllllllyyyyyyyyy slow because every time i move it calls [sp stopAllActions]
What should I do now?
EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:
Now I'm doing this and the enemies are moving to the player even if the player is moving
but there's a problem: the nearer the enemy (is to the player) the slower they are moving...
How to solve this?
//function to apply a velocity to a position with delta
static CGPoint applyVelocity(CGPoint velocity, CGPoint position, float delta){
return CGPointMake(position.x + velocity.x * delta, position.y + velocity.y * delta);
}
-(void)tick:(ccTime)delta {
for (CCSprite *sp in spawnedEnemies) {
CGPoint m = ccpSub(player.position, sp.position);
sp.position = applyVelocity(m, sp.position, 1.0/60.0f);
}
}
I have four ideas:
Schedule a new update selector with a lower frequency and move the enemies in that method: [self schedule:#selector(moveEnemies) interval:0.1];
Only move the enemies when the player.position changes, maybe in your ccTouchesMoved-method.
Instead of using CCActions, set the position of the sprite directly, you need to do some vector-computations.
Use a physics-engine like Box2D (included in Cocos2D SDK). Then you can simply apply a force to each enemy to the direction of the player in each step.
EDIT:
In order to move the enemies with constant velocity, normalize the velocity vector m:
m = ccpMult(ccpNormalize(m), kSpeed);
kSpeed is a constant float value to adjust the speed.
Hope that helps...

cocos2d rotating sprite collision detection

I got 2 sprites, ball and arrow.
the arrow is not moving.
the ball is rotating on it's anchor point.
id rotate = [CCRotateBy actionWithDuration:.5 angle: 360];
I want to detect collision when the ball reaches to arrow.
Tried CGRectIntersectsRect but it does not detect collision.
Any help?
Thanks...
You probably don't want this answer, but I would use Box2D or Chipmunk and use the Vertex Helper application to specify vertices.
use circle-circle collision method.. here is the method..
-(float)asbs:(CGPoint)_arrowPos ballPos:(CGPoint)_ballPos
{
float x = _arrowPos.x-_ballPos.x;
float y = _arrowPos.y-_ballPos.y;
float xy = x*x+y*y;
return xy;
}
if([self asbs:arrow.position ballPos:ball.position]<=size)
{
//collision
}
note that size = ball radius + arrow radius * ball radius + arrow radius
the method above is using a(square) + b(square) = c(square) to check distance between two points..
You might need to convert the ball to world space in an update method then call that rather than the balls position. If it is in a parent layer is position will always be static in respect to its parent.