The CCSliderControl is sub-classed from CCLayer. Here is the .h file for it:
@protocol CCSliderControlDelegate
- (void) valueChanged: (float) value tag: (int) tag;
@end
@interface CCSliderControl : CCLayer {
float value;
id<CCSliderControlDelegate> delegate;
float minX;
float maxX;
}
@property (nonatomic, assign) float value;
@property (nonatomic, retain) id<CCSliderControlDelegate> delegate;
@end
In the init of this class instance, I add two sprites - one for the background, and one for the slider thumb:
-(id) init
{
if ((self = [super init]))
{
CCLOG(@"init %@", self);
self.isTouchEnabled = YES;
value = 0;
// add the slider background
CCSprite *bg = [CCSprite spriteWithFile:@"slider_background.png"]; //- TODO: add this to some texture atlas
[self setContentSize:[bg contentSize]];
bg.position = CGPointMake([bg contentSize].width / 2, [bg contentSize].height / 2);
[self addChild:bg];
// add the slider thumb
CGSize thumb_size;
CCSprite *thumb = [CCSprite spriteWithFile:@"slider_thumb.png"]; //- TODO: add this to some texture atlas
thumb_size = [thumb contentSize];
minX = thumb_size.width / 2;
maxX = [self contentSize].width - thumb_size.width / 2;
thumb.position = CGPointMake(minX, [self contentSize].height / 2);
[self addChild:thumb];
}
return self;
}
The setValue method that sets the value property of the instance also updates the thumb sprite position:
- (void) setValue:(float) newValue
{
if (newValue < 0) newValue = 0;
if (newValue > 1.0) newValue = 1.0;
value = newValue;
CCSprite *thumb = (CCSprite *)[[self children] objectAtIndex:1];
CGPoint pos = thumb.position;
pos.x = minX + newValue * (maxX - minX);
thumb.position = pos;
}
Next step is to register for touch events:
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:-1 swallowsTouches:YES];
}
and then handle the touch events:
-(CGPoint) locationFromTouch:(UITouch *)touch
{
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
CGRect bbox = [self boundingBox];
touchLocation.x -= bbox.origin.x;
touchLocation.y -= bbox.origin.y;
return touchLocation;
}
-(bool) isTouchForMe:(CGPoint)touchLocation
{
CCSprite *bg = (CCSprite *)[[self children] objectAtIndex:0];
return CGRectContainsPoint([bg boundingBox], touchLocation);
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [self locationFromTouch:touch];
bool isTouchHandled = [self isTouchForMe:location];
if (isTouchHandled) {
CCSprite *thumb = (CCSprite *)[[self children] objectAtIndex:1];
thumb.color = ccYELLOW;
CGPoint pos = thumb.position;
pos.x = location.x;
thumb.position = pos;
}
return isTouchHandled; // YES for events I handle
}
-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [self locationFromTouch:touch];
if ((location.x < minX) || (location.x > maxX))
return;
CCSprite *thumb = (CCSprite *)[[self children] objectAtIndex:1];
CGPoint pos = thumb.position;
pos.x = location.x;
thumb.position = pos;
}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
CCSprite *thumb = (CCSprite *)[[self children] objectAtIndex:1];
thumb.color = ccWHITE;
value = (thumb.position.x - minX) / (maxX - minX);
[delegate valueChanged:value tag:self.tag];
}
And the result looks like this:
You can get the source code from bitbucket by using mercurial:
$ hg clone https://iroth_net@bitbucket.org/iroth_net/ccslider
This comment has been removed by the author.
ReplyDeleteSorry i got the finger to move correctly once i properly looked through your project :)
ReplyDeleteOne thing though how would i actually implement this so i can changed the volume of my music? My music is being played like this:
"if(![[CDAudioManager sharedManager]isBackgroundMusicPlaying])
{
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"TileMap.caf"];
}"
Thanks in advance.
Sorry got it fixed no more messages,
ReplyDeleteif anyone else has the problem i had i used this code :
"- (void) valueChanged: (float) value tag: (int) tag
{
if (tag == 1) // music volume
[self updateLabel:value];
[CDAudioManager sharedManager].backgroundMusic.volume = value;
CCLOG (@"Unknown slider");
}"
Hello!
ReplyDeleteThank you for sharing CCSliderControl. I changed it a little:
added Mac OS support and changed hardcoded behavior to CCSprite as background and CCMenuItem as a thumb at init.
Grab it here: https://github.com/psineur/CCSlider
Best Regards,
Stepan
Thanks Stepan - that's cool!
ReplyDeleteHello. First of all I would like to thank you for this control, it has come in handy for an app I am building. However, I would like to know if it is possible to use the control vertically rather than horizontally as I see it is configured.
ReplyDeleteThanks.
Hi Cenobyte - sure, just change the orientation of the graphics and in the ccTouchMoved method compute the value based on y rather than x...
ReplyDeleteThanks for sharing this.
ReplyDelete