Alvaro Cassinelli / Mbed 2 deprecated skinGames_forktest

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

blobConfig.cpp

Committer:
mbedalvaro
Date:
2012-09-23
Revision:
31:5f039cbddee8
Parent:
30:d8af03f01cd4
Child:
32:52273c3291fe

File content as of revision 31:5f039cbddee8:


#include "blobConfig.h"

blobConfig::blobConfig(): numBlobs(0) {
    //blobArray.clear();// there is no need to do this, the vector does not contains anything here.
}

blobConfig::~blobConfig() {
    clearConfig();
}

// =========================================== STANDARD CONFIGURATIONS =============================================================================



void blobConfig::clearConfig() {
    for (int i=0; i<blobArray.size(); i++) delete blobArray[i]; // we must delete the pointer created with new, so the memory for the object is liberated (calls its destructor)
    blobArray.clear();
    numBlobs=0;// this is just equal to blobArray.size()
}

void blobConfig::initConfig(configType cfType,  int numblobs) {
    myConfigType=cfType;
    int i;
    switch(myConfigType) {
        case ONE_ELASTIC_FOLLOWING:
            // computeBoundingBox();
            clearConfig();
            addOneElasticContourFollowing();
        break;
        case ONE_ELASTIC_MOUTH:
            // computeBoundingBox();
            clearConfig();
            addOneElasticLoopContractCentral();
        break;
        case ONE_ELASTIC_MOUTH_SMALL:
            // computeBoundingBox();
            clearConfig();
            addOneElasticLoopContractCentralFast();
        break;
        case BOUNCING_SPOTS:
            // computeBoundingBox();
           clearConfig();
           for (i=0; i<numblobs ; i++) addOneRigidLoopBouncing();
        break;
        case LORENTZ_SPOTS:
         // computeBoundingBox();
            clearConfig();
            for (i=0; i<numblobs ; i++) addOneRigidLoopLorentz();
        break;
        case FOLLOWING_SPOTS:
         // computeBoundingBox();
            clearConfig();
            for (i=0; i<numblobs ; i++) addOneRigidLoopFollowing(vector2Df(CENTER_AD_MIRROR_X+i*200, CENTER_AD_MIRROR_Y+i*200), vector2Df(20,0));
        break;
        case ONE_TRACKING_SPOT:
           clearConfig();
           addOneRigidTrackingSpot();
        break;
         case ONE_TRACKING_SPOT_DOT:
           clearConfig();
           addOneRigidTrackingSpotDot();
        break;
        case AIR_HOCKEY_GAME: 
            // computeBoundingBox();
            clearConfig();
            for (i=0; i<numblobs ; i++) addOneRigidLoopAirHockey();
        break;
        case CIRCULAR_PONG_GAME:
            // computeBoundingBox();
            clearConfig();
            // (1) One SPOT_TRACK to track the background. It will be the number 0 in the config. 
            addOneRigidTrackingSpotDot();
            // (2) Add bouncing spots:
            for (i=0; i<numblobs ; i++) {
                float anglaux=1.0*i/numblobs*2*PI;
                addOneRigidLoopBouncing(vector2Df(CENTER_AD_MIRROR_X+200*cos(anglaux), CENTER_AD_MIRROR_Y+200*sin(anglaux)), 
                                        vector2Df(cos(anglaux),sin(anglaux))*10);
            }
        break;
        case VERTICAL_PINBALL_GAME:
         clearConfig();
         // (1) one (or two9 SPOT_TRACK_DOT to track the background - It will be the number 0 (and 1) in the config. 
          addOneRigidTrackingSpotDot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y+600), 
                                     vector2Df(0,0));
         // (2) one bouncing spot with gravity:
         addOneRigidLoopBouncingGravity(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y-600), 
                                 vector2Df(0,0));                      

        break; 
        case FISH_NET_GAME:
        clearConfig();
         // (1) one SPOT_TRACK_DOT to track the background - It will be the number 0  
          addOneRigidTrackingSpotDot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y),  // CENTERED
                                     vector2Df(0,0));
        // (2) Add bouncing spots without gravity:
            for (i=0; i<numblobs ; i++) {
                float anglaux=1.0*i/numblobs*2*PI;
                addOneRigidLoopBouncing(vector2Df(CENTER_AD_MIRROR_X+400*cos(anglaux), CENTER_AD_MIRROR_Y+400*sin(anglaux)), 
                                        vector2Df(cos(anglaux),sin(anglaux))*10);
            }                      
        break;
        case PAC_MAN_GAME:
            clearConfig();
            //(1) add one very slowly slidind-bouncing spot, the PACMAN (number 0 in the config)
           // addOneRigidLoopPacman(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), vector2Df(20,0));
           // addOneRigidTrackingSpot(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), vector2Df(0,0));
            addOneRigidLoopFollowing(vector2Df(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y), vector2Df(10,0));
            
            // (2) Add some initial SPOT_FOLLOWING or SPOT_GHOST spots (the ghosts):
            //for (int i=0; i<numBlobs; i++) 
            //addOneRigidLoopFollowing(vector2Df(CENTER_AD_MIRROR_X-200, CENTER_AD_MIRROR_Y-200), vector2Df(0,0));
            addOneRigidLoopGhost(vector2Df(CENTER_AD_MIRROR_X+500, CENTER_AD_MIRROR_Y-500), vector2Df(10,0));
            addOneRigidLoopGhost(vector2Df(CENTER_AD_MIRROR_X-500, CENTER_AD_MIRROR_Y-500), vector2Df(10,0));
        break;
        default:
        break;
    }
}

 // ==================== Template spots from which to create multi-spot configurations: =====================

void blobConfig::addOneElasticLoopRelax(vector2Df initpos, vector2Df initspeed) {
    elasticLoop* pBlob= new elasticLoop();
    pBlob->createBlob(blobArray.size(), RELAX, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();

}


void blobConfig::addOneElasticLoopContract(vector2Df initpos, vector2Df initspeed) {
    elasticLoop* pBlob= new elasticLoop();
    pBlob->createBlob(blobArray.size(), CONTRACT, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneElasticLoopContractCentral(vector2Df initpos, vector2Df initspeed) {
    elasticLoop* pBlob= new elasticLoop();
    pBlob->createBlob(blobArray.size(), CONTRACT_CENTRAL, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneElasticLoopContractCentralFast(vector2Df initpos, vector2Df initspeed) {
    elasticLoop* pBlob= new elasticLoop();
    pBlob->createBlob(blobArray.size(), CONTRACT_CENTRAL_FAST, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneElasticContourFollowing(vector2Df initpos, vector2Df initspeed) {

    elasticLoop* pBlob= new elasticLoop();
    pBlob->createBlob(blobArray.size(), CONTOUR_FOLLOWING, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}


void blobConfig:: addOneElasticContourFollowingFAST(vector2Df initpos, vector2Df initspeed) {
    elasticLoop* pBlob= new elasticLoop();
    pBlob->createBlob(blobArray.size(), CONTOUR_FOLLOWING_FAST,  initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneElasticBouncing(vector2Df initpos, vector2Df initspeed) {
    elasticLoop* pBlob= new elasticLoop();
    pBlob->createBlob(blobArray.size(), BOUNCING,  initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}
void blobConfig::addOneRigidLoopBouncingGravity(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_BOUNCING,  initpos, initspeed);
    // (We can use here methods of the child class, even if these are not declared virtual on the base class, because we are doing this BEFORE
    // adding this to the blobArray as a pointer). This is good to set parameters...
    pBlob->gravity.set(0,2.0);  
    pBlob->centerMass.dampMotion = 0.002;
   
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}
void blobConfig::addOneRigidLoopBouncing(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_BOUNCING, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneRigidLoopPacman(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_PACMAN, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}
void blobConfig::addOneRigidLoopGhost(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_GHOST, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}


void blobConfig::addOneRigidLoopLorentz(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_LORENTZ_FORCE, initpos, initspeed);
    // add this loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneRigidLoopAirHockey(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_AIR_HOCKEY,  initpos, initspeed);
    // add this loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneRigidLoopFollowing(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_FOLLOWING, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneRigidLoopTest(vector2Df initpos, vector2Df initspeed) {
    rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_TEST, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneRigidTrackingSpot(vector2Df initpos, vector2Df initspeed) {
   rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_TRACK, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}

void blobConfig::addOneRigidTrackingSpotDot(vector2Df initpos, vector2Df initspeed) {
   rigidLoop* pBlob= new rigidLoop();
    pBlob->createBlob(blobArray.size(), SPOT_TRACK_DOT, initpos, initspeed);
    // add this relaxing loop to the present config:
    blobArray.push_back(pBlob);

    // update auxiliary variable numBlobs (just for easy reference):
    numBlobs=blobArray.size();
}
// ==================================================================================================================================================


void blobConfig::allKill() { // this put all the blobs in "dead" mode, meaning that neither rendering nor update is done (but they are not deleted).
    for (int i=0; i<blobArray.size(); i++) {
        blobArray[i]->render = false;
        blobArray[i]->standByMode = false;
    }
}
void blobConfig::allAlive() {
    for (int i=0; i<blobArray.size(); i++) {
        blobArray[i]->render = true;
        blobArray[i]->standByMode = true;
    }
}

void blobConfig::allStandBy() {
    for (int i=0; i<blobArray.size(); i++) blobArray[i]->standByMode = true;
}

void blobConfig::allResume() {
    for (int i=0; i<blobArray.size(); i++) blobArray[i]->standByMode = false;
}

void blobConfig::allVisible() {
    for (int i=0; i<blobArray.size(); i++) blobArray[i]->render = true;
}

void blobConfig::allInvisible() { // note that they may continue to evolve
    for (int i=0; i<blobArray.size(); i++) blobArray[i]->render = false;
}

void blobConfig::allSetColor(unsigned char c) {
    for (int i=0; i<blobArray.size(); i++) blobArray[i]->setColor(c);
 }

void blobConfig::update() { // update dynamics of the blob configuration:
int i;
float minDist=5000, dist;
bool win;
    // Depending on the config type, perform some special test and updates: 
   switch(myConfigType) {
        // simple behaviours:
        case ONE_ELASTIC_FOLLOWING:
        case ONE_ELASTIC_MOUTH:
        case ONE_ELASTIC_MOUTH_SMALL:
        case BOUNCING_SPOTS:
        case LORENTZ_SPOTS:
        case FOLLOWING_SPOTS:
        case ONE_TRACKING_SPOT:
        case AIR_HOCKEY_GAME:
            // In all these simple cases, update dynamics of each blob independently:
            for (i=0; i<blobArray.size(); i++) {
                 if (blobArray[i]->standByMode==false) blobArray[i]->update();
            }
        break; 
        // more game-like:
        case CIRCULAR_PONG_GAME:
          // spot index 0 is a tracking spot, the background "anchor":
         if (blobArray[0]->standByMode==false) blobArray[0]->update();
         // all the other spots are bouncing spots:
        for (i=1; i<blobArray.size(); i++) {
            if (blobArray[i]->standByMode==false) blobArray[i]->update();
        }
        // GAME CHECK: is some bouncing spot too far from the anchor? if so, make it "explode" (and then dissapear, but leave this for now):
        for (i=1; i<blobArray.size(); i++) {
            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
            if (dist>1000) {
                blobArray[i]->explosion();
                float anglaux=1.0*(i-1)/(blobArray.size()-1)*2*PI;
                 blobArray[i]->setPositionSpeed(vector2Df(CENTER_AD_MIRROR_X+200*cos(anglaux), CENTER_AD_MIRROR_Y+200*sin(anglaux)), 
                                                vector2Df(cos(anglaux),sin(anglaux))*10);
            }
        }
        break;
        case VERTICAL_PINBALL_GAME:
          // spot index 0 is a tracking spot, the background "anchor":
         if (blobArray[0]->standByMode==false) blobArray[0]->update();
         // others are bouncing with gravity:
        for (i=1; i<blobArray.size(); i++) {
            if (blobArray[i]->standByMode==false) blobArray[i]->update();
        }
        // GAME CHECKS:
         for (i=1; i<blobArray.size(); i++) {
            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
            //(1) win (meaning bouncing spot very close to anchor):
            if (dist<60) {
                blobArray[i]->explosion();
                blobArray[i]->setPositionSpeed(vector2Df(blobArray[0]->getCenter().x-400+rand()%800, blobArray[0]->getCenter().y-1200), 
                                                        vector2Df(0, 0));
            }
            //(2) loose (meaning spot went outside range):
            if (blobArray[i]->getCenter().y>blobArray[0]->getCenter().y) {
                blobArray[i]->setPositionSpeed(vector2Df(blobArray[0]->getCenter().x-400+rand()%800, blobArray[0]->getCenter().y-1200), 
                                                        vector2Df(0, 0));
                }
            }
        break; 
        case FISH_NET_GAME:
         // spot index 0 is a tracking spot, the background "anchor":
         if (blobArray[0]->standByMode==false) blobArray[0]->update();
         // all the other spots are bouncing spots:
        for (i=1; i<blobArray.size(); i++) {
            if (blobArray[i]->standByMode==false) blobArray[i]->update();
        }
        // GAME CHECKS: a win only, when all the spots are very close to the mother spot:
         win=true;
         for (i=1; i<blobArray.size(); i++) {
            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
            win&=(dist<80);
        }
        if (win) {
            for (i=1; i<blobArray.size(); i++) {
            blobArray[i]->explosion();
             float anglaux=1.0*(i-1)/(blobArray.size()-1)*2*PI;
                 blobArray[i]->setPositionSpeed(vector2Df(CENTER_AD_MIRROR_X+400*cos(anglaux), CENTER_AD_MIRROR_Y+400*sin(anglaux)), 
                                                vector2Df(cos(anglaux),sin(anglaux))*10);
        }
        }
        break;
        case PAC_MAN_GAME:
        // spot index 0 is the pacman:
        if (blobArray[0]->standByMode==false) blobArray[0]->update();
        // spot 1 and 2 are ghosts:
        if (blobArray[1]->standByMode==false) blobArray[1]->update(blobArray[0]->getCenter());
        if (blobArray[2]->standByMode==false) blobArray[2]->update(blobArray[0]->getCenter()); // pass the position of the PACMAN!
        
        // GAME CHECK: are any ghost too close to the pacman?
        for (i=1; i<blobArray.size(); i++) {
            dist=(blobArray[0]->getCenter()).distance(blobArray[i]->getCenter());
            if (minDist>dist) minDist=dist;
        }
        if (minDist<50) {
             blobArray[0]->explosion();
             // then restart the game: 
            // initConfig(PAC_MAN_GAME);
        }
        
        break;
        default:
        break;
    }
     
    
}

void blobConfig::computeBoundingBox() {
    for (int i=0; i<blobArray.size(); i++) {
        blobArray[i]->computeBoundingBox();
    }
}

void blobConfig::draw() { // draw uses the opengl like renderer (if any), and save projected trajectory in the LaserSensingTrajectory object of each blob
    for (int i=0; i<blobArray.size(); i++) {
        if (blobArray[i]->render==true) blobArray[i]->draw();
    }
}

void blobConfig::sendConfData() {
// For the time being, only "per blob" data sending:
// (b) Per-spot sending of data (note: both are NOT exclusive; so if we want just packaged data, we need to make all the spot STOP sending data.
    for (int i=0; i<blobArray.size(); i++) { 
        if (blobArray[i]->render==true) blobArray[i]->sendData(); // a blob that is in stand-by mode may send data (good for testing with a fixed loop)
    }
}