道歉,如果我已经问过这个,但我非常困难;第一个问题非常不清楚。在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)
}
答案 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中的位置屏幕截图。注意对象如何相对于场景大小保持定位。
答案 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)
}
考虑它的最佳方式是将游戏场景视为自己的屏幕,最后您想要使用此屏幕并对其进行缩放以满足各种设备设置。