2016-12-08 3 views
4

enter image description hereSprite Kit - Иногда шарик исчезает с экрана?

Я новый с комплектом спрайтов. Я пробовал простую игру с мячом с 2 игроками, другой - медленным слежением за мячом. Но я обнаружил проблему. Когда я перемещаю линию на шарик (с краем), шарик исчезает с экрана. В другой раз не проблема, мяч подпрыгивает. В чем проблема?

У меня есть один GameScene, sks и ViewController. Мои узлы спрайтов из sks. Если кто-то объяснит это дело. Будет лучше. Я приложил то, что я сделал ниже.

Мои GameScene:

class GameScene: SKScene { 

var ball = SKSpriteNode() 
var enemy = SKSpriteNode() 
var main = SKSpriteNode() 

override func didMove(to view: SKView) { 

    ball = self.childNode(withName: "ball") as! SKSpriteNode 
    enemy = self.childNode(withName: "enemy") as! SKSpriteNode 
    main = self.childNode(withName: "main") as! SKSpriteNode 

    ball.physicsBody?.applyImpulse(CGVector(dx: -20, dy: -20)) 
    ball.physicsBody?.linearDamping = 0 
    ball.physicsBody?.angularDamping = 0 

    let border = SKPhysicsBody(edgeLoopFrom: self.frame) 
    border.friction = 0 
    border.restitution = 1 

    self.physicsBody = border 

} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

    for touch in touches { 

     let location = touch.location(in: self) 
     main.run(SKAction.moveTo(x: location.x, duration: 0.2)) 
    } 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 

    for touch in touches { 

     let location = touch.location(in: self) 
     main.run(SKAction.moveTo(x: location.x, duration: 0.2)) 
    } 

} 

override func update(_ currentTime: TimeInterval) { 
    // Called before each frame is rendered 

    enemy.run(SKAction.moveTo(x: ball.position.x, duration: 0.5)) 
} 

Посмотреть контроллер:

