SpriteKit支持多种设备方向
我有一个SpriteKit游戏,我想支持所有方向。 现在当我改变方向时,节点不会保持其位置。 我使用SKSceneScaleModeResizeFill
进行缩放,因为它将保持正确的精灵大小。
当我开始游戏时,游戏玩家就像这样定位在中间屏幕:
然后当我旋转设备时,位置变为如下:
这是我的视图控制器代码:
- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; // Configure the view. SKView * skView = (SKView *)self.view; if (!skView.scene) { // Create and configure the scene. SKScene * scene = [MyScene sceneWithSize:skView.bounds.size]; scene.scaleMode = SKSceneScaleModeResizeFill; // Present the scene. [skView presentScene:scene]; } }
我的场景代码:
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0]; //Add spaceship in the center of the view SKSpriteNode *spaceship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship.png"]; spaceship.position = CGPointMake(size.width/2, size.height/2); [spaceship setScale:.3]; [self addChild:spaceship]; } return self; }
在场景resize后,你的精灵会保持其位置 – 你可以从截图中看到它与场景的左下角保持相同的水平和垂直距离。 问题是,在场景resize后,该绝对偏移表示场景中的不同相对位置。
Sprite Kit可以自动调整场景大小,但是场景resize后节点的相对位置不是它可以为你做的事情。 对于如何以不同的大小重新排列场景的内容没有“正确的答案”,因为场景内容的排列是您的应用定义的内容。
在您的SKScene
子类中实现didChangeSize:
并在SKScene
放置您想要的任何逻辑来移动节点。
例如,您可以使用它来使节点将其位置保持为场景大小的相对比例,使用如下所示:
- (void)didChangeSize:(CGSize)oldSize { for (SKNode *node in self.children) { CGPoint newPosition; newPosition.x = node.position.x / oldSize.width * self.frame.size.width; newPosition.y = node.position.y / oldSize.height * self.frame.size.height; node.position = newPosition; } }
根据您场景中的内容以及您的安排,您可能不希望这样。 例如,如果游戏场景的每个角落都有HUD元素,则可能需要它们与角落的固定偏移量,而不是场景大小的一部分。
我添加了类似的问题并发现了这个问题。 我使用viewWillTransitionToSize:withTransitionCoordinator:
解决了不同的问题,如@GOR所述。
我在视图控制器中添加了以下代码(管理SKView及其SKScene)
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { //skView is my SKView object, with scaleMode SKSceneScaleModeResizeFill skView.frame = CGRectMake(0, 0, size.width, size.height); //currentScene is my SKScene object currentScene.size = skView.frame.size; //Then, as all the objects in my scene are children of a unique SKNode* background, I only relocate it currentScene.background.position = CGPointMake(CGRectGetMidX(currentScene.frame), CGRectGetMidY(currentScene.frame)); }
它就像一个魅力!
对于Swift 3,
override func didChangeSize(_ oldSize: CGSize) { for node in self.children{ let newPosition = CGPoint(x:node.position.x / oldSize.width * self.frame.size.width,y:node.position.y / oldSize.height * self.frame.size.height) node.position = newPosition } }
因此,我们可以使用常量并在一行中初始化它。 然后在node.position = newPosition
我们可以设置新位置。
此外,我们还可以利用增强的for循环,从而实现更优雅的解决方案。
- 如何使用watchkit应用程序从命令行生成.ipa文件
- MKAnnotation Swift
- 使用Swift 4.0编译的模块不能在Swift 4.0.1中导入
- 将NSData转换为SecKeyRef
- 一些dynamic高度的tableview单元格,其他高度固定的单元格
- dynamic调整UICollectionViewCell的大小
- 在UICollectionView上dynamic设置布局会导致无法解释的contentOffset更改
- 如何为Mac OS X和Windows 10设置Epson Printer L355 Wi-Fi连接?
- QuincyKit / PLCrashReporter:在崩溃前提供描述