Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple clipped sprite extension for Sparrow
//
// SHClippedSprite.h
// Sparrow
//
// Created by Shilo White on 5/30/11.
// Copyright 2011 Shilocity Productions. All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the Simplified BSD License.
//
#import <Foundation/Foundation.h>
#import "SPSprite.h"
@class SPStage;
@class SPQuad;
@interface SHClippedSprite : SPSprite {
SPQuad *mClip;
SPStage *mStage;
BOOL mClipping;
}
@property (nonatomic, readonly) SPQuad *clip;
@property (nonatomic, assign) BOOL clipping;
+ (SHClippedSprite *)clippedSprite;
@end
//
// SHClippedSprite.m
// Sparrow
//
// Created by Shilo White on 5/30/11.
// Copyright 2011 Shilocity Productions. All rights reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the Simplified BSD License.
//
#import "SHClippedSprite.h"
#import "SPEvent.h"
#import "SPQuad.h"
#import "SPStage.h"
#import "SPDisplayObject.h"
@interface SHClippedSprite ()
- (void)onAddedToStage:(SPEvent *)event;
@end
@implementation SHClippedSprite
@synthesize clip = mClip;
@synthesize clipping = mClipping;
+ (SHClippedSprite *)clippedSprite {
return [[[SHClippedSprite alloc] init] autorelease];
}
- (SHClippedSprite *)init {
if ((self = [super init])) {
mClip = [[SPQuad alloc] init];
mClip.visible = NO;
mClip.width = 0;
mClip.height = 0;
[self addChild:mClip];
mClipping = NO;
[self addEventListener:@selector(onAddedToStage:) atObject:self forType:SP_EVENT_TYPE_ADDED_TO_STAGE];
}
return self;
}
- (void)onAddedToStage:(SPEvent *)event {
[self removeEventListener:@selector(onAddedToStage:) atObject:self forType:SP_EVENT_TYPE_ADDED_TO_STAGE];
mStage = (SPStage *)self.stage;
}
- (void)render:(SPRenderSupport *)support {
if (mClipping) {
glEnable(GL_SCISSOR_TEST);
SPRectangle *clip = [[mClip boundsInSpace:mStage] intersectionWithRectangle:[self.parent boundsInSpace:mStage]];
glScissor((clip.x*[SPStage contentScaleFactor]), (mStage.height*[SPStage contentScaleFactor])-(clip.y*[SPStage contentScaleFactor])-(clip.height*[SPStage contentScaleFactor]), (clip.width*[SPStage contentScaleFactor]), (clip.height*[SPStage contentScaleFactor]));
[super render:support];
glDisable(GL_SCISSOR_TEST);
} else {
[super render:support];
}
}
- (SPRectangle *)boundsInSpace:(SPDisplayObject *)targetCoordinateSpace {
if (mClipping) {
return [mClip boundsInSpace:targetCoordinateSpace];
} else {
return [super boundsInSpace:targetCoordinateSpace];
}
}
- (void)dealloc {
[self removeEventListener:@selector(onAddedToStage:) atObject:self forType:SP_EVENT_TYPE_ADDED_TO_STAGE];
[mClip release];
[super dealloc];
}
@end
@implementation SPDisplayObject (ClippedHitTest)
- (SPDisplayObject*)hitTestPoint:(SPPoint*)localPoint forTouch:(BOOL)isTouch
{
if (isTouch && (!mVisible || !mTouchable)) return nil;
SPDisplayObject *parent = self.parent;
while (parent) {
if ([parent isKindOfClass:[SHClippedSprite class]] && ![[parent boundsInSpace:parent] containsPoint:localPoint])
return nil;
parent = parent.parent;
}
if ([[self boundsInSpace:self] containsPoint:localPoint]) return self;
else return nil;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.