Reputation: 3894
I have a method that allocates a bullet and animates it moving from the front of a spaceship to the top of a screen every time the space bar is pressed.
At the same time I have asteroids in NSImageViews that animate from top of screen to bottom of screen using an NSTimer on repeat.
Inside a collision detection method repeatedly accessed by another timer, I am placing both image views into bounding circles and checking for collision using a circle intersect method.
The problem is the bullet/asteroids don't intersect usually. It only works when my spaceship is in line with an asteroid that has appeared on screen. I can't just hold down fire and spray bullets everywhere to destroy asteroids even when they clearly intersect.
Anyone have a solution to this?
My missile - asteroid collision detection method accessed frequently by an NSTimer:
// Missile - White Asteroid collision.
if (CGRectIntersectsRect(_missile.frame, _asteroid.frame)) {
// set bounding bullet circle.
_missileCircle.centerX = _missile.frame.origin.x + _missile.frame.size.width / 2;
_missileCircle.centerY = _missile.frame.origin.y + _missile.frame.size.height / 2;
_missileCircle.radius = _missile.frame.size.height / 2;
// Set bounding asteroid circle
_astCircle.centerX = _asteroid.frame.origin.x +_asteroid.frame.size.width / 2;
_astCircle.centerY = _asteroid.frame.origin.y +_asteroid.frame.size.height / 2;
_astCircle.radius = _asteroid.frame.size.height / 2 - 10;
if ([self Circle: _astCircle intersectsCircle: _missileCircle]) {
NSLog(@"Missile intersection");
[_missile removeFromSuperview];
[_asteroid removeFromSuperview];
}
}
Here is my missile animation method activated with the space bar:
-(void) animateMissile
{
_missile = [[NSImageView alloc]init];
[_missile setImage:[NSImage imageNamed:@"Brown-Bullet"]];
[_missile setFrame: CGRectMake(_spaceship.frame.origin.x + 21, _spaceship.frame.origin.y + 40, 10, 15)];
[self addSubview:_missile];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = 1.5;
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_missile.animator.frame = CGRectOffset(_missile.frame, 0, self.bounds.size.height+12);
} completionHandler:nil];
}
And the asteroid animation method activated with NSTimer:
-(void) animateDarkAst:(NSTimer *) timer
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
double speed = [self randomDoubleBetween:1.0 and: 2.0];
CGPoint start = CGPointMake(randX, self.bounds.size.height);
[_asteroidDark setFrame:CGRectMake(start.x, start.y, randSize, randSize)];
[self addSubview:_asteroidDark];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = speed;
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroidDark.animator.frame = CGRectOffset(_asteroidDark.frame, 0, -self.bounds.size.height * 2);
} completionHandler:nil];
}
Upvotes: 1
Views: 47
Reputation: 12625
Use SpriteKit! That's exactly the kind of things it's designed for and has the interface and semantics to support. You can write your whole game in that. It will have the responsiveness you need and a tightness and completeness you could virtually never hope to achieve in an app, or could only achieve with so much hard work, lots of code and reinvention of the wheel.
Try it. You'll like it! Bet you can reduce your code to a small fraction of its size and complexity and do so much more so much more easily.
You can load an image into an SKSpriteNode and then move it around, detect collisions, and all kinds of stuff.
Upvotes: 1