1
私はSpriteKit(Mac OSのObjective C)で以下に示すような水平スライダーを作成しようとしています。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アンカーポイントは何ですか? ifが0.5の場合は、(x
@SimonePistecchiaのコメントに_background.position.xがバックグラウンドの中心であると推測すると、 'position.xの代わりに' _background.frame.minX'と '_background.frame.maxX'を使うべきです'と' position.x + width'を使用します。ノブをあなたのバックグラウンドの子にした場合、ノブはその親に対して相対的であるため、 '[-width/2、 width/2]について心配する必要があります。 (私はこのような書式をお勧めします)また、あなたの次の問題がノブでそのバーを移動することを予測するつもりです、私はその効果を達成するためにSKCropNodeを調べることをお勧めします。 – Knight0fDragon
回答者のためにありがとう。私のアンカーポイントはすべてのノードで(0、0.5)なので、私の計算は良い@SimonePistecchia権利だと思いますか? '_knob'は' _background'の子ではありません。クラス全体を見るようにコードを更新します。 – 02fentym