无法识别的选择器发送到实例 - spritekit

时间:2014-09-14 17:54:55

标签: objective-c memory-management sprite-kit

我对编写Objective C代码有点新意,我确信我的风格很糟糕。我已经在这个问题上检查了几个其他解决方案,但我仍然感到困惑。据我所知,到目前为止,这似乎是一个内存管理问题。这是设置,我有2个类,一个名为MyScene.m(通用精灵套件场景)和一个名为Buttons.m的类,用于以编程方式设计按钮。这是一个OS X应用程序(不是IOS APP)。

来自MyScene.m:

-(id)initWithSize:(CGSize)size {
    ...
    NSColor *col = [NSColor colorWithRed:90.0/255.0 green:90.0/255.0 blue:90.0/255.0 alpha:1.0];
    NSColor *col2 = [NSColor colorWithRed:40.0/255.0 green:40.0/255.0 blue:40.0/255.0 alpha:1.0];
    Button *button = [[Button alloc] initRoundRectNormal:col Selected:col2 Size:CGSizeMake(200, 100)];
    button.position = CGPointMake(200, 400);
    [button setText:@"HI"];
    [button setTextSize:80];
    [self addChild:button];
    ...
}

-(void)mouseDown:(NSEvent *)theEvent {
    CGPoint location = [theEvent locationInNode:self];
    SKSpriteNode *spriteTouched = (SKSpriteNode*)[self nodeAtPoint:location];

    if ([spriteTouched.name isEqualToString:@"button"]) {
        Button *button = (Button*)spriteTouched;
        [button setIsPressed:YES];
    }
}

这是整个Button.m类:

#import "Button.h"

@interface Button()

@property SKShapeNode *shape;
@property SKShapeNode *shapeShadow;
@property SKLabelNode *labelShadow;
@property ButtonType shapeType;
@property NSColor *normalColor;
@property NSColor *selectedColor;
@property CGSize size;

@end

@implementation Button

@synthesize label = _label;
@synthesize isPressed = _isPressed;

@synthesize shape = _shape;
@synthesize shapeShadow = _shapeShadow;
@synthesize labelShadow = _labelShadow;
@synthesize shapeType = _shapeType;
@synthesize normalColor = _normalColor;
@synthesize selectedColor = _selectedColor;
@synthesize size = _size;

-(id)initSquareNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor SideLength:(int)sideLength {
    if(self = [super init]) {
        //init colours and size
        _normalColor = normalColor;
        _selectedColor = selectedColor;
        _size = CGSizeMake(sideLength, sideLength);
        _shapeType = SQUARE;
        [self initButton];
    }
    return self;
}

-(id)initRoundRectNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size {
    if(self = [super init]) {
        //init colours and size
        _normalColor = normalColor;
        _selectedColor = selectedColor;
        _size = size;
        _shapeType = ROUNDED_REC;
        [self initButton];
    }
    return self;
}

-(id)initCircleNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size {
    if(self = [super init]) {
        //init colours and size
        _normalColor = normalColor;
        _selectedColor = selectedColor;
        _size = size;
        _shapeType = CIRCLE;
        [self initButton];
    }
    return self;
}

-(void)initButton {
    [self initShape];
    [self initLabel];
    [self initLabelShadow];
}

-(void)initLabel {
    _label = [[SKLabelNode alloc] init];
    _label.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
    _label.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
    _label.zPosition = 2;
    [_shape addChild:_label];
}

-(void)initLabelShadow {
    NSColor *black = [NSColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.4];
    _labelShadow = [_label copy];
    _labelShadow.fontColor = black;
    _labelShadow.position = CGPointMake(_label.position.x, _label.position.y - 5);
    _labelShadow.zPosition = _label.zPosition - 4;
    _labelShadow.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
    _labelShadow.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
    [_label addChild:_labelShadow];
}

-(void)initShape {
    switch (_shapeType) {
        case ROUNDED_REC: {
            _shape = [SKShapeNode node];
            [_shape setPath:CGPathCreateWithRoundedRect(CGRectMake(-(_size.width/2), -(_size.height/2), _size.width, _size.height), 4, 4, nil)];
            _shape.strokeColor = _shape.fillColor = _normalColor;
            [self addChild:_shape];
            break;
        }
        case CIRCLE: {
            _shape = [SKShapeNode node];
            [_shape setPath:CGPathCreateWithRoundedRect(CGRectMake(-(_size.width/2), -(_size.height/2), _size.width, _size.height), _size.width/2, _size.height/2, nil)];
            _shape.strokeColor = _shape.fillColor = _normalColor;
            [self addChild:_shape];
            break;
        }
        case SQUARE: {
            _shape = [SKShapeNode node];
            [_shape setPath:CGPathCreateWithRoundedRect(CGRectMake(-(_size.width/2), -(_size.height/2), _size.width, _size.height), 0, 0, nil)];
            _shape.strokeColor = _shape.fillColor = _normalColor;
            [self addChild:_shape];
            break;
        }
        default:
            break;
    }
    _shape.name = @"button";
    _shape.zPosition = -5;
    _shape.lineWidth = 1;
    [self initShadow];
}

