00001 #include "GameLevel.h"
00002
00003 GameLevel::GameLevel(float width,float height)
00004 {
00005 walls = new std::vector<Wall *>();
00006 GameLevel::width=width;
00007 GameLevel::height=height;
00008 xyRatio = width/height;
00009 fps = 10;
00010 windSpeed = 0.0001;
00011
00012 brickTop = 0.10f*xyRatio;
00013 brickBottom = 0.5f;
00014 brickLeft = 0.105f;
00015 brickRight = 0.895;
00016
00017 brickW = 0.1;
00018 brickH = 0.04f*xyRatio;
00019 numBricksX = 10;
00020 numBricksY = 10;
00021 while (brickW*numBricksX > brickRight-brickLeft) numBricksX--;
00022
00023 bricks = new int[numBricksX*numBricksY]();
00024
00025 brickBottom = brickTop+brickH*numBricksY;
00026 brickLeft = 0.5f-brickW*numBricksX/2.0f;
00027 brickRight = 0.5f+brickW*numBricksX/2.0f;
00028
00029 sliderLine = 1-0.05f*xyRatio;
00030
00031 aktiveTraktorRacket=false;
00032 gameOver=false;
00033 pause=false;
00034 pointdiv=0;
00035 points=0;
00036 lives=0;
00037 racket= new Racket(0.40f,sliderLine,0.2f,1.0f-sliderLine,new Color(255,255,255));
00038 ball= new Ball(0.48f,1-0.05f*xyRatio,0.04f,0.04f*xyRatio,new Color(255,255,255),0.015f);
00039 ball->setCenterPos(racket->getXpos()+racket->getWidth()/2, 0.93f);
00040 ball->setFlying(false);
00041 walls->push_back(new Wall(0.0f,0.0f,0.005f,1.0f,new Color(255,255,255)));
00042 walls->push_back(new Wall(0.995f,0.0f,0.005f,1.0f,new Color(255,255,255)));
00043 walls->push_back(new Wall(0.0f,0.0f,1.0f,0.005f*xyRatio,new Color(255,255,255)));
00044 for (int i=0; i<numBricksX*numBricksY; i++)
00045 {
00046 bricks[i]=i%4;
00047 }
00048
00049 }
00050 void GameLevel::setAktiveTraktorRacket(bool arg)
00051 {
00052 aktiveTraktorRacket=arg;
00053
00054 }
00055 void GameLevel::fireBall()
00056 {
00057 if (lives <= 0) {
00058 restart();
00059 } else if(!ball->isFlying()&&!gameOver&&!pause)
00060 {
00061 ball->setFlying(true);
00062 ball->setVelosity(new vec3(0.0f,-6.0f));
00063 }
00064 }
00065 void GameLevel::clacNextBallPos()
00066 {
00067 if(!ball->isFlying()|| pause)
00068 {
00069 return;
00070 }
00071 float xVelo=0.0;
00072 float yVelo=0.0;
00073 if(!aktiveTraktorRacket)
00074 {
00075 float lengthVelo=velosChannelL->getValueNormPos(*(ball->getCenterPos()));
00076 if (lengthVelo!=0.0) {
00077 xVelo=velosChannelX->getValueNormPos(*(ball->getCenterPos()))/maxxVelos;
00078 yVelo=velosChannelY->getValueNormPos(*(ball->getCenterPos()))/maxxVelos;
00079 }
00080 vec3 * temp=new vec3(xVelo,yVelo);
00081 *temp*=windSpeed;
00082 ball->updateVelosity(temp);
00083 delete temp;
00084 }
00085 else
00086 {
00087 xVelo=-ball->getCenterPos()->v[0]+(racket->getXpos()+racket->getWidth()/2);
00088 yVelo=-ball->getCenterPos()->v[1]+(racket->getYpos()+racket->getHeight()/2);
00089
00090 vec3 * temp=new vec3(xVelo,yVelo);
00091 *temp*=0.001f;
00092 ball->updateVelosity(temp);
00093 delete temp;
00094 pointdiv++;
00095 if(pointdiv>=10)
00096 {
00097 points--;
00098 pointdiv=0;
00099 }
00100
00101 }
00102
00103 ball->move(ball->getVelosity(), fps);
00104
00105 float ballX = ball->getXpos();
00106 float ballY = ball->getYpos();
00107 float ballW = ball->getWidth();
00108 float ballH = ball->getHeight();
00109
00110 if (ballY+ballH >= sliderLine) {
00111 if (ballX < racket->getXpos() + racket->getWidth() && ballX + ballW > racket->getXpos())
00112 {
00113 float deviation = ballX + ballW/2 - racket->getXpos() - racket->getWidth()/2;
00114 deviation = (abs(deviation) < 0.05) ? deviation : 0.05*deviation/abs(deviation);
00115 ball->setVelosity(new vec3(10*(ball->getVelosity()->operator[](0)+deviation/10),-10*abs(ball->getVelosity()->operator[](1))));
00116 }
00117 }
00118 if (ballY+ballH >= 1.0) {
00119 resetBall(true);
00120 } else if (ballX + ballW >= 1.0) {
00121 ball->setVelosity(new vec3(-abs(ball->getVelosity()->operator [](0)),ball->getVelosity()->operator[](1)));
00122 ball->move(ball->getVelosity(), fps);
00123 }
00124 else if (ballY <= 0.0) {
00125 ball->setVelosity(new vec3(ball->getVelosity()->operator[](0),abs(ball->getVelosity()->operator[](1))));
00126 ball->move(ball->getVelosity(), fps);
00127 }
00128 else if (ballX <= 0.0) {
00129 ball->setVelosity(new vec3(abs(ball->getVelosity()->operator[](0)),ball->getVelosity()->operator[](1)));
00130 ball->move(ball->getVelosity(), fps);
00131 }
00132
00133 else if (ballX + ballW >= brickLeft && ballX <= brickRight && ballY + ballH >= brickTop && ballY <= brickBottom) {
00134 int hits[4];
00135 int count = 0;
00136 int pos[4] = {1,1,1,1};
00137 if(ballX >= brickLeft) {
00138 if(ballY >= brickTop) {
00139 hits[count] = floor((ballY-brickTop)/(brickBottom-brickTop)*(float)numBricksY)*numBricksX + floor((ballX-brickLeft)/(brickRight-brickLeft)*numBricksX);
00140 if (bricks[hits[count]]>0) {
00141 count++;
00142 pos[0] = -1;
00143 }
00144 }
00145 if(ballY + ballH <= brickBottom) {
00146 hits[count] = floor((ballY+ballH-brickTop)/(brickBottom-brickTop)*(float)numBricksY)*numBricksX + floor((ballX-brickLeft)/(brickRight-brickLeft)*numBricksX);
00147 if (bricks[hits[count]]>0) {
00148 count++;
00149 pos[2] = -1;
00150 }
00151 }
00152 }
00153 if(ballX + ballW <= brickRight) {
00154 int pos3=1;
00155 int pos2=1;
00156 if(ballY >= brickTop) {
00157 hits[count] = floor((ballY-brickTop)/(brickBottom-brickTop)*numBricksY)*numBricksX + floor((ballX+ballW-brickLeft)/(brickRight-brickLeft)*numBricksX);
00158 if (bricks[hits[count]]>0) {
00159 count++;
00160 pos[1] = -1;
00161 }
00162 }
00163 if(ballY + ballH <= brickBottom) {
00164 hits[count] = floor((ballY+ballH-brickTop)/(brickBottom-brickTop)*numBricksY)*numBricksX + floor((ballX+ballW-brickLeft)/(brickRight-brickLeft)*numBricksX);
00165 if (bricks[hits[count]]>0) {
00166 count++;
00167 pos[3] = -1;
00168 }
00169 }
00170 }
00171
00172 switch (count) {
00173 case 3:
00174 ball->setVelosity(new vec3(-ball->getVelosity()->operator[](0),-ball->getVelosity()->operator[](1)));
00175 bricks[hits[0]]--;
00176 bricks[hits[1]]--;
00177 bricks[hits[2]]--;
00178 points+=5;
00179 break;
00180 case 2:
00181 if (hits[0]==hits[1])
00182 {
00183 bricks[hits[0]]--;
00184 points+=1;
00185 }
00186 else {
00187 bricks[hits[0]]--;
00188 bricks[hits[1]]--;
00189 points+=3;
00190 }
00191 ball->setVelosity(new vec3(pos[0]*pos[1]*ball->getVelosity()->operator[](0),-1*pos[0]*pos[1]*ball->getVelosity()->operator[](1)));
00192 break;
00193 case 1:
00194 bricks[hits[0]]--;
00195 points+=1;
00196 float speed = ball->getVelosity()->length();
00197 ball->setVelosity(new vec3(pos[1]*pos[3]*0.707106781*speed,pos[2]*pos[3]*0.707106781*speed));
00198 }
00199
00200 }
00201
00202 }
00203 void GameLevel::resetBall(bool lifeloss) {
00204 windSpeed = 0.0001;
00205 ball->setFlying(false);
00206 if (lifeloss) lives--;
00207 if(lives<=0)
00208 {
00209 gameOver=true;
00210 }
00211 ball->setCenterPos(racket->getXpos()+racket->getWidth()/2, 1.0f-0.07f*xyRatio);
00212
00213 }
00214 void GameLevel::setRacketXPos(float x)
00215 {
00216 float w=racket->getWidth();
00217 if(x<w/2)
00218 {
00219 x=w/2;
00220 }
00221 else if(x>1-w/2)
00222 {
00223 x=1-w/2;
00224 }
00225 racket->setXpos(x-w/2);
00226 if(!ball->isFlying())
00227 {
00228 ball->setCenterPos(x,1.0f-0.07f*xyRatio);
00229 }
00230 }
00231 void GameLevel::drawLevel(float x, float y, float w, float h)
00232 {
00233 char message[65];
00234 glRasterPos2f(0.0f,0.0f);
00235 if(pause)
00236 {
00237 sprintf_s(message,sizeof(message),"\n Pause \n Lives: %i \n Points: %i ",lives,points);
00238 glutBitmapString(GLUT_BITMAP_HELVETICA_12,(const unsigned char*)message);
00239 return;
00240 }
00241 else
00242 {
00243 sprintf_s(message,sizeof(message),"\n Lives: %i \n Points: %i",lives,points);
00244 glutBitmapString(GLUT_BITMAP_HELVETICA_12,(const unsigned char*)message);
00245 }
00246
00247 glEnable(GL_BLEND);
00248 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00249
00250 glColor4f(1,1,1,1);
00251 if(gameOver)
00252 {
00253 if(lives<=0)
00254 {
00255 glBindTexture(GL_TEXTURE_2D,losetex);
00256 }
00257 else
00258 {
00259 glBindTexture(GL_TEXTURE_2D,wintex);
00260 }
00261 glBegin(GL_QUADS);
00262 glTexCoord2f( 0.0f, 1.0f); glVertex3f( x, (h+y)/2, 0.0f);
00263 glTexCoord2f( 0.0f, 0.0f); glVertex3f( x, (h+y)/2+70, 0.0f);
00264 glTexCoord2f( 1.0f, 0.0f); glVertex3f( x+w, (h+y)/2+70, 0.0f);
00265 glTexCoord2f( 1.0f, 1.0f); glVertex3f( x+w, (h+y)/2, 0.0f);
00266 glEnd();
00267
00268 }
00269 else
00270 {
00271
00272 racket->drawObject(x, y, w, h);
00273 ball->drawObject(x, y, w, h);
00274
00275 for(int i=0; i<walls->size();i++)
00276 {
00277 walls->at(i)->drawObject(x, y, w, h);
00278 }
00279 drawBricks( x, y, w, h);
00280 }
00281
00282 glDisable(GL_BLEND);
00283 }
00284 void GameLevel::drawBricks(float x, float y, float w, float h)
00285 {
00286 int brickCounter=0;
00287 for(int i=0; i<numBricksX*numBricksY;i++)
00288 {
00289 if (bricks[i]==0) continue;
00290 brickCounter++;
00291 float xpos = (float)(i%numBricksX)/numBricksX;
00292 float ypos = floor((float)i/numBricksX)/numBricksY;
00293
00294 float newX=x+(brickLeft+xpos*(brickRight-brickLeft))*w;
00295 float newY=y+(brickTop+ypos*(brickBottom-brickTop))*h;
00296 float newWidth= brickW*w;
00297 float newHight= brickH*h;
00298
00299 glBindTexture(GL_TEXTURE_2D,bricktex);
00300 glBegin(GL_QUADS);
00301 glColor4f((float)i/numBricksX/numBricksY,bricks[i]/3.0,0.5,1.0);
00302 glTexCoord2f( 0.0f, 0.0f); glVertex3f( newX, newY, 0.0f);
00303 glTexCoord2f( 0.0f, 1.0f); glVertex3f( newX, newY+newHight, 0.0f);
00304 glTexCoord2f( 1.0f, 1.0f); glVertex3f( newX+newWidth, newY+newHight, 0.0f);
00305 glTexCoord2f( 1.0f, 0.0f); glVertex3f( newX+newWidth, newY, 0.0f);
00306
00307 glEnd();
00308 }
00309 if(brickCounter==0)
00310 {
00311 gameOver=true;
00312 }
00313 }
00314 void GameLevel::setVelosityFlowChannels(FlowChannel * velosChannelX,FlowChannel * velosChannelY,FlowChannel * velosChannelL)
00315 {
00316 GameLevel::velosChannelX = velosChannelX;
00317 GameLevel::velosChannelY = velosChannelY;
00318 GameLevel::velosChannelL = velosChannelL;
00319 maxxVelos=velosChannelL->getMax();
00320 }
00321 void GameLevel::setTextures(GLuint ball,GLuint wall,GLuint racket,GLuint brick,GLuint lose,GLuint win)
00322 {
00323 losetex=lose;
00324 wintex=win;
00325 bricktex=brick;
00326 GameLevel::racket->setTexture(racket);
00327 GameLevel::ball->setTexture(ball);
00328 for(int i=0; i<walls->size();i++)
00329 {
00330 walls->at(i)->setTexture(wall);
00331 }
00332 }
00333 void GameLevel::restart()
00334 {
00335 if(pause)return;
00336
00337 windSpeed = 0.0001;
00338 resetBall(false);
00339 aktiveTraktorRacket=false;
00340 gameOver=false;
00341 points=0;
00342 lives=5;
00343 for (int i=0; i<numBricksX*numBricksY; i++)
00344 {
00345 bricks[i]=i%4;
00346 }
00347
00348
00349 }
00350 void GameLevel::setPause(int p)
00351 {
00352 pause=(bool)p;
00353 }
00354
00355 bool GameLevel::getPause() {
00356 return pause;
00357 }
00358
00359 void GameLevel::setFPS(float f)
00360 {
00361 fps=f/2;
00362 }
00363
00364 void GameLevel::speedUp() {
00365 windSpeed+=0.00005/fps;
00366 }