2014-10-05 80 views
0

注意:這是用於OS X應用程序,而不是iOS應用程序。自定義按鈕類setuserinteractionenabled

我正在創建一個自定義按鈕類,它是SKSpriteNode的一個子類。我希望這個類能夠處理按鈕按鈕,所以我發現我必須將setuserinteractionenabled設置爲YES。當我在我的自定義按鈕類中這樣做以便mouseDown事件接收消息時,我的SKScene(創建按鈕)不再在單擊按鈕時接收消息。有沒有辦法可以解決這個問題?我甚至嘗試在SKScene中啓用setuserinteractionenabled,但無濟於事。我找不到解決這個問題的任何問題。

Button.h

#import <SpriteKit/SpriteKit.h> 

typedef enum ButtonState { 
    UNPRESSED, 
    PRESSED 
} ButtonState; 

@interface Button : SKSpriteNode 

@property ButtonState state; 

-(id)initButtonWithImage:(NSString*)unselectedImage selectedImage:(NSString*)selectedImage; 
-(void)setButtonState:(NSString*)event; 

@end 

Button.m(自定義按鈕類)

#import "Button.h" 

@interface Button() 

@property SKSpriteNode *image; 
@property SKSpriteNode *unselectedImage; 
@property SKSpriteNode *selectedImage; 

@end 

@implementation Button 

@synthesize state = _state; 
@synthesize image = _image; 
@synthesize unselectedImage = _unselectedImage; 
@synthesize selectedImage = _selectedImage; 

-(id)initButtonWithImage:(NSString*)unselectedImage selectedImage:(NSString*)selectedImage { 
    if (self = [super init]) { 
     _unselectedImage = [[SKSpriteNode alloc] initWithImageNamed:unselectedImage]; 
     _selectedImage = [[SKSpriteNode alloc] initWithImageNamed:selectedImage]; 

     _image = _unselectedImage; 
     _image.name = @"image"; 

     [self addChild:_image]; 
     self.userInteractionEnabled = YES; 

    } 
    return self; 
} 

-(void)setButtonState:(NSString*)event { 
    [self removeAllChildren]; 
    if ([event isEqualToString:@"mousedown"]) 
     _image = _selectedImage; 
    else if ([event isEqualToString:@"mouseup"]) 
     _image = _unselectedImage; 

    [self addChild:_image]; 
} 

-(void)mouseDown:(NSEvent *)theEvent { 
    [self setButtonState:@"mousedown"]; 
} 

-(void)mouseUp:(NSEvent *)theEvent { 
    [self setButtonState:@"mouseup"]; 
} 

@end 

GameMenu.m(一個SKScene)

#import "GameMenu.h" 
#import "NoteBlasterMenu.h" 
#import "ChordAttackMenu.h" 
#import "Button.h" 

@implementation GameMenu 

-(id)initWithSize:(CGSize)size { 
    if (self = [super initWithSize:size]) { 
     /* Setup your scene here */ 
     self.userInteractionEnabled = YES; //allows scene to register clicks 

     [self initBackground]; 
     [self initButtons]; 
     [self setUserInteractionEnabled:YES]; 
    } 
    return self; 
} 

-(void) initBackground { 
    SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:@"menubg"]; 
    bg.position = CGPointMake(self.size.width/2, self.size.height/2); 
    [self addChild:bg]; 
} 

-(void) initButtons { 
    Button *chordAttackButton = [[Button alloc] initButtonWithImage:@"chordattackbutton" 
                 selectedImage:@"chordattackbuttonpressed"]; 
    chordAttackButton.position = CGPointMake(self.size.width/2, self.size.height/2); 
    chordAttackButton.name = @"chordAttackButton"; 
    [self addChild:chordAttackButton]; 

    Button *noteBlasterButton = [[Button alloc] initButtonWithImage:@"noteblasterbutton" 
                 selectedImage:@"noteblasterbuttonpressed"]; 
    noteBlasterButton.position = CGPointMake(self.size.width/2, self.size.height/2 - 150); 
    noteBlasterButton.name = @"noteBlasterButton"; 
    [self addChild:noteBlasterButton]; 
} 

-(void)mouseDown:(NSEvent *)theEvent { 
    CGPoint location = [theEvent locationInNode:self]; 
    NSArray *nodes = [self nodesAtPoint:location]; 

    NSLog(@"I'm being pressed"); 

    for (SKNode *node in nodes) { 
     if ([node isKindOfClass:[Button class]]) { 
      Button *button = (Button*)node; 

      if ([button.name isEqualToString:@"chordAttackButton"]) { 
       SKScene *scene = [ChordAttackMenu sceneWithSize:CGSizeMake(1280, 720)]; 
       [self.view presentScene:scene transition:[SKTransition fadeWithDuration:0.55]]; 
      } 
      else if ([button.name isEqualToString:@"noteBlasterButton"]) { 
       SKScene *scene = [NoteBlasterMenu sceneWithSize:CGSizeMake(1280, 720)]; 
       [self.view presentScene:scene transition:[SKTransition fadeWithDuration:0.55]]; 
      } 
     } 
    } 
} 

@end 

AppDelegate.m

....(header files etc) 
@implementation AppDelegate 

@synthesize window = _window; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    /* Set up the window for the app */ 
    NSRect frame = [_window frame]; 
    frame.size = CGSizeMake(1280, 740); 
    [_window setFrame: frame display: YES animate: NO]; 
    [_window center]; //sets the window to the centre of the screen 

    /* Pick a size for the scene */ 
    //SKScene *scene = [ChordAttackMenu sceneWithSize:CGSizeMake(1280, 720)]; //ChordAttack Menu 
    //SKScene *scene = [MyScene sceneWithSize:CGSizeMake(1280, 720)]; //ChordAttack 
    //SKScene *scene = [NoteBlasterMenu sceneWithSize:CGSizeMake(1280, 720)]; //BassBlaster Menu 
    //SKScene *scene = [NoteBlaster sceneWithSize:CGSizeMake(1280, 720)]; //BassBlaster 
    SKScene *scene = [GameMenu sceneWithSize:CGSizeMake(1280, 720)]; 

    /* Set the scale mode to scale to fit the window */ 
    //scene.scaleMode = SKSceneScaleModeAspectFit; 
    scene.scaleMode = SKSceneScaleModeAspectFill; 

    [self.skView presentScene:scene]; 

    self.skView.showsFPS = YES; 
    self.skView.showsNodeCount = YES; 
} 

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { 
    return YES; 
} 

回答

1

在GameMenu.m您initButtons方法中,通過

chordAttackButton.nextResponder = self; 
noteBlasterButton.nextResponder = self; 

在您的按鈕類設置爲每個按鈕的下一個應答器,由

-(void)mouseDown:(NSEvent *)theEvent { 
    [self setButtonState:@"mousedown"]; 
    [super mouseDown:theEvent]; 
} 

-(void)mouseUp:(NSEvent *)theEvent { 
    [self setButtonState:@"mouseup"]; 
    [super mouseUp:theEvent]; 
} 
通過鼠標向下/向上事件向上響應鏈
0

所以這很奇怪。正如你所看到的,我不是Objective C最好的。但根據蘋果Event Handling Guide處理該事件後,你

[super theEvent]; 

通過它響應鏈但在這種情況下,GameScene是按鈕的父,而不是它的父。所以,你需要做的是調用事件要麼是這樣的:

[self.parent theEvent]; 

[self setNextResponder:referenceToGameScene]; 
[self.nextResponder theEvent]; 

這可能是最好的有,在一個不太令人費解的方式管理這些事件的控制器。因爲每個孩子都說你想把事件傳遞給響應者鏈,所以需要上面的代碼實現。

+0

你是如何做到這一點的?我試過這個,但它給了我一個錯誤。 'chordAttackButton.acceptsFirstResponder = true;' – 02fentym 2014-10-05 02:36:16

+0

對不起,我很笨。你必須在你的按鈕類中覆蓋它。 – hola 2014-10-05 02:38:07

+0

所以我必須爲第一響應者創建一個setter?我有點困惑。我從來沒有以任何身份與第一響應者合作過。請幫助:/ – 02fentym 2014-10-05 02:45:45