2014-05-25 10 views
12

// UPDATE Der aktualisierte Code wurde hinzugefügt, der wie erwartet funktioniert. Siehe didSimulatePhysics-Methode im aktualisierten Code unten. In meinem Fall interessiert es mich nur, ein Zeichen nach links oder rechts auf der x-Achse zu bewegen, wobei 0 auf der x-Achse das absolute links und rechts auf der x-Achse ein konfigurierbarer Wert ist. Das Apple-Abenteuerspiel hat auch sehr geholfen.Verschieben einer Kamera in SpriteKit

// ORIGINAL POST UNTER

Ich arbeite mit Apple SpriteKit und ich kämpfen, um eine Kamera zu implementieren, wie ich es möchte verhalten. Was ich im Code getan habe, ist ein Sprite-Zeichen, zwei Knöpfe und ein rotes Kästchen, das zu Beginn außerhalb der Ansicht rechts daneben ist, zu laden. Ich möchte den Charakter mit den Tasten bewegen. Sobald der Player die Mitte oder das Ende des Bildschirms erreicht hat, wird die Kamera neu ausgerichtet, um zu erkennen, was in der Ansicht nicht zu sehen war. Wenn du dich nach rechts bewegst, solltest du irgendwann die rote Box zeigen, die sich außerhalb der Sicht befindet, sobald der Spieler dort ist. Mit dem Code, den ich unten verwende, kann ich die Kamera jedoch nicht dazu bringen, die Koordinaten an den Hauptcharakter anzupassen. Ich habe mir Apples fortgeschrittenes Scene-Processing-Dokument sowie einige andere Stack-Überlauf-Posts angeschaut, aber ich finde es nicht richtig. Wenn jemand einen Rat geben könnte, würde es geschätzt werden.

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)]; 
    } 
} 

Antwort

22

Wenn Sie die Ansicht möchten immer auf dem Player die Position zentriert werden, Ihren Code mit Berücksichtigung dieser Punkte ändern:

1) Erstellen Sie eine SKNode und nennen es myWorld, worldNode oder irgendein anderer Name wie dieser.

2) In den worldNode [self addChild:worldNode];

3) Fügen Sie alle anderen Knoten zum worldNode, einschließlich Ihrer Spieler.

4) In der didSimulatePhysics Methode, fügen Sie diesen Code:

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

Ihre Ansicht wird nun immer auf dem Player die Position zentriert werden.

Update Mai 2015:

Wenn Sie eine Karte verwenden, der mit Ziegeln gedeckte Map Editor erstellt haben, können Sie den kostenlosen SKAToolKit framework verwenden. Zu den Funktionen gehören die automatische Verfolgung der Player-Kamera, der Test-Player, die Test-HUD- und Sprite-Tasten.

+0

Danke Sangony für die Antwort. Ich habe den Code im ursprünglichen Beitrag so geändert, dass er die vorgeschlagenen Änderungen widerspiegelt. Dieses Zeichen erscheint jedoch oben rechts und die Bewegungstasten sind weg. Ich gehe davon aus, dass ich die Bewegungsschaltflächen in der aktuellen Ansicht irgendwie verankern muss, damit sie sich bewegen, wenn die Ansicht sich anpasst, aber nicht ganz sicher sind, ob die Schaltflächen in der Szene, in der Welt oder in der Kamera verankert sein sollen. – zic10

+0

@ zic10 - Sie können die Steuerschaltflächen direkt der Ansicht hinzufügen, damit sie nicht verschoben werden. Wenn Sie den Mittelpunkt in Bezug auf Ihren Player ändern müssen, können Sie Offsetwerte hinzufügen. Zum Beispiel: ((player.position.x- (self.size.width/2) +20) Der Offset ist der +20. – sangony

+1

Bedeutet das, dass ich den Kamera-Knoten verwerfen kann und einfach alles im myWorld-Knoten tun kann? – zic10