SpriteKit и Swift: изменение размера основного узла прокрутки в зависимости от размера экрана не работает

#ios #swift #sprite-kit

#iOS #swift #sprite-kit

Вопрос:

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

Заранее благодарю вас.

Способ определить, на каком устройстве запущена игра:

 func determineDevice() {

    if view!.bounds.width == 480.0 { //IP4
        isIphone4 = true
        isIphone5 = false
        isIphone6 = false
        isIphone6Plus = false
    }

    if view!.bounds.width == 568.0 { //IP5
        isIphone4 = false
        isIphone5 = true
        isIphone6 = false
        isIphone6Plus = false
    }

    if view!.bounds.width == 667.0 { //IP6
        isIphone4 = false
        isIphone5 = false
        isIphone6 = true
        isIphone6Plus = false
    }

    if view!.bounds.width == 736.0 { //IP6 
        isIphone4 = false
        isIphone5 = false
        isIphone6 = false
        isIphone6Plus = true
    }
}
 

Вот пример, как я устанавливаю размер всех других узлов в моей игре в зависимости от размера экрана:

 class GameScene: SKScene, SKPhysicsContactDelegate {

  var screenWidth:CGFloat = 0
  var screenHeight:CGFloat = 0

override func didMoveToView(view: SKView) {

    screenWidth = self.view!.bounds.width
    screenHeight = self.view!.bounds.height 

    node.size = CGSizeMake(screenWidth / 5.5, screenHeight / 6) 
}
 

}

И последнее, но не менее важное: основной код:

 func initializingScrollingGround() {
    for var index = 0; index < 2; index  = 1 {
        ground = SKSpriteNode(imageNamed:"Ground_Layer")
        ground.size = CGSize(width: frame.width, height: frame.height  / 6)
        ground.position = CGPoint(x: index * Int(ground.size.width), y: Int(screenHeight - 37))
        ground.zPosition = 10
        ground.anchorPoint = CGPointZero
        ground.name = "Ground"

        let offsetX = ground.size.width * ground.anchorPoint.x
        let offsetY = ground.size.height * ground.anchorPoint.y

        let path = CGPathCreateMutable()

        CGPathMoveToPoint(path, nil, 0 - offsetX, 48 - offsetY)
        CGPathAddLineToPoint(path, nil, 0 - offsetX, 0 - offsetY)
        CGPathAddLineToPoint(path, nil, 665 - offsetX, 0 - offsetY)
        CGPathAddLineToPoint(path, nil, 668 - offsetX, 48 - offsetY)

        CGPathCloseSubpath(path)

        ground.physicsBody = SKPhysicsBody(polygonFromPath: path)
        ground.physicsBody?.categoryBitMask = PhysicsCatagory.ground
        ground.physicsBody?.collisionBitMask = PhysicsCatagory.dragon
        ground.physicsBody?.contactTestBitMask = PhysicsCatagory.dragon
        ground.physicsBody?.affectedByGravity = false
        ground.physicsBody?.dynamic = false
        ground.physicsBody?.restitution = 0


        self.worldNode.addChild(ground)
    }
}
 

В методе обновления:

  func moveGround() {
    self.worldNode.enumerateChildNodesWithName("Ground", usingBlock: { (node, stop) -> Void in
        if let Ground = node as? SKSpriteNode {
            Ground.position = CGPoint(x: Ground.position.x - self.groundVelocity, y: Ground.position.y)

            // Checks if ground node is completely scrolled off the screen, if yes, then puts it at the end of the other node.
            if Ground.position.x <= -Ground.size.width {
                Ground.position = CGPointMake(Ground.position.x   Ground.size.width * 2, Ground.position.y)
            }
        }
    })
}
 

Кто-нибудь знает, как я мог бы решить мою проблему?

Комментарии:

1. вы работаете в режиме масштабирования изменения размера?

2. @Knight0fDragon нет, с AspectFill

3. хорошо, тогда ваш подход неверен. Цель scaleMode (за исключением изменения размера) — иметь размер сцены 1, который масштабируется по любому аспекту и размеру. По сути, ваш «размер экрана» — это размер вашей сцены, а длина и высота отдельного пикселя будут определяться разницей в масштабе вашего размера сцены и вашего фактического размера экрана, если это имеет для вас какой-либо смысл

4. чтобы упростить цифры, предположим, что на реальном устройстве 1 пиксель равен 1 дюйму, а в строке 10 пикселей. Вы создаете сцену размером 5 пикселей подряд. При масштабировании 1 пиксель будет иметь длину 2 дюйма, так что мы можем поместить 5 пикселей в длину 10 пикселей. Если мы перейдем к устройству с 15 пикселями, то сцена будет иметь 1 пиксель длиной 3 дюйма.

5. @Knight0fDragon хорошо, я никогда раньше не работал с представлениями, я собираюсь погуглить, как это работает. скоро вернусь. Спасибо

Ответ №1:

Можно попробовать один из подходов SKCameraNode , тогда все ваши узлы будут меняться вместе. В этом примере используется расширение на SKCameraNode и различается только между iPad и iPhone;

 // SKCameraNode Extensions.swift
extension SKCameraNode {
    func updateScaleFor(userInterfaceIdiom: UIUserInterfaceIdiom, isLandscape: Bool) {
        switch userInterfaceIdiom {
            case .phone:
                self.setScale(isLandscape ? 0.75 : 1.0)
            case .pad:
                self.setScale(isLandscape ? 1.0 : 1.25)
            default:
                break
        }
    }
}
 

Затем, когда ваша сцена загружается;

 camera.updateScaleFor(userInterfaceIdiom: UIDevice.current.userInterfaceIdiom, isLandscape: true)