Проблемы со SKPhysicsBody от Texture - PullRequest
0 голосов
/ 08 января 2020

Я искал по inte rnet / StackOverflow в течение последних нескольких дней, но без особого успеха нашел ответ на несколько вопросов, которые, как мне кажется, каким-то образом переплетены.

  1. Как это сделать Я предотвращаю зависание моей игры, когда она рендерит SKPhysicsBody из текстуры?
  2. Почему мои физические тела иногда вообще не создаются, и почему они иногда имеют неправильные формы?

Ниже приведен код, который я использую, чтобы попытаться сгенерировать эти столбы (изображение прикреплен в нижней части поста. В любой момент времени их примерно 6-8, прежде чем они будут удалены. Когда я изменяю форму на просто прямоугольник, я вообще не получаю никаких лагов / зависаний, и каждый раз физический объект создается должным образом. время.

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

fun c createWalls () {

    let scoreNode = SKSpriteNode()

    wallPair = SKNode()
    wallPair.name = "wallPair"

    //MARK: - Top Wall Setup
    let topWall = SKSpriteNode(imageNamed: "Pillar")
    topWall.size = CGSize(width: 100, height: 700)
    topWall.physicsBody = SKPhysicsBody(texture: topWall.texture!, size: topWall.size)
    topWall.position = CGPoint(x: self.frame.maxX+50, y: 0 + 400)
    topWall.physicsBody?.categoryBitMask = PhysicsCategory.Wall
    topWall.physicsBody?.collisionBitMask = PhysicsCategory.Character
    topWall.physicsBody?.contactTestBitMask = PhysicsCategory.Character
    topWall.physicsBody?.isDynamic = false
    topWall.physicsBody?.affectedByGravity = false
    topWall.zRotation = .pi



    //MARK: - Bot Wall Setup
    let botWall = SKSpriteNode(imageNamed: "Pillar")
    botWall.size = CGSize(width: 100, height: 700)
    botWall.physicsBody = SKPhysicsBody(texture: botWall.texture!, size: botWall.size)
    botWall.position = CGPoint(x: self.frame.maxX+50, y: 0 - 400)
    botWall.physicsBody?.categoryBitMask = PhysicsCategory.Wall
    botWall.physicsBody?.collisionBitMask = PhysicsCategory.Character
    botWall.physicsBody?.contactTestBitMask = PhysicsCategory.Character
    botWall.physicsBody?.isDynamic = false
    botWall.physicsBody?.affectedByGravity = false


    scoreNode.size = CGSize(width: 1, height: 600)
    scoreNode.position = CGPoint(x: topWall.position.x+15, y: 0)
    scoreNode.physicsBody = SKPhysicsBody(rectangleOf: scoreNode.size)
    scoreNode.physicsBody?.affectedByGravity = false
    scoreNode.physicsBody?.isDynamic = false
    scoreNode.physicsBody?.categoryBitMask = PhysicsCategory.Score
    scoreNode.physicsBody?.collisionBitMask = 0
    scoreNode.physicsBody?.contactTestBitMask = PhysicsCategory.Character
    scoreNode.color = SKColor.blue

    wallPair.addChild(topWall)
    wallPair.addChild(botWall)
    wallPair.zPosition = 1

    let randomPosition = CGFloat.random(min: -200, max: 200)
    wallPair.position.y = wallPair.position.y + randomPosition
    wallPair.addChild(scoreNode)
    wallPair.run(moveAndRemove)
    self.addChild(wallPair)

}

Pillar Image

1 Ответ

0 голосов
/ 09 января 2020

вы можете использовать это расширение:

extension SKTexture{
  func pristineCopy() -> SKTexture{
      return SKTexture(cgImage:self.cgImage)
  }
}

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

После SKPhysicsBody создает CGPath из этой текстуры, память должна освободиться, поэтому старайтесь не сохранять ее с переменной.

пример:

func createWalls()
    let scoreNode = SKSpriteNode()

    wallPair = SKNode()
    wallPair.name = "wallPair"

    //MARK: - Top Wall Setup
    let topWall = SKSpriteNode(imageNamed: "Pillar")
    topWall.size = CGSize(width: 100, height: 700)
    topWall.physicsBody = SKPhysicsBody(texture: topWall.texture!.pristineCopy(), size: topWall.size)
    topWall.position = CGPoint(x: self.frame.maxX+50, y: 0 + 400)
    topWall.physicsBody?.categoryBitMask = PhysicsCategory.Wall
    topWall.physicsBody?.collisionBitMask = PhysicsCategory.Character
    topWall.physicsBody?.contactTestBitMask = PhysicsCategory.Character
    topWall.physicsBody?.isDynamic = false
    topWall.physicsBody?.affectedByGravity = false
    topWall.zRotation = .pi



    //MARK: - Bot Wall Setup
    let botWall = SKSpriteNode(imageNamed: "Pillar")
    botWall.size = CGSize(width: 100, height: 700)
    botWall.physicsBody = SKPhysicsBody(texture: botWall.texture!.pristineCopy(), size: botWall.size)
    botWall.position = CGPoint(x: self.frame.maxX+50, y: 0 - 400)
    botWall.physicsBody?.categoryBitMask = PhysicsCategory.Wall
    botWall.physicsBody?.collisionBitMask = PhysicsCategory.Character
    botWall.physicsBody?.contactTestBitMask = PhysicsCategory.Character
    botWall.physicsBody?.isDynamic = false
    botWall.physicsBody?.affectedByGravity = false


    scoreNode.size = CGSize(width: 1, height: 600)
    scoreNode.position = CGPoint(x: topWall.position.x+15, y: 0)
    scoreNode.physicsBody = SKPhysicsBody(rectangleOf: scoreNode.size)
    scoreNode.physicsBody?.affectedByGravity = false
    scoreNode.physicsBody?.isDynamic = false
    scoreNode.physicsBody?.categoryBitMask = PhysicsCategory.Score
    scoreNode.physicsBody?.collisionBitMask = 0
    scoreNode.physicsBody?.contactTestBitMask = PhysicsCategory.Character
    scoreNode.color = SKColor.blue

    wallPair.addChild(topWall)
    wallPair.addChild(botWall)
    wallPair.zPosition = 1

    let randomPosition = CGFloat.random(min: -200, max: 200)
    wallPair.position.y = wallPair.position.y + randomPosition
    wallPair.addChild(scoreNode)
    wallPair.run(moveAndRemove)
    self.addChild(wallPair)
}
...