/* Reset Timers */ void GameSession::start_timers() { time_left.start(world->get_level()->time_left*1000); st_pause_ticks_init(); update_time = st_get_ticks(); }
void CJeu::drawPause(SDL_Surface* destination) { long tempsActuel=st_get_ticks(); //On affiche le fond. SDL_BlitSurface(m_pScreenshot,NULL,destination,NULL); if (affiche==true) { SDL_BlitSurface(m_pSpriteOver,NULL,destination,NULL); if (tempsActuel-m_iLastAffiche>=m_iDureeAffiche) { affiche=false; m_iLastAffiche=tempsActuel; } } else { if (tempsActuel-m_iLastAffiche>=m_iDureeAffiche/2) { affiche=true; m_iLastAffiche=tempsActuel; } } }
void CJeu::deplacerRaquette(const int& iElapsedTime, const int& sens) { //On déplace la raquette. if (sens!=0) myRaquette.deplacer(iElapsedTime,sens,myTerrain.GetRect()); if (modifRaquette!=-1 && modifRaquette+10000<st_get_ticks()) { modifRaquette=-1; myRaquette.changerLargeur(3, myTerrain.GetRect()); } }
void CJeu::pauseJeu(char lang[MAX_LANG][256]) { m_iTimerPause=st_get_ticks(); drawJeu(m_pScreenshot); if (m_pSpriteOver!=NULL) SDL_FreeSurface(m_pSpriteOver); SDL_Surface* temp=IMG_Load("data/images/jeu/transparent.png"); m_pSpriteOver=SDL_DisplayFormat(temp); SDL_FreeSurface(temp); TTF_Font *policeTxt = TTF_OpenFont("data/bgothm.ttf", 32); SDL_Color couleurTxt = { 250, 130, 0 }; SDL_Surface* tempTxt=NULL; SDL_Rect centrage; int posY[2]={50,160}; for (int i=0;i<2;i++) { if (tempTxt!=NULL) { SDL_FreeSurface(tempTxt); } tempTxt = TTF_RenderText_Blended(policeTxt, lang[i+17], couleurTxt); centrage.x=105-(tempTxt->w/2); centrage.y=posY[i]; centrage.w=tempTxt->w; centrage.h=tempTxt->h; SDL_BlitSurface(tempTxt,NULL,m_pSpriteOver,¢rage); } TTF_CloseFont(policeTxt); affiche=true; m_iLastAffiche=st_get_ticks(); m_iDureeAffiche=1000; mySon.pauseMusic(); }
void CJeu::reprendreJeu() { long dureePause=(st_get_ticks()-m_iTimerPause); m_iTempsPause+=dureePause; m_iLastStrafe+=dureePause; m_iLastDescente+=dureePause; m_iLastChute+=dureePause; m_iTimerPause=0; mySon.resumeMusic(); }
GameSession::ExitStatus GameSession::run() { Menu::set_current(0); current_ = this; int fps_cnt = 0; update_time = last_update_time = st_get_ticks(); // Eat unneeded events SDL_Event event; while (SDL_PollEvent(&event)) {} draw(); while (exit_status == ES_NONE) { /* Calculate the movement-factor */ double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE); if(!frame_timer.check()) { frame_timer.start(25); ++global_frame_counter; } /* Handle events: */ world->get_tux()->input.old_fire = world->get_tux()->input.fire; process_events(); process_menu(); // Update the world state and all objects in the world // Do that with a constante time-delta so that the game will run // determistic and not different on different machines if(!game_pause && !Menu::current()) { // Update the world check_end_conditions(); if (end_sequence == ENDSEQUENCE_RUNNING) action(frame_ratio/2); else if(end_sequence == NO_ENDSEQUENCE) action(frame_ratio); } else { ++pause_menu_frame; SDL_Delay(50); } draw(); /* Time stops in pause mode */ if(game_pause || Menu::current()) { continue; } /* Set the time of the last update and the time of the current update */ last_update_time = update_time; update_time = st_get_ticks(); /* Pause till next frame, if the machine running the game is too fast: */ /* FIXME: Works great for in OpenGl mode, where the CPU doesn't have to do that much. But the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */ if(last_update_time >= update_time - 12) { SDL_Delay(10); update_time = st_get_ticks(); } /* Handle time: */ if (!time_left.check() && world->get_tux()->dying == DYING_NOT && !end_sequence) world->get_tux()->kill(Player::KILL); /* Handle music: */ if(world->get_tux()->invincible_timer.check() && !end_sequence) { world->play_music(HERRING_MUSIC); } /* are we low on time ? */ else if (time_left.get_left() < TIME_WARNING && !end_sequence) { world->play_music(HURRYUP_MUSIC); } /* or just normal music? */ else if(world->get_music_type() != LEVEL_MUSIC && !end_sequence) { world->play_music(LEVEL_MUSIC); } /* Calculate frames per second */ if(show_fps) { ++fps_cnt; fps_fps = (1000.0 / (float)fps_timer.get_gone()) * (float)fps_cnt; if(!fps_timer.check()) { fps_timer.start(1000); fps_cnt = 0; } } } return exit_status; }
/* --- TITLE SCREEN --- */ void title(void) { random_timer.init(true); walking = true; st_pause_ticks_init(); GameSession session(datadir + "/levels/misc/menu.stl", 0, ST_GL_DEMO_GAME); clearscreen(0, 0, 0); updatescreen(); /* Load images: */ bkg_title = new Surface(datadir + "/images/title/background.jpg", IGNORE_ALPHA); logo = new Surface(datadir + "/images/title/logo.png", USE_ALPHA); img_choose_subset = new Surface(datadir + "/images/status/choose-level-subset.png", USE_ALPHA); /* Generating contrib maps by only using a string_list */ // Since there isn't any world dir or anything, add a hardcoded entry for Bonus Island string_list_init(&worldmap_list); string_list_type files = dfiles("levels/worldmaps/", ".stwm", "couldn't list worldmaps"); for(int i = 0; i < files.num_items; ++i) { if(strcmp(files.item[i], "world1.stwm") == 0) continue; string_list_add_item(&worldmap_list, files.item[i]); } string_list_free(&files); /* --- Main title loop: --- */ frame = 0; /* Draw the title background: */ bkg_title->draw_bg(); update_time = st_get_ticks(); random_timer.start(rand() % 2000 + 2000); Menu::set_current(main_menu); while (Menu::current()) { // if we spent to much time on a menu entry if( (update_time - last_update_time) > 1000) update_time = last_update_time = st_get_ticks(); // Calculate the movement-factor double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE); if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */ frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85; /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */ frame_ratio /= 2; SDL_Event event; while (SDL_PollEvent(&event)) { if (Menu::current()) { Menu::current()->event(event); } // FIXME: QUIT signal should be handled more generic, not locally if (event.type == SDL_QUIT) Menu::set_current(0); } /* Draw the background: */ draw_demo(&session, frame_ratio); if (Menu::current() == main_menu) logo->draw( 160, 30); white_small_text->draw(" SuperTux " VERSION "\n" "Copyright (c) 2003 SuperTux Devel Team\n" "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n" "are welcome to redistribute it under certain conditions; see the file COPYING\n" "for details.\n", 0, 420, 0); /* Don't draw menu, if quit is true */ Menu* menu = Menu::current(); if(menu) { menu->draw(); menu->action(); if(menu == main_menu) { MusicManager* music_manager; MusicRef menu_song; switch (main_menu->check()) { case MNID_STARTGAME: // Start Game, ie. goto the slots menu update_load_save_game_menu(load_game_menu); break; case MNID_CONTRIB: // Contrib Menu puts("Entering contrib menu"); generate_contrib_menu(); break; case MNID_LEVELEDITOR: leveleditor(); Menu::set_current(main_menu); break; case MNID_CREDITS: music_manager = new MusicManager(); menu_song = music_manager->load_music(datadir + "/music/credits.ogg"); music_manager->halt_music(); music_manager->play_music(menu_song,0); display_text_file("CREDITS", bkg_title, SCROLL_SPEED_CREDITS); music_manager->halt_music(); menu_song = music_manager->load_music(datadir + "/music/theme.mod"); music_manager->play_music(menu_song); Menu::set_current(main_menu); break; case MNID_QUITMAINMENU: Menu::set_current(0); break; } } else if(menu == options_menu) { process_options_menu(); } else if(menu == load_game_menu) { if(event.key.keysym.sym == SDLK_DELETE) { int slot = menu->get_active_item_id(); char str[1024]; sprintf(str,"Are you sure you want to delete slot %d?", slot); draw_background(); if(confirm_dialog(str)) { sprintf(str,"%s/slot%d.stsg", st_save_dir, slot); printf("Removing: %s\n",str); remove(str); } update_load_save_game_menu(load_game_menu); update_time = st_get_ticks(); Menu::set_current(main_menu); } else if (process_load_game_menu()) { // FIXME: shouldn't be needed if GameSession doesn't relay on global variables // reset tux scroll_x = 0; //titletux.level_begin(); update_time = st_get_ticks(); } } else if(menu == contrib_menu) { check_contrib_menu(); } else if (menu == contrib_subset_menu) { check_contrib_subset_menu(); } } mouse_cursor->draw(); flipscreen(); /* Set the time of the last update and the time of the current update */ last_update_time = update_time; update_time = st_get_ticks(); /* Pause: */ frame++; SDL_Delay(25); } /* Free surfaces: */ free_contrib_menu(); string_list_free(&worldmap_list); delete bkg_title; delete logo; delete img_choose_subset; }
void title_loop() { // if we spent to much time on a menu entry if( (update_time - last_update_time) > 1000) update_time = last_update_time = st_get_ticks(); // Calculate the movement-factor double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE); if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */ frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85; /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */ frame_ratio /= 2; //printf("pxx: frame ratio: %f\n", frame_ratio); SDL_Event event; while (SDL_PollEvent(&event)) { if (Menu::current()) { Menu::current()->event(event); } // FIXME: QUIT signal should be handled more generic, not locally if (event.type == SDL_QUIT) Menu::set_current(0); } /* Draw the background: */ draw_demo(title_session, frame_ratio); if (Menu::current() == main_menu) logo->draw( 160, 30); white_small_text->draw(" SuperTux " VERSION "\n" "Copyright (c) 2003 SuperTux Devel Team\n" "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n" "are welcome to redistribute it under certain conditions; see the file COPYING\n" "for details.\n", 0, 420, 0); /* Don't draw menu, if quit is true */ Menu* menu = Menu::current(); if(menu) { menu->draw(); menu->action(); if(menu == main_menu) { MusicManager* music_manager; MusicRef menu_song; switch (main_menu->check()) { case MNID_STARTGAME: // Start Game, ie. goto the slots menu update_load_save_game_menu(load_game_menu); break; case MNID_CONTRIB: // Contrib Menu puts("Entering contrib menu"); generate_contrib_menu(); break; case MNID_LEVELEDITOR: leveleditor(); Menu::set_current(main_menu); break; case MNID_CREDITS: music_manager = new MusicManager(); menu_song = music_manager->load_music(datadir + "/music/credits.ogg"); //music_manager->halt_music(); music_manager->play_music(menu_song,0); display_text_file("CREDITS", bkg_title, SCROLL_SPEED_CREDITS); // music_manager->halt_music(); // menu_song = music_manager->load_music(datadir + "/music/theme.ogg"); // music_manager->play_music(menu_song); // Menu::set_current(main_menu); break; case MNID_QUITMAINMENU: Menu::set_current(0); break; } } else if(menu == options_menu) { process_options_menu(); } else if(menu == load_game_menu) { if(event.key.keysym.sym == SDLK_DELETE) { int slot = menu->get_active_item_id(); char str[1024]; sprintf(str,"Are you sure you want to delete slot %d?", slot); draw_background(); if(confirm_dialog(str)) { sprintf(str,"%s/slot%d.stsg", st_save_dir, slot); printf("Removing: %s\n",str); remove(str); } update_load_save_game_menu(load_game_menu); update_time = st_get_ticks(); Menu::set_current(main_menu); } else if (process_load_game_menu()) { // // FIXME: shouldn't be needed if GameSession doesn't relay on global variables // // reset tux // scroll_x = 0; // //titletux.level_begin(); // update_time = st_get_ticks(); } } else if(menu == contrib_menu) { check_contrib_menu(); } else if (menu == contrib_subset_menu) { check_contrib_subset_menu(); } } mouse_cursor->draw(); flipscreen(); /* Set the time of the last update and the time of the current update */ last_update_time = update_time; update_time = st_get_ticks(); /* Pause: */ frame++; //SDL_Delay(25); //printf("pxx: title loop finish\n"); }
//La gestion de la balle doit prendre en compte les différents éléments du terrain... Pas facile facile... //Il faut de plus détruire les briques touchées. void CJeu::deplacerBalle(const int& iElapsedTime) { int nbCaseDetruites; SDL_Rect* raqRect = myRaquette.GetRect(); int raqMidX=raqRect->x + raqRect->w/2; //Ajouter ici éventuellement une boucle pour gérer plusieurs balles. //Il faut gérer les collisions avec les briques, les murs, et la perte des balles. //Tous ceci se fait dans la fonction de déplacement de la balle. //On lui enverra en paramètre le terrain, pour qu'elle puisse procéder a ses test. for (int i=0;i<MAX_BALLES;i++) { if (myBalle[i].getStatutBalle()==1) { //Indique que la balle a été détruite. if (myBalle[i].deplacer(iElapsedTime,myTerrain,raqRect,mySon,myBonus)==true) { m_iNbBalles--; mySon.playEffet(S_PERDU_BALLE); } //Indique les destructions que la balle a causée. if (myTerrain.getBalleDestruction(nbCaseDetruites)==true) { mySon.playEffet(S_CASSE_LIGNE); addToScore(SC_LIGNE_BALLE); addLignes(1); } if (nbCaseDetruites!=0) {mySon.playEffet(S_CASSE_BRIQUE);} addToScore(nbCaseDetruites*SC_CASE_CASSEE); } } //On remet en jeu une nouvelle balle. //On baisse les vies. //+ animations ? if (m_iNbBalles==0 && m_iNiveau!=0) { m_iNbVies--; //Game Over !!!!! if (m_iNbVies==-1) { playing=false; } else { m_iNbBalles++; myBalle[0].startBalle(raqMidX,raqRect->y-myBalle[0].GetRect()->h,getVitesseBalle()); } } //Gestion des bonus est faites en même temps que la gestion des balles. int bonusObtenu[MAX_BONUS]; int nbBonus=myBonus.deplacerBonus(bonusObtenu, iElapsedTime, raqRect); if (nbBonus>0) { mySon.playEffet(S_GAGNE_BONUS); for (int i=0;i<nbBonus;i++) { addToScore(SC_BONUS); switch (bonusObtenu[i]) { case B_ADD_BALLE: if (m_iNbBalles<MAX_BALLES) { int i=0; while (myBalle[i].getStatutBalle()==1) { i++; } myBalle[i].startBalle(raqMidX,raqRect->y-myBonus.GetSurface()->h,getVitesseBalle()); m_iNbBalles++; } break; case B_ACC_BALLE: for (int i=0;i<MAX_BALLES;i++) { if (myBalle[i].getStatutBalle()==1) { myBalle[i].setSpeed(getVitesseBalle()+0.05); } } break; case B_RAL_BALLE: for (int i=0;i<MAX_BALLES;i++) { if (myBalle[i].getStatutBalle()==1) { double temp=getVitesseBalle()-0.2; if (temp<0.1) temp=0.1; myBalle[i].setSpeed(temp); } } break; case B_ADD_SCORE: addToScore(SC_BONUS_SCORE); break; case B_ADD_LIFE: if (m_iNbVies<MAX_VIES) m_iNbVies++; break; case B_DELETE_LINE: flipFigure(); //Supprime deux demi lignes. myTerrain.deleteLine(NBCASEY-1,false); myTerrain.deleteLine(NBCASEY-1,true); flipFigure(); break; case B_BLOQUE_STRAFE: //On bloque la figure latéralement pendant 10 secondes. m_iLastStrafe+=10000; break; case B_SMALL_RAQ: myRaquette.changerLargeur(1, myTerrain.GetRect()); modifRaquette=st_get_ticks(); break; case B_LARGE_RAQ: myRaquette.changerLargeur(4, myTerrain.GetRect()); modifRaquette=st_get_ticks(); break; case B_EXTRA_LARGE_RAQ: myRaquette.changerLargeur(10, myTerrain.GetRect()); modifRaquette=st_get_ticks(); break; case B_EXTRA_SMALL_RAQ: myRaquette.changerLargeur(0, myTerrain.GetRect()); modifRaquette=st_get_ticks(); break; } } } }
//déplacements de la figure. bool CJeu::allMoveFigure(int moveStrafe,bool bas,bool rotation, bool down) { long tempsActuel; int nbLignesFull; bool testDescente; int nbDescentes; bool nouvelleFigure=false; tempsActuel=st_get_ticks(); if (moveStrafe!=0) { if ((tempsActuel-m_iLastStrafe)>=2*m_iDureeStrafe) { m_iLastStrafe=tempsActuel+2*m_iDureeStrafe; if (myTerrain.moveFigure(moveStrafe,0)==true) mySon.playEffet(S_STRAFE); } else if ((tempsActuel-m_iLastStrafe)>=m_iDureeStrafe) { m_iLastStrafe=tempsActuel; if (myTerrain.moveFigure(moveStrafe,0)==true) mySon.playEffet(S_STRAFE); } } if (down==true) { nbDescentes=0; while (myTerrain.moveFigure(0,1)==true) { nbDescentes++; } addToScore(SC_DESCENTE*nbDescentes); //On force le test de descente d'une ligne, qui fait poser la pièce. m_iLastDescente=tempsActuel-m_iDureeAttente; } else { if (bas==true && ((tempsActuel-m_iLastChute)>=m_iDureeChute)) { m_iLastChute=tempsActuel; testDescente=myTerrain.moveFigure(0,1); if (testDescente==false) { m_iLastDescente=tempsActuel-m_iDureeAttente; } } } if (rotation==true) { if (myTerrain.rotationFigure()==true) mySon.playEffet(S_ROTATION); } if (tempsActuel-m_iLastDescente>=m_iDureeAttente) { m_iLastDescente=tempsActuel; if (myTerrain.moveFigure(0,1)==false) { nouvelleFigure=true; mySon.playEffet(S_POSE_BRIQUE); if (myTerrain.dropFigure()==true) { nbLignesFull=myTerrain.findFullLine(); myTerrain.findEmptyLine(); //Ne fais pas de points, car les lignes la ont été cassées en vol par le tetris. //Jouer eventuellement un son. switch (nbLignesFull) { case 0:break; case 1: addToScore(SC_LIGNE_1); mySon.playEffet(S_CASSE_LIGNE); break; case 2: addToScore(SC_LIGNE_2); mySon.playEffet(S_CASSE_LIGNE); break; case 3: addToScore(SC_LIGNE_3); mySon.playEffet(S_CASSE_LIGNE); break; case 4: addToScore(SC_LIGNE_4); mySon.playEffet(S_CASSE_LIGNE); break; } addLignes(nbLignesFull); //Vérifions maintenant si le terrain est vide. //Si c'est le cas, on va le remplir un peu pour rendre le jeu plus marant. if (myTerrain.isEmptyTerrain()==true) { myTerrain.rndFillTerrain(4); addToScore(SC_EMPTY_TERRAIN); } } else { playing=false; } } } return nouvelleFigure; }
void CJeu::initJeu(bool musiqueOn, bool sonsOn, char lang[MAX_LANG][256]) { SDL_Surface* surfTemp,* surfTemp2; myTerrain.initTerrain(lang); myRaquette.initRaquette(120,232,1,0.7); surfTemp=IMG_Load("data/images/jeu/balle.png"); surfTemp2=IMG_Load("data/images/jeu/balle2.png"); m_pImgMasque=IMG_Load("data/images/jeu/masque.png"); for (int i=0;i<MAX_BALLES;i++) { myBalle[i].initBalle(1,surfTemp,surfTemp2); } m_iNbLignesDetruites=0; m_iScore=0; m_iNiveau=0; //Autres params. m_iNbVies=5; m_iNbBalles=0; //Permet notamment de savoir quand on a perdu. setDureeAttente(); m_iLastDescente=st_get_ticks(); m_iDureeStrafe=100; m_iLastStrafe=st_get_ticks(); m_iDureeChute=40; m_iLastChute=st_get_ticks(); playing=true; // variable permettant de déterminer si le joueur n'a pas perdu. modifRaquette=-1; //Temps pause va augmenter a chaque fois qu'on fait une pause. m_iTempsPause=0; m_iTimerPause=0; //Gestion temporaire, pour tester. m_pScore=NULL; m_pNiveau=NULL; m_pSuivant=NULL; m_pLignes=NULL; m_pScreenshot=SDL_CreateRGBSurface(SDL_HWSURFACE, 320, 240, 32, 0, 0, 0, 0); m_pSpriteOver=NULL; //Chargement de la police d'écriture des chiffres : policeChiffres = TTF_OpenFont("data/DS-DIGIB.TTF", 24); makeChiffre(m_pScore,m_iScore); makeChiffre(m_pNiveau,m_iNiveau); makeChiffre(m_pSuivant,5); //Ici, ne compte que pour le premier niveau. makeChiffre(m_pLignes,m_iNbLignesDetruites); mySon.initSon(musiqueOn,sonsOn); myBonus.initBonus(); }