// gère l'affichage graphique et la gestion évènementielle void RenduGraphique::boucleMaitresse() { if(affichage) std::cout << "INI: \tBoucle Maîtresse Lancée" <<std::endl<<std::endl; // intialisations int inter = 0; // variable intermédiaire entière std::string stmp(""); // variable intermédiaire de type string bool interbool = false; // variable intermédiaire de type bool bool pause = false; // vrai quand le programme est en pause bool suivreAstre = false; // vrai quand on suit l'astre sélectionné const Input& input = app->GetInput(); // contient les stattus des touches et boutons en temps réel. // variables relatives à la sourie bool sourisDroit = false, sourisGauche = false; // vrai si appuyé bool boiteInfoBougee = false; // vrai quand la BoiteInfoAstre est ferrée Vector2f posSourie(0,0); // coorodnnées de la sourie par rapport // au dernier endroit cliqué droit // Zoom double calcZoom; // utilisée pour calculer les zooms // Musique int statMsq = 1; // mit à faux si la musique n'est pas utilisable Music msq; if(NAV_ActiverMusique) { // si musique autorisée if(!msq.OpenFromFile(musique)) { FATAL_ERROR("INI: Le fichier de musique n'a pas été ouvert", false); statMsq = 0; // on ne doit pas agir sur la musique ! } else { msq.Play(); msq.SetLoop(true); // on joue la musique en boucle } } else statMsq = 0; Event event; // évènement // boucle évènementielle while(app->IsOpened()) { // si on est pas en pause, on passe au dt suivant ! directive = "SOURIS: deplacer ou selectionner, M: Arreter la musique, A: modifier astre selectionne, ESPACE: changer referentiel, ESC: quitter"; if(!pause) { U->passagedt(); // si un astre est suivis (on suit la sélection), avec sécurité if(suivreAstre && selection != NULL) { vue->Move(selection->GetVitesse().x,selection->GetVitesse().y); // si on suit un astre, on indique bien ce mode ! etat[ETAT_GENERAL] = 'R'; } else etat[ETAT_GENERAL] = 'N'; } // gestion évènementielle while(app->GetEvent(event)) { if(event.Type == Event::Closed) app->Close(); //=================== // TOUCHES DU CLAVIER else if(event.Type == Event::KeyPressed) { switch(event.Key.Code) { case Key::Escape: // fin du programme (avec confirmation) directive = "Quitter ? Oui: Escape, Non: Autre touche"; if(confirmationQuitter(suivreAstre)) app->Close(); break; case Key::Tab: // on saute le nombre indiqué par le tampon, ou la constante utilisateur NAV_PasTab inter = str2num(tampon); tampon = ""; // on vide le tampon // si rien n'est rentré if(inter == 0) inter = NAV_PasTab; for(int i = 0; i < inter; i++) U->passagedt(); if(affichage) std::cout<<inter<<" dt ont été sautés"<<std::endl; break; case Key::Return: // on reviens au zoom normal // étant donné les problèmes d'imprécision, on préfère une technique admettant une petite incertitude. while (fabs(zoomActuel - 1) > 0.09) { if(zoomActuel < 1) { zoomActuel *= NAV_CoefficientMolette; vue->Zoom(NAV_CoefficientMolette); } else if(zoomActuel > 1) { zoomActuel /= NAV_CoefficientMolette; vue->Zoom(1/NAV_CoefficientMolette); } } // de plus, on recentre la fenêtre sur l'origine vue->SetCenter(0,0); break; case Key::Space: // suivre l'astre sélectionné suivreAstre = false; // si un astre est sélectionné if(selection != NULL) suivreAstre = true; // on suit l'astre sélect. break; case Key::Back: // on retire la dernière case du tampon if(tampon.size() == 0) break; stmp = tampon; tampon = ""; for(unsigned int i = 0; i < stmp.size()-1; i++) { tampon += stmp[i]; } break; case Key::Pause: // on met en pause, ou on redémarre pause = !pause; break; // utilisation des lettres, pour différents effets case Key::M: // pour arrêter ou continuer la musique if(statMsq) { // si tout vas bien pour la musique if(msq.GetStatus() != Sound::Playing) msq.Play(); // si en pause, on démarre else // sinon on met en pause msq.Pause(); } break; case Key::A: // modifier l'astre sélectionné // si pas d'astre sélectionné, pas la peine de continuer // Si Ctrl+a : on AJOUTE aux valeurs existantes // Si a : on REMPLACE les valeurs existantes if(input.IsKeyDown(Key::LControl) || // ctrl gauche input.IsKeyDown(Key::LControl)) // ou droit interbool = true; // donc on ajoute else // sinon interbool = false; // on remplace if(selection != NULL) modificationAstre(interbool); if(affichage) std::cout<<"Astre en cours de modification..."<<std::endl; break; case Key::R: // réinitialiser l'Univers U->reinitialiserUnivers(); // on déselectionne et on se suit plus d'astre selection = NULL; suivreAstre = false; if(affichage) std::cout<<"UNIVERS REINITIALISE !"<<std::endl; break; // utilisation des flèches, pour se déplacer dans l'univers // Le nombre de pixel s'adapte au zoom case Key::Up: vue->Move(0, -NAV_PasFleche/zoomActuel); break; case Key::Right: vue->Move(NAV_PasFleche/zoomActuel, 0); break; case Key::Down: vue->Move(0, NAV_PasFleche/zoomActuel); break; case Key::Left: vue->Move(-NAV_PasFleche/zoomActuel, 0); break; // utilisation des chiffres, pour le tampon case Key::Numpad0: case Key::Num0: tampon += '0'; break; case Key::Numpad1: case Key::Num1: tampon += '1'; break; case Key::Numpad2: case Key::Num2: tampon += '2'; break; case Key::Numpad3: case Key::Num3: tampon += '3'; break; case Key::Numpad4: case Key::Num4: tampon += '4'; break; case Key::Numpad5: case Key::Num5: tampon += '5'; break; case Key::Numpad6: case Key::Num6: tampon += '6'; break; case Key::Numpad7: case Key::Num7: tampon += '7'; break; case Key::Numpad8: case Key::Num8: tampon += '8'; break; case Key::Numpad9: case Key::Num9: tampon += '9'; break; case Key::Comma: // virgule, pour les nombres flottants case Key::Period: // ou le point // La SFML ne gère pas le point du keypad tampon += '.'; break; case Key::Subtract: // utile pour faire des négatifs tampon += '-'; break; case Key::Add: // ajoute le tampon au FPS (max 1000, min 1) SFML_FPS += str2num(tampon); if(SFML_FPS > 1000) SFML_FPS = 1000; else if(SFML_FPS < 1) SFML_FPS = 1; tampon = ""; app->SetFramerateLimit(SFML_FPS); if(affichage) std::cout << "Nouvelle valeur de FPS : " << SFML_FPS << std::endl; break; // dans tous les autres cas : default: break; } } // fin gestion appuis de touche //===================== // BOUTONS DE LA SOURIE else if(event.Type == Event::MouseButtonPressed) { // on défini les coordonnées du point de clic posSourie.x = event.MouseButton.X; posSourie.y = event.MouseButton.Y; // si c'est le bouton droit if(event.MouseButton.Button == Mouse::Right) { sourisDroit = true; } // si c'est le gauche else if(event.MouseButton.Button == Mouse::Left) { sourisGauche = true; // si on n'a pas cliqué sur l'interface OBJET_INTERFACE oi = selectionInterface(event.MouseButton.X,event.MouseButton.Y); // on récupère la sortie if(oi == Dehors) { // on sélectionne un astre selectionAstre(event.MouseButton.X,event.MouseButton.Y); } else if(oi == BoiteInfo) { // on a cliqué sur la BoiteInfoAstre // on indique donc que cette boite peut-être déplacée au mouvement de sourie, jusqu'à relâchement du bouton boiteInfoBougee = true; } else if(oi == Barre) { // si clique sur la barre haute // rien à faire pour le moment } } } else if(event.Type == Event::MouseButtonReleased) { // si c'est le bouton droit if(event.MouseButton.Button == Mouse::Right) sourisDroit = false; // si c'est le gauche else if(event.MouseButton.Button == Mouse::Left) { sourisGauche = false; boiteInfoBougee = false; // la boite est déselectionnée, quoiqu'il arrive. } } // mouvement de la molette else if(event.Type == Event::MouseWheelMoved) { calcZoom = -(event.MouseWheel.Delta*NAV_CoefficientMolette); if(NAV_InverserZoom) calcZoom *= -1; // on rapelle que le zoom est une valeur positive // zoom avant si < 1 // zoom arrière si > 1 if(calcZoom > 0) calcZoom = 1/calcZoom; // calcZoom < 1 if(calcZoom < 0) calcZoom = -calcZoom; // calcZoom > 1 vue->Zoom(calcZoom); zoomActuel *= calcZoom; if(affichage) std::cout<<"ZOOM: " << zoomActuel << std::endl; } // fin gestion des boutons de la souris //======================== // MOUVEMENTS DE LA SOURIE else if(event.Type == Event::MouseMoved) { // si la souris bouge et que le bouton droit est appuyé if(sourisDroit) { // on bouge la vue d'un nombre de px égal à la différence entre la position de la sourie et la position de la sourie lorsque le clic gauche à été fait // note : on multiplie pas 1/zoom pour que ce dernier agisse sur le déplacement. Plus logique et pratique float tmpx = -(event.MouseMove.X - posSourie.x)/zoomActuel; float tmpy = -(event.MouseMove.Y - posSourie.y)/zoomActuel; if(NAV_InverserDefilement) { tmpx *= -1; tmpy *= -1; } vue->Move(tmpx, tmpy); // on modifie les coordonnées de la sourie pour éviter d'additionner nombres toujours plus grands posSourie.x = event.MouseMove.X; posSourie.y = event.MouseMove.Y; } // si la souris bouge et que le bouton gauche est appuyé else if(sourisGauche) { // si on a ferré la BoiteInfoAstre if(boiteInfoBougee) { // même technique que pour le clic droit, mais indépendant du zoom (l'interface n'est pas liée au zoom) float tmpx = (event.MouseMove.X - posSourie.x); float tmpy = (event.MouseMove.Y - posSourie.y); bia->addPosition(tmpx, tmpy); // on modifie les coordonnées de la sourie pour éviter d'additionner nombres toujours plus grands posSourie.x = event.MouseMove.X; posSourie.y = event.MouseMove.Y; } } } // fin de gestion des mouvements de la souris } // FIN GESTION EVENEMENT // on vide l'écran (couleur noire) app->Clear(); // et on affiche le shmilblick affichageSFML(); // actualisation de l'écran app->Display(); } // fin de la boucle maîtresse if(affichage) std::cout << "LAB: \tBoucle maîtresse terminée" << std::endl; }
int Game::Run(RenderWindow &win, VideoMode &vMode) { Music m; SoundBuffer playerShootBuffer; SoundBuffer meteorBuffer; meteorBuffer.LoadFromFile("..\\Resources\\meteorexplosion.ogg"); playerShootBuffer.LoadFromFile("..\\Resources\\playerShoot.ogg"); Sound playerSound; Sound meteorSound; meteorSound.SetBuffer(meteorBuffer); playerSound.SetBuffer(playerShootBuffer); playerSound.SetLoop(false); meteorSound.SetLoop(false); m.OpenFromFile("..\\Resources\\asteroid.ogg"); m.SetLoop(true); m.SetVolume(100); PlayerShip ship(player_ship, 2, vMode); EnemyShip enemy(enemy_ship, vMode); Collision col; Event events; Image bg1; Image bg2; Image bg3; bg1.LoadFromFile("..\\Resources\\bg.jpg"); Image stars; string abc = "..\\Resources\\star.png"; stars.LoadFromFile(abc); Sprite sp(bg1); Sprite sp2(bg1); Sprite sp3(bg1); Sprite spStar[10]; Clock clock; srand((unsigned)time(0)); for(int i = 0; i<10; i++) { spStar[i].SetImage(stars); //spStar[i].SetPosition } spStar[0].SetPosition(0,100); spStar[1].SetPosition(70,200); spStar[2].SetPosition(200,300); spStar[3].SetPosition(320,400); spStar[4].SetPosition(460,500); spStar[5].SetPosition(260,300); spStar[6].SetPosition(160,400); spStar[7].SetPosition(400,200); spStar[8].SetPosition(760,100); spStar[9].SetPosition(800,600); int lowestx, highestx, lowesty, highesty, rangex, rangey, random_integerx, random_integery; float time1 = 0; float time2 = 0; bool start = false; //Sprite spStar1(stars); //spStar1.SetPosition(spStar.GetPosition().x, spStar.GetPosition().y - spStar.GetSize().y); sp.Resize((float)vMode.Width, (float)vMode.Height); sp2.Resize((float)vMode.Width, (float)vMode.Height); sp2.SetPosition(sp.GetPosition().x, sp.GetPosition().y - sp.GetSize().y); sp3.SetPosition(sp2.GetPosition().x, sp2.GetPosition().y - sp2.GetSize().y); //spStar.Resize((float)vMode.Width, (float)vMode.Height); bool key = false; bool down = false; Bullet *bul; Meteor* met[METEORCOUNT]; for(int i = 0; i<METEORCOUNT; i++) { met[i] = new Meteor(meteor, vMode); } met[0]->SetPosition(200,-400); met[1]->SetPosition(420,-200); met[2]->SetPosition(720,-400); met[3]->SetPosition(520,-600); met[4]->SetPosition(320,-400); /*met[5]->SetPosition(620,-400); met[6]->SetPosition(100,-400); */ int bulletCount = 0; vector<Bullet*> bulletVector; vector<Meteor*> meteorVector; for(int i = 0; i<METEORCOUNT; i++) { meteorVector.push_back(met[i]); } bool fired = false; bool pressed = false; int count; bool change = false; //win.UseVerticalSync(true); //win.SetFramerateLimit(60); int type = pistol; Image sunImg; sunImg.LoadFromFile("..\\Resources\\Sun.png"); Sprite sunSp(sunImg); sunSp.SetPosition(500,2000); //void* user; //int score = 0; // enemys e(vMode); //Thread thread(Thread::FuncType Move,void* enemy, void* &win, void* ship); m.Play(); while(win.IsOpened()) { while(win.GetEvent(events)) { if(events.Type == Event::Closed) { win.Close(); return -1; } if((events.Type == Event::KeyPressed) && (events.Key.Code == Key::Escape)) { return 0; } if(ship.IsDestroyed() && ((events.Type == Event::KeyPressed) && (events.Key.Code == Key::Return))) { return 0; } } if(win.GetInput().IsKeyDown(Key::Up) && !ship.IsDestroyed()) { ship.Throttled(); } if(!win.GetInput().IsKeyDown(Key::Up)&& !ship.IsDestroyed()) { ship.NoThrottle(); key = false; } if(!win.GetInput().IsKeyDown(Key::Right) && !win.GetInput().IsKeyDown(Key::Up) && !ship.IsDestroyed()) { ship.NoThrottle(); } if(!win.GetInput().IsKeyDown(Key::Left)&& !win.GetInput().IsKeyDown(Key::Up) && !ship.IsDestroyed()) { ship.NoThrottle(); } if(win.GetInput().IsKeyDown(Key::Right) && !ship.IsDestroyed()) { ship.Right(); if(ship.GetPositionX()<=vMode.Width) { //ship.SetSpeed(100); ship.AddVelocity(300,0); ship.MoveSide(win.GetFrameTime()); } } if(win.GetInput().IsKeyDown(Key::Left) && !ship.IsDestroyed()) { ship.Left(); if(ship.GetPositionX()>=0) { ship.AddVelocity(-300,0); //ship.SetSpeed(-100); ship.MoveSide(win.GetFrameTime()); } } if(win.GetInput().IsKeyDown(Key::LShift)) { ship.TellDestroyed(); //ship.Destroyed(); //win.Close(); } if(win.GetInput().IsKeyDown(Key::B)) { } if(win.GetInput().IsKeyDown(Key::Space) && !ship.IsDestroyed()&&!pressed) { playerSound.Play(); bul = new Bullet(bullets, vMode, &ship, type); //bul->ChangeType(type); //bul->ChangeType(pistol); bulletVector.push_back(bul); count = bulletVector.size(); //cout<<count; pressed = true; } if(!win.GetInput().IsKeyDown(Key::Space)) { pressed = false; } if(win.GetInput().IsKeyDown(Key::N)) { type = laser; for(int i = 0; i< METEORCOUNT; i++) { met[i]->SetDestroyed(); } } win.Clear(); ship.MoveUp(win.GetFrameTime()); if(enemy.GetPositionY()>ship.GetPositionY()-500) { enemy.MoveUp(&win, ship); //enemy.NavigatorUp(&win, ship); } //ship.Simulate(win.GetFrameTime(), key, down); for(int i = 0; i<10; i++) { if(spStar[i].GetPosition().y>ship.GetPositionY() + 50) { lowesty=(int)ship.GetPositionY(), highesty=(int)ship.GetPositionY()-600; rangey=(highesty-lowesty)+1; random_integery; random_integery = lowesty+int(rangey*rand()/(RAND_MAX + 1.0)); //cout << random_integery << endl; lowestx=0, highestx=800; rangex=(highestx-lowestx)+1; random_integerx; random_integerx = lowestx+int(rangex*rand()/(RAND_MAX + 1.0)); //cout << random_integerx << endl; spStar[i].SetPosition((float)random_integerx, (float)random_integery); } } for(int i = 0; i<METEORCOUNT; i++) { if(ship.GetPositionY()<=-2000)//Score compare { met[i]->ChangeSpeed(); } met[i]->Update(win.GetFrameTime()); if(met[i]->GetPositionY()>ship.GetPositionY() + 50) { lowesty=(int)ship.GetPositionY() - 600, highesty=(int)ship.GetPositionY()-1200; rangey=(highesty-lowesty)+1; random_integery; random_integery = lowesty+int(rangey*rand()/(RAND_MAX + 1.0)); //cout << random_integery << endl; lowestx=0, highestx=720; rangex=(highestx-lowestx)+1; random_integerx; random_integerx = lowestx+int(rangex*rand()/(RAND_MAX + 1.0)); // cout << random_integerx << endl; if(met[i]->IsDestroyed()) { met[i]->SetAlive(); } met[i]->SetPosition(random_integerx, random_integery); if(!ship.IsDestroyed()) { ship.IncreaseScore(); ship.UpdateScore(); } } met[i]->UpdateAI(); } if(enemy.IsFired()) { if(col.PixelPerfectTest(enemy.GetBullet(), ship.GetSprite())) { //ship.TellDestroyed(); ship.DecreaseHealth(); if(ship.GetHealth()<=0) { ship.TellDestroyed(); } enemy.BulletReset(); enemy.NotAttacking(); } } if(!meteorVector.empty()) { for(int i = 0; i<METEORCOUNT; i++) { if(col.CircleTest(enemy.GetBullet(), meteorVector[i]->GetSprite())) { //win.Close(); //ship.TellDestroyed(); met[i]->SetDestroyed(); meteorSound.Play(); enemy.BulletReset(); } if(col.CircleTest(ship.GetSprite(), meteorVector[i]->GetSprite())) { //win.Close(); ship.TellDestroyed(); met[i]->SetDestroyed(); } if(col.CircleTest(ship.GetSprite(), sunSp)) { //win.Close(); ship.TellDestroyed(); //met[i]->SetDestroyed(); } if(col.PixelPerfectTest(enemy.GetSprite(), meteorVector[i]->GetSprite())) { //win.Close(); enemy.DecreaseHealth(10); met[i]->SetDestroyed(); meteorSound.Play(); } if(col.PixelPerfectTest(enemy.GetSprite(), sunSp)) { //win.Close(); enemy.DecreaseHealth(20); //met[i]->SetDestroyed(); } // if(col.PixelPerfectTest(meteorVector[i]->GetSprite(), enemy.GetNavigator2())||(col.PixelPerfectTest(meteorVector[i]->GetSprite(), enemy.GetNavigator3())||(col.PixelPerfectTest(sunSp, enemy.GetNavigator3()) ))) { //win.Close(); enemy.MoveLeft(1, &win, ship); } else if(col.PixelPerfectTest(meteorVector[i]->GetSprite(), enemy.GetNavigator1())||(col.PixelPerfectTest(meteorVector[i]->GetSprite(), enemy.GetNavigator4())||(col.PixelPerfectTest(sunSp, enemy.GetNavigator4()) ))) { //win.Close(); enemy.MoveRight(&win, ship); } else { enemy.Attacking(); enemy.UpdatePlayerPosition(ship.GetSprite().GetPosition(), &win); } if(!bulletVector.empty()) { for(int j = 0; j< (int)bulletVector.size(); j++) { //if((bulletVector[j]->GetSprite().GetPosition().x >= meteorVector[i]->GetSprite().GetPosition().x && bulletVector[j]->GetSprite().GetPosition().x < meteorVector[i]->GetSprite().GetPosition().x +meteorVector[i]->GetSprite().GetSize().x ) && (bulletVector[j]->GetSprite().GetPosition().y >= meteorVector[i]->GetSprite().GetPosition().y && bulletVector[j]->GetSprite().GetPosition().y < meteorVector[i]->GetSprite().GetPosition().y + meteorVector[i]->GetSprite().GetSize().x)) //{ // //win.Close(); // bulletVector[j]->Hit(); // meteorVector[i]->SetDestroyed(); // delete bulletVector[j]; // bulletVector.erase(bulletVector.begin() + j); //} if(col.PixelPerfectTest(enemy.GetBullet(), ship.GetSprite())) { //ship.TellDestroyed(); /*ship.DecreaseHealth(); if(ship.GetHealth()<=0) { ship.TellDestroyed(); }*/ } if(col.PixelPerfectTest(bulletVector[j]->GetSprite(), enemy.GetSprite())) { enemy.DecreaseHealth(); meteorSound.Play(); bulletVector[j]->Hit(); delete bulletVector[j]; bulletVector.erase(bulletVector.begin() + j); } else if(col.PixelPerfectTest(bulletVector[j]->GetSprite(), meteorVector[i]->GetSprite())) { bulletVector[j]->Hit(); meteorVector[i]->SetDestroyed(); meteorSound.Play(); delete bulletVector[j]; bulletVector.erase(bulletVector.begin() + j); } //if(col.BoundingBoxTest(bulletVector[j]->GetBulletSprite(), meteorVector[i]->GetSprite()))//collision condition should be checked here bullet and other ships //{ // cout<<i<<"T"; // cout<<j<<"T"; // win.Close(); // bulletVector[j]->Hit(); //} } } } } ship.UpdateAI(); if(enemy.GetPositionY()>ship.GetPositionY()-700) enemy.UpdateAI(); if(enemy.IsDestroyed()) { lowestx=200, highestx=620; rangex=(highestx-lowestx)+1; random_integerx; random_integerx = lowestx+int(rangex*rand()/(RAND_MAX + 1.0)); enemy.EnemyReset(random_integerx, ship); if(!ship.IsDestroyed()) { ship.IncreaseScore(10); ship.UpdateScore(); } } //win.Draw(sp); //win.Draw(sp2); //win.Draw(sp3); ship.UpdateHealth(); Drawing drawing; drawing.win = &win; drawing.ship = &ship; drawing.enemy = &enemy; drawing.Bulletvectors = bulletVector; drawing.MeteorCounts = METEORCOUNT; for(int i = 0; i<5; i++) drawing.met[i] = met[i]; win.Draw(sunSp); for(int i = 0; i< 10; i++) win.Draw(spStar[i]); //win.Draw(spStar1); //ship.UpdateScore(); // DrawingTHread(drawing); ship.Draw(&win); //score.SetPosition(100,100); //win.Draw(score); if(enemy.GetPositionY()>ship.GetPositionY()-700) enemy.Draw(&win, ship); for(int i = 0; i<METEORCOUNT; i++) { met[i]->Draw(&win); } if(!bulletVector.empty()) { for(int i = 0; i<(int)bulletVector.size();i++) { //d.Bulletvectors[i]->ChangeType(type); bulletVector[i]->Fired(); bulletVector[i]->Draw(&win, &ship); bulletVector[i]->UpdateBullet(win.GetFrameTime()); bulletVector[i]->UpdateAI(); //if(d.Bulletvectors[i]->GetPositiony()<=ship.GetPositionY()-500) win.Close(); if(bulletVector[i]->GetPositiony()<ship.GetPositionY()-600) { delete bulletVector[i]; bulletVector.erase(bulletVector.begin()+i); //count = d.Bulletvectors.size(); //cout<<count<<"\n"; } } } win.SetView(ship.GetView()); win.Display(); } return 1; }