#include "../Ngck_moteur/Ngck.h" #include "vector.h" enum type { vaisseau_ami, vaisseau_ennemi, tir_simple, sfx_fumee, sfx_explosion }; // Vecteur 2D class i2d { public: i2d() {}; ~i2d() {}; i2d(int _x, int _y) { mX=_x; mY=_y; }; i2d operator += (i2d other) {mX+=other.mX; mY+=other.mY; }; bool operator == (i2d other) {if ( (mX==other.mX) && (mY==other.mY) ) { return true; } else return false; }; bool operator != (i2d other) {if ( (mX!=other.mX) || (mY!=other.mY) ) { return true; } else return false; }; public: int mX; int mY; }; // ---------------------- class entite { public: entite() {}; ~entite() {}; virtual void Init(i2d pos); virtual void Update()=0; virtual void Display()=0; bool IsColliding( entite* other); // Check if a collision occur void ManageCollision( entite* other); // If collision, do collision management void SetType(type _type) { mType=_type; }; bool IsDead() { return mIsDead; } bool CanCollide() { return mCanCollide; }; void SetLifeTime(int time) { mLifeTime=time; }; void SetCollide(bool value) { mCanCollide=value; }; void SetSize(i2d size) { mSize=size; }; public: i2d mSize; i2d mPosition; bool mCanCollide; type mType; // Vaisseau ami, vaisseau enemi, Tir simple, sfx bool mIsDead; // Si vrai, l'entité doit disparaitre int mLifeTime; // -1 = infini, sinon >0 et decroit a chaque trame, =0 = mort }; // ----- void entite::Init(i2d pos) { mPosition=pos; mIsDead=false; mLifeTime=-1; mCanCollide=true; mSize=i2d(1,1); } // ---- class ManagerEntites { public: ManagerEntites() {}; ~ManagerEntites() {}; void Init(); void Update(); void Display(); void AddEntity(entite* entity); private: std::vector mAllEntities; }; // ---- class tirsimple : entite { public: tirsimple() {}; ~tirsimple() {}; void Init(i2d position, i2d direction); void Update(); void Display(); private: i2d mDirection; }; // ---- class vaisseau : entite { public: vaisseau() {}; ~vaisseau() {}; void Init(i2d pos); void Update(); void Display(); void SetVaisseauType(type _type) { SetType(_type); }; public: int tempsfumee; i2d mIADirection; }; // ---- class explosion : entite { public: explosion() {}; ~explosion() {}; void Init(i2d pos); void Update(); void Display(); }; // ---- class fumee : entite { public: fumee() {}; ~fumee() {}; void Init(i2d pos); void Update(); void Display(); }; // ---- // ----------------------------------------------------------- // Globales ManagerEntites gManagerEntites; // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ bool entite::IsColliding(entite* other) // Check if a collision occur { if ( other->mPosition == mPosition ) { return true; } return false; } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void entite::ManageCollision(entite* other) // If collision, do collision management { mIsDead=true; other->mIsDead=true; // Cree une explosion explosion* explo; explo = new explosion(); explo->Init(mPosition); gManagerEntites.AddEntity((entite*)explo); } // ---------------------- // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void ManagerEntites::Init() { mAllEntities.reserve(500); // 500 unités max } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void ManagerEntites::AddEntity(entite* entity) { if ( entity == NULL ) return; mAllEntities.push_back(entity); } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void ManagerEntites::Update() { // Parcours les entites. Utilise un iterateur pour pouvoir supprimer les entites mortes std::vector::iterator it; for (it = mAllEntities.begin(); it != mAllEntities.end(); ) { entite* current; current = *it; // Test si l'entité est morte if ( current->IsDead() ) { it = mAllEntities.erase(it); delete current; continue; } current->Update(); ++it; } // Test les colissons int size; size = mAllEntities.size(); int i,j; for (i=0; iCanCollide() && !mAllEntities[i]->IsDead() ) { for (j=i+1; jIsDead() || !mAllEntities[j]->CanCollide() ) continue; if ( mAllEntities[i]->IsColliding( mAllEntities[j] ) ) { mAllEntities[i]->ManageCollision( mAllEntities[j] ); } } } } // toutes les x secondes, ajoute un enemi if ( ( rand() % 20 ) == 0 ) { vaisseau* _vaisseau; _vaisseau = new vaisseau(); _vaisseau->Init(i2d( (rand()%10)+19,(rand()%20))); gManagerEntites.AddEntity((entite*)_vaisseau); } } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void ManagerEntites::Display() { // Parser les entités // Parser les entités int size; int i; size = mAllEntities.size(); for (i=0; iDisplay(); // Affiche le nombre d'entités KSetDisplayColor(WHITE); char machaine[256]; sprintf(machaine, "Nb entites : %d\n", mAllEntities.size() ); KPrintString(machaine,0,18); } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void tirsimple::Init(i2d position, i2d direction) { entite::Init(position); mDirection=direction; mLifeTime=256; } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void tirsimple::Update() { mLifeTime--; mPosition+=mDirection; // Test si dehors de l'écran // Borne le vaisseau dans l'écran if ( (mPosition.mX<0) || (mPosition.mY<0) || (mPosition.mX>29) || (mPosition.mY>19) ) { mIsDead=true; // demande a mourir } if ( (mLifeTime%4) == 0 ) { // Creation d'une fumee fumee* f; f = new fumee(); f->Init(mPosition); gManagerEntites.AddEntity((entite*)f); } } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void tirsimple::Display() { KSetDisplayColor(YELLOW); KPrintBall(mPosition.mX, mPosition.mY); } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void vaisseau::Init(i2d pos) { entite::Init(pos); SetType(vaisseau_ennemi); // par defaut cree un ennemi tempsfumee=0; mIADirection=i2d(0,0); } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void vaisseau::Update() { i2d oldpos; oldpos = mPosition; // Controle joueur if (mType==vaisseau_ami) { if ( KGetRight() ) mPosition.mX++; if ( KGetLeft() ) mPosition.mX--; if ( KGetUp() ) mPosition.mY--; if ( KGetDown() ) mPosition.mY++; if ( KGetSpace() ) { // Tir un missile tirsimple* tir; tir = new tirsimple(); tir->Init(mPosition, i2d(1,0)); gManagerEntites.AddEntity((entite*)tir); } } else { // Mechant // mIADirection int myrand; // 100 myrand = (rand() % 100); if ( myrand < 10 ) // Mechant, va vers le joueur { mIADirection.mX = -1; mIADirection.mY = 0; } else if ( myrand < 30 ) // Bouge pas { mIADirection.mX = 0; mIADirection.mY = 0; } else if ( myrand < 50 ) // Bouge au pif { mIADirection.mX = (myrand % 3)-1; mIADirection.mY = (myrand % 3)-1; } else if ( myrand < 60 ) // Tir { tirsimple* tir; tir = new tirsimple(); tir->Init(mPosition, i2d(-1,0)); gManagerEntites.AddEntity((entite*)tir); // Stop le vaisseau pour pas se manger le tir mIADirection.mX = 0; mIADirection.mY = 0; } // 50% ne change pas de direction mPosition += mIADirection; } // Borne le vaisseau dans l'écran if (mPosition.mX<0) mPosition.mX=0; if (mPosition.mY<0) mPosition.mY=0; if (mPosition.mX>29) mPosition.mX=29; if (mPosition.mY>19) mPosition.mY=19; tempsfumee++; if ( tempsfumee >= 5 && mPosition != oldpos ) { tempsfumee=0; // Creation d'une fumee fumee* f; f = new fumee(); f->Init(mPosition); gManagerEntites.AddEntity((entite*)f); } } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void vaisseau::Display() { if (mType == vaisseau_ami ) KSetDisplayColor(BLUE); else KSetDisplayColor(RED); KPrintSquare(mPosition.mX, mPosition.mY); } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void explosion::Init(i2d pos) { entite::Init(pos); SetLifeTime(10); SetCollide(false); } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void explosion::Update() { mLifeTime--; if (mLifeTime==0) mIsDead=true; } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void explosion::Display() { KSetDisplayColor(RED); if ( ( mLifeTime % 2 ) == 1 ) { KPrintSquare(mPosition.mX-1, mPosition.mY-1 ); KPrintSquare(mPosition.mX, mPosition.mY-1 ); KPrintSquare(mPosition.mX+1, mPosition.mY-1 ); KPrintSquare(mPosition.mX-1, mPosition.mY ); KPrintSquare(mPosition.mX+1, mPosition.mY ); KPrintSquare(mPosition.mX-1, mPosition.mY+1 ); KPrintSquare(mPosition.mX, mPosition.mY+1 ); KPrintSquare(mPosition.mX+1, mPosition.mY+1 ); } } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void fumee::Init(i2d pos) { entite::Init(pos); SetLifeTime(5); SetCollide(false); } // ------------------------------------------------------------------ // Name : // ------------------------------------------------------------------ void fumee::Update() { mLifeTime--; if (mLifeTime==0) mIsDead=true; } // ------------------------------------------------------------------ // Name : // 3 = nothing // 2 = 1 point // 1 = 4 points // ------------------------------------------------------------------ void fumee::Display() { KSetDisplayColor(WHITE); if ( mLifeTime == 3 ) { KPrintBall(mPosition.mX, mPosition.mY ); } else if ( mLifeTime == 2 ) { KPrintBall(mPosition.mX, mPosition.mY ); //KPrintBall(mPosition.mX-1, mPosition.mY-1 ); //KPrintBall(mPosition.mX+1, mPosition.mY+1 ); } else if ( mLifeTime == 1 ) { //KPrintBall(mPosition.mX+1, mPosition.mY-1 ); //KPrintBall(mPosition.mX-1, mPosition.mY+1 ); } } // ------------------------------------------------------------------ // Name : InitialiseGame // ------------------------------------------------------------------ void InitialiseGame() { gManagerEntites.Init(); vaisseau* _vaisseau; _vaisseau = new vaisseau(); _vaisseau->Init(i2d(3,10)); _vaisseau->SetVaisseauType(vaisseau_ami); gManagerEntites.AddEntity((entite*)_vaisseau); } // ------------------------------------------------------------------ // Name : GameLoop // ------------------------------------------------------------------ void GameLoop() { // Gestion effets speciaux // Gestion entités gManagerEntites.Update(); // Affichage Sfx // Affichage entités gManagerEntites.Display(); } // -----------------------------------------------------------