0

Im freaking out with this collision issue: panned ball breaks out edgeloop body when panned fast. Anyone had simillar problem? Here is scene code ilustrating the issue. (Replacement MyScene in xcode sample - spritekitgame)

#import "SAMyScene.h"

/* Bitmask for the different entities with physics bodies. */
typedef enum : uint32_t {
    SAColliderTypeBall             = 0x1 << 1
    ,SAColliderTypeEdge            = 0x1 << 3
} SAColliderType;

NSString * const SABallName = @"ballNode";

@interface SAMyScene()
@property (nonatomic, strong) UIPanGestureRecognizer *panGestureRecognizer;
@property (nonatomic, strong) SKShapeNode *ball;
@end
@implementation SAMyScene

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */

        NSLog(@"Ball categorie bitmask =%d", SAColliderTypeBall);
        NSLog(@"Edges categorie bitmask =%d", SAColliderTypeEdge);

        self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
        self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
        self.physicsBody.categoryBitMask = SAColliderTypeEdge;
        self.physicsBody.usesPreciseCollisionDetection = YES;
        self.ball = [self newBallNode];
        [self addChild:self.ball];
    }
    return self;
}

- (SKShapeNode *)newBallNode {

    SKShapeNode *ball = [[SKShapeNode alloc] init];
    CGMutablePathRef myPath = CGPathCreateMutable();
    CGFloat radius = 60.0;
    CGPathAddArc(myPath, NULL, 0,0, radius, 0, M_PI*2, YES);
    ball.path = myPath;
    ball.fillColor = [SKColor yellowColor];
    ball.name = SABallName;
    ball.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:radius];
    ball.physicsBody.affectedByGravity = NO;
    ball.physicsBody.dynamic = YES;
    ball.physicsBody.categoryBitMask = SAColliderTypeBall;
    ball.physicsBody.contactTestBitMask = SAColliderTypeEdge;
    ball.physicsBody.collisionBitMask = SAColliderTypeEdge;
    ball.physicsBody.usesPreciseCollisionDetection = YES;
    return ball;
}

-(void)update:(CFTimeInterval)currentTime {
    //Called before each frame is rendered
}

- (UIPanGestureRecognizer *)panGestureRecognizer {
    if (!_panGestureRecognizer) {
        _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                        action:@selector(handlePanFrom:)];
    }
    return _panGestureRecognizer;
}

- (void)didMoveToView:(SKView *)view {

    if (![[self view].gestureRecognizers containsObject:self.panGestureRecognizer]) {
        [[self view] addGestureRecognizer:self.panGestureRecognizer];
    }
}

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {

    if (recognizer.state == UIGestureRecognizerStateBegan) {
    } else if (recognizer.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [recognizer translationInView:recognizer.view];
        translation = CGPointMake(translation.x, - translation.y);
        [self panForTranslation:translation];
        [recognizer setTranslation:CGPointZero inView:recognizer.view];

    } else if (recognizer.state == UIGestureRecognizerStateEnded) {
    }
}

- (void)panForTranslation:(CGPoint)translation {
    CGPoint position = self.ball.position;
    CGPoint newPos = CGPointMake(position.x + translation.x, position.y);
    self.ball.position = newPos;
}

@end
Maq
  • 369
  • 3
  • 13
  • Any reason for not using touch delegates? – ZeMoon Apr 25 '14 at 22:17
  • 1
    Obviously if you set the position directly the body will be placed at that position. Then the physics engine tries to resolve the collision the best way it can. That means you can't prevent the user to drag a body into or over a collision when swiping fast enough when you set the position directly. You'd have to apply a force in the direction of the swipe or create more segments from previous to current point, then move body only one segment per frame (which means the body will be dragging behind the touch). – CodeSmile Apr 25 '14 at 22:59
  • @akashg using touch delegates will be just reinventing pan reconiser, am i right? so any reason for using touch delegates? :P – Maq Apr 26 '14 at 18:21
  • @LearnCocos2D you're right, applying force works - even with huge force (collision occurs). But.. it doesnt give same effect - maybe i need to better adjust force. 'Segments' seem to be tricky to implement becouse of syncing gesutre speed and moving one segment per frame. – Maq Apr 26 '14 at 18:35
  • @LearnCocos2D setting velocity instead of appling force gives more pan-like result. – Maq Apr 26 '14 at 18:44

0 Answers0