📄 effects.cpp
字号:
/* ************************************************************************* * SDL-Ball - DX-Ball/Breakout remake with openGL and SDL for Linux Copyright (C) 2008 DusteD.dk This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. * ************************************************************************* */struct effect_vars { int type; //Hvilken slags effekt er det? bool coldet; //er der collision detection på denne? bool active; //Er denne effekt aktiv GLfloat col[3]; //Hvilken farve har effekten? GLfloat speed; //Hvor hurtigt bevæger den sig GLfloat angle; //I hvilken vinkel udspringer den fra GLfloat spread; //Hvor stor er spredningen (i grader) GLfloat size; //Skalering af elementerne GLfloat gravity; //Hvor stor er tyndgekraften int num; //Hvor mange elementer er der i den int life; //hvor mange ms lever den? textureClass tex; //Texture int effectId; //unique id for this effect};class transit_effect_class { private: int age; GLfloat opacity; public: effect_vars vars; void init() { age=0; opacity = 0.0f; var.transition_half_done=0; } void draw() { age += nonpausingGlobalTicks; if(age < vars.life/2.0) //første halvdel { //Gør solid opacity += vars.life/500.0*nonpausingGlobalMilliTicks; } else { var.transition_half_done=1; //Gør trans, og hvid opacity -= vars.life/500.0*nonpausingGlobalMilliTicks; } glLoadIdentity(); glDisable( GL_TEXTURE_2D ); glTranslatef(0.0, 0.0, -3.0); glColor4f( vars.col[0], vars.col[1], vars.col[2], opacity ); glBegin( GL_QUADS ); glVertex3f(-1.66, 1.25, 0.0); glVertex3f( 1.66, 1.25, 0.0); glVertex3f( 1.66,-1.25, 0.0); glVertex3f(-1.66,-1.25, 0.0); glEnd( ); glEnable( GL_TEXTURE_2D ); } };class sparkle { public: bool active; GLfloat size; GLfloat ang; int life; int lifeleft; pos p,v; //position og vel effect_vars vars; GLfloat bounce,f; //bounce og friktion GLfloat rot; //rotation (random, set at spawn) GLuint texture; //gl texture sparkle() { bounce=0; f=0; active=1; } void draw(int s) { if(lifeleft > 0) { //sanitize lifeleft -= globalTicks; //er vi indenfor skærmen? if(p.x > 1.67 || p.y < -1.7 || p.x < -1.67) { active=0; } v.y -= vars.gravity*globalMilliTicks; v.y -= bounce*globalMilliTicks; if(v.x < 0) { v.x += f*globalMilliTicks; } else { v.x -= f*globalMilliTicks; } p.x += v.x * globalMilliTicks; p.y += v.y * globalMilliTicks; glColor4f(vars.col[0], vars.col[1],vars.col[2], (1.0/(float)life)*(float)lifeleft); glLoadIdentity(); glTranslatef(p.x, p.y, -3.0); glRotatef(rot, 0.0, 0.0, 1.0); GLfloat curSize = size/(float)life * (float)lifeleft; glBindTexture( GL_TEXTURE_2D, texture ); glBegin( GL_QUADS ); glTexCoord2f(0,0); glVertex3f(-curSize, curSize, 0.0); glTexCoord2f(0,1); glVertex3f( curSize, curSize, 0.0); glTexCoord2f(1,1); glVertex3f( curSize,-curSize, 0.0); glTexCoord2f(1,0); glVertex3f(-curSize,-curSize, 0.0); glEnd( ); /* glPointSize((size/(float)life) * (float)lifeleft); glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTranslatef(p.x, p.y, -3.0); glBegin( GL_POINTS ); glVertex3f( 0.0, 0.0, 0.0 ); glEnd( ); glEnable(GL_TEXTURE_2D);*/ } else { active=0; } } void coldet(brick & b) { if(p.x > b.posx-b.width && p.x < b.posx+b.width) { if(p.y > b.posy-b.height && p.y < b.posy+b.height) { //Hvor ramte vi fra? if(p.y < b.posy && !b.n(3)) { //bunden p.y = b.posy-b.height-0.01; } else if(p.y > b.posy && !b.n(2)) { //toppen p.y = b.posy+b.height; if(v.y < 0) { v.y *= -1; v.y /= 2.0; f += 0.01; } } else if(p.x > b.posx && !b.n(1)) { //p.x = b.posx+b.width; //højre if(v.x < 0) v.x *= -1; } else if(p.x < b.posx && !b.n(0)) { //p.x = b.posx-b.width; //venstre if(v.x > 0) v.x *= -1; } } } } void pcoldet(paddle_class & b) { if(p.x > b.posx-b.width && p.x < b.posx+b.width) { if(p.y > b.posy-b.height && p.y < b.posy+b.height) { //Hvor ramte vi fra? if(p.y < b.posy) { //bunden p.y = b.posy-b.height; } if(p.y > b.posy) { //toppen p.y = b.posy+b.height; if(v.y < 0) { v.y *= -1; v.y /= 2.0; f += 0.01; } } else if(p.x > b.posx) { p.x = b.posx+b.width; //højre if(v.x < 0) v.x *= -1; } else if(p.x < b.posx) { p.x = b.posx-b.width; //venstre if(v.x > 0) v.x *= -1; } } } }};class effect_class { private: pos spawn_pos; sparkle* sparks; //wohoo ;) public: transit_effect_class transit; struct effect_vars vars; effect_class() { vars.active=0; //når den bliver oprettet i hukkommelsen er den ikke i brug endnu } void init(pos p) { int i; GLfloat angle=0.0; vars.active=1; spawn_pos=p; int life; //cout << "Spawned effect type " << vars.type << " at " << p.x << "," << p.y << " with " << vars.life << "ms life" << endl; switch(vars.type) { case FX_SPARKS: sparks = new sparkle[vars.num]; if(sparks == NULL) { cout << "Could not allocate " << vars.num << " sparks" << endl; i=vars.num+10; } for(i=0; i < vars.num; i++) { sparks[i].size = rndflt(vars.size,0); life = rndflt(vars.life,0); angle=(RAD/vars.num-1)*(rndflt(vars.num,0.0)); //FIXME: Random angle sparks[i].life = life; sparks[i].lifeleft = life; sparks[i].v.x = (vars.speed*rndflt(vars.speed*2.0,0.0)) * sin(angle); sparks[i].v.y = (vars.speed*rndflt(vars.speed*2.0,0.0)) * cos(angle); sparks[i].vars = vars; sparks[i].rot = rndflt(359,0); sparks[i].p.x = spawn_pos.x; sparks[i].p.y = spawn_pos.y; sparks[i].texture = vars.tex.prop.texture; } break; case FX_TRANSIT: transit.vars = vars; transit.init(); break; } } void draw() { //find ud af hvor længe der er gået siden sidst int i; switch(vars.type) { case FX_SPARKS: for(i=0; i < vars.num; i++) { if(sparks[i].active) { sparks[i].draw(i); } } break; case FX_TRANSIT: transit.draw(); break; } // cout << "Effect type " << vars.type << " alive, age: " << vars.life << endl; vars.life -= globalTicks; if(vars.life < 0) { vars.active=0; switch(vars.type) { case FX_SPARKS: delete[] sparks; //Free sparks again ;) break; } } } void coldet(brick & b) { int i; if(vars.type == FX_SPARKS) { for(i=0; i < vars.num; i++) { if(sparks[i].active) { sparks[i].coldet(b); } } } } void pcoldet(paddle_class & b) { int i; if(vars.type == FX_SPARKS) { for(i=0; i < vars.num; i++) { if(sparks[i].active) { sparks[i].pcoldet(b); } } } }};class effectManager { private: struct effect_vars vars; //denne kopieres over i den næste effekt der bliver spawned int effectId; //ever rising number of a spawned effect. public: list<effect_class>effects; effectManager() { effects.clear(); effectId=0; } void set(int var, GLfloat val) { switch(var) { case FX_VAR_ANGLE: vars.angle = val; break; case FX_VAR_SPEED: vars.speed = val; break; case FX_VAR_SPREAD: vars.spread = val; break; case FX_VAR_SIZE: vars.size = val; break; case FX_VAR_GRAVITY: vars.gravity = val; } } void set(int var, int val) { switch(var) { case FX_VAR_NUM: vars.num=val; break; case FX_VAR_LIFE: vars.life=val; break; case FX_VAR_TYPE: vars.type=val; break; case FX_VAR_COLDET: vars.coldet=val; break; } } void set(int var, GLfloat r, GLfloat g, GLfloat b) { switch(var) { case FX_VAR_COLOR: vars.col[0] = r; vars.col[1] = g; vars.col[2] = b; break; } } void set(int var, textureClass tex) { switch(var) { case FX_VAR_TEXTURE: vars.tex = tex; break; } } //retunerer effektid så der kan checkes om det er aktivt int spawn(pos p) { effectId ++; effect_class tempEffect; vars.effectId = effectId; tempEffect.vars = vars; //kopier det over som er sat op tempEffect.init(p); effects.push_back(tempEffect); return(effectId); } void draw() { int ac=0; for(list <effect_class>::iterator it = effects.begin(); it != effects.end(); ++it) { ac++; it->draw(); if(!it->vars.active) it = effects.erase(it); } } void coldet(brick & b) { if(b.collide && b.active) { for(list <effect_class>::iterator it = effects.begin(); it != effects.end(); ++it) { if(it->vars.coldet) it->coldet(b); } } } void pcoldet(paddle_class & b) { for(list<effect_class>::iterator it = effects.begin(); it != effects.end(); ++it) { if(it->vars.coldet) it->pcoldet(b); } } int isActive(int id) { for(list<effect_class>::iterator it = effects.begin(); it != effects.end(); ++it) { if(it->vars.effectId == id && it->vars.active) { return(1); } } return(0); }};#define MAXMSG 10class glAnnounceTextClass { private: GLuint texture[MAXMSG]; int life[MAXMSG]; int quelen; //hvor mange mangler vi at vise int cur; //hvilken viser vi int age; //Hvor mange ticks var der da vi startede med at vise den. GLfloat zoom,fade; bool fadedir; public: void init() { glGenTextures(MAXMSG, texture); } glAnnounceTextClass() { quelen=0; cur=0; age=0; zoom=0.0; fade=0.0; fadedir=0; } void write(const char *text, int ttl, TTF_Font *font) { SDL_Color color = { 255,255,255 }; writeTxt(font, color, text, texture[quelen],1); life[quelen]=ttl; quelen++; if(quelen > MAXMSG) { quelen=0; } } void draw() { if(quelen>0) { zoom += 4000.0/life[cur] * nonpausingGlobalMilliTicks; if(fadedir) { fade -= 1.0 * nonpausingGlobalMilliTicks; } else { fade += 1.0 * nonpausingGlobalMilliTicks; } glLoadIdentity(); glTranslatef(0.0,0.0,-3.0); glBindTexture(GL_TEXTURE_2D, texture[cur]); GLfloat s=zoom; glEnable (GL_BLEND); s=zoom*0.85; glColor4f(1.0,0.0,0.0,fade); glBegin( GL_QUADS ); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.15625f); glVertex3f( 1.0*s,-0.11*s, 0.0f ); glTexCoord2f(0.0f, 0.15625f); glVertex3f(-1.0*s,-0.11*s, 0.0f ); glEnd( ); s=zoom*0.9; glColor4f(0.0,1.0,0.0,fade); glBegin( GL_QUADS ); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.15625f); glVertex3f( 1.0*s,-0.11*s, 0.0f ); glTexCoord2f(0.0f, 0.15625f); glVertex3f(-1.0*s,-0.11*s, 0.0f ); glEnd( ); s=zoom*0.95; glColor4f(0.0,0.0,1.0,fade); glBegin( GL_QUADS ); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.15625f); glVertex3f( 1.0*s,-0.11*s, 0.0f ); glTexCoord2f(0.0f, 0.15625f); glVertex3f(-1.0*s,-0.11*s, 0.0f ); glEnd( ); s=zoom; glColor4f(1.0,1.0,1.0,fade); glBegin( GL_QUADS ); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0*s, 0.11*s, 0.0f ); glTexCoord2f(1.0f, 0.15625f); glVertex3f( 1.0*s,-0.11*s, 0.0f ); glTexCoord2f(0.0f, 0.15625f); glVertex3f(-1.0*s,-0.11*s, 0.0f ); glEnd( ); age += nonpausingGlobalTicks; if(age > life[cur]*0.50) { fadedir=1; } if(age > life[cur]) { cur++; if(cur > MAXMSG) { cur=0; } quelen--; age=0; zoom=0.0; fade=0.0; fadedir=0; } } else { cur=0; } }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -