1
我试图在SpriteKit(Objective C for Mac OS)中创建一个如下所示的水平滑块。SpriteKit中的自定义滑块
我肯定做错了什么,因为滑块的“旋钮”永不移至左侧,只向右移动,我不知道是什么问题。我正在使用mouseDragged:
方法来处理所有事情。这里的代码如下:
Slider.m
#import "Slider.h"
@interface Slider()
@property CGSize dimensions;
@property SKSpriteNode *background, *foreground, *knob;
@end
@implementation Slider
-(instancetype) initWithDimensions:(CGSize)dimensions Percentage:(double)percentage {
if (self = [super init]) {
_dimensions = dimensions;
_percentage = percentage;
[self initBackgroundSprite];
[self initForegroundSprite];
[self initKnob];
self.userInteractionEnabled = YES;
}
return self;
}
-(void) initBackgroundSprite {
_background = [SKSpriteNode spriteNodeWithImageNamed:@"sliderBG"];
_background.centerRect = CGRectMake(6.0/13.0, 5.0/11.0, 1.0/13.0, 1.0/11.0);
[_background setAnchorPoint:CGPointMake(0, 0.5)];
double xScale = _dimensions.width/_background.frame.size.width;
double yScale = _dimensions.height/_background.frame.size.height;
[_background setXScale:xScale];
[_background setYScale:yScale];
[self addChild:_background];
}
-(void) initForegroundSprite {
_foreground = [SKSpriteNode spriteNodeWithImageNamed:@"sliderFG"];
_foreground.centerRect = CGRectMake(6.0/13.0, 5.0/11.0, 1.0/13.0, 1.0/11.0);
[_foreground setAnchorPoint:CGPointMake(0, 0.5)];
double xScale = _dimensions.width*_percentage/_foreground.frame.size.width;
double yScale = _dimensions.height/_foreground.frame.size.height;
[_foreground setXScale:xScale];
[_foreground setYScale:yScale];
[self addChild:_foreground];
}
-(void) initKnob {
_knob = [SKSpriteNode spriteNodeWithImageNamed:@"sliderKnob"];
_knob.centerRect = CGRectMake(6.0/13.0, 5.0/11.0, 1.0/13.0, 1.0/11.0);
[_knob setAnchorPoint:CGPointMake(0, 0.5)];
double scaleFactor = 2/(_knob.frame.size.height/_background.frame.size.height);
NSLog(@"%f, %f", _knob.frame.size.height, _background.frame.size.height);
[_knob setScale:scaleFactor];
[_knob setZPosition:2];
[_knob setName:@"knob"];
[self addChild:_knob];
}
-(void) mouseDragged:(NSEvent *)event {
CGPoint location = [event locationInNode:self];
NSArray *nodes = [self nodesAtPoint:location];
for (SKNode *node in nodes) {
if ([node isKindOfClass:[SKSpriteNode class]]) {
SKSpriteNode *sprite = (SKSpriteNode*)node;
if ([sprite.name isEqualToString:@"knob"]) {
[self updateKnobPositionWithLocation:location];
}
}
}
}
-(void) updateKnobPositionWithLocation:(CGPoint)location {
double x = location.x;
double y = _knob.position.y; //don't want the y-pos to change
double bgX = _background.position.x; //x pos of slider
double width = _background.frame.size.width; //width of slider
if (x > bgX + width)//if knob goes beyond width of slider, restrict to width
x = bgX + width;
else if (x < bgX)
x = bgX;
[_knob setPosition:CGPointMake(x, y)];
}
下面就来说明行为的视频:
https://drive.google.com/open?id=0B8Zfr1yQCdf-OG5kZFRWNFgxd1k
你有什么x锚点?如果是0.5,则必须更改为else if(x
添加到@SimonePistecchia的评论我会猜测_background.position.x是你的背景的中心,你应该使用'_background.frame.minX'和'_background.frame.maxX'而不是'position.x '和'position.x + width'。如果你把旋钮做成你的背景的一个孩子,那么你只需要担心'[宽度/ 2, 宽度/ 2]',因为旋钮是相对于其父母。 (我会建议像这样格式化)另外,我会预测你的下一个问题将会随着旋钮移动到那个栏,我会建议寻找SKCropNode来达到这个效果。 – Knight0fDragon
谢谢你们的回复。我的所有节点的定位点(0,0.5),所以我认为我的计算很好@SimonePistecchia对不对? '_knob'不是'_background'的孩子。我会更新代码,以便看到整个班级。 – 02fentym