Objective-C的。你的第一个SKScene是如何初始化的?

时间:2015-08-20 14:27:22

标签: ios objective-c sprite-kit

此方法设置初始场景,并在应用程序打开后立即调用:

 #import "GameScene.h"
    #import "WarScene.h"
    #import "Math.h"

    @implementation GameScene
    {
        SKNode *map;
        float oldY;
        float oldX;
        BOOL buttonClicked;
        int thisButton;
        float oldMapPosition;
        float midScreenX;
    float midScreenY;
    int separation;
    float sendY;
    BOOL interacting;
    CGVector speed;
    float oldPosition;
    float newPosition;
    BOOL isReleased;
    int iterations;
    float diff;
    BOOL comeToStop;
    BOOL actualStop;
    BOOL clicked;
}

int numberOfLevels = 20;

-(void)didMoveToView:(SKView *)view {

    /* Setup your scene here */
    map = [SKNode node];

    separation = [UIScreen mainScreen].bounds.size.height;

    if (UIDeviceOrientationIsLandscape((UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation]))
    {
        //landscape mode
        midScreenX = ([[UIScreen mainScreen]bounds].size.width>[[UIScreen mainScreen]bounds].size.height?[[UIScreen mainScreen]bounds].size.width:[[UIScreen mainScreen]bounds].size.height)/2;
        midScreenY = ([[UIScreen mainScreen]bounds].size.width<[[UIScreen mainScreen]bounds].size.height?[[UIScreen mainScreen]bounds].size.width:[[UIScreen mainScreen]bounds].size.height)/2;
    }
    else
    {
        //portrait mode
        midScreenX = [[UIScreen mainScreen]bounds].size.width/2;
        midScreenY = [[UIScreen mainScreen]bounds].size.height/2;
    }

    NSLog(@"Initial Width: %f Height: %f", midScreenX*2, midScreenY*2);

    map.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: CGSizeMake([UIScreen mainScreen].bounds.size.width, separation*(numberOfLevels+1))];
    map.physicsBody.affectedByGravity = NO;
    map.physicsBody.allowsRotation = NO;

    clicked = NO;

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
    tap.numberOfTapsRequired = 1;

    [self.view addGestureRecognizer:tap];

    self.backgroundColor = [SKColor blackColor];

    for (int i = 0; i<numberOfLevels; i += 1) {
        SKLabelNode *title;
        {
            title = [SKLabelNode labelNodeWithFontNamed:@"Cochin"];
            title.text = [NSString stringWithFormat: @"Level %d", 1+i];
            title.fontSize = 60;
            title.position = CGPointMake(CGRectGetMidX(self.frame),
                                         ((i+1)*separation));
            title.fontColor = [UIColor whiteColor];
            title.name = [NSString stringWithFormat: @"Level %d", 1+i];

            [map addChild:title];
        }
    }
    [self addChild:map];

     }

然而,当我从另一个类中调用它时,这与我的预期完全相同:

-(void)continueMethod:(UIButton*)button{

    NSLog(@"InitwithSize to GameScene Width: %f Height: %f", midScreenX*2, midScreenY*2);
    GameScene *map = [[GameScene alloc] initWithSize: CGSizeMake(midScreenX*2 ,midScreenY*2)];
    SKTransition *reveal = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1.0];
    SKView * skView = (SKView *)self.view;
    UIView *viewToRemove = [self.view viewWithTag:3];
    [viewToRemove removeFromSuperview];
    [skView presentScene:map transition:reveal];
}

应该设置的场景并不像我预期的那样出现,或者实际上它是如何用于查看它最后一次初始化的场景。分离变量看起来更大,文本看起来更大,一切都更宽。我已经确认我初始化的UIScreen在整个过程中完全相同。

这让我质疑SKSprite应用程序的初始场景是如何形成的,以及它是否与“initWithSize:”不同,但是,查看游戏模板中的所有代码我都看不到我的第一个场景被召唤。我能找到的最接近initWithSize的是:GameViewController-

中的以下内容
GameScene *scene = [GameScene unarchiveFromFile:@"GameScene"];
    scene.scaleMode = SKSceneScaleModeAspectFill;

首先,这是初始化我的初始场景的原因吗?其次它与initWithSize有什么不同:?最后,如果对前两个问题的回答是肯定的,是否应该使用它来代替initWithsize:?

1 个答案:

答案 0 :(得分:2)

是的,这是初始场景的初始化!您在View Controller中看到的是初始化略有不同。首先使用sks文件,并在视图控制器取消归档时调用initWithCoder:。但是,如果您指定所有相同的维度和属性,则与initWithSize非常不同。

话虽这么说,初始化中的场景scaleMode和视图控制器的scaleMode是不同的。如您所见,视图控制器指定:

scene.scaleMode = SKSceneScaleModeAspectFill;

根据Apple的AspectFill缩放模式:

  

计算每个维度的缩放因子,并选择两者中较小的一个。场景的每个轴都按相同的缩放因子缩放。这可以保证整个场景可见,但可能需要在视图中使用信箱。

另一方面,初始化场景时,保留默认的scaleMode,恰好是SKSceneScaleModeFill。这会将场景的每个轴映射到视图,从而获得扭曲的场景。你需要做的只是陈述:

map.scaleMode = SKSceneScaleModeAspectFill;

这将使用与原始场景中相同的缩放模式,您现在看到的失真将消失。

希望这有帮助,如果您有疑问,请与我联系。