注意:這是用於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;
}
你是如何做到這一點的?我試過這個,但它給了我一個錯誤。 'chordAttackButton.acceptsFirstResponder = true;' – 02fentym 2014-10-05 02:36:16
對不起,我很笨。你必須在你的按鈕類中覆蓋它。 – hola 2014-10-05 02:38:07
所以我必須爲第一響應者創建一個setter?我有點困惑。我從來沒有以任何身份與第一響應者合作過。請幫助:/ – 02fentym 2014-10-05 02:45:45