Skip to content

Instantly share code, notes, and snippets.

Created December 1, 2012 13:51
Show Gist options
  • Save anonymous/4182355 to your computer and use it in GitHub Desktop.
Save anonymous/4182355 to your computer and use it in GitHub Desktop.
//
// HeroTail.mm
// contreJour
//
// Created by Mokus on 11/27/10.
// Copyright 2010 bboygames. All rights reserved.
//
#import "HeroTail.h"
#import "HeroBodyClip.h"
#import "Maths.h"
#import "PointAndAngle.h"
#import "ContreDrawUtil.h"
#import "GraphUtil.h"
#import "ContreJourConstants.h"
#import "CocosUtil.h"
const float CENTER_ANGLE = M_PI/2;
const float ANGLE_LIMIT = M_PI*3/8;
const float MIDDLE1_DISTANCE = 30;
const float MIDDLE2_DISTANCE = 50;
const float END_DISTANCE = 70;
@implementation HeroTail
@synthesize limitAngles;
@synthesize speed;
@synthesize borderWidth;
-(id) initTailWithColor:(ccColor4B)_color
{
if((self=[super init]))
{
color = _color;
currentAngle = 0;
speed = 0;
middle = [[PointAndAngle alloc]initWithLength:r(MIDDLE1_DISTANCE) angleStep:0.02f angleOffset:0];
middle2 = [[PointAndAngle alloc]initWithLength:r(MIDDLE2_DISTANCE) angleStep:0.019f angleOffset:M_PI/2];
end = [[PointAndAngle alloc]initWithLength:r(END_DISTANCE) angleStep:0.018 angleOffset:M_PI];
points = [[NSMutableArray arrayWithObjects:middle,middle2,end,nil] retain];
borderWidth = 2;
// surfaceArray = nil;
}
return self;
}
-(id) init
{
if((self=[self initTailWithColor:BLACK_COLOR]))
{
}
return self;
}
-(ccColor4B) endColor
{
ccColor4B result = color;
result.a = 0;
return result;
}
-(void) setLimitAngles:(BOOL)value
{
limitAngles = value;
}
-(void) update:(float) time
{
float targetAngle = currentAngle;
if(limitAngles)
{
targetAngle = [Maths simplifyAngleRadians:currentAngle startValue:CENTER_ANGLE - M_PI];
targetAngle = clampf(targetAngle, CENTER_ANGLE - ANGLE_LIMIT, CENTER_ANGLE + ANGLE_LIMIT);
}
PointAndAngle* firstPoint = [points objectAtIndex:0];
float angle = [Maths simplifyAngleRadians:targetAngle startValue:firstPoint.angle - M_PI];
float timeCoeff = time * 30;
for(PointAndAngle* pointAndAngle in points)
{
float angleCoeff = fmin(fabs(pointAndAngle.angle - angle) / M_PI * 2, 0.5);
float diff = pointAndAngle.angleStep * speed * angleCoeff * timeCoeff;
pointAndAngle.angle = [Maths stepTo:pointAndAngle.angle target:angle maxStep:diff];
pointAndAngle.angle = clampf(pointAndAngle.angle, firstPoint.angle - M_PI/8, firstPoint.angle + M_PI/8);
[pointAndAngle update:speed / 2 * timeCoeff onGround:limitAngles timeCoeff:timeCoeff];
}
[self triangulate];
}
-(void) triangulate
{
PointsPair bodyPoints;
[ContreDrawUtil getPointsPairForPoints:CGPointZero start:middle.position end:CGPointZero width:(r(HERO_RADIUS_PIXELS) - borderWidth)*2 result:bodyPoints];
CGPoint center = [Maths getCenterPoint:middle.position with:middle2.position];
PointsPair middleControls;
PointsPair middlePoints;
PointsPair endControls;
[ContreDrawUtil getPointsPairForPoints:middle.position start:middle2.position end:center width:r(HERO_RADIUS_PIXELS)/2 result:middleControls];
[ContreDrawUtil getPointsPairForPoints:center start:middle2.position end:center width:r(HERO_RADIUS_PIXELS)/2 result:middlePoints];
[ContreDrawUtil getPointsPairForPoints:middle2.position start:middle2.position end:center width:r(HERO_RADIUS_PIXELS)/3 result:endControls];
CGPoint lastCenter = [Maths getCenterPoint:bodyPoints.first with:bodyPoints.second];
CGPointVector polygon;
polygon.push_back(bodyPoints.first);
polygon.push_back(middleControls.first);
polygon.push_back(middlePoints.first);
polygon.push_back(endControls.first);
polygon.push_back(end.position);
polygon.push_back(endControls.second);
polygon.push_back(middlePoints.second);
polygon.push_back(middleControls.second);
polygon.push_back(bodyPoints.second);
polygon.push_back(lastCenter);
surface = CGPointVector();
if(vertices.size() == 0)
vertices = CGPointVector(polygon.size()*3);
verticesCount = [GraphUtil createBezierTriangles:polygon surface: surface outTriangles:vertices segments:2];
if(colors.size() == 0)
{
colors = ccColor4BVector(polygon.size()*6);
border = CGPointVector(polygon.size()*6);
[GraphUtil createGradientColors:polygon.size() startColor:color endColor:[self endColor] colors:colors];
}
[GraphUtil createGradientBorder:surface width:borderWidth vertices:border];
}
-(void) setOpacity:(GLubyte)value
{
if(value != self.opacity)
{
[super setOpacity:value];
color.a = value;
for(uint i = 0; i < colors.size()/6; i++)
{
int j = i*6;
colors[j].a = value;
colors[j+1].a = value;
colors[j+3].a = value;
}
}
}
-(void) draw
{
[super draw];
[GraphUtil fillTriangles:vertices trianglesSize:verticesCount color:color];
[GraphUtil fillTriangles:border colors:colors];
}
-(void) setMovementDirection:(float)value
{
currentAngle = value + M_PI;
}
-(void) dealloc
{
for(PointAndAngle* item in points)
[item release];
[points release];
[super dealloc];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment