我有几个物体从屏幕顶部“掉落”,当它们被敲击时,闪电击中它们。我的问题是,当其中一个物体被敲击并且闪电击中时,我的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);
}
答案 0 :(得分:1)
你正在做太多计算以获得你想要的效果
我不想让你重写你的代码..但是通过点
来看待贝塞尔曲线here就是我的意思(将张力设置为0.5或smth ..以获得闪电般的效果)
这样做......或者只是制作一堆或随机生成的图像(闪电),然后将它们放在图像的顶部以获得闪电效果。你所做的对于小型设备而言太贵了
答案 1 :(得分:1)
如果您将闪电作为PNG图像导入批处理节点纹理,您的FPS将大大提高。假设您同时从不同方向发射多个闪电图像,这只会导致一次调用OpenGL,并且该调用将没有绘图逻辑,因为图像已经在应用程序外部创建。