-(void)initShadow {
    float r = 0.0, g = 0.0, b = 0.0, a = 0.8;
    NSColor *black = [NSColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a];
    _shapeShadow = [_shape copy];
    _shapeShadow.fillColor = black;
    _shapeShadow.strokeColor = [NSColor colorWithRed:255.0*a/255.0 green:255.0*a/255.0 blue:255*a/255.0 alpha:0.8];
    _shapeShadow.lineWidth = 1;
    _shapeShadow.zPosition = _shape.zPosition - 1;

    CGPoint shadowPosition = CGPointMake(_shape.position.x, _shape.position.y - 10);
    _shapeShadow.position = shadowPosition;

    [self addChild:_shapeShadow];
}

-(void)setText:(NSString*)text {
    _label.text = text;
    _labelShadow.text = text;
}

-(void)setTextSize:(int)size {
    _label.fontSize = size;
    _labelShadow.fontSize = size;
}

-(void)setIsPressed:(bool)isPressed {
    if (isPressed)
        _shape.fillColor = _shape.strokeColor = _selectedColor;
    else
        _shape.fillColor = _shape.strokeColor = _normalColor;
}

-(bool)isPressed {
    return _isPressed;
}

@end

来自Button.h:

#import <SpriteKit/SpriteKit.h>

typedef enum ButtonType {
    CIRCLE,
    SQUARE,
    ROUNDED_REC
} ButtonType;

@interface Button : SKSpriteNode

@property SKLabelNode* label;
@property bool isPressed;

-(id)initSquareNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor SideLength:(int)sideLength;
-(id)initRoundRectNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size;
-(id)initCircleNormal:(NSColor*)normalColor Selected:(NSColor*)selectedColor Size:(CGSize)size;
-(void)setText:(NSString*)text;
-(void)setTextSize:(int)size;

@end

万一你想知道我想要做什么,我试图在点击它时改变按钮的颜色。

这是错误:

    2014-09-14 13:49:05.625 UI[1602:303] -[SKShapeNode setIsPressed:]: unrecognized selector sent to instance 0x61800011fd10
    2014-09-14 13:49:05.626 UI[1602:303] -[SKShapeNode setIsPressed:]: unrecognized selector sent to instance 0x61800011fd10
    2014-09-14 13:49:05.628 UI[1602:303] (
    0   CoreFoundation                      0x00007fff8494225c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff8b94fe75 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff8494512d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x00007fff848a0272 ___forwarding___ + 1010
    4   CoreFoundation                      0x00007fff8489fdf8 _CF_forwarding_prep_0 + 120
    5   UI                                  0x0000000100001f01 -[MyScene mouseDown:] + 257
    6   SpriteKit                           0x0000000100016a05 -[SKView mouseDown:] + 374
    7   AppKit                              0x00007fff8d12aa58 -[NSWindow sendEvent:] + 11296
    8   AppKit                              0x00007fff8d0c95d4 -[NSApplication sendEvent:] + 2021
    9   AppKit                              0x00007fff8cf199f9 -[NSApplication run] + 646
    10  AppKit                              0x00007fff8cf04783 NSApplicationMain + 940
    11  UI                                  0x0000000100002042 main + 34
    12  libdyld.dylib                       0x00007fff8ceef5fd start + 1
    13  ???                                 0x0000000000000003 0x0 + 3
)

1 个答案:

答案 0 :(得分:1)

您的按钮由一组对象组成:形状,文本和文本阴影。我假设您希望代码调用setIsPressed,如果任何用户选择了其中一个对象。目前,您的代码仅检查是否选择了形状(这导致错误,因为SKShape没有名为isPressed的属性)。我建议你概括你的代码,以便处理所有情况。这是一种方法:

-(void)mouseDown:(NSEvent *)theEvent {
    CGPoint location = [theEvent locationInNode:self];
    // Search all nodes at location for a Button
    NSArray *nodes = [self nodesAtPoint:location];
    for (SKNode *node in nodes) {
        if ([node isKindOfClass:[Button class]]) {
             [((Button *)node) setIsPressed];
             break;
        }
    }
}

另外,也许Button应该是SKNode的子类而不是SKSpriteNode。