【发布时间】:2017-07-12 07:46:01
【问题描述】:
我正在尝试在 SpriteKit 中创建一个水平滑块,如下所示(在 Objective C for Mac OS 中)。
我肯定做错了什么,因为滑块的“旋钮”永远不会向左移动,它只会向右移动,我不确定问题出在哪里。我正在使用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 锚点是什么? if 为 0.5 你必须更改为 else if (x
-
添加到@SimonePistecchia 的评论我会猜测_background.position.x 是你背景的中心,你应该使用
_background.frame.minX和_background.frame.maxX而不是position.x和@ 987654329@。如果您将旋钮设置为背景的子级,那么您只需要担心[-width/2 , width/2],因为旋钮将与其父级相关。 (我会推荐这样的格式)另外,我预测你的下一个问题将是用旋钮移动那个栏,我建议查看 SKCropNode 来实现这个效果。 -
感谢大家的回复。我的所有节点的锚点都是 (0, 0.5) 所以我认为我的计算很好@SimonePistecchia 对吗?
_knob不是_background的子代。我将更新代码,以便您看到整个班级。 -
如果没有其他条件,_knob 可以向后滑动吗?
-
尝试使用SKConstrain
标签: objective-c macos sprite-kit slider