1. 程式人生 > >cocos2dx 跟隨光線效果實現

cocos2dx 跟隨光線效果實現

     在實際遊戲程式設計中,有很多效果是需要自己程式設計實現而非幀動畫,特別是可通過引數控制效果的動畫。此篇文章主要說明下《忍者必須死》流線光效果的實現原理。

效果圖如下:


因為這種效果是動態的,所以需要實時繪製出來,也就是使用gl的一些繪圖函數了,主要還是計算好頂點的位置和顏色。

先定義頂點結構,此後告訴gl頂點是怎麼定義的、因為這裡不使用紋理,就不要紋理座標了。

typedef struct{
float Position[3];
float Color[4];
} Vertex;

需要用到索引陣列以簡化資料的傳遞,索引的建立就按照三角形的逆序依次輸入就行。先假設一根光線使用21的頂點。

Vertex trackpt[21];

for(int i=0;i<=20;++i){
trackpt[i].Position[0]=0;
trackpt[i].Position[1]=0;
trackpt[i].Position[2]=0;
trackpt[i].Color[0]=0;
trackpt[i].Color[1]=1;
trackpt[i].Color[2]=0;
trackpt[i].Color[3]=(float)i/30.0;

}

在每一幀繪製的地方設定跟蹤最前面一頂點

for(int i=0;i<20;++i)
{
trackpt[i].Position[0]=trackpt[i+1].Position[0];
trackpt[i].Position[1]=trackpt[i+1].Position[1];

更新最前面一頂點的位置,這裡可以自己定義光線的形狀,先假設就是上面效果圖的那種。

std::vector<Vertex> ttt;
tiarr.clear();
for(int i=0;i<=20;++i)
{
if(d==0)
{
ttt.push_back(trackpt[i]);
}
else
{
float x3,y3,x4,y4;
if(trackpt[i].Position[0]==trackpt[20].Position[0])
{
d=0;
}
tempfunc(trackpt[i-1].Position[0],trackpt[i-1].Position[1],
trackpt[i].Position[0],trackpt[i].Position[1],d,
x3,y3,x4,y4);
Vertex vt1={{x3,y3,0}, {color.x,color.y, color.z, 0}, {1, 0}};
Vertex vt2={{x4,y4,0}, {color.x,color.y, color.z, 0}, {1, 0}};
             
if(trackpt[i].Position[0]==trackpt[20].Position[0])
{
vt1.Color[3]=0;
vt2.Color[3]=0;
}
trackpt[i].Color[0]=color.x;
trackpt[i].Color[1]=color.y;
trackpt[i].Color[2]=color.z;
ttt.push_back(vt1); ttt.push_back(trackpt[i]); ttt.push_back(vt2);
if(i-1==0)
{
tiarr.push_back(0);
tiarr.push_back(1);
tiarr.push_back(2);
tiarr.push_back(0);
tiarr.push_back(2);
tiarr.push_back(3);
}
else
{
int imax=3*i;
tiarr.push_back(imax-4);  tiarr.push_back(imax-3); tiarr.push_back(imax-1);
tiarr.push_back(imax-3);  tiarr.push_back(imax-1); tiarr.push_back(imax);
tiarr.push_back(imax-4);  tiarr.push_back(imax-5); tiarr.push_back(imax-2);
tiarr.push_back(imax-4);  tiarr.push_back(imax-2); tiarr.push_back(imax-1);
}
}
       d+=((float)i+1)*maxdis*0.001;
}

頂點設定完畢,接著使用gl繪製

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex)*ttt.size(),ttt.data(), GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*tiarr.size(),tiarr.data(),GL_STATIC_DRAW);

glDrawElements(GL_TRIANGLES,tiarr.size(), GL_UNSIGNED_SHORT, 0);

如果沒有意外的話,您 將會看到上圖的 流線光效果了。實際效果如下: