Created
December 1, 2012 13:51
-
-
Save anonymous/4182355 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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