我正在开发一个小应用程序,在那里我将一个tilemap(JSTilemap)加载到精灵工具包中。
这一切都很好,除了瓷砖地图在纵向看起来正常和精细,但当我翻转到风景时它似乎爆炸了。我没有添加任何代码只是导入JSTilemap头和这段代码initwithsize。
self.map = [JSTileMap mapNamed:@"tilemap.tmx"];
[self addChild:self.map];
我还下载了一个带有平铺贴图的简单项目,当我旋转时,尺寸保持不变,只有当我尝试模仿代码时,我的贴图仍然会在旋转时爆炸。
是否有一些设置来限制我错过了?
答案 0 :(得分: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;
答案 1 :(得分:0)
我假设"爆炸"你的意思是拉伸和/或缩放不恰当?尝试将SKScene上的scaleMode更改为SKSceneScaleModeAspectFill
。
答案 2 :(得分:0)
您知道,在运行您的应用程序时,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高& #34; (我使用的是iPhone 5S)。这意味着即使我们在“目标/部署信息”部分中选择了“横向”模式,场景也将以“纵向”模式呈现。我们希望宽度超过高度(568宽和320高)!但为什么所有这一切都在发生?问题在于内部。 iOS应用程序生命周期从纵向中的每个应用程序开始,并且在加载过程中仅切换到横向。因此故事板加载,它加载了初始的视图控制器,它仍然认为它处于纵向方向。此视图控制器将自动加载View对象(对于SKView的Sprite Kit)。我们仍处于纵向导向。加载了View对象,这将导致在View Controller中回调viewDidLoad。我们仍处于纵向导向。但是在viewDidLoad方法中,我们创建了我们的场景(SKScene)传递当前高度&宽度。仍然纵向方向。所有这一切都只花了不到一秒钟,但只有在此之后,应用程序才意识到它应该在Landscape中,并且View Controller切换到Landscape并使用View获取View。根据您的设置,场景将要做的是尝试通过向上扩展以填充可用空间来做出反应,并且我们将放弃内容,因为它内部仍然处于纵向方向...只是扩大规模。我们如何解决这个问题?我们的场景正在viewDidLoad中创建,但是当发生这种情况时,应用程序还不知道我们应该处于横向模式。所以我们需要创建我们的场景,但是我们只需要稍后在这个过程中执行它 - 在iOS应用程序生命周期实现我们处于横向模式之后。有几种不同的方法可以做到这一点。我喜欢的是viewWillLayoutSubviews。它是另一种内置的View Controller方法。它在viewDidLoad之后和转换到Landscape模式后自动调用。因此,如果我们将场景创建推迟几毫秒,直到我们在viewWillLayoutSubviews方法中,那么我们可以使用正确的方向创建它。所以复制&粘贴viewDidLoad中的所有代码(除了调用[super 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高"。乌拉!