做游戏新手引导式必不可少的一部分,使用opengl封装一个新手引导类,可以通用,代码如下:
.h文件
#ifndef __GUIDE_H__
#define __GUIDE_H__
#include "cocos2d.h"
#include "cocos-ext.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "gles/gl.h"
#endif
#include "global.h"
using namespace cocos2d::extension;
USING_NS_CC;
struct Rect{
float rx,ry,rwidth,rheight;
Rect(float x,float y,float width,float height)
{
rx=x;
ry=y;
rwidth=width;
rheight=height;
}
bool operator< (const Rect& r) const{return rx<r.rx;}
bool containsPoint(const CCPoint& point) const
{
bool bRet = false;
if (point.x >= rx && point.x <=rx+rwidth
&& point.y >= ry && point.y <=ry+rheight)
{
bRet = true;
}
return bRet;
}
};
class Guide : public cocos2d::CCLayer
{
public:
~Guide();
void clear();
static void reset();
static GLuint vertexBuffer;
static GLuint indexBuffer;
float gx,gy,m_width,m_height;
float cd,m_precd;
bool bsrcclick;
static int param;
static Guide* gthis;
CCRect m_src;
int m_type;
float sumlen,curlen;
std::string talkstr;
CCLabelTTF* m_talk;
float tscalex,tscaley,transval;
static CCGLProgram * pg;
static void sreset();
virtual bool init();
void SetTransparent(float val);
void update(float delta);
std::map<Rect,CCCallFuncND*> m_monitor,m_premonitor;
std::map<Rect,CCCallFuncND*> m_strike,m_prestrike;
void delayjoin1(float dt);
void delayjoin2(float dt);
void AddMonitor(Rect rc,CCCallFuncND* cn);
void AddPierce( Rect rc,CCCallFuncND* cn);
char* AlignTxt(char* text,float width);
void onEnter();
CREATE_FUNC(Guide);
void SetFocus(float x,float y,float width,float height,bool flag=true,int type=0,CCTexture2D* tex=0);//type:0椭圆 1矩形 2图片形状
CCNode* CreateLabel(char* text,float x,float y,float width=0);
CCNode* CreateArrow(float x,float y,float angle=0);
static CCRenderTexture * m_circle;
static CCRenderTexture * m_arrow;
static CCRenderTexture * m_rc;
CCTexture2D* texture2d;//做剪裁形状
static void drawcircle();
static void drawarrow();
static void drawrc();
virtual void draw();
void onDraw();
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
void createHand(int dir,CCPoint pt=ccp(-1,-1));
void createTutor(char *txt,bool ani=false);
static CCScale9Sprite* CreateTextSprite(char *text,float width=0);
static CCLabelTTF* GetFitLabel(char *text,float width);
};
#endif // __GUIDE_H__
.cpp文件
#include "Guide.h"
const char* shader_frag="\n#ifdef GL_ES\n\
precision lowp float;\
\n#endif\n\
uniform sampler2D CC_Texture0;\
uniform float tval;\
varying vec4 v_fragmentColor;\
varying vec2 v_texCoord;\
void main()\
{\
vec4 color=texture2D(CC_Texture0,v_texCoord);\
gl_FragColor =vec4(0.0,0.0,0.0,(1.0-color.a)*tval);\
}";
const char* shader_vert="attribute vec4 a_position;\
attribute vec2 a_texCoord;\
attribute vec4 a_color;\
\n#ifdef GL_ES\n\
varying lowp vec4 v_fragmentColor;\
\n#else\n\
varying vec4 v_fragmentColor;\
\n#endif\n\
varying vec2 v_texCoord;\
void main()\
{\
gl_Position = CC_MVPMatrix * a_position;\
v_fragmentColor = a_color;\
v_texCoord = a_texCoord;\
}";
unsigned char utf8_look_for_table[] =
{
1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
};
#define UTFLEN(x) utf8_look_for_table[(x)]
int getUtf8Length(char *str)
{
int clen = strlen(str);
int len = 0;
for(char *ptr = str;*ptr!=0&&len<clen;len++, ptr+=UTFLEN((unsigned char)*ptr));
return len;
}
char* subUtfString(const char *str, unsigned int start, unsigned int end)
{
int len = getUtf8Length((char*)str);
if(start >= len) return NULL;
if(end > len) end = len;
char *sptr = (char*)str;
for(int i = 0; i < start; ++i,sptr+=UTFLEN((unsigned char)*sptr));
char *eptr = sptr;
for(int i = start; i < end; ++i,eptr += UTFLEN((unsigned char)*eptr));
int retLen = eptr - sptr;
char *retStr = (char*)malloc(retLen+1);
memcpy(retStr, sptr, retLen);
retStr[retLen] = 0;
return retStr;
}
CCGLProgram *Guide::pg=0;
CCRenderTexture *Guide::m_circle=0;
CCRenderTexture *Guide::m_arrow=0;
CCRenderTexture *Guide::m_rc=0;
GLuint Guide::vertexBuffer=0;
GLuint Guide::indexBuffer=0;
void Guide::clear()
{
/*
std::map<Rect,CCCallFuncND*>::iterator it;
for(it=m_monitor.begin();it!=m_monitor.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
for(it=m_strike.begin();it!=m_strike.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
m_monitor.clear();
m_strike.clear();*/
}
Guide::~Guide()
{
/*GLuint garr[]={vertexBuffer,indexBuffer};
glDeleteBuffers(2,garr);*/
gthis=0;
std::map<Rect,CCCallFuncND*>::iterator it;
for(it=m_monitor.begin();it!=m_monitor.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
for(it=m_strike.begin();it!=m_strike.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
m_monitor.clear();
m_strike.clear();
}
void Guide::drawcircle()
{
return;
int seg=20;
float a=180,b=180,xoff=200,yoff=200,scope=20;
a+=scope; b+=scope;
float gap=2*a/seg;
int k=2*a/gap+1;
int sumct1=2*k-1;
a-=scope; b-=scope;
gap=2*a/seg;
k=2*a/gap+1;
int sumct=2*k;
Vertex *vt=new Vertex[sumct+sumct1];
GLushort* cindex=new GLushort[sumct1*2];
vt[0].Position[0]=xoff;
vt[0].Position[1]=yoff;
vt[0].Position[2]=0;
vt[0].Color[0]=1;
vt[0].Color[1]=1;
vt[0].Color[2]=0;
vt[0].Color[3]=1;
int count=1;
for(float i=a+xoff;i>=-a+xoff;i-=gap)
{
vt[count].Position[0]=i;
vt[count].Position[1]=sqrt(1-pow((i-xoff)/a,2))*b+yoff;
vt[count].Position[2]=0;
vt[count].Color[0]=0;
vt[count].Color[1]=1;
vt[count].Color[2]=0;
vt[count].Color[3]=0.9;
++count;
}
for(float i=-a+xoff+gap;i<=a+xoff;i+=gap)
{
vt[count].Position[0]=i;
vt[count].Position[1]=-sqrt(1-pow((i-xoff)/a,2))*b+yoff;
vt[count].Position[2]=0;
vt[count].Color[0]=0;
vt[count].Color[1]=1;
vt[count].Color[2]=0;
vt[count].Color[3]=0.9;
++count;
}
a+=scope; b+=scope; gap=2*a/seg;
for(float i=a+xoff;i>=-a+xoff;i-=gap)
{
vt[count].Position[0]=i;
vt[count].Position[1]=sqrt(1-pow((i-xoff)/a,2))*b+yoff;
vt[count].Position[2]=0;
vt[count].Color[0]=0;
vt[count].Color[1]=1;
vt[count].Color[2]=0;
vt[count].Color[3]=0;
++count;
}
for(float i=-a+xoff+gap;i<=a+xoff;i+=gap)
{
vt[count].Position[0]=i;
vt[count].Position[1]=-sqrt(1-pow((i-xoff)/a,2))*b+yoff;
vt[count].Position[2]=0;
vt[count].Color[0]=0;
vt[count].Color[1]=1;
vt[count].Color[2]=0;
vt[count].Color[3]=0;
++count;
}
int ct1=1,ct2=sumct;
for(int i=0;i<sumct1*2;++i)
{
if(i%2==0)
cindex[i]=ct1++;
else
{
cindex[i]=ct2++;
}
}
CCGLProgram *tpg=CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionColor);
tpg->use();
tpg->setUniformsForBuiltins();
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex)*(sumct+sumct1),vt, GL_STATIC_DRAW);
GLint _positionLocation = glGetAttribLocation(tpg->getProgram(), "a_position");
GLint _colorLocation = glGetAttribLocation(tpg->getProgram(), "a_color");
glEnableVertexAttribArray(_positionLocation);
glEnableVertexAttribArray(_colorLocation);
glVertexAttribPointer(_positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Position));
glVertexAttribPointer(_colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Color));
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH,GL_NICEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH,GL_NICEST);
glDrawArrays(GL_TRIANGLE_FAN,0,sumct);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*sumct1*2,cindex,GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLE_STRIP,sumct1*2, GL_UNSIGNED_SHORT, 0);
delete []vt;
delete []cindex;
glDisable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Guide::drawarrow()
{
return;
Vertex vt[]={
{{25,3,0},{1,1,1,1},{1,1}},
{{75,3,0},{1,1,1,1},{1,1}},
{{75,75,0},{1,1,1,1},{1,1}},
{{100,75,0},{1,1,1,1},{1,1}},
{{50,100,0},{1,1,1,1},{1,1}},
{{3,75,0},{1,1,1,1},{1,1}},
{{25,75,0},{1,1,1,1},{1,1}}
};
GLushort index[]={
0,1,6,1,2,6,3,4,5
};
CCGLProgram *tpg=CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionColor);
tpg->use();
tpg->setUniformsForBuiltins();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH,GL_NICEST);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(vt),vt, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index),index,GL_STATIC_DRAW);
GLint _positionLocation = glGetAttribLocation(tpg->getProgram(), "a_position");
GLint _colorLocation = glGetAttribLocation(tpg->getProgram(), "a_color");
glEnableVertexAttribArray(_positionLocation);
glEnableVertexAttribArray(_colorLocation);
glVertexAttribPointer(_positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Position));
glVertexAttribPointer(_colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Color));
glDrawElements(GL_TRIANGLES,9, GL_UNSIGNED_SHORT, 0);
for(int i=0;i<7;++i)
{
vt[i].Color[0]=0;
vt[i].Color[1]=0;
vt[i].Color[2]=0; vt[i].Color[3]=1;
}
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(vt),vt, GL_STATIC_DRAW);
glLineWidth(1);
glDrawArrays(GL_LINE_LOOP,0,7);
glDisable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Guide::drawrc()
{
return;
Vertex vt[]={
{{2,2,0},{0,0,0,1},{1,1}},
{{398,2,0},{0,0,0,1},{1,1}},
{{2,398,0},{0,0,0,1},{1,1}},
{{398,398,0},{0,0,0,1},{1,1}},
};
GLushort lindex[]={
0,1,3,2
};
CCGLProgram *tpg=CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionColor);
tpg->use();
tpg->setUniformsForBuiltins();
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(vt),vt, GL_STATIC_DRAW);
GLint _positionLocation = glGetAttribLocation(tpg->getProgram(), "a_position");
GLint _colorLocation = glGetAttribLocation(tpg->getProgram(), "a_color");
glEnableVertexAttribArray(_positionLocation);
glEnableVertexAttribArray(_colorLocation);
glVertexAttribPointer(_positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Position));
glVertexAttribPointer(_colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Color));
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
for(int i=0;i<4;++i)
{
vt[i].Color[0]=0.3;
vt[i].Color[1]=0.6;
vt[i].Color[2]=0.2;
vt[i].Color[3]=1;
}
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(vt),vt, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(lindex),lindex,GL_STATIC_DRAW);
glLineWidth(1);
glDrawElements(GL_LINE_LOOP,4, GL_UNSIGNED_SHORT, 0);
glDisable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
CCLabelTTF* Guide::GetFitLabel(char *text,float width)
{
CCLabelTTF* pLabel = CCLabelTTF::create(text, "Arial", 24);
std::string tempstr=std::string(text),srcstr(text),rs;
int flag=0,flag1=0,curlen=0,slen=0,offset=0;
while(1)
{
int tplen=getUtf8Length((char*)tempstr.c_str());
if(pLabel->getContentSize().width>=width&&tplen>0)
{
if(flag1==1)
{
flag=flag1=0;
slen=slen-curlen;
for(int i=1;i<curlen;++i)
{
slen+=1;
tempstr=subUtfString(srcstr.c_str(),offset,offset+slen);
pLabel->setString(tempstr.c_str());
if(pLabel->getContentSize().width>width)
{
slen-=1;
break;
}
}
tempstr=subUtfString(srcstr.c_str(),offset,offset+slen);
rs.append(tempstr);
rs.append("\n");
offset+=slen;
tempstr=subUtfString(srcstr.c_str(),offset,-1);
pLabel->setString(tempstr.c_str());
continue;
}
curlen=getUtf8Length((char*)tempstr.c_str())/2;
tempstr=subUtfString(srcstr.c_str(),offset,offset+curlen);
pLabel->setString(tempstr.c_str());
flag=1;
continue;
}
if(pLabel->getContentSize().width<width&&tplen>0&&flag==1)
{
if(curlen<=1)
curlen=1;
else
curlen=curlen/2;
slen=tplen+curlen;
tempstr=subUtfString(srcstr.c_str(),offset,offset+slen);
pLabel->setString(tempstr.c_str());
flag1=1;
continue;
}
if(pLabel->getContentSize().width<width&&tplen>0)
{
tempstr=subUtfString(srcstr.c_str(),offset,-1);
rs.append(tempstr);
break;
}
}
pLabel->setString(rs.c_str());
pLabel->setAnchorPoint(CCPointZero);
pLabel->setHorizontalAlignment(kCCTextAlignmentLeft);
return pLabel;
}
CCScale9Sprite* Guide::CreateTextSprite(char *text,float width)
{
CCTexture2D *tx=m_rc->getSprite()->getTexture();
CCSize sz=tx->getContentSize();
//CCScale9Sprite* sp = CCScale9Sprite::createWithSpriteFrame(
// CCSpriteFrame::createWithTexture(tx,CCRect(0,0,sz.width,sz.height)));
char bkname[32]="guide/22.png";
if(width>=960)
strcpy(bkname,"guide/222.png");
CCScale9Sprite* sp = CCScale9Sprite::create(bkname);
sp->setAnchorPoint(ccp(0,0));
if(width<960)
sp->setOpacity(200);
sp->setInsetBottom(9);
sp->setInsetRight(9);
sp->setInsetTop(9);
sp->setInsetLeft(9);
CCSize bksize=sp->getContentSize();
if(width==0)
{
width=bksize.width;
}
CCLabelTTF* pLabel=GetFitLabel(text,width);
CCSize extenSize = CCSizeMake(pLabel->getContentSize().width+20,pLabel->getContentSize().height+20);
sp->setContentSize(extenSize);
sp->addChild(pLabel,10);
pLabel->setPosition(ccpAdd(sp->getPosition(),ccp(10,10)));
return sp;
}
void Guide::draw()
{
CCLayer::draw();
onDraw();
if(curlen<sumlen)
{
curlen+=0.2;
char *sub = subUtfString(talkstr.c_str(), 0,curlen);
m_talk->setString(sub);
}
}
void Guide::update(float delta)
{
cd+=delta;
if(cd>3)
{
unscheduleUpdate();
}
}
void Guide::onDraw()
{
return ;
CCDirector* director = CCDirector::sharedDirector();
CCSize sz=director->getWinSize();
CCSize psz=texture2d->getContentSize();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
float w1=psz.width,h1=psz.height,w=sz.width,h=sz.height;
pg->use();
pg->setUniformsForBuiltins();
GLint _positionLocation = glGetAttribLocation(pg->getProgram(), "a_position");
GLint _colorLocation = glGetAttribLocation(pg->getProgram(), "a_color");
GLint _textureLocation = glGetAttribLocation(pg->getProgram(), "a_texCoord");
GLint _textureUniform = glGetUniformLocation(pg->getProgram(), "CC_Texture0");
GLint tval = glGetUniformLocation(pg->getProgram(), "tval");
glUniform1f(tval,transval);
float tx=gx-w1/2,ty=gy-w1/2;
tx-=tscalex;ty-=tscaley; w1+=tscalex*2; h1+=tscaley*2;
float tw=w1,th=h1;
Vertex ttt1[] = {
// Front
{{0,0,0}, {1, 1, 0, 1}, {-tx/tw,1+ty/th}},
{{w,0,0}, {1, 1, 1,1}, {1+(w-w1-tx)/tw,1+ty/th}},
{{0,h,0}, {1, 1, 1, 1}, {-tx/tw, -(h-ty-h1)/th}},
{{w,h,0}, {1, 1, 1, 1}, {1+(w-w1-tx)/tw, -(h-ty-h1)/th}}
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(ttt1),ttt1, GL_STATIC_DRAW);
glEnableVertexAttribArray(_positionLocation);
glEnableVertexAttribArray(_colorLocation);
glEnableVertexAttribArray(_textureLocation);
glVertexAttribPointer(_positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Position));
glVertexAttribPointer(_colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Color));
glVertexAttribPointer(_textureLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid*)offsetof(Vertex, TexCoord));
set sampler
ccGLBindTexture2DN(0, texture2d->getName());
glUniform1i(_textureUniform, 0); // unnecc in practice
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH,GL_NICEST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
float clr[]={0,0,0,0};
//glTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, clr);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
glDisable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Guide::delayjoin1(float dt)
{
std::map<Rect,CCCallFuncND*>::iterator it;
for(it=m_monitor.begin();it!=m_monitor.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
m_monitor.clear();
for(it=m_strike.begin();it!=m_strike.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
m_strike.clear();
m_monitor.insert(m_premonitor.begin(),m_premonitor.end());
m_premonitor.clear();
}
void Guide::delayjoin2(float dt)
{
std::map<Rect,CCCallFuncND*>::iterator it;
for(it=m_monitor.begin();it!=m_monitor.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
m_monitor.clear();
for(it=m_strike.begin();it!=m_strike.end();++it)
{
if(it->second->isSingleReference())
it->second->release();
}
m_strike.clear();
m_strike.insert(m_prestrike.begin(),m_prestrike.end());
m_prestrike.clear();
}
void Guide::AddMonitor(Rect rc,CCCallFuncND* cn)
{
if(cn)
cn->retain();
m_premonitor[rc]=cn;
scheduleOnce(schedule_selector(Guide::delayjoin1),0.1);
}
void Guide::AddPierce(Rect rc,CCCallFuncND* cn)
{
if(cn)
cn->retain();
m_prestrike[rc]=cn;
scheduleOnce(schedule_selector(Guide::delayjoin2),0.1);
}
char* Guide::AlignTxt(char* text,float width)
{
static char str1[256];
memset(str1,0,256);
std::string str;
CCLabelTTF* pLabel1 = CCLabelTTF::create(text, "Arial", 24);
CCLabelTTF* pLabel2 = CCLabelTTF::create(" ", "Arial", 24);
float wd1=pLabel1->getContentSize().width;
float wd2=pLabel2->getContentSize().width;
int sct=(width-wd1)/wd2;
str+="\n";
for(int i=0;i<sct/2;++i)
{
str+=" ";
}
str+=text;
for(int i=0;i<sct/2+4;++i)
{
str+=" ";
}
strcpy(str1,str.c_str());
return str1;
}
bool Guide::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
if(isVisible()==false)
return true;
if(cd<m_precd)
return true;
std::map<Rect,CCCallFuncND*>::iterator pit;
for(pit=m_strike.begin();pit!=m_strike.end();++pit)
{
if(pit->first.containsPoint(pTouch->getLocation()))
{
if(pit->second)
{
pit->second->setTarget(this);
pit->second->execute();
}
return false;
}
}
std::map<Rect,CCCallFuncND*>::iterator it;
for(it=m_monitor.begin();it!=m_monitor.end();++it)
{
if(it->first.containsPoint(pTouch->getLocation()))
{
if(it->second)
{
it->second->setTarget(this);
it->second->execute();
}
return true;
}
}
if(m_src.containsPoint(pTouch->getLocation()))
{
if(bsrcclick)
{
removeFromParentAndCleanup(true);
return false;
}
}
return true;
}
void Guide::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){}
void Guide::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
}
void Guide::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent){}
void Guide::SetFocus(float x,float y,float width,float height,bool flag,int type,CCTexture2D* tex)
{
gx=x;
gy=y;
m_width=width;
m_height=height;
m_type=type;
bsrcclick=flag;
m_src=CCRect(gx-m_width/2,gy-height/2,m_width,m_height);
switch (type)
{
case 0:
texture2d=m_circle->getSprite()->getTexture();
break;
case 1:
texture2d=m_rc->getSprite()->getTexture();
break;
case 2:
texture2d=tex;
break;
}
CCSize sz=texture2d->getContentSize();
tscalex=(m_width-sz.width)/2;
tscaley=(m_height-sz.height)/2;
}
CCNode* Guide::CreateLabel(char* text,float x,float y,float width)
{
CCNode* plabel=CreateTextSprite(text,width);
plabel->setPosition(x,y);
addChild(plabel);
return plabel;
}
CCNode* Guide::CreateArrow(float x,float y,float angle)
{
//CCSprite *spr=CCSprite::createWithTexture(m_arrow->getSprite()->getTexture());
CCSprite *spr=CCSprite::create("guide/11.png");
spr->setPosition(ccp(x,y));
spr->setRotation(angle);
addChild(spr,10);
return spr;
}
void Guide::onEnter()
{
CCLayer::onEnter();
this->setTouchEnabled(true);
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-1000000,true);
}
void Guide::SetTransparent(float val)
{
transval=val;
}
void Guide::reset()
{
if(vertexBuffer==0)
glGenBuffers( 1, &vertexBuffer );
if(indexBuffer==0)
glGenBuffers( 1, &indexBuffer );
if(pg==0)
{
pg=new CCGLProgram();
pg->initWithVertexShaderByteArray(shader_vert,shader_frag);
pg->link();
pg->updateUniforms();
}
if(m_circle==0)
{
m_circle=CCRenderTexture::create(400,400);
m_circle->begin();
drawcircle();
m_circle->end();
m_circle->retain();
m_circle->getSprite()->getTexture()->setAntiAliasTexParameters();
}
if(m_arrow==0)
{
m_arrow=CCRenderTexture::create(100,100);
m_arrow->begin();
drawarrow();
m_arrow->end();
m_arrow->retain();
m_arrow->getSprite()->getTexture()->setAntiAliasTexParameters();
}
if(m_rc==0)
{
m_rc=CCRenderTexture::create(400,400);
m_rc->begin();
drawrc();
m_rc->end();
m_rc->retain();
m_rc->getSprite()->getTexture()->setAntiAliasTexParameters();
}
}
void Guide::sreset()
{
if(pg)
{
pg->reset();
pg->initWithVertexShaderByteArray(shader_vert,shader_frag);
pg->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
pg->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
pg->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
pg->link();
pg->updateUniforms();
}
}
void Guide::createHand(int dir,CCPoint pt)
{
CCPoint temp;
if(dir==0)//左边
{
temp.x=200; temp.y=270;
if(pt.x!=-1) temp=pt;
CCSprite* spr=CCSprite::create("circle.png");
CCSprite* spr1=CCSprite::create("thumb1.png");
spr->runAction(CCRepeatForever::create(CCSequence::create(CCScaleTo::create(0.6,1.5),CCScaleTo::create(0.6,1.0),0)));
spr->setPosition(ccp(temp.x,temp.y));
spr1->setFlipX(true);
spr1->setPosition(ccp(temp.x-30,temp.y-45));
spr1->runAction(CCRepeatForever::create(CCSequence::create(CCMoveBy::create(0.6,ccp(15,15)),CCMoveBy::create(0.6,ccp(-15,-15)),0)));
addChild(spr,10);
addChild(spr1,10);
}
else if(dir==1)//右边
{
temp.x=800; temp.y=270;
if(pt.x!=-1) temp=pt;
CCSprite* spr=CCSprite::create("circle.png");
CCSprite* spr1=CCSprite::create("thumb1.png");
spr->runAction(CCRepeatForever::create(CCSequence::create(CCScaleTo::create(0.6,1.5),CCScaleTo::create(0.6,1.0),0)));
spr->setPosition(ccp(temp.x,temp.y));
spr1->setPosition(ccp(temp.x+30,temp.y-45));
spr1->runAction(CCRepeatForever::create(CCSequence::create(CCMoveBy::create(0.6,ccp(-15,15)),CCMoveBy::create(0.6,ccp(15,-15)),0)));
addChild(spr,10);
addChild(spr1,10);
}
}
void Guide::createTutor(char *txt,bool ani)
{
CCSprite* spr1=CCSprite::create("guide/tutor.png");
spr1->setPosition(ccp(465,90));
addChild(spr1);
m_talk=GetFitLabel(txt,960-180);
curlen=sumlen=getUtf8Length((char*)m_talk->getString());
if(ani)
{
curlen=1;
}
talkstr=m_talk->getString();
char *sub = subUtfString(talkstr.c_str(), 0, curlen);
m_talk->setString(sub);
m_talk->setAnchorPoint(ccp(0,1));
m_talk->setPosition(ccp(330,150));
addChild(m_talk);
}
int Guide::param=0;
Guide* Guide::gthis=0;
bool Guide::init()
{
CCLog("------------------------ Guide::init()----------------------");
gthis=this;
cd=0;
m_precd=0.2;
gx=0;
gy=0;
m_width=0;
m_height=0;
scheduleUpdate();
transval=0.6;
if(vertexBuffer==0)
glGenBuffers( 1, &vertexBuffer );
if(indexBuffer==0)
glGenBuffers( 1, &indexBuffer );
if(pg==0)
{
pg=new CCGLProgram();
pg->initWithVertexShaderByteArray(shader_vert,shader_frag);
pg->link();
pg->updateUniforms();
}
if(m_circle==0)
{
m_circle=CCRenderTexture::create(400,400);
m_circle->begin();
drawcircle();
m_circle->end();
m_circle->retain();
m_circle->getSprite()->getTexture()->setAntiAliasTexParameters();
}
if(m_arrow==0)
{
m_arrow=CCRenderTexture::create(100,100);
m_arrow->begin();
drawarrow();
m_arrow->end();
m_arrow->retain();
m_arrow->getSprite()->getTexture()->setAntiAliasTexParameters();
}
if(m_rc==0)
{
m_rc=CCRenderTexture::create(400,400);
m_rc->begin();
drawrc();
m_rc->end();
m_rc->retain();
m_rc->getSprite()->getTexture()->setAntiAliasTexParameters();
}
texture2d =m_circle->getSprite()->getTexture();
return true;
}