/***************************************************************************** * * Copyright (C) 2003 Cédric Brégardis * * This file is part of BRIQUOLO * * BRIQUOLO is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * BRIQUOLO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with BRIQUOLO; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *****************************************************************************/ #include #include "BriquePolygone.h" #include "ExplosionBrique.h" #include #include #include #include "BibliothequeSon.h" #ifndef M_PI #define M_PI 3.14159265359 #endif #define SIGN(a) (((a)<0)?-1:1) BriquePolygone::BriquePolygone(TableauBase * p_TableauBase): ElementTableau(p_TableauBase), _Z(0), _VitesseZ(9), _Rotation(0), _Rayon(0), _VitesseRotation(0) { _Z=2*M_PI*(rand()/(RAND_MAX+0.0))-1; } BriquePolygone::BriquePolygone(const BriquePolygone & p_BriquePolygone): ElementTableau(p_BriquePolygone), _ListPoint(p_BriquePolygone._ListPoint), _VitesseZ(9) { _Z=2*M_PI*(rand()/(RAND_MAX+0.0))-1; } BriquePolygone::~BriquePolygone() { } void BriquePolygone::Maj() { _Z+=MOGL_Temps::GetVariationDistance(_VitesseZ); if (_Z>=2*M_PI) { _Z-=static_cast(2*M_PI); } _ElementArbre->ReinitialiserPosition(); _ElementArbre->AjouterTranslation(_Rayon, 0,0); MOGL_Struct_Vecteur vect; vect.x=0; vect.y=0; vect.z=-_VitesseRotation; vect = MOGL_Temps::GetVariationVecteurAngle(vect); vect.z += _Rotation; _Rotation = vect.z; MOGL_MatriceTransformation mat = MOGL_MatriceTransformation::FabriqueRotation(0,0,_Rotation); _ElementArbre->AjouteTransformation(mat); _ElementArbre->AjouterTranslation(_X,_Y,sin(_Z)/4); } void BriquePolygone::InitialiserPosition() { _ElementArbre->ReinitialiserPosition(); _ElementArbre->AjouterTranslation(_Rayon, 0,0); MOGL_MatriceTransformation mat = MOGL_MatriceTransformation::FabriqueRotation(0,0,_Rotation); _ElementArbre->AjouteTransformation(mat); _ElementArbre->AjouterTranslation(_X,_Y,0); } void BriquePolygone::SetPosition(double p_X, double p_Y) { _X=p_X; _Y=p_Y; if (_ElementArbre!=NULL) { _ElementArbre->ReinitialiserPosition(); _ElementArbre->AjouterTranslation(_X,_Y,sin(_Z)/4); } } void BriquePolygone::_AnalyserLigne() { ElementCollision::_AnalyserLigne(); It_Map_Params it; it = _Params.find("rspeed"); if (it != _Params.end()) { stringstream st(it->second); st>>_VitesseRotation; } else { _VitesseRotation = 0; } it = _Params.find("r"); if (it != _Params.end()) { stringstream st(it->second); st>>_Rayon; } else { _Rayon = 0; } it = _Params.find("ri"); if (it != _Params.end()) { stringstream st(it->second); st>>_Rotation; } else { _Rotation = 0; } } Struct_Collision BriquePolygone::TesterCollision(Balle * p_Balle) { Struct_Collision collision; collision.TempsCollision = p_Balle->GetTempsMax(); collision.VitesseX=p_Balle->GetVitesseTotaleX(); collision.VitesseY=p_Balle->GetVitesseTotaleY(); Struct_Collision col, colCircle, colSegment; float rot = _VitesseRotation*3.14159/180; float roti = -_Rotation*3.14159/180; ListIt_Point it = _ListPoint.begin(); float xPrev = it->x; float yPrev = it->y; col = _CircleCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(), p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(), _X, _Y, roti, xPrev + _Rayon, yPrev, 0, 0, 0, rot, p_Balle->GetTempsMax()); for(it++; it != _ListPoint.end(); it++) { float x = it->x; float y = it->y; colSegment = _SegmentCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(), p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(), _X, _Y, roti, xPrev + _Rayon, yPrev, x + _Rayon, y, 0, 0, rot, 0, p_Balle->GetTempsMax()); colCircle = _CircleCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(), p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(), _X, _Y, roti, x + _Rayon, y, 0, 0, 0, rot, p_Balle->GetTempsMax()); if (colSegment.TempsCollision < col.TempsCollision) { col = colSegment; } if (colCircle.TempsCollision < col.TempsCollision) { col = colCircle; } xPrev = x; yPrev = y; } // Pour finir on teste le segment entre le premier et le dernier point : // on ferme le polygone it = _ListPoint.begin(); float x = it->x; float y = it->y; colSegment = _SegmentCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(), p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(), _X, _Y, roti, xPrev + _Rayon, yPrev, x + _Rayon, y, 0, 0, rot, 0, p_Balle->GetTempsMax()); if (colSegment.TempsCollision < col.TempsCollision) { col = colSegment; } if (col.TempsCollision < p_Balle->GetTempsMax()) { float angle = (360 - (_Modulo(_Rotation, 360)) + _Modulo(90 * SIGN(_VitesseRotation), 360)) * 3.14159/180; float vit = _VitesseRotation * 3.14159/180 * _Rayon; float vit_x = vit * cosf(angle); float vit_y = vit * sinf(angle); if (fabs(col.VitesseX) < fabs(vit_x)) { col.VitesseX = vit_x; } if (fabs(col.VitesseY) < fabs(vit_y)) { col.VitesseY = vit_y; } float fact = sqrt(col.VitesseX*col.VitesseX + col.VitesseY*col.VitesseY) / p_Balle->GetVitesseTotale(); col.AddFacteurCollision = fact; col.VitesseX /= fact; col.VitesseY /= fact; } return col; } bool BriquePolygone::Toucher(Balle * p_Balle, double p_Temps) { BibliothequeSon::SonExplosion->Jouer(false); return true; } Point BriquePolygone::GetVisualCenter() { MOGL_Struct_Vecteur vect={_Rayon, 0, 0}; MOGL_MatriceTransformation mat = MOGL_MatriceTransformation::FabriqueRotation(0,0,_Rotation); MOGL_Struct_Vecteur vect2 = mat.MultiplierVecteur(vect); return Point(vect2.x + _X, vect2.y + _Y); } void BriquePolygone::_AjouterPoint(float p_X, float p_Y) { _ListPoint.push_back(Point(p_X, p_Y)); }