在 skview 中创建按钮以指向不同的场景

Posted

技术标签:

【中文标题】在 skview 中创建按钮以指向不同的场景【英文标题】:creating buttons in skview to point to different scenes 【发布时间】:2014-02-21 16:49:06 【问题描述】:

我是第一次尝试精灵套件。只是为了说明这一点,我已经阅读了文档,但我还不能安静地掌握创建多个按钮的想法。我可以创建按钮。它们出现在我的视图中,但我无法将功能附加到它们以指向不同的视图。这是我用于创建按钮等的代码:

#import "Levels.h"
#import "MyScene.h"
#import "MyScene1.h"

@interface Levels ()
@property BOOL contentCreated;
@end

@implementation Levels

- (void)didMoveToView: (SKView *) view

    if (!self.contentCreated)
    
        [self createSceneContents];
        self.contentCreated = YES;
    


- (void)createSceneContents

    self.backgroundColor = [SKColor blueColor];
    self.scaleMode = SKSceneScaleModeAspectFit;
    [self addChild: [self button]];
    [self addChild: [self button1]];
    [self addChild: [self button2]];
    [self addChild: [self button3]];


- (SKLabelNode *)button

    SKLabelNode *button = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
    button.text = @"Level 1";
    button.fontSize = 42;
    button.position = CGPointMake(CGRectGetMidX(self.frame),250);
    button.name = @"button";
    return button;

- (SKLabelNode *)button1

    SKLabelNode *button1 = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
    button1.text = @"Level 2";
    button1.fontSize = 42;
    button1.position = CGPointMake(CGRectGetMidX(self.frame),200);
    button1.name = @"button1";
    return button1;

- (SKLabelNode *)button2

    SKLabelNode *button2 = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
    button2.text = @"Level 3";
    button2.fontSize = 42;
    button2.position = CGPointMake(CGRectGetMidX(self.frame),150);
    button2.name = @"button2";
    return button2;

- (SKLabelNode *)button3

    SKLabelNode *button3 = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
    button3.text = @"Level 4";
    button3.fontSize = 42;
    button3.position = CGPointMake(CGRectGetMidX(self.frame),100);
    button3.name = @"button3";
    return button3;


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *button = [self nodeAtPoint:location];
    SKNode *button1 = [self nodeAtPoint:location];
    SKNode *button2 = [self nodeAtPoint:location];
    SKNode *button3 = [self nodeAtPoint:location];
    //if fire button touched, bring the rain
    if (button != nil)
    
        button.name = nil;
        SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
        SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.25];
        SKAction *pause = [SKAction waitForDuration: 0.5];
        SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
        SKAction *remove = [SKAction removeFromParent];
        SKAction *moveSequence = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
        [button runAction: moveSequence completion:^
            SKScene *spaceshipScene  = [[MyScene alloc] initWithSize:self.size];
            SKTransition *doors = [SKTransition doorsOpenVerticalWithDuration:0.5];
            [self.view presentScene:spaceshipScene transition:doors];
        ];
    

    if (button1 != nil)
    
        button1.name = nil;
        SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
        SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.25];
        SKAction *pause = [SKAction waitForDuration: 0.5];
        SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
        SKAction *remove = [SKAction removeFromParent];
        SKAction *moveSequence1 = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
        [button runAction: moveSequence1 completion:^
            SKScene *spaceshipScene1  = [[MyScene1 alloc] initWithSize:self.size];
            SKTransition *doors1 = [SKTransition doorsOpenVerticalWithDuration:0.5];
            [self.view presentScene:spaceshipScene1 transition:doors1];
        ];
    
    if (button2 != nil)
    
        button2.name = nil;
        SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
        SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.25];
        SKAction *pause = [SKAction waitForDuration: 0.5];
        SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
        SKAction *remove = [SKAction removeFromParent];
        SKAction *moveSequence2 = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
        [button runAction: moveSequence2 completion:^
            SKScene *spaceshipScene2  = [[MyScene alloc] initWithSize:self.size];
            SKTransition *doors2 = [SKTransition doorsOpenVerticalWithDuration:0.5];
            [self.view presentScene:spaceshipScene2 transition:doors2];
        ];
    
    if (button3 != nil)
    
        button3.name = nil;
        SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
        SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.25];
        SKAction *pause = [SKAction waitForDuration: 0.5];
        SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
        SKAction *remove = [SKAction removeFromParent];
        SKAction *moveSequence3 = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
        [button runAction: moveSequence3 completion:^
            SKScene *spaceshipScene3  = [[MyScene alloc] initWithSize:self.size];
            SKTransition *doors3 = [SKTransition doorsOpenVerticalWithDuration:0.5];
            [self.view presentScene:spaceshipScene3 transition:doors3];
        ];
    