class GameViewController: UIViewController { 

override func viewDidLoad() { 
    super.viewDidLoad() 

    if let view = self.view as! SKView? { 
     // Load the SKScene from 'GameScene.sks' 
     if let scene = SKScene(fileNamed: "GameScene") { 
      // Set the scale mode to scale to fit the window 
      scene.scaleMode = .aspectFill 

      // Present the scene 
      view.presentScene(scene) 
     } 

     view.ignoresSiblingOrder = true 


    } 
} 

override var prefersStatusBarHidden: Bool { 
    return true 
} 

настройки Pad:

pad

настройки Шаровые:

ball

Some updates

Я пробовал некоторые сообщения в функции обновления, а затем столкнулся с таким же случае мяч выходит за пределы с левой стороны устройства (с помощью картинки 6S)

enter image description here

enter image description here

2016-12-08 14:27:54.436485 Pong[14261:3102941] fatal error: ball out of left bounds: file

enter image description here

+0

Что такое -474.846 ...? Это позиция x или y? У каждого сообщения об ошибке есть такой же номер или они начинаются с 0? Это на устройстве или в симуляторе? –

+0

@SteveIves Моя точка привязки 0,5, поэтому -474 для этого размера не означает, что мяч выходит за пределы экрана левой стороны? – tobeiosdev

ответ

1

Насколько легко воспроизвести проблему? В update() напечатайте положение шара, чтобы увидеть, где оно находится, когда оно «исчезло». (это даст много результатов, поэтому будьте предупреждены).

Из того, что вы опубликовали, это не похоже на то, что мяч установлен на столкновение с границей, то есть мяч не будет реагировать (т.е. отскакивать) от границы, а сама граница неподвижна (поскольку это краевой физический корпус). Это, в сочетании с высокой скоростью шара (от жесткого удара), может привести к тому, что вы так сильно ударили по мячу с помощью «основного» спрайта, что он прошел через границу - используя preciseCollisionDetection=true, можно решить эту проблему, но придать границе категорию сначала добавьте это к шару collisionBitMask.

+0

Он мог бы установить быструю проверку в 'update', чтобы выплюнуть сообщение об ошибке, если мяч выходит за пределы границы. Я не вижу, как мяч может пройти через стену, если они находятся в одном и том же положении и столкновении ... Кроме срыва. – Fluidity

+0

@Fluidity, да - я об этом подумал, но если что-то еще происходит, и спрайт, который он снимает со сцены, проверка может не срабатывать. Но мой способ будет генерировать LOADS сообщений журнала, и если потребуется какое-то время, чтобы воспроизвести проблему, это может быть непрактично. Возможно, сделайте чек, чтобы увидеть, если ball.frame «пересекает» self.frame, а если нет, то распечатайте положение мяча. –

+1

@ Плотность Я определенно видел, как быстро движущиеся объекты перемещаются по границе физики в виде симулятора (но да, сбой) - не уверен, видел ли я, если на устройстве. Но если мяч не сталкивается с границей, то он не будет двигаться, поэтому возможно, что шар и граница будут перекрываться, а затем физический движок попытается сделать, а затем НЕ перекрыться, и он может переместить шар в неправильная сторона границы. –

1

вот пример того, что Стив говорит (в вашем .update())

if ball.position.x > frame.maxX { fatalError(" ball out of right bounds") } 
if ball.position.x < frame.minX { fatalError(" ball out of left bounds") } 
if ball.position.y > frame.maxY { fatalError(" ball out of top bounds") } 
if ball.position.y < frame.minY { fatalError(" ball out of bottom bounds) } 

вы можете также просто спам окна отладки:

print(ball.position) 

Это поможет вам выяснить, что если ваш мяч пролетел через границу, или если он где-то уничтожен, или какая-то другая ошибка.

В качестве обходного пути (на данный момент) я бы просто заменил вышеуказанный «fatalError» на «ball.position = CGPoint(x: 0, y: 0)» или какую-нибудь другую позицию, чтобы «сбросить» мяч в случае его потери.

Вы даже можете сохранить последнюю позицию в переменной, а затем восстановить ее до того, как вызывается триггер if-statements.

var lastBallLocation = CGPoint(x: 0, y: 0) // Just to initialize 
override func update(prams) { 
    if ball.position.x > frame.maxX { ball.position = lastBallLocation } 
    // .. copy the other three cases 
    lastBallLocation = ball.position // update only on successful position 

Или, вы можете попробовать сделать стены толще (используйте узел формы или spritenode и положите их на внешней стороне рамы, такие как стены домов, и ваш взгляд на экране это «номер»)

make sure to give SKSpriteNode a physics body so will bounce off the red blocks

каждая стенка также имеет тело физика для подпрыгивания:

enter image description here

+0

Пораженный левый фатальная ошибка. Посмотрите мое последнее изменение. – tobeiosdev

+0

@tobeiosdev ok. Так что ваш шар определенно проходит через стену. Вы пытались заменить «fatalError» на сброс кода шага, который я предложил? Вы также можете попытаться сделать стены толще (поставить другой узел как стену на каждой границе) – Fluidity

+0

Как вы можете видеть мою игру GameScene, как я могу утолстить стену в этом случае? пожалуйста подробно подробно. – tobeiosdev

2

Ты pinchin g мяч против стены, с врагом. Это означает, что силы в конечном итоге достаточно, чтобы создать достаточную скорость движения/силы шара, чтобы преодолеть физическую систему, поэтому она всплывает сквозь стену. Если вы заставите врага остановиться, прежде чем он завяжет мяч против стены, вы должны быть в порядке.

Это «pincing» происходит из-за этой строки кода:

enemy.run(SKAction.moveTo(x: ball.position.x, duration: 0.5))

Это делает противник гоняют мяч, который является хорошей идеей для игры в мяч, но на пути его перемещение неправильное. Использование действия означает, что противник применяет к нему бесконечную силу и нацеливается на середину мяча.

Итак, когда мяч доходит до стены, он останавливается против объекта физики с бесконечной статической силой, тогда этот противник приходит и применяет бесконечную силу с другой стороны ... и мяч либо всплывает внутри границ врагом или над другой стороной стены, потому что она раздроблена бесконечными силами.

Таким образом, вам нужно либо очень внимательно следить за тем, как вы управляете врагом с помощью Действия, либо использовать силы для управления противником, поскольку они не будут бесконечными, и физическая система сможет вернуться к враг.

+0

это переполнение? Кроме того, возможно, проще всего установить ограничение на скорость шара ... проверять обновление, если оно превышает пороговое значение, а затем сбросить его/укупорить. Это похоже на то, что Apple должно было уже реализовать ... – Fluidity

+1

@Fluidity добавил немного, чтобы ответить, чтобы объяснить, что я имею в виду под pincing – Confused

+1

Это проблема, с которой сталкиваются многие пользователи физики в первый раз, не понимая, что они необходимо зафиксировать использование физики или использовать алгоритмические средства управления движением. Эти два не очень хорошо сочетаются ... физическая система часто страдает от бесконечной силы, которую имеют алгоритмически мотивированные объекты. Все каламбуры предназначены. – Confused