00001 #include "main.h"
00002
00003 Player::Player(Gui* gui, Level* level, IAudio* audio, IRender* render, Camera& camera)
00004 : m_gui(gui), m_level(level), m_audio(audio), m_render(render), m_camera(camera)
00005 {
00006 m_alreadyShot = false;
00007
00008 m_selectedBall = EXPLOSIVE_BALL;
00009
00010 m_currentLevel = 0;
00011 m_levelNames[0] = TEXT("../bin/meshes/level0.rvl");
00012 m_levelNames[1] = TEXT("../bin/meshes/level1.rvl");
00013 m_levelNames[2] = TEXT("../bin/meshes/level2.rvl");
00014 m_levelNames[3] = TEXT("../bin/meshes/level3.rvl");
00015 m_levelNames[4] = TEXT("../bin/meshes/level4.rvl");
00016 m_levelNames[5] = TEXT("../bin/meshes/level5.rvl");
00017
00018 m_cannonSoundBuffer = m_audio->createBuffer(TEXT("../bin/sound/sound_cannon.wav"), fileWAVE);
00019 m_cannonSound = 0;
00020
00021 m_explosionBuffer = m_audio->createBuffer(TEXT("../bin/sound/explosion.wav"), fileWAVE);
00022 m_explosionSound = 0;
00023
00024 m_ballCount[STANDARD_BALL] = 0;
00025 m_ballCount[FAST_BALL] = 0;
00026 m_ballCount[STRONG_BALL] = 0;
00027 m_ballCount[EXPLOSIVE_BALL] = 1;
00028
00029 m_ballOffPosition(0) = -50.0f;
00030 m_ballOffPosition(1) = -50.0f;
00031 m_ballOffPosition(2) = -50.0f;
00032
00033
00034 m_saveFilenames[0] = TEXT("state1.sav");
00035 m_saveFilenames[1] = TEXT("state2.sav");
00036 m_saveFilenames[2] = TEXT("state3.sav");
00037 m_saveFilenames[3] = TEXT("state4.sav");
00038 m_saveFilenames[4] = TEXT("state5.sav");
00039 m_saveFilenames[5] = TEXT("state6.sav");
00040 m_saveFilenames[6] = TEXT("state7.sav");
00041 m_saveFilenames[7] = TEXT("state8.sav");
00042 m_saveFilenames[8] = TEXT("state9.sav");
00043
00044 for(int i = 0; i < 9; i++) {
00045 m_saveStates[i].loadFromFile(m_saveFilenames[i]);
00046 }
00047 }
00048
00049 Player::~Player(void)
00050 {
00051 }
00052
00053 void Player::loadCannonball(IPhysic *physic)
00054 {
00055
00056
00057 float3 rotation;
00058
00059 rotation(0) = 0.0f;
00060 rotation(1) = 0.0f;
00061 rotation(2) = 0.0f;
00062
00063 if(!m_level->loadGeometry(TEXT("../bin/meshes/cannonball.rvl"), "cannonball", m_cannonballGeometries[0])) {
00064 printf("cannonball not found!");
00065 exit(0xFF);
00066 }
00067
00068 if(!m_level->loadGeometry(TEXT("../bin/meshes/cannonballFast.rvl"), "cannonball", m_cannonballGeometries[1])) {
00069 printf("cannonballFast not found!");
00070 exit(0xFF);
00071 }
00072
00073
00074 if(!m_level->loadGeometry(TEXT("../bin/meshes/cannonballHeavy.rvl"), "cannonball", m_cannonballGeometries[2])) {
00075 printf("cannonballHeavy not found!");
00076 exit(0xFF);
00077 }
00078
00079 if(!m_level->loadGeometry(TEXT("../bin/meshes/cannonballBomb.rvl"), "cannonball", m_cannonballGeometries[3])) {
00080 printf("cannonballBomb not found!");
00081 exit(0xFF);
00082 }
00083
00084 m_level->setItemGeometry(cannonball, m_cannonballGeometries[STANDARD_BALL]);
00085 m_level->setItemGeometry(cannonballFast, m_cannonballGeometries[FAST_BALL]);
00086 m_level->setItemGeometry(cannonballStrong, m_cannonballGeometries[STRONG_BALL]);
00087 m_level->setItemGeometry(cannonballBomb, m_cannonballGeometries[EXPLOSIVE_BALL]);
00088
00089
00090
00091 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00092 m_cannonballBodies[i] = physic->createSphere(m_ballOffPosition, rotation, 1.0f, 1.0f, 0, 0, true);
00093
00094
00095 m_cannonballBodies[i]->stopMotion();
00096 m_cannonballInstances[i] = m_render->createColorDrawCall(m_cannonballGeometries[i], m_cannonballBodies[i]);
00097 m_cannonballInstances[i]->visible = false;
00098 }
00099
00100
00101 m_cannonballBodies[STANDARD_BALL]->setMass(5);
00102 m_cannonballBodies[FAST_BALL]->setMass(3);
00103 m_cannonballBodies[STRONG_BALL]->setMass(8);
00104 m_cannonballBodies[EXPLOSIVE_BALL]->setMass(4);
00105
00106 m_cannonballInstances[STANDARD_BALL]->visible = true;
00107 }
00108
00109 void Player::loadBallLabels()
00110 {
00111 m_cannonballLabels[STANDARD_BALL] = m_gui->createLabel(724, 568, 256, 128, 4);
00112 m_cannonballLabels[STANDARD_BALL]->setName(TEXT("HUD"));
00113 m_gui->addControl(m_cannonballLabels[STANDARD_BALL]);
00114
00115 m_cannonballLabels[FAST_BALL] = m_gui->createLabel(724, 568, 256, 128, 0);
00116 m_cannonballLabels[FAST_BALL]->setName(TEXT("HUD"));
00117 m_gui->addControl(m_cannonballLabels[FAST_BALL]);
00118
00119 m_cannonballLabels[STRONG_BALL] = m_gui->createLabel(724, 568, 256, 128, 1);
00120 m_cannonballLabels[STRONG_BALL]->setName(TEXT("HUD"));
00121 m_gui->addControl(m_cannonballLabels[STRONG_BALL]);
00122
00123 m_cannonballLabels[EXPLOSIVE_BALL] = m_gui->createLabel(724, 568, 256, 128, 2);
00124 m_cannonballLabels[EXPLOSIVE_BALL]->setName(TEXT("HUD"));
00125 m_gui->addControl(m_cannonballLabels[EXPLOSIVE_BALL]);
00126
00127 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00128 m_cannonballLabels[i]->setVisible(false);
00129 }
00130
00131 m_ballCountLabel = m_gui->createLabel(935, 585,16, 32, 10);
00132 m_ballCountLabel->setName(TEXT("HUD"));
00133 m_gui->addControl(m_ballCountLabel);
00134 m_ballCountLabel->setVisible(false);
00135
00136 m_saved = m_gui->createLabel(120, 560, 80, 32, 100);
00137 m_saved->setName(TEXT("HUD"));
00138 m_saved->setVisible(false);
00139 m_gui->addControl(m_saved);
00140
00141 m_loaded = m_gui->createLabel(120, 560, 96, 32, 101);
00142 m_loaded->setName(TEXT("HUD"));
00143 m_loaded->setVisible(false);
00144 m_gui->addControl(m_loaded);
00145 }
00146
00147
00148 void Player::setBallType(int ballType)
00149 {
00150 float3 currentPos = m_cannonballBodies[m_selectedBall]->getPosition();
00151 if(ballType == -2) {
00152
00153 if(--m_selectedBall == -1) ballType = BALL_TYPE_COUNT - 1;
00154 else ballType = m_selectedBall;
00155
00156 } else if(ballType == -1) {
00157
00158 ballType = ++m_selectedBall % BALL_TYPE_COUNT;
00159 }
00160
00161 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00162 if(i == ballType) {
00163 m_cannonballLabels[i]->setVisible(true);
00164 m_ballCountLabel->setIndex(m_ballCount[i]);
00165 m_ballCountLabel->setVisible(true);
00166 m_cannonballInstances[i]->visible = true;
00167 } else {
00168 m_cannonballLabels[i]->setVisible(false);
00169 m_cannonballInstances[i]->visible = false;
00170 }
00171 m_cannonballBodies[i]->setGlobalPosition(m_ballOffPosition);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 m_selectedBall = ballType;
00181 m_ballsLeftLabel->setIndex(m_ballCount[m_selectedBall]);
00182 m_cannonballBodies[m_selectedBall]->setGlobalPosition(currentPos);
00183 }
00184
00185 void Player::resetCannonLabels()
00186 {
00187 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00188 m_cannonballLabels[i]->setVisible(false);
00189 }
00190 m_ballCountLabel->setVisible(false);
00191 }
00192
00193
00194 void Player::playExplosionSound()
00195 {
00196 m_audio->free(m_explosionSound);
00197 m_explosionSound = m_audio->createSound(m_explosionBuffer, false, &getMovingCannonPosition(false));
00198 m_explosionSound->play();
00199 }
00200
00201 void Player::applyForce(float3 vec)
00202 {
00203 m_audio->free(m_cannonSound);
00204 m_cannonSound = m_audio->createSound(m_cannonSoundBuffer, false, &getMovingCannonPosition(false));
00205 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00206 if(i == m_selectedBall) m_cannonballInstances[i]->visible = true;
00207 else m_cannonballInstances[i]->visible = false;
00208 }
00209
00210 if(!m_alreadyShot) {
00211
00212 m_cannonballBodies[m_selectedBall]->setGlobalPosition(m_startPosition);
00213 m_alreadyShot = true;
00214 }
00215
00216 m_cannonballBodies[m_selectedBall]->applyForce(vec);
00217 m_cannonSound->play();
00218 m_ballCount[m_selectedBall]--;
00219
00220 m_ballsLeftLabel->setIndex(m_ballCount[m_selectedBall]);
00221
00222
00223 }
00224
00225 float3 Player::getCannonPosition()
00226 {
00227 float3 position;
00228 if(!m_alreadyShot) {
00229 m_cannonballBodies[m_selectedBall]->setGlobalPosition(m_startPosition);
00230 return m_startPosition;
00231 } else {
00232 position = m_cannonballBodies[m_selectedBall]->getPosition();
00233 m_cannonballBodies[m_selectedBall]->stopMotion();
00234
00235 }
00236
00237 return position;
00238 }
00239
00240
00241 void Player::restart()
00242 {
00243
00244
00245
00246
00247 m_cannonballBodies[m_selectedBall]->stopMotion();
00248 m_cannonballBodies[m_selectedBall]->setGlobalPosition(m_startPosition);
00249 m_ballCount[STANDARD_BALL] = STARTING_BALLS_COUNT;
00250
00251 m_ballsLeftLabel->setIndex(m_ballCount[m_selectedBall]);
00252 }
00253
00254 bool Player::checkWinCondition()
00255 {
00256 float3 position;
00257 position = m_cannonballBodies[m_selectedBall]->getPosition();
00258
00259 if(m_level->intersectsEnd(position, 3.0f)){
00260
00261 m_cannonballBodies[m_selectedBall]->stopMotion();
00262 if(m_currentLevel < 5) {
00263 loadNewLevel(++m_currentLevel);
00264
00265 } else {
00266 m_gui->showWinnerLabel();
00267 return true;
00268 }
00269 return false;
00270 }
00271
00272
00273
00274
00275
00276
00277 return false;
00278
00279 }
00280
00281 void Player::loadNewLevel(int levelNumber)
00282 {
00283
00284 m_level->load(m_levelNames[levelNumber], TEXT("../bin/textures/"));
00285
00286
00287 m_camera.setPosition(m_level->getStart());
00288
00289 {
00290 wchar* file[6];
00291
00292 #define CASE(levelNumber) \
00293 file[0] = TEXT("../bin/textures/")TEXT(#levelNumber)TEXT("_up.bmp");\
00294 file[1] = TEXT("../bin/textures/")TEXT(#levelNumber)TEXT("_down.bmp");\
00295 file[2] = TEXT("../bin/textures/")TEXT(#levelNumber)TEXT("_west.bmp");\
00296 file[3] = TEXT("../bin/textures/")TEXT(#levelNumber)TEXT("_east.bmp");\
00297 file[4] = TEXT("../bin/textures/")TEXT(#levelNumber)TEXT("_south.bmp");\
00298 file[5] = TEXT("../bin/textures/")TEXT(#levelNumber)TEXT("_north.bmp")
00299
00300 switch(levelNumber){
00301 case 1: CASE(1); break;
00302 case 2: CASE(2); break;
00303 case 3: CASE(3); break;
00304 case 4: CASE(4); break;
00305 default: CASE(0); break;
00306 }
00307
00308 TextureData textureData[6];
00309 for(int i=0; i<6; i++){
00310 if(loadTextureData(file[i], 0, 0, textureData[i]) == false)
00311 printf("Skybox texture %i not found.\n", i);
00312 }
00313
00314 m_render->createSkyBox(textureData[0], textureData[1], textureData[2], textureData[3], textureData[4], textureData[5]);
00315 }
00316
00317 m_startPosition = m_level->getStart();
00318 m_alreadyShot = false;
00319 for(int i = 0; i < 3; i++) {
00320 m_cannonballInstances[i]->visible = false;
00321 }
00322 m_currentLevel = levelNumber;
00323 }
00324
00325 bool Player::isMoving()
00326 {
00327 if(m_alreadyShot) {
00328 bool move = m_cannonballBodies[m_selectedBall]->isMoving();
00329 return move;
00330 } else
00331 return false;
00332 }
00333
00334
00335 void Player::setBallsLeftLabel(pIControl ballsLeft)
00336 {
00337 m_ballsLeftLabel = ballsLeft;
00338 m_ballsLeftLabel->setIndex(1);
00339 }
00340
00341 float3 Player::getMovingCannonPosition(bool slowDown)
00342 {
00343
00344 if (slowDown) m_cannonballBodies[m_selectedBall]->slowDown();
00345 return m_cannonballBodies[m_selectedBall]->getPosition();
00346 }
00347
00348 void Player::checkForLevelObjects()
00349 {
00350 LevelItem item;
00351 int object = m_level->intersectsItem(m_cannonballBodies[m_selectedBall]->getPosition());
00352 if(object != -1) {
00353 item = m_level->getItem(object);
00354
00355 m_ballCount[item.item] += item.value;
00356 m_level->removeItem(object);
00357 }
00358 }
00359
00360 void Player::resetOtherCannonBalls()
00361 {
00362 float3 position = m_cannonballBodies[m_selectedBall]->getPosition();
00363
00364 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00365 m_cannonballBodies[m_selectedBall]->setPosition(position);
00366 }
00367 }
00368
00369 bool Player::outOfBalls()
00370 {
00371 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00372 if(m_ballCount[i] > 0) return false;
00373 }
00374 return true;
00375 }
00376
00377
00378 void Player::saveGameState(int saveSlot, float3 cameraPosition)
00379 {
00380 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00381 m_saveStates[saveSlot].setBallCount(i, m_ballCount[i]);
00382 }
00383 m_saveStates[saveSlot].setSelectedBall(m_selectedBall);
00384 m_saveStates[saveSlot].setLevel(m_currentLevel);
00385 m_saveStates[saveSlot].setBallPosition(m_cannonballBodies[m_selectedBall]->getPosition());
00386 m_saveStates[saveSlot].setCameraPosition(cameraPosition);
00387 m_saveStates[saveSlot].setSaved();
00388 m_saved->setVisible(true);
00389 }
00390
00391 float3 Player::loadGameState(int saveSlot, float3 cameraPosition)
00392 {
00393 if(!m_saveStates[saveSlot].saveAvailable())
00394 return cameraPosition;
00395
00396 for(int i = 0; i < BALL_TYPE_COUNT; i++) {
00397 m_ballCount[i] = m_saveStates[saveSlot].getBallCount(i);
00398 }
00399 m_cannonballBodies[m_selectedBall]->setGlobalPosition(m_saveStates[saveSlot].getBallPosition());
00400 setBallType(m_saveStates[saveSlot].getSelectedBall());
00401
00402 if(m_saveStates[saveSlot].getLevel() != m_currentLevel)
00403 loadNewLevel(m_saveStates[saveSlot].getLevel());
00404
00405 m_loaded->setVisible(true);
00406
00407 return m_saveStates[saveSlot].getCameraPosition();
00408 }
00409
00410
00411 void Player::saveGameStatesToFiles()
00412 {
00413 for(int i = 0; i < 9; i++) {
00414 m_saveStates[i].saveToFile(m_saveFilenames[i]);
00415 }
00416 }
00417
00418 void Player::explosion()
00419 {
00420 m_cannonballBodies[EXPLOSIVE_BALL]->stopMotion();
00421 m_cannonballInstances[EXPLOSIVE_BALL]->visible = false;
00422 }