从代码示例中,确实很难遵循你想要做的事情。值得注意的是,目前还不清楚你是如何(或者甚至是如何)制作各种观点的动画。
无论您是否在进行动画制作,从您的代码示例中不清楚AstronautMove
被调用的位置。您是否打算从touchesBegan
和touchesEnded
拨打电话?但根据迄今已分享的内容,我没有看到你打电话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。
我知道上述两个例子都不是你正在做的事情,但希望它能说明一些用于识别碰撞的技术,这些技术可以适用于你的应用。
我们从你的代码示例中推断出你刚才改变'Astronaut.center',你没有做任何动画,只是瞬间改变框架?如果您正在做任何动画,请向我们展示该代码。你也可以询问'CGRectIntersectRect',但不要告诉我们你在哪里调用它。最重要的是,我们没有足够的资源来帮助您诊断正在发生的事情,更不用说提出任何建议。 – Rob
我只是上下移动框架。底部是着陆区。当宇航员和着陆区域框架碰触时,会发生碰撞。但是,当我将宇航员向上移动时,会显示更大的图像(50x113),而当我将宇航员向下移动时,会显示更小的图像(50x85)。当我靠近着陆区域时,我会按下去显示更大的图像并发生碰撞。 – user2932903
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