iPhone 4,5,5和6+模拟器未对准节点

时间:2015-12-19 02:38:42

标签: ios iphone swift sprite-kit

道歉,如果我已经问过这个,但我非常困难;第一个问题非常不清楚。在iPhone 6模拟器上在SpriteKit中创建了一个游戏,当运行其他大小的模拟器时,一切都被抛弃了。我没有使用任何.sks,.xib或故事板。有没有办法以编程方式调整游戏大小,以便所有屏幕尺寸都有正确的位置?如有必要,将发布代码。

编辑: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)
       }

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

你是在Reddit的Swift部分发布的那个人吗?这是我的代码适用于所有iPhone设备,因为我在Reddit帖子上以同样的方式回答了它。这是更深刻的答案。

在View Controller中,在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

如果您在视图移动到的类场景中没有覆盖init,请在类中添加以下内容。

//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()函数内调用此函数。现在要定位对象,你所要做的就是在playableArea上使用CGRectGet ...属性来正确定位对象。

//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 4S iPhone 6 Plus

答案 2 :(得分: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)
   }

考虑它的最佳方式是将游戏场景视为自己的屏幕,最后您想要使用此屏幕并对其进行缩放以满足各种设备设置。