Created
April 9, 2013 19:04
-
-
Save lukaswelte/5348440 to your computer and use it in GitHub Desktop.
TinyWings ground infinite modification
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
#import <Foundation/Foundation.h> | |
#import "Box2D.h" | |
#define kMaxHillKeyPoints 10 | |
#define kMaxHillVertices 1000 | |
#define kMaxBorderVertices 5000 | |
#define kHillSegmentWidth 10 | |
@interface Ground : CCNode { | |
ccVertex2F hillKeyPoints[kMaxHillKeyPoints]; | |
int nHillKeyPoints; | |
int fromKeyPointI; | |
int toKeyPointI; | |
ccVertex2F hillVertices[kMaxHillVertices]; | |
ccVertex2F hillTexCoords[kMaxHillVertices]; | |
int nHillVertices; | |
ccVertex2F borderVertices[kMaxBorderVertices]; | |
int nBorderVertices; | |
float _offsetX; | |
float _offsetY; | |
float _length; | |
b2World *world; | |
b2Body *body; | |
int screenW; | |
int screenH; | |
int textureSize; | |
} | |
@property (nonatomic, strong) CCSprite *stripes; | |
@property (nonatomic, assign) float groundStartY; | |
@property (nonatomic, assign) float groundEndY; | |
@property (nonatomic, assign) float xPosition; | |
+ (id) groundWithWorld:(b2World*)w andLength:(int)lenght andOffsetX:(float)xOffset Y:(float)yOffset; | |
- (id) initWithWorld:(b2World*)w andLength:(int)lenght andOffsetX:(float)xOffset Y:(float)yOffset; | |
- (void) reset; | |
@end |
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
#import "Ground.h" | |
@interface Ground() | |
- (CCSprite*) generateGroundSprite; | |
- (CCTexture2D*) generateGroundTexture; | |
- (void) renderGround; | |
- (void) generateHillKeyPoints; | |
- (void) generateBorderVertices; | |
@end | |
@implementation Ground | |
+ (id) groundWithWorld:(b2World*)w andLength:(int)lenght andOffsetX:(float)xOffset Y:(float)yOffset { | |
return [[self alloc] initWithWorld:w andLength:lenght andOffsetX:xOffset Y:yOffset]; | |
} | |
- (id) initWithWorld:(b2World*)w andLength:(int)lenght andOffsetX:(float)xOffset Y:(float)yOffset { | |
if ((self = [super init])) { | |
world = w; | |
CGSize size = [[CCDirector sharedDirector] winSize]; | |
screenW = size.width; | |
screenH = size.height; | |
textureSize = 512; | |
_offsetX = _xPosition = xOffset; | |
_offsetY = _groundEndY = yOffset; | |
_length = lenght; | |
self.stripes = [self generateGroundSprite]; | |
[self generateHillKeyPoints]; | |
[self generateBorderVertices]; | |
[self createHillVertices]; | |
} | |
return self; | |
} | |
- (void) dealloc { | |
self.stripes = nil; | |
} | |
- (CCSprite*) generateGroundSprite { | |
CCTexture2D *texture = [self generateGroundTexture]; | |
CCSprite *sprite = [CCSprite spriteWithTexture:texture]; | |
ccTexParams tp = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_CLAMP_TO_EDGE}; | |
[sprite.texture setTexParameters:&tp]; | |
return sprite; | |
} | |
- (CCTexture2D*) generateGroundTexture { | |
CCRenderTexture *rt = [CCRenderTexture renderTextureWithWidth:1024 height:256]; | |
[rt begin]; | |
[self renderGround]; | |
[rt end]; | |
return rt.sprite.texture; | |
} | |
- (void) renderGround { | |
CCSprite *s = [CCSprite spriteWithFile:@"groundTexture.png"]; | |
s.anchorPoint = ccp(0,0); | |
s.position = ccp(0, 0); | |
[s visit]; | |
[s visit]; // more contrast | |
} | |
- (void) generateHillKeyPoints { | |
nHillKeyPoints = 0; | |
float x, y, dx, dy, ny; | |
// starting point | |
x = 0; | |
y = _offsetY; | |
hillKeyPoints[nHillKeyPoints++] = (ccVertex2F){x, y}; | |
// middle points | |
int minDX = round(_length/11), rangeDX = round(_length/22); | |
int minDY = 25, rangeDY = 35; | |
float sign = -1; // +1 - going up, -1 - going down | |
float maxHeight = 60; | |
float minHeight = 10; | |
while (nHillKeyPoints < kMaxHillKeyPoints-2) { | |
dx = arc4random()%rangeDX+minDX; | |
x += dx; | |
dy = arc4random()%rangeDY+minDY; | |
ny = y + dy*sign; | |
if(ny > maxHeight) ny = maxHeight; | |
if(ny < minHeight) ny = minHeight; | |
y = ny; | |
sign *= -1; | |
hillKeyPoints[nHillKeyPoints++] = (ccVertex2F){x, y}; | |
} | |
x = _length; | |
dy = arc4random()%rangeDY+minDY; | |
ny = y + dy*sign; | |
if(ny > maxHeight) ny = maxHeight; | |
if(ny < minHeight) ny = minHeight; | |
y = ny; | |
_groundEndY = y; | |
hillKeyPoints[nHillKeyPoints++] = (ccVertex2F){x, y}; | |
} | |
- (void) generateBorderVertices { | |
nBorderVertices = 0; | |
ccVertex2F p0, p1, pt0, pt1; | |
p0 = hillKeyPoints[0]; | |
for (int i=1; i<nHillKeyPoints; i++) { | |
p1 = hillKeyPoints[i]; | |
int hSegments = floorf((p1.x-p0.x)/kHillSegmentWidth-1); | |
float dx = (p1.x - p0.x) / hSegments; | |
float da = M_PI / hSegments; | |
float ymid = (p0.y + p1.y) / 2; | |
float ampl = (p0.y - p1.y) / 2; | |
pt0 = p0; | |
borderVertices[nBorderVertices++] = pt0; | |
for (int j=1; j<hSegments+1; j++) { | |
pt1.x = p0.x + j*dx; | |
pt1.y = ymid + ampl * cosf(da*j); | |
borderVertices[nBorderVertices++] = pt1; | |
pt0 = pt1; | |
} | |
p0 = p1; | |
} | |
} | |
- (void) createHillVertices { | |
nHillVertices = 0; | |
ccVertex2F p0, p1; | |
p0 = borderVertices[0]; | |
for (int i=1; i<nBorderVertices; i++) {; | |
p1 = borderVertices[i]; | |
// triangle strip between p0 and p1 | |
hillVertices[nHillVertices] = (ccVertex2F){p0.x, p0.y-(float)textureSize}; | |
hillTexCoords[nHillVertices++] = (ccVertex2F){p0.x/(float)textureSize, 1.0f}; | |
hillVertices[nHillVertices] = (ccVertex2F){p1.x, p1.y-(float)textureSize}; | |
hillTexCoords[nHillVertices++] = (ccVertex2F){p1.x/(float)textureSize, 1.0f}; | |
hillVertices[nHillVertices] = (ccVertex2F){p0.x, p0.y}; | |
hillTexCoords[nHillVertices++] = (ccVertex2F){p0.x/(float)textureSize, 0}; | |
hillVertices[nHillVertices] = (ccVertex2F){p1.x, p1.y}; | |
hillTexCoords[nHillVertices++] = (ccVertex2F){p1.x/(float)textureSize , 0}; | |
p0 = p1; | |
} | |
} | |
- (void) reset { | |
_offsetX = _xPosition; | |
_offsetY = _groundStartY; | |
[self generateHillKeyPoints]; | |
[self generateBorderVertices]; | |
[self createHillVertices]; | |
} | |
- (void) draw { | |
self.shaderProgram = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTexture]; | |
CC_NODE_DRAW_SETUP(); | |
ccGLBindTexture2D( _stripes.texture.name ); | |
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords ); | |
[self.shaderProgram use]; | |
[self.shaderProgram setUniformForModelViewProjectionMatrix]; | |
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(CGPoint), hillVertices); | |
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(CGPoint), hillTexCoords); | |
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nHillVertices); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment