为了账号安全,请及时绑定邮箱和手机立即绑定

在SKScene中设置按钮

在SKScene中设置按钮

HUH函数 2019-08-27 10:22:29
在SKScene中设置按钮我发现它UIButtons不能很好地工作SKScene,所以我试图子类化SKNode来制作一个按钮SpriteKit。我希望它工作的方式是,如果我初始化一个按钮SKScene并启用触摸事件,那么按钮将在我SKScene按下时调用我的方法。我很感激任何能让我找到解决这个问题的建议。谢谢。
查看完整描述

3 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

我已经制作了自己的Button-Class,我正在使用它。SKButton.h:


#import <SpriteKit/SpriteKit.h>

@interface SKButton : SKSpriteNode


@property (nonatomic, readonly) SEL actionTouchUpInside;

@property (nonatomic, readonly) SEL actionTouchDown;

@property (nonatomic, readonly) SEL actionTouchUp;

@property (nonatomic, readonly, weak) id targetTouchUpInside;

@property (nonatomic, readonly, weak) id targetTouchDown;

@property (nonatomic, readonly, weak) id targetTouchUp;


@property (nonatomic) BOOL isEnabled;

@property (nonatomic) BOOL isSelected;

@property (nonatomic, readonly, strong) SKLabelNode *title;

@property (nonatomic, readwrite, strong) SKTexture *normalTexture;

@property (nonatomic, readwrite, strong) SKTexture *selectedTexture;

@property (nonatomic, readwrite, strong) SKTexture *disabledTexture;


- (id)initWithTextureNormal:(SKTexture *)normal selected:(SKTexture *)selected;

- (id)initWithTextureNormal:(SKTexture *)normal selected:(SKTexture *)selected disabled:(SKTexture *)disabled; // Designated Initializer


- (id)initWithImageNamedNormal:(NSString *)normal selected:(NSString *)selected;

- (id)initWithImageNamedNormal:(NSString *)normal selected:(NSString *)selected disabled:(NSString *)disabled;


/** Sets the target-action pair, that is called when the Button is tapped.

 "target" won't be retained.

 */

- (void)setTouchUpInsideTarget:(id)target action:(SEL)action;

- (void)setTouchDownTarget:(id)target action:(SEL)action;

- (void)setTouchUpTarget:(id)target action:(SEL)action;


@end

SKButton.m:


#import "SKButton.h"

#import <objc/message.h>



@implementation SKButton


#pragma mark Texture Initializer


/**

 * Override the super-classes designated initializer, to get a properly set SKButton in every case

 */

- (id)initWithTexture:(SKTexture *)texture color:(UIColor *)color size:(CGSize)size {

    return [self initWithTextureNormal:texture selected:nil disabled:nil];

}


- (id)initWithTextureNormal:(SKTexture *)normal selected:(SKTexture *)selected {

    return [self initWithTextureNormal:normal selected:selected disabled:nil];

}


/**

 * This is the designated Initializer

 */

- (id)initWithTextureNormal:(SKTexture *)normal selected:(SKTexture *)selected disabled:(SKTexture *)disabled {

    self = [super initWithTexture:normal color:[UIColor whiteColor] size:normal.size];

    if (self) {

        [self setNormalTexture:normal];

        [self setSelectedTexture:selected];

        [self setDisabledTexture:disabled];

        [self setIsEnabled:YES];

        [self setIsSelected:NO];


        _title = [SKLabelNode labelNodeWithFontNamed:@"Arial"];

        [_title setVerticalAlignmentMode:SKLabelVerticalAlignmentModeCenter];

        [_title setHorizontalAlignmentMode:SKLabelHorizontalAlignmentModeCenter];


        [self addChild:_title];

        [self setUserInteractionEnabled:YES];

    }

    return self;

}


#pragma mark Image Initializer


- (id)initWithImageNamedNormal:(NSString *)normal selected:(NSString *)selected {

    return [self initWithImageNamedNormal:normal selected:selected disabled:nil];

}


- (id)initWithImageNamedNormal:(NSString *)normal selected:(NSString *)selected disabled:(NSString *)disabled {

    SKTexture *textureNormal = nil;

    if (normal) {

        textureNormal = [SKTexture textureWithImageNamed:normal];

    }


    SKTexture *textureSelected = nil;

    if (selected) {

        textureSelected = [SKTexture textureWithImageNamed:selected];

    }


    SKTexture *textureDisabled = nil;

    if (disabled) {

        textureDisabled = [SKTexture textureWithImageNamed:disabled];

    }


    return [self initWithTextureNormal:textureNormal selected:textureSelected disabled:textureDisabled];

}





#pragma -

#pragma mark Setting Target-Action pairs


- (void)setTouchUpInsideTarget:(id)target action:(SEL)action {

    _targetTouchUpInside = target;

    _actionTouchUpInside = action;

}


- (void)setTouchDownTarget:(id)target action:(SEL)action {

    _targetTouchDown = target;

    _actionTouchDown = action;

}


- (void)setTouchUpTarget:(id)target action:(SEL)action {

    _targetTouchUp = target;

    _actionTouchUp = action;

}


#pragma -

#pragma mark Setter overrides


- (void)setIsEnabled:(BOOL)isEnabled {

    _isEnabled = isEnabled;

    if ([self disabledTexture]) {

        if (!_isEnabled) {

            [self setTexture:_disabledTexture];

        } else {

            [self setTexture:_normalTexture];

        }

    }

}


- (void)setIsSelected:(BOOL)isSelected {

    _isSelected = isSelected;

    if ([self selectedTexture] && [self isEnabled]) {

        if (_isSelected) {

            [self setTexture:_selectedTexture];

        } else {

            [self setTexture:_normalTexture];

        }

    }

}


#pragma -

#pragma mark Touch Handling


/**

 * This method only occurs, if the touch was inside this node. Furthermore if 

 * the Button is enabled, the texture should change to "selectedTexture".

 */

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    if ([self isEnabled]) {

        objc_msgSend(_targetTouchDown, _actionTouchDown);

        [self setIsSelected:YES];

    }

}


/**

 * If the Button is enabled: This method looks, where the touch was moved to.

 * If the touch moves outside of the button, the isSelected property is restored

 * to NO and the texture changes to "normalTexture".

 */

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    if ([self isEnabled]) {

        UITouch *touch = [touches anyObject];

        CGPoint touchPoint = [touch locationInNode:self.parent];


        if (CGRectContainsPoint(self.frame, touchPoint)) {

            [self setIsSelected:YES];

        } else {

            [self setIsSelected:NO];

        }

    }

}


/**

 * If the Button is enabled AND the touch ended in the buttons frame, the

 * selector of the target is run.

 */

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];

    CGPoint touchPoint = [touch locationInNode:self.parent];


    if ([self isEnabled] && CGRectContainsPoint(self.frame, touchPoint)) {

        objc_msgSend(_targetTouchUpInside, _actionTouchUpInside);

    }

    [self setIsSelected:NO];

    objc_msgSend(_targetTouchUp, _actionTouchUp);

}

示例:要初始化按钮,请编写以下行:


    SKButton *backButton = [[SKButton alloc] initWithImageNamedNormal:@"buttonNormal" selected:@"buttonSelected"];

    [backButton setPosition:CGPointMake(100, 100)];

    [backButton.title setText:@"Button"];

    [backButton.title setFontName:@"Chalkduster"];

    [backButton.title setFontSize:20.0];

    [backButton setTouchUpInsideTarget:self action:@selector(buttonAction)];

    [self addChild:backButton];

此外,您需要在班级中使用'buttonAction'方法。 *不保证本课程在每种情况下都能正常使用。我对Objective-c还很新。*


如果您认为有做,这是恼人的和毫无意义的,你可以通过设置禁用构建设置检查“启用严格的检查objc_msgSend Calls',以” No'


查看完整回答
反对 回复 2019-08-27
  • 3 回答
  • 0 关注
  • 704 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信