2016-12-05 8 views
1

This question и другие обсуждают, как отслеживать узел в SpriteKit, используя SKCameraNode.SpriteKit: как плавно анимировать SKCameraNode при отслеживании узла, но только после того, как узел перемещает Y пикселей?

Однако наши потребности различаются.

Другие решения, такие как обновление положения камеры в update(_ currentTime: CFTimeInterval) SKScene, не работают, потому что мы хотим только отрегулировать положение камеры после того, как узел переместил Y пикселей вниз по экрану.

Другими словами, если узел перемещается на 10 пикселей вверх, камера должна оставаться неподвижной. Если узел перемещается влево или вправо, камера должна оставаться неподвижной.

Мы попытались анимировать положение камеры с течением времени, а не мгновенно, но запуск SKAction против камеры внутри update(_ currentTime: CFTimeInterval) ничего не может сделать.

+0

просто отслеживайте местоположение спрайта и ограничивайте движение камеры, исходя из этого местоположения. – GeneCode

+0

@GeneCode да, но где? 'update (_ currentTime: CFTimeInterval)' не работает, когда мы пытались анимировать движение SKCameraNode? – Crashalot

+0

Да, установка SKAction в методе обновления не является хорошей практикой, потому что обновление вызывается много раз в секунду. – GeneCode

ответ

3

Я как раз быстро сделал это. Я считаю, что это то, что вы ищете? (фактическая анимация гладкая, просто я должен был сжать GIF)

enter image description here

Это обновление Код:

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

    SKShapeNode *ball = (SKShapeNode*)[self childNodeWithName:@"ball"]; 
    if (ball.position.y>100) camera.position = ball.position; 

    if (fabs(ball.position.x-newLoc.x)>10) { 
     // move x 
     ball.position = CGPointMake(ball.position.x+stepX, ball.position.y); 
    } 

    if (fabs(ball.position.y-newLoc.y)>10) { 
     // move y 
     ball.position = CGPointMake(ball.position.x, ball.position.y+stepY); 
    } 
} 
+0

Спасибо за усилия, но это эффективно то, что мы делали раньше. Это привело к очень резкому движению, потому что узел быстро перемещается (падает с гравитацией). – Crashalot

+0

Если ваше движение вяло, это, скорее всего, не из-за этого, но связано с тем, как вы перемещаете свой спрайт. Вы реализовали скорость TimeElapsed * для перемещения спрайта? – GeneCode

+0

Или, может быть, с тех пор, как вы используете физику, лучше всего поставить все, что связано с движениями в делегате didsimulatephysics? – GeneCode

1

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

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

class MyCharacter : SKSpriteNode 
{ 
    override var position : CGPoint 
    { 
     didSet 
     { 

      if let scene = self.scene, let camera = scene.camera,(abs(position.y - camera.position.y) > 10) 
      { 
       let move = SKAction.move(to: position, duration:0.1) 
       move.timingMode = .easeInEaseOut 
       camera.run(move,withKey:"moving") 
      } 
     } 
    } 
} 

Edit: @Epsilon напомнил мне, что SKActions и SKPhysics доступ к переменной непосредственно вместо того, чтобы идти через хранимого имущества, так что это не будет работать. В этом случае сделайте это по методу didFinishUpdate:

override func didFinishUpdate() 
{ 
    //character should be a known property to the class, calling find everytime is too slow 
    if let character = self.character, let camera = self.camera,(abs(character.position.y - camera.position.y) > 10) 
    { 
     let move = SKAction.move(to: character.position, duration:0.1) 
     move.timingMode = .easeInEaseOut 
     camera.run(move,withKey:"moving") 
    } 
} 
+0

, если камера только движется вниз, затем вытащите абс и сделайте это <= -10 – Knight0fDragon

+1

Это будет работать, только если вы установите позицию персонажа напрямую. Если вы перемещаете символ с действием или применяете силу/импульс к его «физике», 'didSet' не будет вызываться, потому что свойство position не устанавливается напрямую. – Epsilon

+0

Это правда, вы можете обойти это, выполнив character.position = character.position на didFinishUpdate, который возвращает нас обратно в GeneCodes, просто используя другую функцию, или используйте customActions для перемещения вместо использования встроенного для перемещения ваш спрайт – Knight0fDragon