2015-12-19 3 views
1

Извинения, если я уже спросил об этом, но Im очень застрял; первый вопрос был очень неясным. Создал игру в SpriteKit на симуляторе iPhone 6, а при работе с другими симуляторами все выбрасывалось из выравнивания. Я не использую никаких .sks, .xib или раскадровки. Есть ли способ программно изменить размер игры так, чтобы все размеры экрана имели правильное положение? При необходимости отправьте код.iPhone 4, 5, 5 и 6+ симуляторы смещающие узлы

Редактировать: GameViewController:

import UIKit 
    import SpriteKit 
    var sceneSize = UIScreen.mainScreen().bounds 
var screenWidth = sceneSize.width 
var screenHeight = sceneSize.height 
    class GameViewController: UIViewController { 
var scene: GameScene! 

override func viewDidLayoutSubviews() { 

super.viewWillLayoutSubviews() 


    let skView = self.view as! SKView 
    skView.multipleTouchEnabled = false 
    scene = GameScene(size: skView.bounds.size) 
    //scene.scaleMode = .AspectFill 
    scene.scaleMode = SKSceneScaleMode.ResizeFill 
    skView.presentScene(scene) 
    scene.anchorPoint = CGPointMake(0, 0) 
    skView.showsFPS = false 
    skView.showsNodeCount = false 
    skView.ignoresSiblingOrder = true 
      let completionBlock:() -> Void = { 

    } 

    let errorBlock: (NSError!) -> Void = { error in 
     print("error") 

} 
    RevMobAds.startSessionWithAppID("", withSuccessHandler: completionBlock, andFailHandler: errorBlock); 

} 

override func shouldAutorotate() -> Bool { 
    return true 
} 

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { 
    if UIDevice.currentDevice().userInterfaceIdiom == .Phone { 
     return .AllButUpsideDown 
    } else { 
     return .All 
    } 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Release any cached data, images, etc that aren't in use. 
} 

override func prefersStatusBarHidden() -> Bool { 
    return true 
} 

}

Редактировать 2 GameScene:

import Foundation 
import SpriteKit 
import UIKit 
    var sceneSize = UIScreen.mainScreen().bounds 
    var screenWidth = sceneSize.width 
    var screenHeight = sceneSize.height 
    class GameScene: SKScene { 

     player.position = CGPointMake(screenWidth/5, screenHeight/3) 
     } 
+0

