如何让两个动画 NSImageView 发生碰撞?
How can I get two animated NSImageViews to collide?
我有一个方法可以分配一颗子弹,并在每次按下 space 栏时将其从 space 船的前部移动到屏幕顶部。
同时,我在 NSImageViews 中有小行星,它们使用 NSTimer 重复从屏幕顶部到屏幕底部进行动画处理。
在另一个计时器重复访问的碰撞检测方法中,我将两个图像视图放入边界圆中并使用圆相交方法检查碰撞。
问题是 bullet/asteroids 通常不相交。只有当我的 space 飞船与出现在屏幕上的小行星对齐时,它才会起作用。我不能只是按住火力并向各处喷射子弹来摧毁小行星,即使它们明显相交。
有人对此有解决方案吗?
我的导弹-小行星碰撞检测方法经常被一个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];
}
}
这是我用 space 栏激活的导弹动画方法:
-(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];
}
以及用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];
}
使用SpriteKit!这正是它为之设计的东西,并且有接口和语义来支持。您可以在其中编写整个游戏。它将具有您需要的响应能力以及您几乎永远无法希望在应用程序中实现的紧密性和完整性,或者只能通过如此多的努力工作、大量代码和重新发明轮子才能实现。
试试吧。你会喜欢的!我敢打赌,您可以将代码的大小和复杂性减少到原来的一小部分,并且可以更轻松地完成更多工作。
您可以将图像加载到 SKSpriteNode 中,然后四处移动、检测碰撞和各种东西。
我有一个方法可以分配一颗子弹,并在每次按下 space 栏时将其从 space 船的前部移动到屏幕顶部。
同时,我在 NSImageViews 中有小行星,它们使用 NSTimer 重复从屏幕顶部到屏幕底部进行动画处理。
在另一个计时器重复访问的碰撞检测方法中,我将两个图像视图放入边界圆中并使用圆相交方法检查碰撞。
问题是 bullet/asteroids 通常不相交。只有当我的 space 飞船与出现在屏幕上的小行星对齐时,它才会起作用。我不能只是按住火力并向各处喷射子弹来摧毁小行星,即使它们明显相交。
有人对此有解决方案吗?
我的导弹-小行星碰撞检测方法经常被一个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];
}
}
这是我用 space 栏激活的导弹动画方法:
-(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];
}
以及用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];
}
使用SpriteKit!这正是它为之设计的东西,并且有接口和语义来支持。您可以在其中编写整个游戏。它将具有您需要的响应能力以及您几乎永远无法希望在应用程序中实现的紧密性和完整性,或者只能通过如此多的努力工作、大量代码和重新发明轮子才能实现。
试试吧。你会喜欢的!我敢打赌,您可以将代码的大小和复杂性减少到原来的一小部分,并且可以更轻松地完成更多工作。
您可以将图像加载到 SKSpriteNode 中,然后四处移动、检测碰撞和各种东西。