Objective c iOS游戏中的图形渲染错误

Objective c iOS游戏中的图形渲染错误,objective-c,ios,cocos2d-iphone,ios-simulator,lag,Objective C,Ios,Cocos2d Iphone,Ios Simulator,Lag,我试着按照教程写一个小翅膀类型的游戏 我被困在最后了。我没有画连绵起伏的山丘,而是画了一幅非常难看的三角形。我在下面贴了一些截图 我在教程中提到要取消注释这些东西,使其在调试器中正确显示。我已经这样做了,它还在这样做。我想知道这只是一个模拟器还是我把事情搞砸了。无论发生什么,它都是周期性渲染的,所以我认为余弦函数在数学方面一定是有效的,但这仍然不能解释这种行为。基本上,我被难住了 这是我正在使用的代码 HelloWorldLayer.h #import "cocos2d.h" #import

我试着按照教程写一个小翅膀类型的游戏

我被困在最后了。我没有画连绵起伏的山丘,而是画了一幅非常难看的三角形。我在下面贴了一些截图

我在教程中提到要取消注释这些东西,使其在调试器中正确显示。我已经这样做了,它还在这样做。我想知道这只是一个模拟器还是我把事情搞砸了。无论发生什么,它都是周期性渲染的,所以我认为余弦函数在数学方面一定是有效的,但这仍然不能解释这种行为。基本上,我被难住了

这是我正在使用的代码

HelloWorldLayer.h

#import "cocos2d.h"
#import "Terrain.h"
/*#import "Box2D.h"
#import "GLES-Render.h"*/

// HelloWorldLayer
@interface HelloWorldLayer : CCLayer
{
    CCSprite *_background;
    Terrain *_terrain;
/*b2World* world;
GLESDebugDraw *m_debugDraw;*/
}

// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;
// adds a new sprite at a given coordinate
//-(void) addNewSpriteWithCoords:(CGPoint)p;

@end
HelloWorldLayer.m

#import "HelloWorldLayer.h"

//Pixel to metres ratio. Box2D uses metres as the unit for measurement.
//This ratio defines how many pixels correspond to 1 Box2D "metre"
//Box2D is optimized for objects of 1x1 metre therefore it makes sense
//to define the ratio so that your most common object type is 1x1 metre.
#define PTM_RATIO 32

// enums that will be used as tags
/*enum {
kTagTileMap = 1,
kTagBatchNode = 1,
kTagAnimation1 = 1,
};*/


// HelloWorldLayer implementation
@implementation HelloWorldLayer


+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];

// add layer as a child to scene
[scene addChild: layer];

// return the scene
return scene;
}

-(CCSprite *)spriteWithColor:(ccColor4F)bgColor textureSize:(float)textureSize {

// 1: Create new CCRenderTexture
CCRenderTexture *rt = [CCRenderTexture renderTextureWithWidth:textureSize height:textureSize];

// 2: Call CCRenderTexture:begin
[rt beginWithClear:bgColor.r g:bgColor.g b:bgColor.b a:bgColor.a];


//Add Gradient to image

/*The basic idea is we’ll draw a black rectangle on top of the texture, but it will be completely transparent up top, and opaque at the bottom. This will keep the top untouched, but gradually darken the image going down*/
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

float gradientAlpha;
CGPoint vertices[4];
ccColor4F colors[4];
int nVertices = 0;

vertices[nVertices] = CGPointMake(0, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0 };
vertices[nVertices] = CGPointMake(textureSize, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};
vertices[nVertices] = CGPointMake(0, textureSize);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};
vertices[nVertices] = CGPointMake(textureSize, textureSize);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};

glVertexPointer(2, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);

// 3: Draw into the texture
// We'll add this later
CCSprite *noise = [CCSprite spriteWithFile:@"Noise.png"];
[noise setBlendFunc:(ccBlendFunc){GL_DST_COLOR, GL_ZERO}];
noise.position = ccp(textureSize/2, textureSize/2);
[noise visit];

// 4: Call CCRenderTexture:end
[rt end];


// 5: Create a new Sprite from the texture
return [CCSprite spriteWithTexture:rt.sprite.texture];

}


-(CCSprite *)stripedSpriteWithColor1:(ccColor4F)c1 color2:(ccColor4F)c2 
                     textureSize:(float)textureSize stripes:(int)nStripes {


// 1:Create new CCRenderTexture
CCRenderTexture *rt = [CCRenderTexture renderTextureWithWidth:textureSize height:textureSize];

// 2: Call CCRenderTexture:begin
[rt beginWithClear:c1.r g:c1.g b:c1.b a:c1.a];

// 3: Draw into the texture

// Layer 1: Stripes
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

CGPoint vertices[nStripes*6];
int nVertices = 0;
float x1 = -textureSize;
float x2;
float y1 = textureSize;
float y2 = 0;
float dx = textureSize/ nStripes*2;
float stripeWidth = dx/2;
for (int i = 0; i<nStripes; i++) {
    x2 = x1 +textureSize;
    vertices[nVertices++]=CGPointMake(x1, y1);
    vertices[nVertices++]=CGPointMake(x1+stripeWidth, y1);
    vertices[nVertices++]=CGPointMake(x2, y2);
    vertices[nVertices++]= vertices[nVertices-2];
    vertices[nVertices++]= vertices[nVertices-2];
    vertices[nVertices++]=CGPointMake(x2+stripeWidth, y2);
    x1 += dx;
}

glColor4f(c2.r, c2.g, c2.b, c2.a);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)nVertices);

// layer 2: gradient
glEnableClientState(GL_COLOR_ARRAY);

float gradientAlpha = 0.7;
ccColor4F colors[4];
nVertices = 0;

vertices[nVertices] = CGPointMake(0, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0 };
vertices[nVertices] = CGPointMake(textureSize, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};
vertices[nVertices] = CGPointMake(0, textureSize);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};
vertices[nVertices] = CGPointMake(textureSize, textureSize);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};

glVertexPointer(2, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);

// layer 3: top highlight 
float borderWidth = textureSize/16;
float borderAlpha = 0.3f;
nVertices = 0;

vertices[nVertices] = CGPointMake(0, 0);
colors[nVertices++] = (ccColor4F){1,1,1,borderAlpha};
vertices[nVertices] = CGPointMake(textureSize, 0);
colors[nVertices++] = (ccColor4F){1,1,1,borderAlpha};

vertices[nVertices] = CGPointMake(0, borderWidth);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};
vertices[nVertices] = CGPointMake(textureSize, borderWidth);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};

glVertexPointer(2, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);             

// Layer 2: Noise 
CCSprite *noise = [CCSprite spriteWithFile:@"Noise.png"];
[noise setBlendFunc:(ccBlendFunc){GL_DST_COLOR, GL_ZERO}];
noise.position = ccp(textureSize/2, textureSize/2);
[noise visit];

// 4: Call CCRenderTexture:end
[rt end];

// 5: Create a new Sprite from the texture
return [CCSprite spriteWithTexture:rt.sprite.texture];
 }


 -(ccColor4F)randomBrightColor {    
while (true) {
    float requiredBrightness = 192;
    ccColor4B randomColor = ccc4(arc4random() % 255,
                                arc4random() % 255,
                                arc4random() % 255,
                                255);
    if (randomColor.r > requiredBrightness ||
        randomColor.g > requiredBrightness ||
        randomColor.b > requiredBrightness) {
        return ccc4FFromccc4B(randomColor);
    }
}
}

-(void)genBackground {
[_background removeFromParentAndCleanup:YES];

ccColor4F bgColor = [self randomBrightColor];
/*new code*/
//ccColor4F color2 = [self randomBrightColor];
/*new code*/
_background = [self spriteWithColor:bgColor textureSize:512];
/*new code*/
// int nStripes = ((arc4random() % 4) + 1) * 2;
//_background = [self stripedSpriteWithColor1:bgColor color2:color2 textureSize:512 stripes:nStripes];

//self.scale = 0.5;
/*new code*/

CGSize winSize = [CCDirector sharedDirector].winSize;
_background.position = ccp(winSize.width/2,winSize.height/2);
ccTexParams tp = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
[_background.texture setTexParameters:&tp];

[self addChild:_background z:-1];

ccColor4F color3 = [self randomBrightColor];
ccColor4F color4 = [self randomBrightColor];
CCSprite *stripes = [self stripedSpriteWithColor1:color3 color2:color4 textureSize:512 stripes:4];
ccTexParams tp2 = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_CLAMP_TO_EDGE};
[stripes.texture setTexParameters:&tp2];
_terrain.stripes = stripes;


/*The important part is the texture parameters:
GL_LINEAR is a fancy way of saying “when displaying the texture at a smaller or larger scale than the original size, take a weighted average of the nearby pixels.”
GL_REPEAT is a fancy way of saying “if you try to index a texture at a coordinate outside the texture bounds, put what would be there if the texture were to continuously tile.”*/
}

// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {
    _terrain = [Terrain node];
    [self addChild:_terrain z:1];
    [self genBackground];
    self.isTouchEnabled = YES;
    [self scheduleUpdate];
}

self.scale = 1.0; 
return self;



}

-(void)update:(ccTime)dt {
float PIXELS_PER_SECOND = 100;
static float offset = 0;
offset += PIXELS_PER_SECOND * dt;

CGSize textureSize = _background.textureRect.size;
[_background setTextureRect:CGRectMake(offset, 0, textureSize.width, textureSize.height)];
[_terrain setOffsetX:offset];
}

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self genBackground];
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
/*delete world;
world = NULL;

delete m_debugDraw;*/

// don't forget to call "super dealloc"
[super dealloc];
}
@end
地形

#import "Terrain.h"
#import "HelloWorldLayer.h"

@implementation Terrain
@synthesize stripes = _stripes;

-(void)generateHills {

/*


 The strategy in this algorithm is the following:
Increment x-axis in the range of 160 + a random number between 0-40
Increment y-axis in the range of 60 + a random number between 0-40
Except: reverse the y-axis offset every other time.
Don’t let the y value get too close to the top or bottom (paddingTop, paddingBottom)
Start offscreen to the left, and hardcode the second point to (0, winSize.height/2), so      there’s a hill coming up from the left offscreen.*/

CGSize winSize = [CCDirector sharedDirector].winSize;

float minDX = 160;
float minDY = 60;
int rangeDX = 80;
int rangeDY= 40;

float x = -minDX;
float y = winSize.height/2 - minDY;

float dy, ny;
float sign = 1;// +1 - going up, -1 - going  down
float paddingTop = 20;
float paddingBottom = 20;

for (int i=0; i<kMaxHillKeyPoints; i++) {
    _hillKeyPoints[i] = CGPointMake(x, y);
    if (i == 0) {
        x = 0;
        y = winSize.height/2;
    } else {
        x+=rand()%rangeDX+minDX;
        while (true) {
            dy = rand()%rangeDY + minDY;
            ny = y + dy*sign;
            if (ny < winSize.height - paddingTop && ny > paddingBottom) {
                break;
            }
        }

        y = ny;
    }

    sign *= -1;
}

/*float x = 0;
float y = winSize.width/2;
for (int i = 0; i<kMaxHillKeyPoints; ++i) {
    _hillKeyPoints[i] = CGPointMake(x, y);
    x += winSize.width/2;
    y = random() % (int) winSize.height;
}*/
}

-(void)resetHillVertices {

CGSize winSize = [CCDirector sharedDirector].winSize;

static int prevFromKeyPointI = -1;
static int prevToKeyPointI = -1;


// key points interval for drawing

    // key points interval for drawing
   while (_hillKeyPoints[_fromKeyPointI+1].x < _offsetX-winSize.width/8/self.scale) {
    _fromKeyPointI++;
     }
    while (_hillKeyPoints[_toKeyPointI].x < _offsetX+winSize.width*9/8/self.scale) {
    _toKeyPointI++;
    }


if (prevFromKeyPointI != _fromKeyPointI || prevToKeyPointI != _toKeyPointI) {

    // vertices for visible area
    _nHillVertices = 0;
    _nBorderVertices =0;
    CGPoint p0, p1, pt0, pt1;
    p0 = _hillKeyPoints[_fromKeyPointI];
    for (int i = _fromKeyPointI+1; i<_toKeyPointI+1; i++) {
        p1 = _hillKeyPoints[i];

        // triangle strip between p0 and p1
        int hSegments = floorf((p1.x-p0.x)/kHillSegmentWidth);
        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;

            _hillVertices[_nHillVertices] = CGPointMake(pt0.x, 0);
            _hillTexCoords[_nHillVertices++] = CGPointMake(pt0.x/512, 1.0f);
            _hillVertices[_nHillVertices] = CGPointMake(pt1.x, 0);
            _hillTexCoords[_nHillVertices++] = CGPointMake(pt1.x/512, 1.0f);

            _hillVertices[_nHillVertices] = CGPointMake(pt0.x, pt0.y);
            _hillTexCoords[_nHillVertices++] = CGPointMake(pt0.x/512, 0);
            _hillVertices[_nHillVertices] = CGPointMake(pt1.x, pt1.y);
            _hillVertices[_nHillVertices++] = CGPointMake(pt1.x/512, 0);

            pt0 = pt1;
        }
        p0 = p1;
    }

    prevFromKeyPointI = _fromKeyPointI;
    prevToKeyPointI = _toKeyPointI;
}



}

-(id)init {
if ((self = [super init])) {
    [self generateHills];
}
[self resetHillVertices];

return self;

}

-(void) draw {



glBindTexture(GL_TEXTURE_2D, _stripes.texture.name);
glDisableClientState(GL_COLOR_ARRAY);

glColor4f(1, 1, 1, 1);
glVertexPointer(2, GL_FLOAT, 0, _hillVertices);
glTexCoordPointer(2, GL_FLOAT, 0, _hillTexCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)_nHillVertices);
   // glEnableClientState(GL_COLOR_ARRAY);


for (int i= MAX(_fromKeyPointI, 1); i <= _toKeyPointI; ++i) {


    glColor4f(1.0, 0, 0, 1.0);
    //ccDrawLine(_hillKeyPoints[i-1], _hillKeyPoints[i]);

    glColor4f(1.0, 1.0, 1.0, 1.0);

    CGPoint p0 = _hillKeyPoints[i-1];
    CGPoint p1 = _hillKeyPoints[i];
    int hSegments = floorf((p1.x-p0.x)/kHillSegmentWidth);
    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;

    CGPoint pt0, pt1;
    pt0 = p0;
    for (int j= 0; j<hSegments+1; ++j) {
        pt1.x = p0.x +j*dx;
        pt1.y = ymid + ampl * cosf(da*j);

        //ccDrawLine(pt0, pt1);

        pt0 = pt1;
    }

}
}

-(void)setOffsetX:(float)newOffsetX {
_offsetX = newOffsetX;
self.position = CGPointMake(-_offsetX*self.scale, 0);
[self resetHillVertices];
}
-(void) dealloc {
[_stripes release];
_stripes = NULL;
[super dealloc];
}

@end

只是一种预感,你可能正在使用CoCoS2D2.0吗


因为您发布的代码使用OpenGL ES 1.1命令,而当您使用COCOS2D2.x时,该命令将无法正常工作。如果您使用的是CoCoS2D2.0,请在v1.x中再试一次。

只是一种预感,您是否正在使用CoCoS2D2.0


因为您发布的代码使用OpenGL ES 1.1命令,而当您使用COCOS2D2.x时,该命令将无法正常工作。如果您使用的是cocos2d 2.0,请使用v1.x重试。

解决了问题

  _hillVertices[_nHillVertices] = CGPointMake(pt0.x, 0);
        _hillTexCoords[_nHillVertices++] = CGPointMake(pt0.x/512, 1.0f);
        _hillVertices[_nHillVertices] = CGPointMake(pt1.x, 0);
        _hillTexCoords[_nHillVertices++] = CGPointMake(pt1.x/512, 1.0f);

        _hillVertices[_nHillVertices] = CGPointMake(pt0.x, pt0.y);
        _hillTexCoords[_nHillVertices++] = CGPointMake(pt0.x/512, 0);
        _hillVertices[_nHillVertices] = CGPointMake(pt1.x, pt1.y);
        _hillVertices[_nHillVertices++] = CGPointMake(pt1.x/512, 0); //This line should be 
                                                                     //modifying the
                                                                     //_hillTexCoords
                                                                     //array 

解决了问题

  _hillVertices[_nHillVertices] = CGPointMake(pt0.x, 0);
        _hillTexCoords[_nHillVertices++] = CGPointMake(pt0.x/512, 1.0f);
        _hillVertices[_nHillVertices] = CGPointMake(pt1.x, 0);
        _hillTexCoords[_nHillVertices++] = CGPointMake(pt1.x/512, 1.0f);

        _hillVertices[_nHillVertices] = CGPointMake(pt0.x, pt0.y);
        _hillTexCoords[_nHillVertices++] = CGPointMake(pt0.x/512, 0);
        _hillVertices[_nHillVertices] = CGPointMake(pt1.x, pt1.y);
        _hillVertices[_nHillVertices++] = CGPointMake(pt1.x/512, 0); //This line should be 
                                                                     //modifying the
                                                                     //_hillTexCoords
                                                                     //array