Возможный дубликат [Различные размеры симуляторов iPhone, которые бросают узлы неуместны] (http://stackoverflow.com/questions/34363501/different-iphone-simulator-sizes-throwing-nodes-out-of-place) – Caleb

+0

I знаю, но он не ответил на мой вопрос. –

+0

@RaeTucker ваш вопрос точно такой же, как ваш старый вопрос, вместо того, чтобы создавать новый вопрос, вам действительно нужно просто отредактировать старый. Я бы удалил старый вопрос, так как он никому не принесет никаких выгод. – Knight0fDragon

ответ

0

Во-первых, установить GameScene SKSceneScalode (это обнаруживается предварительно запрограммированы в GameViewController к .ResizeFill

Затем скопируйте следующий код в GameScene:

Import UIKit 
var screenSize = UIScreen.mainscreen().bounds 
var screenWidth = screenSize.width 
var screenHeight = screenSize.height 

Это будет хранить ширину и высоту экрана в переменных screenWidth и screenHeight. Теперь, когда вы создаете свои spriteNodes и другие объекты, используйте эти две переменные в качестве основы. Вот пример

someNode.position = CGPoint(x: screenWidth/5 y: screenHeight/3) 
+0

Это все еще не работает должным образом, и у меня есть то, что вы ответили дословно. –

+0

Не могли бы вы разместить какой-нибудь код? Сначала GameViewController – Jamman00

+0

Если что-то еще, что вы хотите увидеть, дайте мне знать. –

0

Вы тот же человек, который размещен в разделе Swift в Reddit? Вот мой код, который работает для всех устройств iPhone, так как я хорошо ответил на сообщение Reddit таким же образом. Вот более глубокий ответ.

В вашем контроллере просмотра введите следующий код внутри viewDidLoad().

//Create a scene object with the max size of an iPhone 6 Plus at 1920 x 1080 
//That means it can easily scale down to the 6, 5, and 4S. 
let mainScene = GameScene(size: CGSize(width: 1920, height: 1080)) 

//To fill the scene and fit for all sizes 
mainScene.scaleMode = .AspectFill 

//Prepare the view 
let mainView = self.view as! SKView 
mainView.showsFPS = true  
mainView.showsNodeCount = true 
mainView.ignoresSiblingOrder = true 

//Move to the required scene 
mainView.presentScene(mainScene, transition: SKTransition.fadeWithDuration(1)) 

На сцене класса добавьте следующие переменные вверху.

//Will be used to get the ratio of the device 
let deviceWidth = UIScreen.mainScreen().bounds.width 
let deviceHeight = UIScreen.mainScreen().bounds.height 
let maxAspectRatio: CGFloat 
let playableArea: CGRect 

Если вы уже не имеете переопределения инициализации внутри класса сцены, вид которой движется, добавьте следующую внутри класса.

//Overrides the superclasses' SKScene init 
override init(size: CGSize) { 

    //Initializes the maxAspectRatio variable 
    maxAspectRatio = deviceHeight/deviceWidth 
    print("The ratio of the device is: \(maxAspectRatio)") 


    //Prepares the rectangle view that is viewable by the user (ONLY FOR PORTRAIT MODE) 
    let playableWidth = size.height/maxAspectRatio 
    let playableMargin = (size.width - playableWidth)/2.0 
    playableArea = CGRect(x: playableMargin, y: 0, width: playableWidth, height: size.height) 

    /*USE THIS CODE IF YOUR APP IS IN LANDSCAPE MODE***************************************** 
    let playableHeight = size.width/maxAspectRatio 
    let playableMargin = (size.height - playableHeight)/2.0 
    playableArea = CGRect(x: 0, y: playableMargin, width: size.width, height: playableHeight) 
    *///************************************************************************************* 


    //Find out what kind of device the user is using 
    if maxAspectRatio == (4/3) { 

     //The iPhone's 4S ratio is 4:3 
     print("The user is using an iPhone 4S") 

    } else { 

     //That means the ratio is not 4:3, so it probably is 16:9 
     print("The user is using an iPhone 5, 6, 6S, or 6 Plus.") 
    } 

    //Assigns the size of the scene to the superclass init of SKScene 
    //Must be called after all variables are initialed in this class 
    super.init(size: size) 
} 
required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

Добавьте следующую функцию внутри класса сцены, чтобы вы могли видеть область видимости, которую видит пользователь. Он рисует красный прямоугольник. Затем просто вызовите эту функцию внутри функции didMoveToView(). Теперь, чтобы позиционировать объекты, все, что вам нужно сделать, это использовать свойства CGRectGet ... на playableArea, чтобы правильно позиционировать объекты.

//Used to draw the rectangle or the view of the phone 
func drawPlayableArea() { 
    let shape = SKShapeNode() 
    let path = CGPathCreateMutable() 
    CGPathAddRect(path, nil, playableArea) 
    shape.path = path 
    shape.strokeColor = SKColor.redColor() 
    shape.lineWidth = 8 
    addChild(shape) 
} 

override func didMoveToView(view: SKView) { 

    drawPlayableArea() 

    //Examples used to position objects on a screen related to the playable area or viewable area 
    //This works for all iPhone devices as well as iPods. 

    let label = SKLabelNode(fontNamed: "Arial") 
    label.fontColor = SKColor.whiteColor() 
    label.text = "Hello, Redditor!" 
    label.position = CGPoint(x: CGRectGetMidX(playableArea), y: CGRectGetMidY(playableArea)) 
    addChild(label) 

    let score = SKLabelNode(fontNamed: "Arial") 
    score.verticalAlignmentMode = .Top 
    score.horizontalAlignmentMode = .Left 
    score.fontColor = SKColor.whiteColor() 
    score.text = "Score: 100" 
    score.position = CGPoint(x: CGRectGetMinX(playableArea) + 20, y: CGRectGetMaxY(playableArea) - 20) 
    addChild(score) 

    backgroundColor = SKColor.blackColor() 
} 

Here are the github files if you need to understand the code more.

Скриншоты позиций в качестве 4S и 6 Plus. Обратите внимание, как объекты остаются на месте относительно размера сцены.

iPhone 4SiPhone 6 Plus

+0

Да, я ха-ха. У меня есть узлы, настроенные в файле plist, поэтому предоставление им позиции, кроме '(position.x, position.y)', действительно все испортит. Есть ли способ изменить это? –

+0

Ну, я никогда не использовал файлы plist для позиций объектов, поэтому, если вы пытаетесь заставить его работать на несколько устройств, вам может потребоваться переосмыслить ваш подход. –

0

ОК я успел перечитать это, и я думаю, что я знаю, что происходит, я оставлю мой старый ответ здесь, как хорошо.

Новый ответ: Что здесь происходит, вы устанавливаете размер своей сцены во время создания представления, прежде чем будут применены любые автоматические ограничения. Таким образом, размер вашего изображения не совпадает с размером экрана.Таким образом, ваша сцена становится того же размера, независимо от устройства, тогда вы применяете математику на основе вашего экрана, и все отбрасывается. Что вам нужно сделать: 1) Убедитесь, что моя теория правильная, и что во время создания вашей сцены размер не совпадает с размером экрана, затем 2) создайте сцену во время изменения размера представления Устройство.

Старый ответ: Причина, по которой все выбрасывается из-за выравнивания, заключается в том, что ваша игровая сцена изменяется на основе устройства. Вам нужно установить единый постоянный размер для того, чтобы делать то, что вы делаете let scene = GameScene(size:CGSizeMake(400,300))
Где 400 x 300 можно изменить в зависимости от ваших потребностей. это даст вам игровой уголок фиксированного размера для работы, поэтому ваши узлы будут размещены одинаково. Затем, чтобы обрабатывать размер экрана, вы устанавливаете режим масштабирования сцен в зависимости от размера или соответствия формы, в зависимости от того, хотите ли вы потерять информацию, но не имеете черных полос или черных полос и показывать всю информацию. (изменение размера будет искажать ваше изображение, растягивая, если это то, что вы хотите). для этого это просто scene.scaleMode = .AspectFill

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

Внутри кода сцены используйте ширину и высоту сцены, чтобы манипулировать узлов, а не экран

class GameScene: SKScene { 
    override func didMoveToView(view: SKView) { 
    player.position = CGPointMake(scene.frame.width/5, scene.frame.height/3) 
    } 

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

+0

Хорошо, это имеет смысл, спасибо. Есть ли условие, которое я могу использовать, чтобы установить его на разные размеры экрана? (например, код для разных устройств) –

+0

не 100% определенно, но попробовал сделатьMoveToSuperview – Knight0fDragon

+0

Хорошо, также у меня есть узлы, настроенные в файле plist (их много), и они вот-вот меняются в основном. Есть ли способ сосредоточить их на всех устройствах? –

Смежные вопросы