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

Ios 在skview中创建指向不同场景的按钮,ios,objective-c,ios7,sprite-kit,Ios,Objective C,Ios7,Sprite Kit,我第一次尝试雪碧套装。简单地说,我已经浏览了文档,但是我还不能完全理解创建多个按钮的想法。我可以创建好按钮。它们出现在我的视图中,但我不能为了指向不同的视图而将函数附加到它们上。下面是我用来创建按钮等的代码: #import "Levels.h" #import "MyScene.h" #import "MyScene1.h" @interface Levels () @property BOOL contentCreated; @end @implementation Levels -

我第一次尝试雪碧套装。简单地说,我已经浏览了文档,但是我还不能完全理解创建多个按钮的想法。我可以创建好按钮。它们出现在我的视图中,但我不能为了指向不同的视图而将函数附加到它们上。下面是我用来创建按钮等的代码:

#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)touchesbeated:(NSSet*)toucheevent:(UIEvent*)event
方法中的按钮1到3,它会很好地加载场景,不会崩溃。谁能帮我解决这个问题吗。我知道我没有正确地声明其他三个按钮,但我似乎无法正确地实现它们。

我写了一个答案,创建了一个专门用作按钮的类。它是可用的,允许您为按钮的选定和正常状态设置图像,以及为触动内部事件和触动内部事件调用的方法。我认为将按钮创建为此类的实例会更容易,然后将移动部分指定给单独方法中的新场景,并将其设置为事件调用的动作。当你使用这个类时,你甚至不必乱动
触摸开始。

我写了一个答案,创建了一个专门用作按钮的类。它是可用的,允许您为按钮的选定和正常状态设置图像,以及为触动内部事件和触动内部事件调用的方法。我认为将按钮创建为此类的实例会更容易,然后将移动部分指定给单独方法中的新场景,并将其设置为事件调用的动作。使用此类时,您甚至不必处理
touchsbegind

您应该只在
-(void)touchsbegind:(NSSet*)touchsevent:(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];
    }];
}

您应该只在
-(void)touchesbeated:(NSSet*)toucheevent:(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];
    }];
}

[button runAction:moveSequence1 completion:…]应该是[button 1 runAction:moveSequence1 completion:…]吗?button 2和button 3也是这样吗?@AndyOS 1,我只是这样命名,认为这会有所不同。如果我只是将按钮的名称更改为按钮1、2、3,每次按下任何按钮,所有按钮都会移动,然后场景崩溃。只要我能让代码正常工作,我愿意改变代码或整个事情。有什么想法吗?[button runAction:moveSequence1 completion:…]应该是[button 1 runAction:moveSequence1 completion:…]而且button 2和button 3也是这样吗?@AndyOS 1,我只是这样命名,认为这会有所不同。如果我只是将按钮的名称更改为按钮1、2、3,每次按下任何按钮,所有按钮都会移动,然后场景崩溃。只要我能让代码正常工作,我愿意改变代码或整个事情。有什么想法吗?我看过你上的课。非常漂亮。如何在skview中实现按钮并引用类?顺便说一下,您的帖子。@XCodeMonkey
#导入“SKBButtonNode.h”
并创建节点<代码>SKBButtonNode*按钮=[[SKBButtonNode alloc]initWithImageNamedNormal:normalImage selected:selectedImage];按钮位置=位置;[button SetTouchUpInsiderGet:self action:@selector(按下按钮时调用的操作)]
然后您将定义方法
actionToBeCalledWhenButtonPressed
它将返回
void
谢谢,我一定会尝试,因为我还在探索spritekit+我看了你上的课。非常漂亮。如何在skview中实现按钮并引用类?顺便说一下,您的帖子。@XCodeMonkey
#导入“SKBButtonNode.h”
并创建节点<代码>SKBButtonNode*按钮=[[SKBButtonNode alloc]initWithImageNamedNormal:normalImage selected:selectedImage];按钮位置=位置;[button SetTouchUpInsiderGet:self action:@selector(按下按钮时调用的操作)]然后您将定义方法
actionToBeCalledWhenButtonPressed
它将返回
void
谢谢,我一定会尝试,因为我还在探索spritekit+一个很好的方便的课程,兄弟。:)非常感谢。工作起来很有魅力。它节省了我很多时间,并且消除了冗余。再次感谢你,伙计(1)并接受:谢谢。工作起来很有魅力。它节省了我很多时间,并且消除了冗余。再次感谢你,伙计(1)并接受: