Skip to content

Instantly share code, notes, and snippets.

@seanh
Created February 2, 2011 20:13
Show Gist options
  • Select an option

  • Save seanh/808322 to your computer and use it in GitHub Desktop.

Select an option

Save seanh/808322 to your computer and use it in GitHub Desktop.
//
// Sprite.h
// MyGame
//
// Created by Sean Hammond on 02/12/2010.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface Sprite : CCNode <CCTargetedTouchDelegate>
{
CCSprite *spriteNode; // spriteNode is not declared private because subclasses need access to it.
@private
CGRect baseRect;
NSArray *regions;
NSString *file;
}
/*!
* The textureRect of the sprite, in world coordinates.
*
* This property just forwards sprite.textureRect converted to world
* coordinates, for convenience.
*/
@property (readonly) CGRect textureRect;
/*!
* A CGRect in the sprite's own coordinate space, representing the base area of
* the sprite.
*/
@property (readonly) CGRect baseRect;
@property (readonly) NSArray *regions;
/*!
* Initialise a sprite using a sprite dictionary from TouchJSON.
*
*/
-(id)initWithDict:(NSDictionary *)dict;
/*!
* Return YES if the given rect intersects this sprite's base rect, NO
* otherwise.
*
* @param The rect to test for intersection, a CGRect in world coordinates.
*/
-(BOOL) intersectsBase:(CGRect)worldSpaceRect;
/*!
* This method is called by Scene after the sprite has been positioned in the
* scene. Subclasses should override this method.
*/
-(void) go;
/*!
* This method is called whenever the user touches the sprite.
* Subclasses should override this method if they want to respond to touches.
*
* @result YES to claim the touch.
*/
-(BOOL) wasTouched;
@end
//
// Sprite.m
// MyGame
//
// Created by Sean Hammond on 02/12/2010.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "Sprite.h"
#import "Config.h"
#import "Util.h"
#import "Logger.h"
@implementation Sprite
@synthesize baseRect;
@synthesize regions;
CGRect initBaseRect(NSDictionary *baseDict)
{
NSDictionary *blDict = [baseDict objectForKey:@"bottom left"];
NSDictionary *trDict = [baseDict objectForKey:@"top right"];
CGPoint bl = CGPointMake([[blDict objectForKey:@"x"] floatValue], [[blDict objectForKey:@"y"] floatValue]);
CGPoint tr = CGPointMake([[trDict objectForKey:@"x"] floatValue], [[trDict objectForKey:@"y"] floatValue]);
float width = tr.x - bl.x;
float height = tr.y - bl.y;
CGRect baseRect = CGRectMake(bl.x, bl.y, width, height);
return baseRect;
}
-(id)initWithDict:(NSDictionary *)dict
{
if( (self=[super init] ))
{
// Initialise baseRect.
baseRect = initBaseRect([dict objectForKey:@"base"]);
// Initialise spriteNode.
file = [[dict objectForKey:@"file"] retain];
spriteNode = [[CCSprite alloc] initWithFile:file];
[self addChild:spriteNode];
// Position spriteNode so that its bottom-middle point is at (0,0) in
// this node's coordinate space.
spriteNode.position = ccp(0, (spriteNode.contentSize.height/2.0)*spriteNode.scale);
// Initialise regions.
regions = [dict objectForKey:@"regions"];
}
return self;
}
// Implement the textureRect property.
-(CGRect) textureRect
{
return convertNodeRectToWorld(spriteNode, spriteNode.textureRect);
}
// This method is meant to be overridden by subclasses.
-(void) go
{
}
-(BOOL) intersectsBase:(CGRect)worldSpaceRect
{
CGPoint nodeSpaceOrigin = [self convertToNodeSpace:worldSpaceRect.origin];
CGRect nodeSpaceRect = CGRectMake(nodeSpaceOrigin.x, nodeSpaceOrigin.y, worldSpaceRect.size.width, worldSpaceRect.size.height);
return CGRectIntersectsRect(nodeSpaceRect, baseRect);
}
-(void) draw
{
[super draw];
if (DRAWBASES==YES)
{
CGFloat minX = CGRectGetMinX(self.baseRect);
CGFloat maxX = CGRectGetMaxX(self.baseRect);
CGFloat minY = CGRectGetMinY(self.baseRect);
CGFloat maxY = CGRectGetMaxY(self.baseRect);
CGPoint vertices[] = { ccp(minX,minY), ccp(maxX,minY), ccp(maxX,maxY), ccp(minX,maxY) };
glLineWidth(4);
glColor4ub(255,255,255,255);
ccDrawPoly(vertices,4,YES);
glColor4ub(0,0,0,255);
glPointSize(5);
ccDrawPoint(ccp(0,0));
glColor4ub(255,255,255,255);
glLineWidth(1);
}
}
/*!
* Called whenever this CCNode enters the stage.
*/
-(void) onEnter
{
// Register to receive targeted touch events.
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
[super onEnter];
}
/*!
* Called whenever this CCNode exits the stage.
*/
-(void) onExit
{
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
[super onExit];
}
-(BOOL) containsTouchLocation:(UITouch *)touch
{
return CGRectContainsPoint(spriteNode.textureRect, [spriteNode convertTouchToNodeSpace:touch]);
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
if ([self containsTouchLocation:touch])
{
[[Logger sharedLogger] logMessage:[NSString stringWithFormat:@"Sprite '%@' was touched", self] withLevel:LogLevelInfo name:@"Touches"];
return [self wasTouched];
}
else
{
return NO;
}
}
// This method should be overridden by subclasses if they want to respond to
// touches.
-(BOOL) wasTouched
{
return YES;
}
-(NSString *) description
{
return file;
}
-(void) dealloc
{
[file release];
[spriteNode release];
[super dealloc];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment