我正在开发一个小应用程序,在这个应用程序中,我将tilemap ( JSTilemap )加载到sprite工具包中。
这一切都很好,除了瓷砖地图看起来正常和良好的肖像,但当我翻转到风景,它似乎爆炸。我没有添加任何代码,只是导入了JSTilemap头,这段代码初始化了大小。
self.map = [JSTileMap mapNamed:@"tilemap.tmx"];
[self addChild:self.map];
我还下载了一个带有磁贴地图的简单项目,当我旋转时,大小保持不变,只是如果我试图模仿代码,我的磁贴地图似乎仍然会在我旋转它时爆炸。
是否有一些设置可以限制我遗漏的内容?
发布于 2015-03-27 09:18:51
您应该使用-(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;
发布于 2014-04-06 20:38:19
发布于 2015-06-12 09:15:59
只是想让你知道,当运行你的应用程序时,iPhone总是以纵向模式开始。这与Sprite Kit无关。它是关于一般的iOS生命周期和视图问题。扭曲内容或完全丢失内容就是因为这个原因。在制作游戏时,通常使用肖像或风景。同时使用它们的情况非常少见。要理解为什么您的内容被“拉伸”,请将以下代码写入到SKScene的initWithSize方法中:
NSLog(@"In initWithSize, at %0.f wide and %0.f high", size.width, size.height);
启动游戏并查看NSLog消息。即使我们认为我们是在横向模式下开始的(也就是说,如果你倾斜你的手机,等待游戏加载或稍晚一点),NSLog消息显示“在initWithSize中,320宽568高”(我使用的是iPhone 5S)。这意味着即使我们在Targets/Deployment Info部分选择了Landscape模式,场景也是以纵向模式渲染的。我们希望宽度大于高度(568宽,320高)!但是为什么会发生这一切呢?问题出在内部。iOS应用程序生命周期开始于纵向中的每个应用程序,只有在加载过程中才切换到横向。所以故事板加载,它加载初始的视图控制器,它仍然认为它是纵向的。该视图控制器将自动加载视图对象(对于Sprite Kit,即SKView)。我们还在做纵向定向。视图对象已加载,这将导致在视图控制器中回调viewDidLoad。我们还在做纵向定向。但在viewDidLoad方法中,这是我们创建场景(SKScene)的地方,传入当前的高度和宽度。仍然是肖像定向。所有这一切只花了不到一秒钟的时间,但只有在这之后,应用程序才意识到它应该处于Landscape中,并且View Controller切换到Landscape the the View with it。根据你的设置,场景要做的是试图通过放大来填充可用的空间来对此做出反应,我们将会松散内容,因为在内部它仍然是放大的肖像orientation...just。我们该如何解决这个问题呢?我们的场景是在viewDidLoad中创建的,但是当发生这种情况时,应用程序还不知道我们应该处于横向模式。所以我们需要创建我们的场景,但是我们只需要在这个过程的后面一点-在iOS应用程序生命周期意识到我们处于横向模式之后。有几种不同的方法可以做到这一点。我喜欢的是viewWillLayoutSubviews。它是另一个内置的View Controller方法。它会在viewDidLoad之后和转换到横向模式后自动调用。因此,如果我们将场景创建延迟几毫秒,直到我们处于viewWillLayoutSubviews方法中,那么我们就可以用正确的方向创建它。因此,复制并粘贴viewDidLoad中的所有代码(除了对超级viewDidLoad;的调用),并将其放入viewWillLayoutSubviews。现在只有一个问题了。viewWillLayoutSubviews可能会被调用几次,或者在生命周期中至少被调用一次以上。没关系。我们只是不想多次创建场景。因此,一旦我们抓取了视图,我们将创建一个if语句来检查该视图中是否有Scene对象。如果没有,我们将创建它并返回它。否则,我们不需要这样做。下面是所有这些代码在创建我们的场景的View Controller中的样子。
//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”。万岁!
https://stackoverflow.com/questions/22795821
复制