I was testing my app on different devices and realized the sprite movements were quite inconsistent (running considerably faster on some devices as compared to others). I found this post and followed the instructions and removed the size parameters from all my SKScene
s then I got the error:
我在不同设备上测试我的应用程序,并意识到精灵运动非常不一致(在某些设备上运行速度比其他设备快得多)。我发现这篇文章并按照说明从我所有的SKScenes中删除了大小参数然后我收到了错误:
fatal error: use of unimplemented initializer 'init(size:)' for class 'SuperGame.PosterScene'
Please see my PosterScene
class below and the GameViewController
class in which it is called.
请参阅下面的PosterScene类和调用它的GameViewController类。
PosterScene
PosterScene
class PosterScene: SKScene {
override init(){
super.init()
let posterImage = SKSpriteNode(imageNamed: "poster")
posterImage.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
self.addChild(posterImage)
let sequence = SKAction.sequence([ SKAction.wait(forDuration: 3.0), SKAction.run({ self.changeToMainMenuScene() }) ])
self.run(sequence)
}
func changeToMainMenuScene () {
let mainMenuScene = MainMenuScene()
self.view!.presentScene(mainMenuScene)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
GameViewController:
GameViewController:
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let skView = self.view as? SKView
if skView?.scene == nil {
skView?.showsFPS = true
skView?.showsNodeCount = true
skView?.showsPhysics = true
skView?.ignoresSiblingOrder = false
//starting the game with the Poster Scene
let posterScene = PosterScene()
posterScene.scaleMode = .resizeFill
skView?.presentScene(posterScene)
}
}
override var shouldAutorotate : Bool {
return true
}
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return UIInterfaceOrientationMask.allButUpsideDown
} else {
return UIInterfaceOrientationMask.all
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override var prefersStatusBarHidden : Bool {
return true
}
required init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)!
}
}
2 个解决方案
#1
1
You have asked me to take a look at this question.
你让我看看这个问题。
You game does not feel consistent across devices because in your GameViewController you set scene scale mode to .resizeFill. In most cases the default .aspectFill setting is the best option.
您的游戏在各种设备上都不一致,因为在您的GameViewController中,您将场景比例模式设置为.resizeFill。在大多数情况下,默认的.aspectFill设置是最佳选择。
In regards to the error message you need to give the scene a size in the init method when you are not using the xCode level editor e.g
关于错误消息,当您不使用xCode级别编辑器时,您需要在init方法中为场景指定大小,例如
let scene = GameScene(size: CGSize(width: ..., height: ...))
There is basically 2 options for size
大小基本上有两种选择
1) Set the scene size to iPad, which is what I personally do. This is also what Apple uses in DemoBots and what was the default setting in xCode 7. So scene size is either 1024x768 (landscape) or 768x1024 (portrait).
1)将场景大小设置为iPad,这是我个人所做的。这也是Apple在DemoBots中使用的,以及xCode 7中的默认设置。因此场景大小为1024x768(横向)或768x1024(纵向)。
I design my game area with the iPhone in mind, and simply show some more background, usually ground and sky, on iPads. This is what a lot of popular games I like to play do e.g. Modern Combat 5, Limbo, Altos Adventure, Leos Fortune, The Line Zen, Tower Dash.
我在设计我的游戏区域时考虑到iPhone,并在iPad上显示更多背景,通常是地面和天空。这就是我喜欢玩的很多热门游戏,例如现代战斗5,凌波,Altos冒险,青少狮财富,线禅,塔短跑。
2) Set the scene size to iPhones and show more background on iPhones and less on iPads e.g. Lumino City. So scene size would be what xCode 8 uses, either 1334x750 (landscape) or 750x1334 (portrait).
2)将场景大小设置为iPhone并在iPhone上显示更多背景,在iPad上显示更少背景,例如卢米诺市。因此场景大小将是xCode 8使用的,1334x750(横向)或750x1334(纵向)。
This way your game should feel consistent across all devices. The only thing you might have to do is tweak some UI, like button positioning, between iPad and iPhone.
这样,您的游戏应该在所有设备上保持一致。您可能要做的唯一事情是在iPad和iPhone之间调整一些UI,如按钮定位。
Hope this helps
希望这可以帮助
#2
0
Here is how your code layout should look. As you can see, I designed the scene to be the size of iPhone 6. This means on all other phones, the image will scale (but you will still see everything), but will look perfect on the 6. On the iPad, the image will get chopped off on the top and the bottom by 12.5% each, due to the iPad being a 3:4 and not 9:16
以下是代码布局的外观。正如你所看到的,我将场景设计为iPhone 6的大小。这意味着在所有其他手机上,图像将缩放(但你仍然可以看到所有内容),但在6上看起来会很完美。在iPad上,由于iPad是3:4而不是9:16,因此图像将在顶部和底部各自被砍掉12.5%
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let skView = self.view as? SKView
if skView?.scene == nil {
skView?.showsFPS = true
skView?.showsNodeCount = true
skView?.showsPhysics = true
skView?.ignoresSiblingOrder = false
//starting the game with the Poster Scene
let posterScene = PosterScene(size:CGSize(width:375,height:667))
posterScene.scaleMode = .aspectFill
skView?.presentScene(posterScene)
}
}
override var shouldAutorotate : Bool {
return true
}
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return UIInterfaceOrientationMask.allButUpsideDown
} else {
return UIInterfaceOrientationMask.all
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override var prefersStatusBarHidden : Bool {
return true
}
required init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)!
}
}
and
和
class PosterScene: SKScene {
override init(size:CGSize){
super.init(size:size)
self.anchorPoint = CGPoint(x:0.5,y:0.5) //let's put 0,0 at the center of the screen
let posterImage = SKSpriteNode(imageNamed: "poster")
posterImage.position = CGPoint.zero
self.addChild(posterImage)
let sequence = SKAction.sequence([ SKAction.wait(forDuration: 3.0), SKAction.run({ self.changeToMainMenuScene() }) ])
self.run(sequence)
}
func changeToMainMenuScene () {
let mainMenuScene = MainMenuScene()
self.view!.presentScene(mainMenuScene)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
#1
1
You have asked me to take a look at this question.
你让我看看这个问题。
You game does not feel consistent across devices because in your GameViewController you set scene scale mode to .resizeFill. In most cases the default .aspectFill setting is the best option.
您的游戏在各种设备上都不一致,因为在您的GameViewController中,您将场景比例模式设置为.resizeFill。在大多数情况下,默认的.aspectFill设置是最佳选择。
In regards to the error message you need to give the scene a size in the init method when you are not using the xCode level editor e.g
关于错误消息,当您不使用xCode级别编辑器时,您需要在init方法中为场景指定大小,例如
let scene = GameScene(size: CGSize(width: ..., height: ...))
There is basically 2 options for size
大小基本上有两种选择
1) Set the scene size to iPad, which is what I personally do. This is also what Apple uses in DemoBots and what was the default setting in xCode 7. So scene size is either 1024x768 (landscape) or 768x1024 (portrait).
1)将场景大小设置为iPad,这是我个人所做的。这也是Apple在DemoBots中使用的,以及xCode 7中的默认设置。因此场景大小为1024x768(横向)或768x1024(纵向)。
I design my game area with the iPhone in mind, and simply show some more background, usually ground and sky, on iPads. This is what a lot of popular games I like to play do e.g. Modern Combat 5, Limbo, Altos Adventure, Leos Fortune, The Line Zen, Tower Dash.
我在设计我的游戏区域时考虑到iPhone,并在iPad上显示更多背景,通常是地面和天空。这就是我喜欢玩的很多热门游戏,例如现代战斗5,凌波,Altos冒险,青少狮财富,线禅,塔短跑。
2) Set the scene size to iPhones and show more background on iPhones and less on iPads e.g. Lumino City. So scene size would be what xCode 8 uses, either 1334x750 (landscape) or 750x1334 (portrait).
2)将场景大小设置为iPhone并在iPhone上显示更多背景,在iPad上显示更少背景,例如卢米诺市。因此场景大小将是xCode 8使用的,1334x750(横向)或750x1334(纵向)。
This way your game should feel consistent across all devices. The only thing you might have to do is tweak some UI, like button positioning, between iPad and iPhone.
这样,您的游戏应该在所有设备上保持一致。您可能要做的唯一事情是在iPad和iPhone之间调整一些UI,如按钮定位。
Hope this helps
希望这可以帮助
#2
0
Here is how your code layout should look. As you can see, I designed the scene to be the size of iPhone 6. This means on all other phones, the image will scale (but you will still see everything), but will look perfect on the 6. On the iPad, the image will get chopped off on the top and the bottom by 12.5% each, due to the iPad being a 3:4 and not 9:16
以下是代码布局的外观。正如你所看到的,我将场景设计为iPhone 6的大小。这意味着在所有其他手机上,图像将缩放(但你仍然可以看到所有内容),但在6上看起来会很完美。在iPad上,由于iPad是3:4而不是9:16,因此图像将在顶部和底部各自被砍掉12.5%
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let skView = self.view as? SKView
if skView?.scene == nil {
skView?.showsFPS = true
skView?.showsNodeCount = true
skView?.showsPhysics = true
skView?.ignoresSiblingOrder = false
//starting the game with the Poster Scene
let posterScene = PosterScene(size:CGSize(width:375,height:667))
posterScene.scaleMode = .aspectFill
skView?.presentScene(posterScene)
}
}
override var shouldAutorotate : Bool {
return true
}
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return UIInterfaceOrientationMask.allButUpsideDown
} else {
return UIInterfaceOrientationMask.all
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override var prefersStatusBarHidden : Bool {
return true
}
required init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)!
}
}
and
和
class PosterScene: SKScene {
override init(size:CGSize){
super.init(size:size)
self.anchorPoint = CGPoint(x:0.5,y:0.5) //let's put 0,0 at the center of the screen
let posterImage = SKSpriteNode(imageNamed: "poster")
posterImage.position = CGPoint.zero
self.addChild(posterImage)
let sequence = SKAction.sequence([ SKAction.wait(forDuration: 3.0), SKAction.run({ self.changeToMainMenuScene() }) ])
self.run(sequence)
}
func changeToMainMenuScene () {
let mainMenuScene = MainMenuScene()
self.view!.presentScene(mainMenuScene)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}