2016-01-23 85 views
0

我寫此代碼爲GAME OVER了現場我有一個遊戲:兒童SkShapeNode定位混亂

#import "GameOverScene.h" 
#import "SharedInfo.h" 
@implementation GameOverScene 

-(void)didMoveToView:(SKView *)view { 
    /* Setup your scene here */ 

    [self setupView]; 

} 

-(void)showGameEndingWithGameInformation:(NSDictionary *)gameEndingInformation{ 

} 
-(void)setupView{ 
    SKLabelNode *GOTitle = [SKLabelNode labelNodeWithFontNamed:@"Generica Bold"]; 
    GOTitle.fontSize = 40.f; 
    NSString* text = [NSString stringWithFormat:@"GAME OVER"]; 
    [GOTitle setText:text]; 
    GOTitle.position = CGPointMake(CGRectGetMidX(self.frame), self.frame.size.height- GOTitle.frame.size.height*1.5); 
    [GOTitle setFontColor:[[SharedInfo sharedManager]colorFromHexString:@"#2EB187"]]; 
    [self addChild: GOTitle]; 


    SKLabelNode *replayButton = [SKLabelNode labelNodeWithFontNamed:@"Quicksand-Bold"]; 
    replayButton.fontSize = 25.f; 
    NSString* replayText = [NSString stringWithFormat:@"Play Again"]; 
    [replayButton setText:replayText]; 
    replayButton.name = kGOSceneReplayButton; 
    replayButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)- self.frame.size.height/5); 
    [replayButton setFontColor:[SKColor whiteColor]]; 
    SKShapeNode *bgNode = [SKShapeNode shapeNodeWithRectOfSize:replayButton.frame.size]; 
    [bgNode setFillColor:[UIColor redColor]]; 

    [replayButton addChild:bgNode]; 
    [self addChild:replayButton]; 

    NSLog(@"replay dimensions: %@",NSStringFromCGRect(replayButton.frame)); 
    SKLabelNode *returnButton = [SKLabelNode labelNodeWithFontNamed:@"Quicksand-Bold"]; 
    returnButton.fontSize = 25.f; 

    NSString* returnText = [NSString stringWithFormat:@"Return To Main Menu"]; 
    [returnButton setText:returnText]; 
    returnButton.name = kGOSceneReturnToMainButton; 
    returnButton.position = CGPointMake(CGRectGetMidX(self.frame), replayButton.position.y -self.frame.size.height/7 ); 
    [returnButton setFontColor:[SKColor whiteColor]]; 

    [self addChild:returnButton]; 

} 

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ 

    UITouch *touch = [touches anyObject]; 
    CGPoint location = [touch locationInNode:self]; 
    SKNode *sprite = [self nodeAtPoint:location]; 

    NSLog(@"sprite name: %@",sprite.name); 

    if ([sprite.name isEqualToString:kGOSceneReturnToMainButton]||[sprite.name isEqualToString:kGOSceneReturnToMainButton]) { 
     //return to main menu or retry 

     [self.gameEndingSceneDelegate goToScene:sprite.name withOptions:nil]; //Sort out the options later on. 

    } 

} 
@end 

當我雖然運行它,我得到這個:

enter image description here

有兩個問題我很困惑。首先,爲什麼我在場景中有8個節點,我真的應該有4個節點?我認爲節點翻倍,但這只是一個猜測。

更令人困惑的問題是紅色的SKShapeNode定位。我讀過縮放父節點可能會給子SKShapeNode帶來問題,但我沒有縮放任何東西。另外,爲什麼它將我的紅色矩形放置在一個隨機位置(它不是父級的中間,或者與底部相對應)。

非常感謝所有的幫助提前。

UPDATE 1:所以下面的建議,我檢查了我的方法是否被調用兩次,從而創建重複。沒有運氣,因爲它只被調用一次。神祕感依然強勁!

至於定位有心計,我改變了代碼稍微設置紅色矩形的位置,它的父節點匹配:

SKLabelNode *replayButton = [SKLabelNode labelNodeWithFontNamed:@"Quicksand-Bold"]; 
replayButton.fontSize = 25.f; 
NSString* replayText = [NSString stringWithFormat:@"Play Again"]; 
[replayButton setText:replayText]; 
replayButton.name = kGOSceneReplayButton; 
replayButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)- self.frame.size.height/5); 
[replayButton setFontColor:[SKColor whiteColor]]; 
SKShapeNode *bgNode = [SKShapeNode shapeNodeWithRectOfSize:replayButton.frame.size]; 
[bgNode setFillColor:[UIColor redColor]]; 


[self addChild:replayButton]; 
bgNode.position = replayButton.position; 
[replayButton addChild:bgNode]; 

但在更新後,我得到這個:

enter image description here

萬一有幫助,這是我做的呈現什麼場景:

SKView * skView = (SKView *)self.view; 
skView.showsFPS = YES; 
skView.showsNodeCount = YES; 
/* Sprite Kit applies additional optimizations to improve rendering performance */ 
skView.ignoresSiblingOrder = YES; 
scene = [GameOverScene sceneWithSize:self.view.frame.size]; 
[(GameOverScene*)scene setGameEndingSceneDelegate:self]; 
[(GameOverScene*)scene setScaleMode: SKSceneScaleModeAspectFill]; 
[(GameOverScene*)scene showGameEndingWithGameInformation:self.gameEndingInfo]; 

// Present the scene. 
[skView presentScene:scene transition:sceneTransition]; 

而且,這是我的NSLog輸出:

重播尺寸:{{221,91},{127,25}

我有一種感覺,因爲我把我的場景的setScaleMode,它會變得很奇怪,但沒有別的東西是不尋常的,所以不知道該怎麼做。我想也許只是爲我的標籤創建一個圖像,並將SKLabelNode更改爲SKSpriteNode並設置圖像,所以我跳過添加紅色矩形作爲標籤節點的背景。我想添加矩形的原因實際上是爲了提供更大的命中目標,因此如果有人知道更簡單,更直接的方式,我會非常感激。

UPDATE 3:

我還嘗試設置矩形的位置以匹配父標籤節點的:

bgNode.position = [replayButton convertPoint:CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)- self.frame.size.height/5) fromNode:self]; 

矩形在同一地點作爲最後的更新結束(所有一直到屏幕的右側)

+0

@ originaluser2我試了兩個,setupView只被調用一次,並且更新後的代碼發生了怪異的事情!我已經使用代碼更新更新了原始帖子。這很奇怪! – Septronic

+0

@ originaluser2當添加SKLabelNode時,在iOS 9模擬器中,節點數量增加2。所以,這不是OP的錯誤。 – Whirlwind

+0

@Whirlwind事情是我在設備上運行它。 – Septronic

回答

1

有你的代碼的幾個問題:

  1. lineWidth屬性,它的默認值爲1.0。它應該是0.0f

  2. verticalAlignmentMode屬性和它的默認基線對齊方式。它應該是SKLabelVerticalAlignmentModeCenter

  3. 錯誤地定位形狀節點。它應該是(0,0)

爲了解決這個問題,更改標籤的垂直對齊方式:

replayButton.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter; 

集shapenode的財產的lineWidth到0.0F:

bgNode.lineWidth = 0.0f; 

,並刪除此行:

//bgNode.position should be CGPointZero which is (0,0) 
bgNode.position = replayButton.position; 

不過,我會st遠離這種方法。在這種情況下不需要SKShapeNode。您可以使用SKSpriteNode。重要的是SKShapeNodeSKLabelNode不能分批繪製,也就是說,當像SKSpriteNode那樣渲染時,不能在一次繪製過程中繪製。看看this。你的例子太簡單了,無法解決性能問題,但總的來說,你應該記住所有這些。

如果您的按鈕文字在遊戲過程中永不改變,您應該考慮使用SKSpriteNode用紋理初始化。如果對SpriteKit的預製按鈕感興趣,請看SKAButton

希望這會有所幫助!

+0

很棒!這一點(當然,填充標籤文本背後的地方!):)你提到的SKAButton看起來非常好,但我只有幾個按鈕,並且不確定是否使用第三方庫很多。但我已經爲未來的項目記下了它!感謝一堆! – Septronic