注意:这是一个OS应用程序,而不是iOS应用程序。
我正在创建一个自定义按钮类,它是SKSpriteNode的一个子类。我希望类能够按下句柄按钮,所以我发现必须将setuserinteractionenabled设置为YES。当我在自定义按钮类中这样做时,使mouseDown事件接收创建按钮的SKScene消息时,当单击按钮时不再接收消息。我有办法解决这个问题吗?我甚至尝试在SKScene中启用setuserinteraction,但没有效果。我找不到任何问题来解决这个问题。
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;
@endButton.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"];
}
@endGameMenu.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]];
}
}
}
}
@endAppDelegate.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;
}发布于 2014-10-05 02:28:29
所以这很奇怪。正如你所知,我不是目标c的最佳人选。但是根据苹果的说法,事件处理指南在你处理这个事件之后,你把它传递到响应链上。
[super theEvent];但是在这种情况下,GameScene是按钮的父级,而不是它的superview。因此,您需要做的是将事件称为这样的事件:
[self.parent theEvent];或
[self setNextResponder:referenceToGameScene];
[self.nextResponder theEvent];最好有一个控制器,以一种不那么复杂的方式管理这些事件。因为每个子节点都添加了要将事件传递到响应链中的信息,因此需要实现上面的代码。
https://stackoverflow.com/questions/26198917
复制相似问题