SKSpriteNode с автоматической правильной ориентацией physicsBody

Что было бы лучшим способом заставить Swift SKSpriteNode автоматически корректировать свою ориентацию после того, как у него было несколько ударов по физике и теперь он не находится в ориентации по умолчанию?

Например, у меня есть 2D-человечек, которого сбивает в сторону другой объект, и я хотел бы, чтобы человечек-палка наклонился и переориентировался в положение стоя по умолчанию.


person Revick    schedule 06.02.2015    source источник
comment
применять угловой импульс в зависимости от того, с какой стороны он находится с возможной силой или чаще применяя импульс, чем больше персонаж наклонился   -  person LearnCocos2D    schedule 06.02.2015


Ответы (2)


В прошлом я делал это так: ждал, пока физическое тело остановится, выключал физический движок для крупье, переориентировал крупье, снова включал физический движок.

Напишите себе действие standupAction, которое анимирует переориентацию крупье, может быть, просто вращение или прыжок вверх. Затем сделайте что-то вроде следующего.

Извините, этот Objective-C не Swift, не знаю, быстрый, но его должно быть легко перевести.

if (stickman.physicsBody.resting) {
    stickman.physicsBody.dynamic = NO;
    [stickman runAction:[SKAction sequence:@[
              standupAction,
              [SKAction runBlock:^{ stickman.physicsBody.dynamic = YES;}]
              ]]];
}

Единственным недостатком этого подхода является то, что иногда может пройти целая секунда, пока крупье не остановится. Box2d занимает довольно много времени, чтобы успокоиться. Но выглядит очень реалистично, если подождать.

В качестве альтернативы, вы можете просто проверить ориентацию человечка и, если он потерял равновесие более чем на 45 градусов, переориентировать его с помощью импульсов. Я нахожу импульсы очень трудными, чтобы знать, сколько силы нужно приложить, когда вам нужно точное движение, подобное этому.

person Patrick Collins    schedule 06.02.2015
comment
Спасибо, я не подумал об отдыхе! 1 секунда не должна быть существенным ожиданием в моем случае. - person Revick; 06.02.2015

Просто чтобы обновить, я не мог позволить себе сделать physicsBody не динамическим.

Моя сцена обновляет каждый узел, как и в игре Apple Adventure, поэтому я реализовал поворот в методе обновления подкласса SKSpriteNode как таковой:

if (isTouchingGround) {
            if self.zRotation != 0 && !rotating {
                let actions = [
                    SKAction.runBlock {
                        self.rotating = true
                    },
                    SKAction.rotateToAngle(0, duration: 1.0),
                    SKAction.runBlock {
                        self.rotating = false
                    }]
                runAction(SKAction.sequence(actions))

            }
        }
person Revick    schedule 07.02.2015
comment
Apple Adventure не использует физический движок для расчета гравитации и т. д. Вы вручную изменяете вращение, в то время как физическим телом управляет физический движок. Это может вызвать сбои, когда физический движок борется с вами за контроль над движением персонажа. Я бы согласился с первоначальным предложением @LearnCocos2D, используя импульсы, чтобы повернуть его обратно на 0. - person Patrick Collins; 09.02.2015