2014-02-08 78 views
-1

我有两个图像:第一个图像大小是50x85,第二个图像大小是50x113。当我触摸屏幕图像上升,显示第二个图像,当我释放屏幕图像下降,第一个图像显示。现在的问题是,当我触摸屏幕碰撞发生的时间早于未触摸屏幕时。碰撞检测(CGRectIntersectRect)

我怎样才能使第二张图像在底部约30px不会发生碰撞,但图像仍然会在那里?


编辑:下面是一些代码:

-(void)AstronautMove 
{ 
    [self Collision]; 
    Astronaut.center = CGPointMake(Astronaut.center.x, Astronaut.center.y + Y); 
} 

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    Y = -10; 
    x.image = [UIImage imageNamed:@"y.png"]; 
} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    Y = 17; 
    x.image = [UIImage imageNamed:@"x.png"]; 
} 

-(void)Collision 
{ 
    if (CGRectIntersectsRect(Astronaut.frame, Landingarea.frame)) { 
     [self EndGame]; 
     AstronautFire.hidden = YES; 
     RedBorder.hidden = NO; 
     AstronautCrashed.hidden = NO; 
    } 

    if (CGRectIntersectsRect(AstronautFire.frame, Landingarea.frame)) { 
     [self EndGame]; 
     AstronautFire.hidden = YES; 
     RedBorder.hidden = NO; 
     AstronautCrashed.hidden = NO; 
    } 
} 

我只是移动框架上下。底部是着陆区。当宇航员和着陆区域框架碰触时,会发生碰撞。但是,当我将宇航员向上移动时,会显示更大的图像(50x113),而当我将宇航员向下移动时,会显示更小的图像(50x85)。当我靠近着陆区域时,我会按下去显示更大的图像并发生碰撞。

+0

我们从你的代码示例中推断出你刚才改变'Astronaut.center',你没有做任何动画,只是瞬间改变框架?如果您正在做任何动画,请向我们展示该代码。你也可以询问'CGRectIntersectRect',但不要告诉我们你在哪里调用它。最重要的是,我们没有足够的资源来帮助您诊断正在发生的事情,更不用说提出任何建议。 – Rob

+0

我只是上下移动框架。底部是着陆区。当宇航员和着陆区域框架碰触时,会发生碰撞。但是,当我将宇航员向上移动时,会显示更大的图像(50x113),而当我将宇航员向下移动时,会显示更小的图像(50x85)。当我靠近着陆区域时,我会按下去显示更大的图像并发生碰撞。 – user2932903

+0

AstronautFire是更大的图像。 - (无效)碰撞{ 如果(CGRectIntersectsRect(Astronaut.frame,Landingarea.frame)){ [自残局]; AstronautFire.hidden = YES; RedBorder.hidden = NO; AstronautCrashed.hidden = NO; } if(CGRectIntersectsRect(AstronautFire.frame,Landingarea.frame)){self.EndGameGame; AstronautFire.hidden = YES; RedBorder.hidden = NO; AstronautCrashed.hidden = NO; } } – user2932903

回答

1

从代码示例中,确实很难遵循你想要做的事情。值得注意的是,目前还不清楚你是如何(或者甚至是如何)制作各种观点的动画。

无论您是否在进行动画制作,从您的代码示例中不清楚AstronautMove被调用的位置。您是否打算从touchesBegantouchesEnded拨打电话?但根据迄今已分享的内容,我没有看到你打电话AstronautMove,因此看不到你可能如何检测碰撞。

就我个人而言,我原以为你会想动画动画的意见(它会呈现更现实和有吸引力的意见移动)。然后,当动画正在进行时,请继续检查是否有碰撞。在如何“继续检查”方面,您可以使用NSTimer或者更好的方法是使用CADisplayLink(每次屏幕更新时调用方法的机制)。

例如,你可以这样做:

@interface ViewController() 

@property (nonatomic, strong) UIView *view1; 
@property (nonatomic, strong) UIView *view2; 

@property (nonatomic, strong) CADisplayLink *displayLink; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)]; 
    view1.backgroundColor = [UIColor lightGrayColor]; 
    [self.view addSubview:view1]; 
    self.view1 = view1; 

    UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50, 150, 50, 50)]; 
    view2.backgroundColor = [UIColor darkGrayColor]; 
    [self.view addSubview:view2]; 
    self.view2 = view2; 
} 

#pragma mark - Handle touches 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [self startAnimationTo:CGPointMake(50, 250) collisionChecking:YES]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [self startAnimationTo:CGPointMake(50, 50) collisionChecking:NO]; 
} 

#pragma mark - Handle starting and stopping of animation 

- (void)startAnimationTo:(CGPoint)point collisionChecking:(BOOL)collisionChecking 
{ 
    if (collisionChecking) 
     [self startDisplayLink]; 

    [UIView animateWithDuration:2.0 delay:0.0 options:0 animations:^{ 
     CGRect frame = self.view1.frame; 
     frame.origin = point; 
     self.view1.frame = frame; 
    } completion:^(BOOL finished) { 
     // in case we never have collision, let's make sure we stop the display link 
     if (collisionChecking) 
      [self stopDisplayLink]; 
    }]; 
} 

- (void)stopAnimation 
{ 
    CALayer *layer = self.view1.layer.presentationLayer; 

    [self.view1.layer removeAllAnimations]; 
    self.view1.frame = layer.frame; 
    [self stopDisplayLink]; 
} 

