Endless Runner переместите плеер для равной сложности независимо от соотношения сторон

#ios #swift #sprite-kit

#iOS #swift #набор для создания спрайтов

Вопрос:

Я создаю endless runner для iphone в ландшафтном режиме с помощью SpriteKit. Я настроил сцену как таковую:

 override func viewDidLayoutSubviews() {

    let scene = GameScene(size: CGSize(width: 812, height: 375))
    let skView = view as! SKView
    scene.backgroundColor = UIColor.red
    scene.scaleMode = .aspectFill
    skView.presentScene(scene)
    skView.showsFPS = true
    skView.showsNodeCount = true
    print("Screen Size: (GlobalProperties.screenSize.width) x (GlobalProperties.screenSize.height)")
    print("Scene Size: (scene.size.width) x (scene.size.height)")


} 
  

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

  override func didMove(to view: SKView) {

    let player = SKSpriteNode(texture: SKTexture(imageNamed: "CuteMelon"))
    player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    player.position = CGPoint(x: frame.width - 600, y: frame.midY)
    self.addChild(player)

    let rect = SKSpriteNode(color: .orange, size: CGSize(width: 550, height: 200))
    rect.anchorPoint = CGPoint(x: 1, y: 0.5)
    rect.position = CGPoint(x: frame.width-50, y: frame.height/2)
    self.addChild(rect)
}
  

Я добавил прямоугольник, чтобы посмотреть, был ли в обоих случаях проигрыватель на 600 пикселей справа (оставив пробел в 50 пикселей, чтобы убедиться, что он не выходит за пределы)

Результат следующий:

iPhone XR:https://imgur.com/y6OYHkK который работает так, как задумано

iPhone 8:https://imgur.com/nkrx5By который не помещает прямоугольник на 50 пикселей от правой границы рамки.

Что мне нужно сделать, чтобы исправить эту проблему, или мне следует решить ее совершенно другим способом? Спасибо

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

1. если вы программируете для самого широкого устройства (iphone X), вам не придется беспокоиться о том, что видно, потому что обрезка будет происходить сверху и снизу. Конечно, я бы рекомендовал просто создать квадратную сцену, тогда вы никогда не столкнетесь с этой проблемой ни на каких будущих устройствах.

2. @Knight0fDragon но этого не происходит, если вы посмотрите на изображения, которые вы можете видеть на iphone 8, они обрезаются по бокам фона

3. Из-за вашего размера сцены не учитывается высота других устройств, поэтому ваша заливка аспектами растягивает сцену по высоте, а не по ширине

4. Ваш рост 200, но вам нужен рост 309,75, чтобы соответствовать сцене с разрешением 9: 16. 412.5 для ipad…. черт возьми, iphone x должен быть 253,84, так что даже это неправильно

5. Создайте свою сцену в виде квадрата размером 500 500, но сделайте основную видимую область высотой 250. Все, что находится за пределами этой высоты, является дополнительной прорисовкой для учета различных соотношений сторон

Ответ №1:

Просто определите разницу между размером сцены и экрана и переместите камеру на половину этого расстояния. Формула abs((sceneWidth - screenWidth * sceneHeight/screenHeight)/2) даст вам это. Что это делает, так это масштабирует экран до любой высоты сцены, затем вычитает две разницы из ширины и возвращает половину этого значения.

  override func didMove(to view: SKView) {
    let widthPadding = abs((self.frame.width - (UIScreen.main.bounds.width *  self.frame.height / UIScreen.main.bounds.height )) / 2)
    self.camera = self.camera ?? SKCameraNode()

    self.camera.position.x  = widthPadding

    let player = SKSpriteNode(texture: SKTexture(imageNamed: "CuteMelon"))
    player.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    player.position = CGPoint(x: frame.width - 600, y: frame.midY)
    self.addChild(player)

    let rect = SKSpriteNode(color: .orange, size: CGSize(width: 550, height: 200))
    rect.anchorPoint = CGPoint(x: 1, y: 0.5)
    rect.position = CGPoint(x: frame.width-50, y: frame.height/2)
    self.addChild(rect)
}
  

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

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