Skip to content

Instantly share code, notes, and snippets.

@patrick99e99
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrick99e99/693fa8e84ceba845ba47 to your computer and use it in GitHub Desktop.
Save patrick99e99/693fa8e84ceba845ba47 to your computer and use it in GitHub Desktop.
#import "StatusMessage.h"
@interface StatusMessage ()
@property (nonatomic, strong) NSString *identifier;
@property (nonatomic, weak) id<StatusMessageDelegate>delegate;
@property (nonatomic) NSUInteger state;
@property (nonatomic) CGPoint targetPosition;
@end
@implementation StatusMessage
enum animationTags { SCROLL_ACTION_TAG = 0,
FLASH_ACTION_TAG };
enum statusData {
FLASH_TIMES = 5
};
enum states {
SHOULD_AUTO_DISMISS_STATE = 1 << 0,
SHOULD_FLASH_STATE = 1 << 1,
SHOULD_SCALE_SPEED_STATE = 1 << 2,
DISMISSED_STATE = 1 << 3,
};
static CGFloat scrollSpeedScale = 600.0f;
static CGFloat flashSpeed = 0.25f;
static ccTime scrollSpeed = 1.0f;
-(instancetype)initWithString:(NSString *)string
identifier:(NSString *)identifier
flash:(BOOL)flash
autoDismiss:(BOOL)autoDismiss
delegate:(id<StatusMessageDelegate>)delegate {
if (self = [super init]) {
self.scale = 0.75f;
self.fntFile = NOTEBLASTER_FONT;
self.position = ccp(0, 0);
self.blendFunc = ADDITIVE_BLENDING;
self.alignment = kCCTextAlignmentLeft;
self.anchorPoint = ccp(0.0f, 0.5f);
self.string = string;
self.identifier = identifier;
self.delegate = delegate;
if (autoDismiss) [self markAsShouldAutoDismiss];
if (flash) [self markAsShouldFlash];
}
return self;
}
-(void)scrollLeft {
[self markAsShouldScaleSpeed];
[self scrollWithStart:[self offScreenRightXPos]
middle:[self centerXPos]
finish:[self offScreenLeftXPos]];
}
-(void)scrollUp {
[self markAsShouldNotScaleSpeed];
CGPoint middle = [self centerXPos];
[self scrollWithStart:ccp(middle.x, -48)
middle:middle
finish:ccp(middle.x, 48)];
}
-(void)scrollWithStart:(CGPoint)start
middle:(CGPoint)middle
finish:(CGPoint)finish {
self.position = start;
self.visible = YES;
self.targetPosition = finish;
ccTime duration = [self durationForStart:start end:middle];
CCSequence *actions = [CCSequence actions:
[CCMoveTo actionWithDuration:duration
position:middle],
[self conditionalFlashSequence],
[self conditionalScrollFinish], nil];
actions.tag = SCROLL_ACTION_TAG;
[self runAction:actions];
}
-(id)conditionalFlashSequence {
if ([self shouldFlash]) {
return [CCSequence actionOne:[CCCallFunc actionWithTarget:self selector:@selector(flash)]
two:[CCDelayTime actionWithDuration:(flashSpeed * 2 * [self flashTimes])]];
} else {
return [CCActionInstant action];
}
}
-(id)conditionalScrollFinish {
return ([self shouldAutoDismiss]) ?
[self scrollFinishSequenceForMessageDisrupted:NO] :
[CCActionInstant action];
}
-(CCSequence *)scrollFinishSequenceForMessageDisrupted:(BOOL)disrupted {
__weak typeof (self) weakSelf = self;
ccTime duration = [self durationForStart:self.position end:self.targetPosition];
return [CCSequence actionOne:[CCMoveTo actionWithDuration:duration
position:self.targetPosition]
two:[CCCallBlock actionWithBlock:^{
weakSelf.visible = NO;
if (disrupted) {
[weakSelf.delegate didDisruptScrolling:weakSelf];
} else {
[weakSelf.delegate didFinishScrolling:weakSelf];
}
}]];
}
-(ccTime)durationForStart:(CGPoint)start end:(CGPoint)end {
ccTime duration;
if ([self shouldScaleSpeed]) {
CGFloat distance = ccpDistance(start, end);
duration = distance / scrollSpeedScale;
} else {
duration = scrollSpeed;
}
return duration;
}
-(void)disruptScroll {
if ([self shouldFlash]) {
[self stopActionByTag:SCROLL_ACTION_TAG];
[self runAction:[self scrollFinishSequenceForMessageDisrupted:YES]];
}
}
-(void)flash {
__weak typeof (self) weakSelf = self;
CCSequence *action = [CCRepeat actionWithAction:
[CCSequence actions:
[CCFadeOut actionWithDuration:flashSpeed],
[CCFadeIn actionWithDuration:flashSpeed],
[CCCallBlock actionWithBlock:^{
if ([weakSelf wasDismissed]) {
[weakSelf stopActionByTag:FLASH_ACTION_TAG];
}
}], nil]
times:[self flashTimes]];
action.tag = FLASH_ACTION_TAG;
[self runAction:action];
}
-(NSUInteger)flashTimes {
return [self shouldAutoDismiss] ? FLASH_TIMES : 9999;
}
-(CGPoint)offScreenLeftXPos {
return ccp(-[self scaledContentWidth], 0);
}
-(CGPoint)centerXPos {
return ccp(((self.parent.contentSize.width - [self scaledContentWidth]) / 2) + COCOS_HACK_OFFSET_X, 0);
}
-(CGPoint)offScreenRightXPos {
return ccp(self.parent.contentSize.width, 0);
}
-(CGFloat)scaledContentWidth {
return self.contentSize.width * self.scale;
}
# pragma mark - states
-(void)markAsShouldAutoDismiss {
self.state |= SHOULD_AUTO_DISMISS_STATE;
}
-(BOOL)shouldAutoDismiss {
return !!(self.state & SHOULD_AUTO_DISMISS_STATE);
}
-(void)markAsShouldFlash {
self.state |= SHOULD_FLASH_STATE;
}
-(BOOL)shouldFlash {
return !!(self.state & SHOULD_FLASH_STATE);
}
-(void)markAsDismissed {
self.state |= DISMISSED_STATE;
}
-(BOOL)wasDismissed {
return !!(self.state & DISMISSED_STATE);
}
-(void)markAsShouldScaleSpeed {
self.state |= SHOULD_SCALE_SPEED_STATE;
}
-(void)markAsShouldNotScaleSpeed {
self.state &= ~SHOULD_SCALE_SPEED_STATE;
}
-(BOOL)shouldScaleSpeed {
return !!(self.state & SHOULD_SCALE_SPEED_STATE);
}
@end
#import "CCLabelBMFont.h"
#import "StatusMessageDelegate.h"
@interface StatusMessage : CCLabelBMFont
-(instancetype)initWithString:(NSString *)string
identifier:(NSString *)identifier
flash:(BOOL)flash
autoDismiss:(BOOL)autoDismiss
delegate:(id<StatusMessageDelegate>)delegate;
-(NSString *)identifier;
-(void)scrollLeft;
-(void)scrollUp;
-(void)disruptScroll;
-(CGFloat)scaledContentWidth;
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment