1

画面の上部から「落下」するオブジェクトがいくつかあり、それらをタップすると落雷が発生します。私の問題は、オブジェクトの1つがタップされ、落雷が発生すると、FPSが低下し、ゲームが遅れることです。

誰かが私がこの遅れを減らすのを手伝ってくれるか、私を正しい方向に導くことができますか?私はそれを修正する方法についての手がかりがありません。私のゲームは終了しました、そしてこれは私を妨げている唯一のものです...

これが稲妻のコードです。

Lightning.h

//
//  Lightning.h
//  Trundle
//
//  Created by Robert Blackwood on 12/1/09.
//  Copyright 2009 Mobile Bros. All rights reserved.
//

#import "cocos2d.h"

/*! This will draw lighting and return the midpoint */
CGPoint drawLightning(CGPoint pt1, CGPoint pt2, int displace, int minDisplace, unsigned long randSeed, float width);
void drawSmoothLine(CGPoint *pos1, CGPoint *pos2, float width);
void drawSmoothPointAt(CGPoint *pos, float width);
void fillSmoothRectangle(CGRect *r, float width);

@interface Lightning : CCNode <CCRGBAProtocol>
{
    CGPoint _strikePoint;
    CGPoint _strikePoint2;
    CGPoint _strikePoint3;

    ccColor3B   _color;
    GLubyte     _opacity;
    BOOL        _split;
    BOOL        _glow;

    int _displacement;
    int _minDisplacement;
    float _lighteningWidth;

    unsigned long _seed;
}

@property (readwrite, assign) CGPoint strikePoint;
@property (readwrite, assign) CGPoint strikePoint2;
@property (readwrite, assign) CGPoint strikePoint3;
@property (readwrite, assign) ccColor3B color;
@property (readwrite, assign) GLubyte opacity;
@property (readwrite, assign) BOOL split;
@property (readwrite, assign) BOOL glow;
@property (readwrite, assign) int displacement;
@property (readwrite, assign) int minDisplacement;
@property (readwrite, assign) float lighteningWidth;
@property (readwrite, assign) unsigned long seed;

+(id) lightningWithStrikePoint:(CGPoint)strikePoint strikePoint2:(CGPoint)strikePoint2;

-(id) initWithStrikePoint:(CGPoint)strikePoint strikePoint2:(CGPoint)strikePoint2;

-(void) strikeRandom;
-(void) fade;

@end

Lightning.m

//
//  Lightning.m
//  Trundle
//
//  Created by Robert Blackwood on 12/1/09.
//  Copyright 2009 Mobile Bros. All rights reserved.
//

#import "Lightning.h"

@implementation Lightning

@synthesize strikePoint = _strikePoint;
@synthesize strikePoint2 = _strikePoint2;
@synthesize strikePoint3 = _strikePoint3;
@synthesize color = _color;
@synthesize opacity = _opacity;
@synthesize displacement = _displacement;
@synthesize minDisplacement = _minDisplacement;
@synthesize lighteningWidth = _lighteningWidth;
@synthesize seed = _seed;
@synthesize split = _split;
@synthesize glow = _glow;

+(id) lightningWithStrikePoint:(CGPoint)strikePoint strikePoint2:(CGPoint)strikePoint2
{
    return [[[self alloc] initWithStrikePoint:strikePoint strikePoint2:strikePoint2] autorelease];
}

-(id) initWithStrikePoint:(CGPoint)strikePoint strikePoint2:(CGPoint)strikePoint2
{
    if ((self = [super init]))
    {
        _strikePoint = strikePoint;
        _strikePoint2 = ccp(0, 0);
        _strikePoint3 = strikePoint2;

        _color = ccc3(255, 190, 255);

        //random style
        _displacement = 100 + CCRANDOM_0_1() * 200;
        _minDisplacement = 4 + CCRANDOM_0_1() * 10;
        _lighteningWidth = 2.0f;
        _split = YES;
        _glow = YES;

        [self strikeRandom];
    }

    return self;
}

-(void) draw
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glColor4ub(_color.r, _color.g, _color.b, _opacity);

    drawLightning(_strikePoint3, _strikePoint, _displacement, _minDisplacement, _seed, _lighteningWidth);

    if (_glow)
    {
        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
        glColor4ub(50, 0, 255, _opacity);
        drawLightning(_strikePoint3, _strikePoint, _displacement, _minDisplacement, _seed, 7);
    }

    if (_opacity != 255)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    if (_opacity != 255)
        glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);

    glColor4f(1.0, 1.0, 1.0, 1.0);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);
}

-(void) strikeRandom
{
    _glow = YES;
    _seed = rand();
    [self fade];
}

- (void) removeLightning {
    self.visible = NO;
}

- (void) fade
{
    self.visible = YES;
    self.opacity = 255;

    [self runAction:[CCSequence actions: 
                    // [DelayTime actionWithDuration:1.0],
                     [CCShow action],
                     [CCFadeOut actionWithDuration:0.5],
                     [CCCallFunc actionWithTarget:self selector:@selector(removeLightning)],
                     nil]];
}

-(void)dealloc
{
    [super dealloc];
}

@end

int getNextRandom(unsigned long *seed)
{
    //taken off a linux site (linux.die.net)
    (*seed) = (*seed) * 1103515245 + 12345;
    return ((unsigned)((*seed)/65536)%32768);
}

CGPoint drawLightning(CGPoint pt1, CGPoint pt2, int displace, int minDisplace, unsigned long randSeed, float width)
{   
    CGPoint mid = ccpMult(ccpAdd(pt1,pt2), 0.5f);

    if (displace < minDisplace)
    {
        //ccDrawLine(pt1, pt2);
        drawSmoothLine(&pt1, &pt2, width);
        drawSmoothPointAt(&mid, width);
    }
    else
    {
        int r = getNextRandom(&randSeed);
        mid.x += (((r % 101)/100.0)-.5)*displace;
        r = getNextRandom(&randSeed);
        mid.y += (((r % 101)/100.0)-.5)*displace;

        drawLightning(pt1,mid,displace/2,minDisplace,randSeed,width);
        drawLightning(pt2,mid,displace/2,minDisplace,randSeed,width);
    }

    return mid;
} 

void drawSmoothLine(CGPoint *pos1, CGPoint *pos2, float width)
{
    GLfloat lineVertices[12], currentColor[4]; 
    GLint   red, green, blue, alpha;
    CGPoint dir, tan;

    dir.x = pos2->x - pos1->x;
    dir.y = pos2->y - pos1->y;
    float len = sqrtf(dir.x * dir.x + dir.y * dir.y);
    if(len < 0.00001)
        return;
    dir.x = dir.x / len;
    dir.y = dir.y / len;
    tan.x = -width * dir.y;
    tan.y = width * dir.x;

    lineVertices[0] = pos1->x + tan.x;
    lineVertices[1] = pos1->y + tan.y;
    lineVertices[2] = pos2->x + tan.x;
    lineVertices[3] = pos2->y + tan.y;
    lineVertices[4] = pos1->x;
    lineVertices[5] = pos1->y;
    lineVertices[6] = pos2->x;
    lineVertices[7] = pos2->y;
    lineVertices[8] = pos1->x - tan.x;
    lineVertices[9] = pos1->y - tan.y;
    lineVertices[10] = pos2->x - tan.x;
    lineVertices[11] = pos2->y - tan.y;

    glGetFloatv(GL_CURRENT_COLOR, currentColor);
    red = 255.0 * currentColor[0];
    green = 255.0 * currentColor[1];
    blue = 255.0 * currentColor[2];
    alpha = 255.0 * currentColor[3];

    const GLubyte lineColors[] = {
        red, green, blue, 0,
        red, green, blue, 0,
        red, green, blue, alpha,
        red, green, blue, alpha,
        red, green, blue, 0,
        red, green, blue, 0,
    };

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, lineVertices);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, lineColors);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);

    glDisableClientState(GL_COLOR_ARRAY);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);
}

void drawSmoothPointAt(CGPoint *position, float width)
{
    GLfloat pntVertices[2*6], currentColor[4]; 
    GLint   red, green, blue, alpha;

    pntVertices[0] = position->x;
    pntVertices[1] = position->y;
    pntVertices[2] = position->x - width;
    pntVertices[3] = position->y - width;
    pntVertices[4] = position->x - width;
    pntVertices[5] = position->y + width;
    pntVertices[6] = position->x + width;
    pntVertices[7] = position->y + width;
    pntVertices[8] = position->x + width;
    pntVertices[9] = position->y - width;
    pntVertices[10] = position->x - width;
    pntVertices[11] = position->y - width;

    glGetFloatv(GL_CURRENT_COLOR, currentColor);
    red = 255.0 * currentColor[0];
    green = 255.0 * currentColor[1];
    blue = 255.0 * currentColor[2];
    alpha = 255.0 * currentColor[3];

    const GLubyte pntColors[] = {
        red, green, blue, alpha,
        red, green, blue, 0,
        red, green, blue, 0,
        red, green, blue, 0,
        red, green, blue, 0,
        red, green, blue, 0,
    };

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, pntVertices);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, pntColors);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

    glDisableClientState(GL_COLOR_ARRAY);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);
}
4

2 に答える 2

1

あなたはあなたが望む効果を得るためにあまりにも多くの計算をしている

私はあなたにあなたのコードを書き直させたくありません..しかし、ポイントを通してベジェ曲線を調べてください

これが私の意味です(稲妻のような効果を得るには、張力を0.5またはsmthに設定します)

それを行うか、または単に束またはランダムに生成された画像(稲妻)を作成し、それらを画像の上に置いて稲妻の効果を得るだけです..あなたがしていることは小さなデバイスには高すぎます

于 2012-04-30T02:17:24.850 に答える
1

稲妻をバッチノードテクスチャのPNG画像としてインポートすると、FPSが劇的に向上します。異なる方向から同時に発火する複数の稲妻画像があるとすると、OpenGLへの合計呼び出しは1回だけになり、画像はアプリの外部ですでに作成されているため、その呼び出しには描画ロジックがありません。

于 2012-05-01T08:10:16.757 に答える