我正在使用SpriteKit和Swift编写iOS游戏。我对SpriteKit还不是很熟悉。
我希望支持iPhone和iPad的两种方向,并发现了这个链接:multiple orientations in SpriteKit 在模拟器和设备上,它的工作方式如预期一样,但在设备上,我注意到一些SKSpriteNodes在设备旋转动画之前略微失真。
这在SKLabelNodes中非常明显,其中文本会根据方向变化而略微扭曲或拉伸。
我知道为什么会出现这种失真,但确认并解决问题将是非常棒的。
在设备上,代码与链接中描述的相同,但我已经更新为Swift 3。
由于它可以处理设备方向的更改,因此在设备旋转时,我看到didChangeSize...被多次调用,因此我更喜欢使用viewWillTransitionToSize...。谢谢。Leon
我希望支持iPhone和iPad的两种方向,并发现了这个链接:multiple orientations in SpriteKit 在模拟器和设备上,它的工作方式如预期一样,但在设备上,我注意到一些SKSpriteNodes在设备旋转动画之前略微失真。
这在SKLabelNodes中非常明显,其中文本会根据方向变化而略微扭曲或拉伸。
我知道为什么会出现这种失真,但确认并解决问题将是非常棒的。
在设备上,代码与链接中描述的相同,但我已经更新为Swift 3。
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let scene = GameScene(size:self.view.bounds.size)
scene.scaleMode = .resizeFill
(self.view as! SKView).presentScene(scene)
}
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return .allButUpsideDown
} else {
return .all
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override var prefersStatusBarHidden: Bool {
return true
}
}
class GameScene: SKScene {
var currentNode: CustomNode!
override func didMove(to view: SKView) {
self.backgroundColor = SKColor.white
transitionToScene(sceneType: .Menu)
}
override func didChangeSize(_ oldSize: CGSize) {
currentNode?.layout()
}
func transitionToScene(sceneType: SceneTransition) {
switch sceneType {
case .Menu:
currentNode?.dismissWithAnimation(animation: .Right)
currentNode = MenuNode(gameScene: self)
currentNode.presentWithAnimation(animation: .Right)
case .Scores:
currentNode?.dismissWithAnimation(animation: .Left)
currentNode = ScoresNode(gameScene: self)
currentNode.presentWithAnimation(animation: .Left)
default: fatalError("Unknown scene transition.")
}
}
}
class CustomNode: SKNode {
weak var gameScene: GameScene!
init(gameScene: GameScene) {
self.gameScene = gameScene
super.init()
}
func layout() {}
func presentWithAnimation(animation:Animation) {
layout()
let invert: CGFloat = animation == .Left ? 1 : -1
self.position = CGPoint(x: invert*gameScene.size.width, y: 0)
gameScene.addChild(self)
let action = SKAction.move(to: CGPoint(x: 0, y: 0), duration: 0.3)
action.timingMode = SKActionTimingMode.easeInEaseOut
self.run(action)
}
func dismissWithAnimation(animation:Animation) {
let invert: CGFloat = animation == .Left ? 1 : -1
self.position = CGPoint(x: 0, y: 0)
let action = SKAction.move(to: CGPoint(x: invert*(-gameScene.size.width), y: 0), duration: 0.3)
action.timingMode = SKActionTimingMode.easeInEaseOut
self.run(action, completion: {self.removeFromParent()})
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MenuNode: CustomNode {
var label: SKLabelNode
var container: SKSpriteNode
override func layout() {
container.position = CGPoint(x: gameScene.size.width/2.0, y: gameScene.size.height/2.0)
}
override init(gameScene: GameScene) {
label = SKLabelNode(text: "Menu Scene")
label.horizontalAlignmentMode = .center
label.verticalAlignmentMode = .center
container = SKSpriteNode(color: UIColor.black, size: CGSize(width: 200, height: 200))
container.addChild(label)
super.init(gameScene: gameScene)
self.addChild(container)
self.isUserInteractionEnabled = true
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.gameScene.transitionToScene(sceneType: .Scores)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class ScoresNode: CustomNode {
var label: SKLabelNode
var container: SKSpriteNode
override func layout() {
container.position = CGPoint(x: gameScene.size.width/2.0, y: gameScene.size.height/2.0)
}
override init(gameScene: GameScene) {
label = SKLabelNode(text: "Scores Scene")
label.horizontalAlignmentMode = .center
label.verticalAlignmentMode = .center
container = SKSpriteNode(color: UIColor.black, size: CGSize(width: 200, height: 200))
container.addChild(label)
super.init(gameScene: gameScene)
self.addChild(container)
self.isUserInteractionEnabled = true
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.gameScene.transitionToScene(sceneType: .Menu)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
enum SceneTransition{
case Menu, Scores
}
enum Animation {
case Left, Right, None
}
来源: Epic Byte
我也尝试使用了以下方法:
viewWillTransitionToSize...
由于它可以处理设备方向的更改,因此在设备旋转时,我看到didChangeSize...被多次调用,因此我更喜欢使用viewWillTransitionToSize...。谢谢。Leon