@end

使用上面的代码,当我按下第一个按钮时,场景出现,然后冻结,哦,项目会崩溃。我想这与我声明按钮的方式有关。如果我在- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 方法中注释掉按钮 1 到 3,它会很好地加载场景并且不会崩溃。有人可以帮我解决这个问题。我知道我没有以正确的方式声明其他三个按钮,但我似乎无法正确实现它们。

【问题讨论】:

是 [button runAction: moveSequence1 completion: .. ] 应该是 [button1 runAction: moveSequence1 completion: ..] 和 button2 和 button3 一样吗? @AndyOS 1,我只是这样命名它们,认为它会有所作为。如果我只是将按钮的名称更改为按钮 1、2、3,则每次按下任何按钮时,它们都会移动,然后场景崩溃。只要我能让它工作,我愿意更改该代码或整个事情。有什么想法吗? 【参考方案1】:

您应该只在- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 中分配一次节点,然后根据其名称检查它是哪个节点:

- (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:@"button"]) 
        [self runButtonActionOnNode:node];
    
    else if ([node.name isEqualToString:@"button1"]) 
        [self runButtonActionOnNode:node];
    
    else if  ([node.name isEqualToString:@"button2"]) 
         [self runButtonActionOnNode:node];
    
    else if ([node.name isEqualToString:@"button3"]) 
         [self runButtonActionOnNode:node];
    

我还将您的操作代码放入一个方法中,以减少重复:

-(void)runButtonActionOnNode:(SKNode*) node
    node.name = nil;
    SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
    SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.25];
    SKAction *pause = [SKAction waitForDuration: 0.5];
    SKAction *fadeAway = [SKAction fadeOutWithDuration: 0.25];
    SKAction *remove = [SKAction removeFromParent];
    SKAction *moveSequence = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
    [node runAction: moveSequence completion:^
         SKScene *spaceshipScene  = [[MyScene alloc] initWithSize:self.size];
         SKTransition *doors = [SKTransition doorsOpenVerticalWithDuration:0.5];
         [self.view presentScene:spaceshipScene transition:doors];
    ];

【讨论】:

非常感谢。奇迹般有效。它为我节省了大量时间并消除了冗余。再次感谢人。 + 1 并接受。 :)【参考方案2】:

我写了一个答案,创建了一个特定于用作按钮的类。它可用here 并允许您为按钮的选定状态和正常状态设置图像,以及为触摸内部事件和触摸内部事件调用的方法。我认为将按钮创建为此类的实例会更容易,然后将移动部分分配到单独方法中的新场景,并将它们设置为事件调用的操作。使用此类时,您甚至不必与touchesBegan 混淆。

【讨论】:

我看到了你做的课。很漂亮。您将如何在 skview 中实现按钮并引用该类?顺便给你的帖子投了票。 @XCodeMonkey #import "SKBButtonNode.h" 并创建节点。 SKBButtonNode *button = [[SKBButtonNode alloc] initWithImageNamedNormal:normalImage selected:selectedImage]; button.position = position; [button setTouchUpInsideTarget:self action:@selector(actionToBeCalledWhenButtonPressed)]; 然后您将定义方法 actionToBeCalledWhenButtonPressed 它应该返回 void 谢谢,我一定会尝试的,因为我还在探索 spritekit。 +1 一个好用的类兄弟。:)

以上是关于在 skview 中创建按钮以指向不同的场景的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中创建浮动操作按钮

如何在情节提要中创建一个按钮以启动在 xcode swift 中使用 spritekit 创建的游戏

在 C++ 中创建一个指向另一个元素的向量

SpriteKit 暂停和恢复 SKView

如何在 Swift 中创建具有自定义形状的 UIButton?

06 在Gitee中创建远程仓库