00001 00002 // 00003 // Das Tank - Copyright (C) 2006, 2007 Windsor Schmidt <windsor@windsorworld.net> 00004 // 00005 // This program is free software; you can redistribute it and/or modify it 00006 // under the terms of the GNU General Public License as published by the Free 00007 // Software Foundation; either version 2 of the License, or (at your option) 00008 // any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, but WITHOUT 00011 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00013 // more details. 00014 // 00015 // You should have received a copy of the GNU General Public License along with 00016 // this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00017 // Place, Suite 330, Boston, MA 02111-1307 USA 00018 // 00020 00021 00022 #ifndef STDAFX 00023 #include "stdafx.h" 00024 #endif 00025 00026 using namespace std; 00027 00028 GameState * DasGame; // main game state pointer 00029 00031 // globals for GUI and OpenGL 00033 SDL_Surface* screen; 00034 SDL_Event event; 00035 00036 //gcn::SDLInput* input; // Input driver 00037 gcn::OpenGLGraphics* graphics; // Graphics driver 00038 gcn::OpenGLSDLImageLoader* imageLoader; // For loading images 00039 gcn::Gui* gui; // A Gui object - binds it all together 00040 gcn::ImageFont* font_small; // small font 00041 gcn::ImageFont* font_big; // big font 00042 00043 // default widgets (make them global) 00044 gcn::Container* top; // A top level GUI container 00045 00046 00056 int main(int argc, char **argv) 00057 { 00058 int done; 00059 00060 // try initializing the default device, at 44100hz stereo 16-bits 00061 if(ENABLE_SOUND) 00062 { 00063 // if not, then use 'NO SOUND' device. 00064 if(!BASS_Init(-1,44100,0,0,NULL)) BASS_Init(0,44100,0,0,NULL); 00065 } 00066 else BASS_Init(0,44100,0,0,NULL); 00067 00068 // initialize SDL for video output 00069 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) == -1) exit(1); // quit if this fails 00070 00071 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 00072 00073 // create OpenGL screen surface 00074 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_HWSURFACE | 00075 SDL_HWACCEL | 00076 SDL_OPENGL | 00077 RUN_FULLSCREEN); 00078 if(screen == NULL) // quit if that fails 00079 { 00080 SDL_Quit(); 00081 exit(1); 00082 } 00083 00084 // SDL configuration 00085 SDL_WM_SetCaption("Das Tank", NULL); 00086 SDL_ShowCursor(SDL_DISABLE); 00087 SDL_EnableUNICODE(1); 00088 00089 00090 // guichan initialization 00091 imageLoader = new gcn::OpenGLSDLImageLoader(); 00092 gcn::Image::setImageLoader(imageLoader); 00093 00094 graphics = new gcn::OpenGLGraphics(); 00095 00096 // tell OpenGL graphics how big the screen is 00097 graphics->setTargetPlane(SCREEN_WIDTH, SCREEN_HEIGHT); 00098 00099 // container for gui elements 00100 top = new gcn::Container(); 00101 00102 // set the dimension of the top container to match the screen 00103 top->setDimension(gcn::Rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); 00104 gui = new gcn::Gui(); 00105 00106 // set gui to use the SDLGraphics object 00107 gui->setGraphics(graphics); 00108 00109 // set the top container 00110 gui->setTop(top); 00111 00112 // load the image fonts 00113 font_small = new gcn::ImageFont("tex/font_small.bmp"," !\"#$^&`()*+,-./0123456789:;<=>?abcdefghijklmnopqrstuvwxyz"); 00114 font_big = new gcn::ImageFont("tex/font_big.bmp"," !#+,-.0123456789:?ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 00115 00116 // The global font is static and must be set. 00117 gcn::Widget::setGlobalFont(font_small); 00118 00119 initWidgets(); // initialize gui widgets 00120 00121 InitGL(SCREEN_WIDTH, SCREEN_HEIGHT); // Initialize OpenGL graphics 00122 00123 InitTextures(); // load textures from disk 00124 00125 InitSound(); // load sounds from disk 00126 00127 InitCollision(); // load collision interaction matrices from disk 00128 00130 // master game loop 00132 int menuSelection = MENUID_NULL; 00133 bool firstLoop = true; 00134 DasGame = new GameState(); 00135 00136 //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 00137 00138 while(menuSelection != MENUID_QUIT) 00139 { 00140 if(firstLoop == true) // first time in menu since being in-game 00141 { 00142 PlayMusic(MUSICID_MENU); // start or restart menu music 00143 firstLoop = false; 00144 } 00145 00146 menuSelection = MainMenu(graphics, font_small); 00147 00148 switch(menuSelection) 00149 { 00150 case MENUID_START: 00151 StopMusic(MUSICID_MENU); 00152 00153 DasGame->World = InitGame(DasGame->iCurrentLevel); // load current level in to new world 00154 PlayGame(DasGame->World); 00155 KillGame(DasGame->World); // delete all world data structures 00156 00157 // advance levels and loop back to first level if already at the last 00158 if(DasGame->bAutoAdvanceLevel) DasGame->iCurrentLevel++; 00159 if(DasGame->iCurrentLevel > DasGame->iMaxLevel) DasGame->iCurrentLevel = 1; 00160 00161 00162 firstLoop = true; // flag that we're fresh out of a game 00163 break; 00164 case MENUID_OPTIONS: 00165 OptionsMenu(graphics, font_small, DasGame); 00166 break; 00167 case MENUID_HIGHSCORES: 00168 HighScoreMenu(graphics, font_small); 00169 break; 00170 case MENUID_CREDITS: 00171 Credits(graphics, font_small); 00172 break; 00173 case MENUID_QUIT: 00174 break; 00175 } 00176 } 00178 // end of master game loop 00180 00181 SDL_Quit(); // Kill SDL and OpenGL 00182 BASS_Free(); // Kill BASS 00183 return 0; // Go home 00184 } 00185 00186 00200 int PlayGame(CWorld * ThisWorld) 00201 { 00202 //PlayMusic(MUSICID_INGAME); // start music 00203 PlayLevelMusic(ThisWorld->musicFile); 00204 00205 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 00206 00207 int timer = 0; 00208 int victor = 0; 00209 00210 // FPS variables 00211 int fps = 0; 00212 int frameCounter = 0; 00213 Uint32 timeStamp = 0; 00214 00215 Uint32 iStartingTimeStamp = SDL_GetTicks(); 00216 Uint32 iStartingTimeElapsed = 0; 00217 00218 Uint32 EffectsTimer = SDL_GetTicks(); 00219 Uint32 PhysicsTimer = SDL_GetTicks(); 00220 Uint32 StartingTimer = SDL_GetTicks(); 00221 00222 CEffect * StartFX = NULL; 00223 Vector vGuyPos, vOffset; 00224 00225 SDL_Event event; // use to store incoming events 00226 static char string[256]; // use to format / store HUD messages before printing 00227 00228 ThisWorld->bGameOver = false; // signal that the game is still in progress 00229 00230 while (ThisWorld->bGameOver == false) 00231 { 00232 // update 'frames per second' variable 00233 ThisWorld->iCurrentTime = SDL_GetTicks(); 00234 00235 if(ThisWorld->iCurrentTime >= timeStamp + 1000) 00236 { 00237 timeStamp = ThisWorld->iCurrentTime; 00238 fps = frameCounter; 00239 frameCounter = 0; 00240 } 00241 frameCounter++; 00242 00243 //ThisWorld->Player[0]->iInput[INPUT_FIRE] = false; // limit one fire per key-down 00244 //ThisWorld->Player[1]->iInput[INPUT_FIRE] = false; 00245 00246 // get input events and transform them in to player input 00247 while(SDL_PollEvent(&event)) 00248 { 00249 if(ThisWorld->bTakeInput) 00250 { 00251 switch(event.type) 00252 { 00253 // handle joystick input from players 00254 case SDL_JOYBUTTONDOWN: 00255 if(event.jbutton.which == DasGame->iGreenPlayerJoystick) // player 1 00256 { 00257 switch(event.jbutton.button) 00258 { 00259 case 0: 00260 ThisWorld->Player[1]->iInput[INPUT_FIRE] = true; 00261 break; 00262 } 00263 } 00264 00265 if(event.jbutton.which == DasGame->iBrownPlayerJoystick) // player 2 00266 { 00267 switch(event.jbutton.button) 00268 { 00269 case 0: 00270 ThisWorld->Player[0]->iInput[INPUT_FIRE] = true; 00271 break; 00272 } 00273 } 00274 break; 00275 00276 case SDL_JOYBUTTONUP: // a little redundant? 00277 if(event.jbutton.which == DasGame->iGreenPlayerJoystick) // player 1 00278 { 00279 switch(event.jbutton.button) 00280 { 00281 case 0: 00282 ThisWorld->Player[1]->iInput[INPUT_FIRE] = false; 00283 break; 00284 } 00285 } 00286 if(event.jbutton.which == DasGame->iBrownPlayerJoystick) // player 2 00287 { 00288 switch(event.jbutton.button) 00289 { 00290 case 0: 00291 ThisWorld->Player[0]->iInput[INPUT_FIRE] = false; 00292 break; 00293 } 00294 } 00295 break; 00296 00297 case SDL_JOYHATMOTION: 00298 if(event.jhat.which == DasGame->iGreenPlayerJoystick) // player 1 00299 { 00300 if(event.jhat.value & SDL_HAT_UP) ThisWorld->Player[1]->iInput[INPUT_UP] = true; 00301 else ThisWorld->Player[1]->iInput[INPUT_UP] = false; 00302 if(event.jhat.value & SDL_HAT_DOWN) ThisWorld->Player[1]->iInput[INPUT_DOWN] = true; 00303 else ThisWorld->Player[1]->iInput[INPUT_DOWN] = false; 00304 if(event.jhat.value & SDL_HAT_LEFT) ThisWorld->Player[1]->iInput[INPUT_LEFT] = true; 00305 else ThisWorld->Player[1]->iInput[INPUT_LEFT] = false; 00306 if(event.jhat.value & SDL_HAT_RIGHT) ThisWorld->Player[1]->iInput[INPUT_RIGHT] = true; 00307 else ThisWorld->Player[1]->iInput[INPUT_RIGHT] = false; 00308 } 00309 00310 if(event.jhat.which == DasGame->iBrownPlayerJoystick) // player 2 00311 { 00312 if(event.jhat.value & SDL_HAT_UP) ThisWorld->Player[0]->iInput[INPUT_UP] = true; 00313 else ThisWorld->Player[0]->iInput[INPUT_UP] = false; 00314 if(event.jhat.value & SDL_HAT_DOWN) ThisWorld->Player[0]->iInput[INPUT_DOWN] = true; 00315 else ThisWorld->Player[0]->iInput[INPUT_DOWN] = false; 00316 if(event.jhat.value & SDL_HAT_LEFT) ThisWorld->Player[0]->iInput[INPUT_LEFT] = true; 00317 else ThisWorld->Player[0]->iInput[INPUT_LEFT] = false; 00318 if(event.jhat.value & SDL_HAT_RIGHT) ThisWorld->Player[0]->iInput[INPUT_RIGHT] = true; 00319 else ThisWorld->Player[0]->iInput[INPUT_RIGHT] = false; 00320 } 00321 break; 00322 00323 // handle keyboard input from players 00324 case SDL_KEYUP: 00325 switch(event.key.keysym.sym) 00326 { 00327 case SDLK_KP4: 00328 ThisWorld->Player[0]->iInput[INPUT_LEFT] = false; 00329 break; 00330 00331 case SDLK_KP6: 00332 ThisWorld->Player[0]->iInput[INPUT_RIGHT] = false; 00333 break; 00334 00335 case SDLK_KP5: 00336 ThisWorld->Player[0]->iInput[INPUT_DOWN] = false; 00337 break; 00338 00339 case SDLK_KP8: 00340 ThisWorld->Player[0]->iInput[INPUT_UP] = false; 00341 break; 00342 00343 case SDLK_RETURN: 00344 ThisWorld->Player[0]->iInput[INPUT_FIRE] = false; 00345 break; 00346 00347 case SDLK_a: 00348 ThisWorld->Player[1]->iInput[INPUT_LEFT] = false; 00349 break; 00350 00351 case SDLK_d: 00352 ThisWorld->Player[1]->iInput[INPUT_RIGHT] = false; 00353 break; 00354 00355 case SDLK_s: 00356 ThisWorld->Player[1]->iInput[INPUT_DOWN] = false; 00357 break; 00358 00359 case SDLK_w: 00360 ThisWorld->Player[1]->iInput[INPUT_UP] = false; 00361 break; 00362 00363 case SDLK_TAB: 00364 ThisWorld->Player[1]->iInput[INPUT_FIRE] = false; 00365 break; 00366 } 00367 break; 00368 00369 case SDL_KEYDOWN: 00370 switch(event.key.keysym.sym) 00371 { 00372 case SDLK_ESCAPE: // user pressed escape, so exit 00373 ThisWorld->bGameOver = true; 00374 break; 00375 00376 case SDLK_KP4: 00377 ThisWorld->Player[0]->iInput[INPUT_LEFT] = true; 00378 break; 00379 00380 case SDLK_KP6: 00381 ThisWorld->Player[0]->iInput[INPUT_RIGHT] = true; 00382 break; 00383 00384 case SDLK_KP5: 00385 ThisWorld->Player[0]->iInput[INPUT_DOWN] = true; 00386 break; 00387 00388 case SDLK_KP8: 00389 ThisWorld->Player[0]->iInput[INPUT_UP] = true; 00390 break; 00391 00392 case SDLK_RETURN: 00393 ThisWorld->Player[0]->iInput[INPUT_FIRE] = true; 00394 break; 00395 00396 case SDLK_a: 00397 ThisWorld->Player[1]->iInput[INPUT_LEFT] = true; 00398 break; 00399 00400 case SDLK_d: 00401 ThisWorld->Player[1]->iInput[INPUT_RIGHT] = true; 00402 break; 00403 00404 case SDLK_s: 00405 ThisWorld->Player[1]->iInput[INPUT_DOWN] = true; 00406 break; 00407 00408 case SDLK_w: 00409 ThisWorld->Player[1]->iInput[INPUT_UP] = true; 00410 break; 00411 00412 case SDLK_TAB: 00413 ThisWorld->Player[1]->iInput[INPUT_FIRE] = true; 00414 break; 00415 00416 case SDLK_PAGEUP: 00417 ThisWorld->iRenderStyle = RENDERSTYLE_PERSPECTIVE; 00418 break; 00419 00420 case SDLK_PAGEDOWN: 00421 ThisWorld->iRenderStyle = RENDERSTYLE_FLAT; 00422 break; 00423 } 00424 break; 00425 } 00426 } 00427 } 00428 00429 if((SDL_GetTicks() - PhysicsTimer) > 10) 00430 { 00431 PhysicsUpdate(ThisWorld); // update the state of the world 00432 PhysicsTimer = SDL_GetTicks(); 00433 } 00434 00435 ProcessTileCollisions(ThisWorld); // process effects of tiles that players are on 00436 00437 DoCollisions(ThisWorld); // process collisions and their effects 00438 00439 RemoveDeadObjects(ThisWorld); // clean up after the mess 00440 00441 UpdateAnimation(ThisWorld); // step animation frames 00442 00443 DrawGLScene(ThisWorld); // draw the game world (tiles and objects) 00444 00445 if((SDL_GetTicks() - EffectsTimer) > 20) 00446 { 00447 ThisWorld->UpdateEffects(40); // step the effects 00448 EffectsTimer = SDL_GetTicks(); 00449 } 00450 00451 if((SDL_GetTicks() - StartingTimer) > 10) 00452 { 00453 iStartingTimeElapsed ++; 00454 } 00455 00456 // if just beginning this round, let players get ready with a countdown 00457 graphics->setFont(font_big); 00458 00459 switch(ThisWorld->iStartingState) 00460 { 00461 case STARTINGSTATE_IDLE: 00462 if(iStartingTimeElapsed > 1000) 00463 { 00464 PlaySound(SOUNDID_READY); 00465 InitStripeAlpha(); 00466 ThisWorld->iStartingState = STARTINGSTATE_READY; 00467 00468 // make sure the little guy starts off in the right place relative to her tank 00469 vOffset.y = -0.6; 00470 vOffset.z = 0; 00471 VRotate2D(DegreesToRadians(ThisWorld->Player[1]->fAngle), vOffset); 00472 vGuyPos = ThisWorld->Player[1]->Position + vOffset; 00473 00474 StartFX = new CEffect(EFFECTID_TILEANIM); 00475 StartFX->TAnim = new TileAnim(vGuyPos,ThisWorld->Player[1]->fAngle,6000,ANIMID_GREEN_HOP_IN,80,1,true); 00476 ThisWorld->Player[1]->ParentWorld->AddEffect(StartFX); 00477 } 00478 break; 00479 00480 case STARTINGSTATE_READY: 00481 00482 DrawStripe(.15,-.15,1); 00483 graphics->_beginDraw(); 00484 graphics->drawText("READY",SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2), 00485 gcn::Graphics::CENTER); 00486 graphics->_endDraw(); 00487 00488 if(iStartingTimeElapsed > 2500) 00489 { 00490 PlaySound(SOUNDID_SET); 00491 InitStripeAlpha(); 00492 ThisWorld->iStartingState = STARTINGSTATE_SET; 00493 00494 // make sure the little guy starts off in the right place relative to her tank 00495 vOffset.x = 0; 00496 vOffset.y = 0.6; 00497 vOffset.z = 0; 00498 VRotate2D(DegreesToRadians(ThisWorld->Player[0]->fAngle), vOffset); 00499 vGuyPos = ThisWorld->Player[0]->Position + vOffset; 00500 00501 StartFX = new CEffect(EFFECTID_TILEANIM); 00502 StartFX->TAnim = new TileAnim(vGuyPos, ThisWorld->Player[0]->fAngle,3000,ANIMID_BROWN_HOP_IN,80,1,true); 00503 ThisWorld->Player[0]->ParentWorld->AddEffect(StartFX); 00504 } 00505 break; 00506 00507 case STARTINGSTATE_SET: 00508 00509 DrawStripe(.15,-.15,1); 00510 graphics->_beginDraw(); 00511 graphics->drawText("SET",SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2), 00512 gcn::Graphics::CENTER); 00513 graphics->_endDraw(); 00514 00515 if(iStartingTimeElapsed > 4000) 00516 { 00517 PlaySound(SOUNDID_GO); 00518 InitStripeAlpha(); 00519 ThisWorld->iStartingState = STARTINGSTATE_GO; 00520 ThisWorld->bTakeInput = true; 00521 } 00522 break; 00523 00524 case STARTINGSTATE_GO: 00525 00526 DrawStripe(.15,-.15,1); 00527 graphics->_beginDraw(); 00528 graphics->drawText("GO!!!",SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2), 00529 gcn::Graphics::CENTER); 00530 graphics->_endDraw(); 00531 00532 if(iStartingTimeElapsed > 5500) 00533 { 00534 ThisWorld->iStartingState = STARTINGSTATE_RUN; 00535 } 00536 break; 00537 } 00538 00539 // somebody won this game 00540 if(ThisWorld->iStartingState == STARTINGSTATE_VICTORY) 00541 { 00542 if(timer == 0) 00543 { 00544 PlaySound(SOUNDID_VICTORY); 00545 InitStripeAlpha(); 00546 } 00547 00548 if(timer>=0 && timer<5000) 00549 { 00550 switch(victor) 00551 { 00552 case 0: 00553 00554 if(ThisWorld->Player[0]->iHealth > 0 && ThisWorld->Player[1]->iHealth <= 0) victor = 1; 00555 if(ThisWorld->Player[0]->iHealth <= 0 && ThisWorld->Player[1]->iHealth > 0) victor = 2; 00556 if(ThisWorld->Player[0]->iHealth <= 0 && ThisWorld->Player[1]->iHealth <= 0) victor = 3; 00557 break; 00558 00559 case 1: 00560 DrawStripe(.15,-.15,1); 00561 graphics->_beginDraw(); 00562 graphics->drawText("BROWN TANK WINS!", 00563 SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2), 00564 gcn::Graphics::CENTER); 00565 graphics->_endDraw(); 00566 break; 00567 00568 case 2: 00569 DrawStripe(.15,-.15,1); 00570 graphics->_beginDraw(); 00571 graphics->drawText("GREEN TANK WINS!", 00572 SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2), 00573 gcn::Graphics::CENTER); 00574 graphics->_endDraw(); 00575 break; 00576 00577 case 3: 00578 DrawStripe(.15,-.15,1); 00579 graphics->_beginDraw(); 00580 graphics->drawText("TIE GAME!", 00581 SCREEN_WIDTH/2,SCREEN_HEIGHT/2 - (font_big->getHeight() / 2), 00582 gcn::Graphics::CENTER); 00583 graphics->_endDraw(); 00584 break; 00585 } 00586 } 00587 00588 timer++; 00589 00590 if (timer == 5000) ThisWorld->bGameOver = true; 00591 } 00592 00593 // draw the on-screen stats 00594 graphics->setFont(font_small); 00595 graphics->_beginDraw(); 00596 00597 sprintf_s(string, "%d", fps); 00598 graphics->drawText(string, 25, SCREEN_HEIGHT - font_big->getHeight() - 5, gcn::Graphics::LEFT); 00599 graphics->setFont(font_big); 00600 00601 if(ThisWorld->Player[1]->iAmmo == -1) 00602 { 00603 sprintf_s(string, "?", ThisWorld->Player[1]->iAmmo); 00604 graphics->drawText(string, 20, 120, gcn::Graphics::LEFT); 00605 } 00606 else 00607 { 00608 sprintf_s(string, "%d", ThisWorld->Player[1]->iAmmo); 00609 graphics->drawText(string, 20, 120, gcn::Graphics::LEFT); 00610 00611 } 00612 00613 if(ThisWorld->Player[0]->iAmmo == -1) 00614 { 00615 sprintf_s(string, "?", ThisWorld->Player[0]->iAmmo); 00616 graphics->drawText(string, SCREEN_WIDTH - 120, 120, gcn::Graphics::LEFT); 00617 } 00618 else 00619 { 00620 sprintf_s(string, "%d", ThisWorld->Player[0]->iAmmo); 00621 graphics->drawText(string, SCREEN_WIDTH - 120, 120, gcn::Graphics::LEFT); 00622 00623 } 00624 00625 graphics->_endDraw(); 00626 00627 //debugText(NULL); // display last debug text message 00628 00629 // swap buffers to display, since we're double buffered. 00630 SDL_GL_SwapBuffers(); 00631 } 00632 00633 // control passes here when the game is over 00634 00635 StopMusic(MUSICID_INGAME); // stop playing music before returning to main menu 00636 00637 return 0; 00638 } 00639 00640 00652 CWorld * InitGame(int level) 00653 { 00654 CWorld * ThisWorld = new CWorld; 00655 ThisWorld->iStartingState = STARTINGSTATE_IDLE; 00656 ThisWorld->bTakeInput = false; // freeze players until round starts 00657 00658 #ifdef DEBUG_IMPATIENT 00659 ThisWorld->iStartingState = STARTINGSTATE_RUN; 00660 ThisWorld->bTakeInput = true; 00661 #endif 00662 00663 ThisWorld->fZoomBias = 0.5; 00664 char string[256]; 00665 00666 sprintf_s(string, "lvl\\%d.lvl", level); // get level filename from level # 00667 00668 ThisWorld->LoadLevel(string); // load level from disk 00669 00671 // create a tank and insert in world as a player 00673 CObject * BrownTank; 00674 BrownTank = new CObject(TYPEID_TANK, ThisWorld); 00675 BrownTank->iHealth -= DasGame->iBrownHandicap; 00676 BrownTank->iTint = TINTID_ARMYBROWN; 00677 BrownTank->iDamageSound = SOUNDID_HIT; 00678 BrownTank->Position.x = 22; 00679 BrownTank->Position.y = 16; 00680 BrownTank->iNormalAnim = ANIMID_TANKROLL; 00681 BrownTank->iNormalAnimSpeed = 100; 00682 BrownTank->iRemovalEffects = 2; 00683 BrownTank->iRemovalEffect[0] = EFFECTID_TILEANIM; 00684 BrownTank->iRemovalEffect[1] = EFFECTID_PSYSTEM; 00685 BrownTank->iRemovalAnim = ANIMID_BROWNTANKEXPLODE; 00686 BrownTank->iRemovalAnimSpeed = 200; 00687 BrownTank->iLingerTime = 9000; 00688 BrownTank->fAngle = 180; 00689 BrownTank->fSubAngle = 180; 00690 00691 ThisWorld->Player[0] = BrownTank; 00692 ThisWorld->AddObject(BrownTank); 00693 00695 // create a tank and insert in world as a player 00697 CObject * GreenTank; 00698 GreenTank = new CObject(TYPEID_TANK, ThisWorld); 00699 GreenTank->iHealth -= DasGame->iGreenHandicap; 00700 GreenTank->iTint = TINTID_ARMYGREEN; 00701 GreenTank->iDamageSound = SOUNDID_HIT; 00702 GreenTank->Position.x = 10; 00703 GreenTank->Position.y = 16; 00704 GreenTank->iNormalAnim = ANIMID_TANKROLL; 00705 GreenTank->iNormalAnimSpeed = 500; 00706 GreenTank->iRemovalEffects = 2; 00707 GreenTank->iRemovalEffect[0] = EFFECTID_TILEANIM; 00708 GreenTank->iRemovalEffect[1] = EFFECTID_PSYSTEM; 00709 GreenTank->iRemovalAnim = ANIMID_GREENTANKEXPLODE; 00710 GreenTank->iRemovalAnimSpeed = 500; 00711 GreenTank->iLingerTime = 9000; 00712 00713 ThisWorld->Player[1] = GreenTank; 00714 ThisWorld->AddObject(GreenTank); 00715 00716 return ThisWorld; 00717 } 00718 00719 00731 int KillGame(CWorld * ThisWorld) 00732 { 00733 delete ThisWorld; 00734 00735 return 0; 00736 } 00737 00738 00744 void initWidgets() 00745 { 00746 top->setOpaque(false); 00747 } 00748 00749 void debugText(const char * text) 00750 { 00751 static char string[256]; 00752 00753 if(text == NULL) 00754 { 00755 graphics->setFont(font_small); 00756 graphics->_beginDraw(); 00757 graphics->drawText(string,SCREEN_WIDTH/2,SCREEN_HEIGHT/2,gcn::Graphics::CENTER); 00758 graphics->_endDraw(); 00759 } 00760 else 00761 { 00762 strcpy_s(string, text); 00763 } 00764 } 00765 00767 float DegreesToRadians(float deg) 00768 { 00769 return deg * PI / 180.0f; 00770 } 00771 00773 float RadiansToDegrees(float rad) 00774 { 00775 return rad * 180.0f / PI; 00776 } 00777 00784 int ToggleFullScreen(GameState * State) 00785 { 00786 State->bFullScreen = !State->bFullScreen; // toggle the fullscreen state flag 00787 00788 // initialize SDL for video output 00789 SDL_QuitSubSystem(SDL_INIT_VIDEO); 00790 00791 if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) return 1; // quit if this fails 00792 00793 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 00794 00795 // create OpenGL screen surface 00796 if(State->bFullScreen) 00797 { 00798 screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0, 00799 SDL_HWSURFACE|SDL_HWACCEL|SDL_OPENGL|SDL_FULLSCREEN); 00800 } 00801 else 00802 { 00803 screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0, SDL_HWSURFACE|SDL_HWACCEL|SDL_OPENGL); 00804 } 00805 00806 if(screen == NULL) // quit if that fails 00807 { 00808 SDL_Quit(); 00809 return 1; 00810 } 00811 00812 // SDL configuration 00813 SDL_WM_SetCaption("Das Tank", NULL); 00814 SDL_ShowCursor(SDL_DISABLE); 00815 00816 // guichan initialization 00817 imageLoader = new gcn::OpenGLSDLImageLoader(); 00818 gcn::Image::setImageLoader(imageLoader); 00819 00820 graphics = new gcn::OpenGLGraphics(); 00821 00822 // tell OpenGL graphics how big the screen is 00823 graphics->setTargetPlane(SCREEN_WIDTH, SCREEN_HEIGHT); 00824 00825 // container for gui elements 00826 top = new gcn::Container(); 00827 00828 // set the dimension of the top container to match the screen 00829 top->setDimension(gcn::Rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); 00830 gui = new gcn::Gui(); 00831 00832 // set gui to use the SDLGraphics object 00833 gui->setGraphics(graphics); 00834 00835 // set the top container 00836 gui->setTop(top); 00837 00838 // load the image fonts 00839 font_small = new gcn::ImageFont("tex/font_small.bmp"," !\"#$^&`()*+,-./0123456789:;<=>?abcdefghijklmnopqrstuvwxyz"); 00840 font_big = new gcn::ImageFont("tex/font_big.bmp"," !#+,-.0123456789:?ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 00841 00842 // The global font is static and must be set. 00843 gcn::Widget::setGlobalFont(font_small); 00844 00845 initWidgets(); // initialize gui widgets 00846 00847 InitGL(SCREEN_WIDTH, SCREEN_HEIGHT); // Initialize OpenGL graphics 00848 00849 InitTextures(); // initialize textures 00850 00851 return 0; 00852 }
Copyright Windsor Schmidt 2006 - All rights reserved.