Перемещение камеры в SpriteKit

//UPDATE Добавлен обновленный код, который работает так, как я ожидал. См. Метод didSimulatePhysics в обновленном коде ниже. В моем случае, я забочусь только о перемещении символа влево или вправо по оси x, где 0 по оси x является абсолютной левой и правой по оси x, является настраиваемым значением. Приключенческая игра Apple действительно очень помогла.

//ОРИГИНАЛЬНАЯ ПОЧТА НИЖЕ

Я работаю с Apple SpriteKit, и я изо всех сил пытаюсь реализовать камеру, как я бы хотел, чтобы она себя вела. То, что я сделал в коде, - это загрузить символ спрайта, две кнопки и красную рамку, которая находится справа от представления в начале. То, что я хотел бы сделать, - это перемещать персонажа с помощью кнопок, и как только игрок достигнет середины или конца экрана, камера снова настроится, чтобы открыть то, что не видно в представлении. Поэтому перемещение вправо должно в конечном итоге отображать красную рамку, которая находится вне поля зрения, как только игрок попадает туда. Однако, используя код, который я использую ниже, я не могу заставить камеру следовать и полностью регулировать координаты главного героя. Я посмотрел на продвинутый документ обработки документации Apple, а также на несколько других записей, но, похоже, не может быть прав. Если кто-то может предложить некоторые советы, это будет оценено.

enter image description here

#define cameraEdge 150

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        /* Setup your scene here */
        //320 568


        self.backgroundColor = [SKColor whiteColor];

        myWorld = [[SKNode alloc] init];
        [self addChild:myWorld];

        mainCharacter = [SKSpriteNode spriteNodeWithImageNamed:@"0"];
        mainCharacter.physicsBody.dynamic = YES;
        mainCharacter.name = @"player";

        mainCharacter.position = CGPointMake(20, 20);

        CGRect totalScreenSize = CGRectMake(0, 0, 800, 320);

        SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(60, 60)];

          SKSpriteNode *boxTwo = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(60, 60)];
           SKSpriteNode *boxThree = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(60, 60)];
        boxThree.position = CGPointMake(40, 50);

        [myWorld addChild:boxThree];

        boxTwo.position = CGPointMake(1100, 50);

        box.position = CGPointMake(650, 50);

        [myWorld addChild:box];
        [myWorld addChild:boxTwo];


       self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:totalScreenSize];

        self.physicsWorld.gravity = CGVectorMake(0, -5);
        mainCharacter.name = @"mainCharacter";


        mainCharacter.physicsBody.linearDamping = 0;
        mainCharacter.physicsBody.friction = 0;
        mainCharacter.physicsBody.restitution = 0;
        mainCharacter.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:mainCharacter.size];

       [myWorld addChild:mainCharacter];

        [self addChild:[self buildLeftButton]];
        [self addChild:[self buildRightButton]];

    }

    return self;
}

- (void)didSimulatePhysics
{
    SKSpriteNode *hero = mainCharacter;

    if(hero)
    {
        CGPoint heroPosition = hero.position;
        CGPoint worldPosition = myWorld.position;

        NSLog(@"%f", heroPosition.x);

        CGFloat xCoordinate = worldPosition.x + heroPosition.x;

        if(xCoordinate < cameraEdge && heroPosition.x > 0)
        {
            worldPosition.x = worldPosition.x - xCoordinate + cameraEdge;
            self.worldMovedForUpdate = YES;
        }

        else if(xCoordinate > (self.frame.size.width - cameraEdge) && heroPosition.x < 2000)
        {
            worldPosition.x = worldPosition.x + (self.frame.size.width - xCoordinate) - cameraEdge;
            self.worldMovedForUpdate = YES;
        }

        myWorld.position = worldPosition;
    }
}

-(SKSpriteNode *)buildLeftButton
{
    SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:@"left"];
    leftButton.position = CGPointMake(20, 20);
    leftButton.name = @"leftButton";
    leftButton.zPosition = 1.0;
    return leftButton;
}

-(SKSpriteNode *)buildRightButton
{
    SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:@"right"];
    leftButton.position = CGPointMake(60, 20);
    leftButton.name = @"rightButton";
    leftButton.zPosition = 1.0;
    return leftButton;
}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];

    if([node.name isEqualToString:@"leftButton"])
    {
             [mainCharacter.physicsBody applyImpulse:CGVectorMake(-120, 0)];
    }

    else if([node.name isEqualToString:@"rightButton"])
    {
       [mainCharacter.physicsBody applyImpulse:CGVectorMake(120, 10)];
    }
}

Ответ 1

Если вы хотите, чтобы представление всегда было сосредоточено на позиции вашего игрока, измените свой код с учетом этих точек:

1) Создайте SKNode и вызовите его myWorld, worldNode или любое другое имя, подобное этому.

2) Добавьте worldNode [self addChild:worldNode];

3) Добавьте все остальные узлы в worldNode, включая ваш плеер.

4) В методе didSimulatePhysics добавьте этот код:

worldNode.position = CGPointMake(-(player.position.x-(self.size.width/2)), -(player.position.y-(self.size.height/2)));

Теперь ваше мнение будет всегда сосредоточено на позиции вашего игрока.

Обновление до 2015 года:

Если вы используете карту, созданную с помощью Tiled Map Editor, вы можете использовать бесплатную инфраструктуру SKAToolKit. Особенности включают в себя плейер камеры автоматически следовать, тест-плеер, проверить HUD и кнопки спрайтов.