SpriteKit не может изменить SKPhysicsJointLimit maxLength

У меня есть простой проект, в котором у меня есть два SKShapeNodes с SKPhysicsBody для каждого. У меня есть SKPhysicsJointLimit, который их соединяет. Пока программа работает, мне нужно изменить свойство SKPhysicsJointLimit.maxLength. Однако, хотя значение изменяется, физика на экране этого не показывает.

Я запускаю Xcode 6.4 и развертываю iOS 7.0+.

Как изменить свойство maxLength, чтобы оно обновляло физику сустава?

У меня есть мой код, который изменен из проекта SpriteKit по умолчанию:

GameScene.h

#import <SpriteKit/SpriteKit.h>

@interface GameScene : SKScene

@property (strong) SKShapeNode *node1;
@property (strong) SKShapeNode *node2;
@property (strong) SKPhysicsJointLimit *limitJoint;
@property bool running;

@end

GameScene.m

#import "GameScene.h"

@implementation GameScene

-(void)didMoveToView:(SKView *)view {
    self.running = NO;

    // Create a simple square path for the nodes to use
    CGMutablePathRef square = CGPathCreateMutable();
    CGPathMoveToPoint(square, NULL, -10, 10);
    CGPathAddLineToPoint(square, NULL, -10, -10);
    CGPathAddLineToPoint(square, NULL, 10, -10);
    CGPathAddLineToPoint(square, NULL, 10, 10);
    CGPathAddLineToPoint(square, NULL, -10, 10);
    CGPathCloseSubpath(square);

    // Create node 1
    self.node1 = [SKShapeNode node];
    self.node1.position = CGPointMake(450, 512);
    self.node1.path = square;
    self.node1.fillColor = [SKColor blackColor];
    // I know that I'm using a circular physics body here, but for me a circle is fine
    self.node1.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
    // Will turn it on after the user taps the screen, so that we can watch it run
    self.node1.physicsBody.dynamic = NO;
    [self.scene addChild:self.node1];

    // Create node 2
    self.node2 = [SKShapeNode node];
    self.node2.position = CGPointMake(550, 512);
    self.node2.path = square;
    self.node2.fillColor = [SKColor blackColor];
    self.node2.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10];
    // Node 2 will always stay in place
    self.node2.physicsBody.dynamic = NO;
    [self.scene addChild:self.node2];

    // Create the limit joint between the two nodes
    self.limitJoint = [SKPhysicsJointLimit jointWithBodyA:self.node1.physicsBody bodyB:self.node2.physicsBody anchorA:self.node1.position anchorB:self.node2.position];
    [self.scene.physicsWorld addJoint:self.limitJoint];
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (self.running) {
        // Set the new maxLength
        float newMaxLength = self.limitJoint.maxLength + 50.0;
        [self.limitJoint setMaxLength:newMaxLength];
        NSLog(@"New length: %f", self.limitJoint.maxLength);
    } else {
        // Turn on the physics for node 1
        self.running = YES;
        self.node1.physicsBody.dynamic = YES;
    }
}

-(void)update:(CFTimeInterval)currentTime {
    // Nothing here
}

@end

Вывод этого кода:

2015-08-18 19:55:33.494 LimitTest[6925:60b] New length: 150.000015
2015-08-18 19:55:33.706 LimitTest[6925:60b] New length: 200.000031
2015-08-18 19:55:33.897 LimitTest[6925:60b] New length: 250.000031
2015-08-18 19:55:34.134 LimitTest[6925:60b] New length: 300.000031
2015-08-18 19:55:34.381 LimitTest[6925:60b] New length: 350.000031
2015-08-18 19:55:34.614 LimitTest[6925:60b] New length: 400.000061
2015-08-18 19:55:35.784 LimitTest[6925:60b] New length: 450.000061
2015-08-18 19:55:36.136 LimitTest[6925:60b] New length: 500.000061
2015-08-18 19:55:36.401 LimitTest[6925:60b] New length: 550.000061
2015-08-18 19:55:36.630 LimitTest[6925:60b] New length: 600.000061
2015-08-18 19:55:36.890 LimitTest[6925:60b] New length: 650.000122
2015-08-18 19:55:37.130 LimitTest[6925:60b] New length: 700.000122
2015-08-18 19:55:37.368 LimitTest[6925:60b] New length: 750.000122
2015-08-18 19:55:37.611 LimitTest[6925:60b] New length: 800.000183
2015-08-18 19:55:37.846 LimitTest[6925:60b] New length: 850.000183
2015-08-18 19:55:38.102 LimitTest[6925:60b] New length: 900.000244
2015-08-18 19:55:38.313 LimitTest[6925:60b] New length: 950.000244
2015-08-18 19:55:38.568 LimitTest[6925:60b] New length: 1000.000244

Я почти уверен, что действительно маленькое десятичное значение - это просто некоторая неточность, о которой я не беспокоюсь. Я просто показываю, что свойство maxLength меняется.

Я видел здесь этот вопрос, который был задан более года назад, но без решения. В комментариях он говорит, что нашел решение, и его краткое описание исправления касается внесения изменений перед возвратом объекта. Но, насколько я могу судить, ко мне это не относится. Кто-то попросил у него разъяснений, но, похоже, их проигнорировали.


person Gliderman    schedule 19.08.2015    source источник
comment
Решение OP состояло в том, чтобы создать новый сустав с новым значением maxLength.   -  person 0x141E    schedule 19.08.2015


Ответы (1)


0x141E предоставил информацию о том, как это сделать, сделать подключение я не мог. В основном создайте новый сустав после удаления первого. У меня есть глобальная переменная для моего сустава, и это отлично сработало для меня. Вот код, который я сейчас использую в touchesBegan

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (self.running) {
        // Create the new maxLength
        float newMaxLength = self.limitJoint.maxLength + 50.0;
        [self.scene.physicsWorld removeJoint:self.limitJoint];

        self.limitJoint = [SKPhysicsJointLimit jointWithBodyA:self.node1.physicsBody bodyB:self.node2.physicsBody anchorA:self.node1.position anchorB:self.node2.position];
        [self.limitJoint setMaxLength:newMaxLength];

        [self.scene.physicsWorld addJoint:self.limitJoint];
        NSLog(@"New length: %f", self.limitJoint.maxLength);
    } else {
        self.running = YES;
        self.node1.physicsBody.dynamic = YES;
    }
}
person Gliderman    schedule 19.08.2015