#pragma mark - Handle the display link & check for collisions 

- (void)startDisplayLink 
{ 
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(checkForCollision:)]; 
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
} 

- (void)stopDisplayLink 
{ 
    [self.displayLink invalidate]; 
    self.displayLink = nil; 
} 

- (void)checkForCollision:(CADisplayLink *)displayLink 
{ 
    // Note, when checking for collision while an animation is underway, the `frame` of the 
    // view represents the final location of the view, not the current location. To get the 
    // current location, one has to grab the `presentationLayer`. So, we're going to get the 
    // `presentationLayer` of each of the views and use those to determine a collision. 

    CALayer *layer1 = self.view1.layer.presentationLayer; 
    CALayer *layer2 = self.view2.layer.presentationLayer; 

    if (CGRectIntersectsRect(layer1.frame, layer2.frame)) { 
     [self stopAnimation]; 
    } 
} 

@end 

或者,在搭载iOS 7,您可以使用UIKit的动态动画的意见运动,识别程序使用UICollisionBehavior和分配collisionDelegate碰撞:

@interface ViewController() <UICollisionBehaviorDelegate> 

@property (nonatomic, strong) UIView *view1; 
@property (nonatomic, strong) UIView *view2; 

@property (nonatomic, strong) UIDynamicAnimator *animator; 
@property (nonatomic, strong) UISnapBehavior *snap; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)]; 
    view1.backgroundColor = [UIColor lightGrayColor]; 
    [self.view addSubview:view1]; 
    self.view1 = view1; 

    UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(50, 150, 50, 50)]; 
    view2.backgroundColor = [UIColor darkGrayColor]; 
    [self.view addSubview:view2]; 
    self.view2 = view2; 

    self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; 

    // create behavior that will detect collisions, calling the `UICollisionBehaviorDelegate` 
    // methods if and when collisions are detected 

    UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[view1, view2]]; 
    collision.translatesReferenceBoundsIntoBoundary = YES; 
    collision.collisionDelegate = self; 
    [self.animator addBehavior:collision]; 

    // in this example, I'm going to fix `view2` where it is, so it doesn't move when 
    // `view1` collides with it 

    UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:self.view2 attachedToAnchor:self.view2.center]; 
    [self.animator addBehavior:attachment]; 

    // finally, let's specify that neither view1 nor view2 should rotate when 
    // snapping, colliding, etc. 

    UIDynamicItemBehavior *noRotate = [[UIDynamicItemBehavior alloc] initWithItems:@[view1, view2]]; 
    noRotate.allowsRotation = NO; 
    [self.animator addBehavior:noRotate]; 
} 

- (void)addSnap:(CGPoint)point 
{ 
    [self removeSnap]; 

    self.snap = [[UISnapBehavior alloc] initWithItem:self.view1 snapToPoint:point]; 
    [self.animator addBehavior:self.snap]; 
    [self.animator updateItemUsingCurrentState:self.view1]; 
} 

- (void)removeSnap 
{ 
    if (self.snap) { 
     [self.animator removeBehavior:self.snap]; 
     self.snap = nil; 
    } 
} 

#pragma mark - Handle touches 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [self addSnap:CGPointMake(75, 225)]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [self addSnap:CGPointMake(75, 75)]; 
} 

#pragma mark - UICollisionBehaviorDelegate 

// you can use these to be informed when there is a collision 

- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier atPoint:(CGPoint)p 
{ 
    NSLog(@"%s", __FUNCTION__); 

    [self removeSnap]; 
} 

- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item1 withItem:(id<UIDynamicItem>)item2 atPoint:(CGPoint)p 
{ 
    NSLog(@"%s", __FUNCTION__); 

    [self removeSnap]; 
} 
@end 

或者,对于游戏,SpriteKit可能会更好。你可以谷歌“SpriteKit的例子”,你可能会发现很多很好的介绍SpriteKit。

我知道上述两个例子都不是你正在做的事情,但希望它能说明一些用于识别碰撞的技术,这些技术可以适用于你的应用。

+0

1.这是用于移动代码,Y为int。 2.下面是代码: - (空)运动{ [自我碰撞]; Image.center = CGPointMake(Image.center.x,Image.center.y + Y); } - (无效)的touchesBegan:(NSSet中*)触摸withEvent:方法(的UIEvent *)事件{ OTHER STUFF } Y = -7; (NSSet *)触及事件:(UIEvent *)事件{ }其他东西 } } Y = 7; } – user2932903

+1

@ user2932903 1.像所有你与我们共享的代码片段,这是不足以诊断问题。如果你对碰撞没有被发现的时候有任何疑问,那么魔鬼将会处于这些细节中。 2.请停止在评论中张贴代码;这真的很难阅读。编辑您的原始问题,在那里更新代码示例。 3.就像'AstronautMoved'方法一样,你不会向我们展示'Moving'正在调用的地方和方式。如果您没有向我们显示您所说的位置,我们无法诊断为什么没有检测到碰撞。 – Rob

+1

Rob在这里提供了一个完整的示例以及评论,代码和推理。不仅涵盖最初提出的碰撞检测,还包括诸如“UIKit Dynamics”之类的较新主题之一。这是一个非常好的答案,值得赞赏。 +1 – Unheilig