1

我正在开发一个小应用程序,我在其中将 tilemap ( JSTilemap ) 加载到 sprite kit 中。

这一切都很好,除了平铺贴图在纵向上看起来很正常而且很好,但是当我翻转到横向时,它似乎爆炸了。我没有添加任何代码,只是导入了 JSTilemap 标头和此代码 initwithsize。

self.map = [JSTileMap mapNamed:@"tilemap.tmx"];
[self addChild:self.map];

我还下载了一个带有瓷砖地图的简单项目,当我旋转时,尺寸保持不变,只是如果我尝试模仿代码,我的瓷砖地图在旋转时似乎仍然会爆炸。

是否有一些设置来限制我缺少的这一点?

4

3 回答 3

1

你应该使用-(id)initWithSize:(CGSize)size而不是-(void)didMoveToView:(SKView *)view

 -(id)initWithSize:(CGSize)size {
        if (self = [super initWithSize:size]) {
     JSTileMap* tiledMap = [JSTileMap mapNamed:@"level1.tmx"];
            if (tiledMap)
                [self addChild:tiledMap];
            self.userInteractionEnabled = YES;
        }
        return self;
    }

同样在 GameViewController 中(如果您使用的是默认模板类),您应该更改场景初始化sceneWithSize

    /*
    // Create and configure the scene.
    GameScene *scene = [GameScene unarchiveFromFile:@"GameScene"];
    scene.scaleMode = SKSceneScaleModeAspectFill;
    */

   // Create and configure the scene.
    SKScene * scene = [GameScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;
于 2015-03-27T09:18:50.870 回答
0

我认为“炸毁”是指不恰当地拉伸和/或缩放?尝试将 SKScene 上的 scaleMode 更改为SKSceneScaleModeAspectFill.

于 2014-04-06T20:38:18.637 回答
0

如您所知,在运行您的应用程序时,iPhone 始终以纵向模式启动。这与 Sprite Kit 无关。这是关于一般的 iOS 生命周期和视图问题。歪曲内容或丢失内容完全是因此而发生的。制作游戏时,通常使用纵向或横向。将它们一起使用是非常罕见的。要了解为什么您的内容被“拉伸”,请将以下代码写入您的 SKScene 的 initWithSize 方法:

NSLog(@"In initWithSize, at %0.f wide and %0.f high", size.width, size.height);

启动游戏并查看 NSLog 消息。即使我们认为我们是在横向模式下开始的(也就是说,如果您倾斜手机并等待游戏加载或稍后执行),NSLog 消息显示“In initWithSize, at 320 wide and 568 high”(我' m 使用 iPhone 5S)。这意味着即使我们在 Targets/Deployment Info 部分中选择了横向模式,场景也会以纵向模式渲染。我们希望宽度大于高度(568 宽和 320 高)!但为什么会发生这一切?问题在内部。iOS 应用程序生命周期从纵向开始每个应用程序,并且仅在加载过程中切换到横向。所以情节提要加载,它加载了初始视图控制器,它仍然认为它是纵向的。此视图控制器将自动加载视图对象(对于 Sprite Kit 即 SKView)。我们仍处于纵向。View 对象已加载,这将导致 viewDidLoad 在 View Controller 中被回调。我们仍处于纵向。但是在 viewDidLoad 方法中,我们创建场景(SKScene)并传入当前高度和宽度。仍然是纵向。所有这一切都只需要几分之一秒,但只有在此之后,应用程序才意识到它应该在 Landscape 中,并且 View Controller 切换到 Landscape 并带上 View。根据您的设置,场景将尝试通过扩大以填充可用空间来对此做出反应,并且我们将松散内容,因为在内部它' s 仍然是纵向的……只是放大了。我们如何解决这个问题?我们的场景是在 viewDidLoad 中创建的,但是当这种情况发生时,应用程序还不知道我们应该处于横向模式。所以我们需要创建我们的场景,但我们只需要在这个过程中稍晚一点——在 iOS 应用程序生命周期意识到我们处于横向模式之后。有几种不同的方法可以做到这一点。我喜欢的是viewWillLayoutSubviews。它是另一种内置的 View Controller 方法。在 viewDidLoad 和切换到横向模式之后会自动调用它。因此,如果我们将场景创建推迟几毫秒,直到我们进入 viewWillLayoutSubviews 方法,那么我们可以以正确的方向创建它。所以复制 & 粘贴 viewDidLoad 中的所有代码(除了对 [super viewDidLoad]; 的调用)并将其放入 viewWillLayoutSubviews。现在只有1个问题。viewWillLayoutSubviews 可能会在生命周期中被调用几次或至少一次以上。没关系。我们只是不想多次创建场景。因此,一旦我们抓住了视图,我们将创建一个 if 语句来检查该视图中是否有 Scene 对象。如果没有,我们将创建它并返回它。否则,我们不需要这样做。以下是所有这些代码在创建场景的视图控制器中的外观。没关系。我们只是不想多次创建场景。因此,一旦我们抓住了视图,我们将创建一个 if 语句来检查该视图中是否有 Scene 对象。如果没有,我们将创建它并返回它。否则,我们不需要这样做。以下是所有这些代码在创建场景的视图控制器中的外观。没关系。我们只是不想多次创建场景。因此,一旦我们抓住了视图,我们将创建一个 if 语句来检查该视图中是否有 Scene 对象。如果没有,我们将创建它并返回它。否则,我们不需要这样做。以下是所有这些代码在创建场景的视图控制器中的外观。

//Method can be deleted (It's called behind the scenes regardless).
-(void)viewDidLoad
{
    [super viewDidLoad];
}


//Called AFTER viewDidLoad & after the view shifts to landscape (which is what we want).
-(void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews]; //Don't really need to call this method (but a good habit just in case Apple ever changes that).

    //Configure the view.
    _skView = (SKView *)self.view;
    _skView.showsFPS = YES;
    _skView.showsNodeCount = YES;
    //_skView.showsPhysics = YES;

    //viewWillLayoutSubviews might get called several times & that's ok. But, we don't want several GameScenes to be created. Therefore...
    //Is there a scene object in that view? If there ISN'T, we'll create it.
    if (!_skView.scene)
    {
        //Create & configure the scene.
        SKScene *sceneGame = [MainMenuScene sceneWithSize:_skView.bounds.size];
        sceneGame.scaleMode = SKSceneScaleModeAspectFill;

        //Present the scene.
        [_skView presentScene:sceneGame transition:[SKTransition fadeWithDuration:0.5]];
    }
    //If there is, we don't need to do that.
}

现在继续运行它。现在一切都应该看起来不错。NSLog 消息现在应该说“在 initWithSize,宽 568 高 320”。欢呼!

于 2015-06-12T09:15:58.917 回答