ofDocsexamples events customEventExample src ofApp.cpp
#include "ofApp.h"


/*

 This example demonstrates a simple game. We have a GameEvent class that is
 used to store the bullet and bug that just collided.


 Topics:
 ofEventArgs
 ofAddListener
 ofRemove
 vector math
 objects & classes

 by: Todd Vanderlin

 */

//--------------------------------------------------------------
bool ofApp::shouldRemoveBullet(Bullet &b) {

    if(b.bRemove) return true;


    bool bRemove = false;

    // get the rectangle of the OF world
    ofRectangle rec = ofGetCurrentViewport();

    // check if the bullet is inside the world
    if(rec.inside(b.pos) == false) {
        bRemove = true;
    }



    return bRemove;
}

//--------------------------------------------------------------
bool ofApp::shouldRemoveBug(Bug &b) {
    return b.bRemove;
}

//--------------------------------------------------------------
void ofApp::setup() {

    ofBackgroundHex(0xc5c9b2);
    ofSetFrameRate(60);

    bFire = false;
    bugsKilled = 0;
    maxBullets = 30;

    // add some random holes for the bugs to come out
    int nHoldes = 10;
    for(int i=0; i<nHoldes; i++) {
        glm::vec2 p(ofRandomWidth(), ofRandomHeight());
        holes.push_back(p);
    }

    // listen to any of the events for the game
    ofAddListener(GameEvent::events, this, &ofApp::gameEvent);

}

//--------------------------------------------------------------
void ofApp::gameEvent(GameEvent &e) {

    cout << "Game Event: "+e.message << endl;
    e.bug->timeBugKilled = ofGetElapsedTimef();
    e.bug->bSquashed = true;

    e.bullet->bRemove = true;

    bugsKilled ++;
}

//--------------------------------------------------------------
void ofApp::update() {

    if((int)ofRandom(0, 20)==10) {

        int randomHole = ofRandom(holes.size());

        Bug newBug;
        newBug.pos = holes[randomHole];
		newBug.vel = glm::vec2(ofRandom(-1, 1), ofRandom(-1, 1));
        bugs.push_back(newBug);
    }

    for(unsigned int i=0; i<bugs.size(); i++) {

        bugs[i].update();

        // bug pos and size
        float   size = bugs[i].size;
        glm::vec2 pos  = bugs[i].pos;

        // wrap the bugs around the screen
        if(pos.x > ofGetWidth()-size)  bugs[i].pos.x = -size;
        if(pos.x < -size)              bugs[i].pos.x = ofGetWidth()-size;
        if(pos.y > ofGetHeight()+size) bugs[i].pos.y = -size;
        if(pos.y < -size)              bugs[i].pos.y = ofGetHeight()-size;

    }

    // check if we should remove any bugs
    ofRemove(bugs, shouldRemoveBug);

    // update the bullets
    for(unsigned int i=0; i<bullets.size(); i++) {
        bullets[i].update();
    }

    // check if we want to remove the bullet
    ofRemove(bullets, shouldRemoveBullet);


    // did we hit a bug loop we are checking to see if a bullet
    // hits a bug. if so we are going to launch an event for the game
    for(unsigned int i=0; i<bullets.size(); i++) {
        for(unsigned int j=0; j<bugs.size(); j++) {

            glm::vec2 a       = bullets[i].pos;
            glm::vec2 b       = bugs[j].pos;
            float   minSize = bugs[j].size;

			if(glm::distance(a,b) < minSize) {

                static GameEvent newEvent;
                newEvent.message = "BUG HIT";
                newEvent.bug     = &bugs[j];
                newEvent.bullet  = &bullets[i];

                ofNotifyEvent(GameEvent::events, newEvent);
            }

        }
    }


}

//--------------------------------------------------------------
void ofApp::draw(){

    // draw the bug holes
    for(unsigned int i=0; i<holes.size(); i++) {
        ofSetColor(100);
		ofDrawCircle(holes[i], 10);
        ofSetColor(40);
		ofDrawCircle(holes[i], 7);
    }

    for(unsigned int i=0; i<bugs.size(); i++) {
        bugs[i].draw();
    }

    // draw the bullets
    for(unsigned int i=0; i<bullets.size(); i++) {
        bullets[i].draw();
    }



    // game stats
    ofSetColor(10);
    ofDrawBitmapString("Bullets "+ofToString(bullets.size())+"\nBugs Killed: "+ofToString(bugsKilled), 20, 20);


    // gun
    glm::vec2 gunPos(ofGetWidth()/2, ofGetHeight()-20);
    glm::vec2 mousePos(ofGetMouseX(), ofGetMouseY());

    // get the vector from the mouse to gun
    glm::vec2 vec = normalize(mousePos - gunPos);
    vec *= 100;

    // get the angle of the vector for rotating the rect
    float angle = ofRadToDeg(atan2(vec.y, vec.x)) - 90;

    ofPushMatrix();
    ofTranslate(gunPos.x, gunPos.y);
    ofRotateZDeg(angle);

    ofFill();
    ofSetColor(10);
    ofDrawRectangle(-10, 0, 20, 100);

    float bulletPct = ofMap(bullets.size(), 0, maxBullets, 0.0, 100.0);
    ofSetColor(100);
    ofDrawRectangle(-10, 0, 20, bulletPct);

    ofSetColor(100);
    ofDrawRectangle(-10, 90, 20, 10);

    if(bFire) {
        ofSetColor(220, 0, 0);
        ofDrawRectangle(-10, 97, 20, 3);
    }
    ofPopMatrix();

    ofSetColor(255);
	ofDrawCircle(gunPos.x, gunPos.y, 2);

}

//--------------------------------------------------------------
void ofApp::keyPressed(int key) {
    if(key == ' ') {
        if(bullets.size() < maxBullets) {
            bFire = true;

            Bullet b;

            // the two points for the mouse and gun
            glm::vec2 gunPt(ofGetWidth()/2, ofGetHeight()-20);
            glm::vec2 mousePt(ofGetMouseX(), ofGetMouseY());

            // the vector between the two, and normalized = 0.0 - 1.0
			glm::vec2 vec = glm::normalize(mousePt - gunPt);

            // bullet position = the start pos of the gun
            // and the vec scaled by 100
            glm::vec2 bulletPos = gunPt + (vec * 100);

            b.pos     = bulletPos;
            b.vel     = vec * ofRandom(9, 12); // randomly make it faster
            b.bRemove = false;

            // add the bullets to the array
            bullets.push_back(b);
        }
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key) {
    bFire = false;
}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}