目前,我正在做一个作业,我必须为此制作一个植绒系统,并使用行为不同的不同子类。我正在使用OpenFrameworks和C++。
我刚接触Open Frameworks和C++。

作为基础,我们使用以下代码:
https://sites.google.com/site/ofauckland/examples/ofxflocking-example

但是,问题是,这段代码的结构与我以前习惯的不同;用“new ...”制作新的类对象

我的问题是,如何使用两个植绒类?首先,例如仅使用其他颜色。

到目前为止,我添加的子类之一是:

class Team1 : public Boid {
public:

   Team1(): Boid() {};
   Team1(int x, int y): Boid(x,y) {};



   void draw()
    {

    }
};

我对父类(super class)Boid的虚空绘制使用了虚拟虚空绘制,并使用了boids.push_back(* new Team1());在设置和鼠标拖动中。这给出了以下错误:
  • Team1之前的预期类型说明
  • 预期)Team1之前
  • 没有匹配函数可以调用std::vector<Boid, std::allocator<Boid> >::push_back(int&)

  • 完整代码:(所有代码都在一个testapp.cpp文件中,以排除链接问题)
    //number of boids
    const int BoidAmount = 25;
    

    父类(super class)Boid:
    class Boid {
    public:
    Boid();
    Boid(int x, int y);
    
    void update(vector<Boid> &boids);
    virtual void draw() {};
    
    void seek(ofVec2f target);
    void avoid(ofVec2f target);
    void arrive(ofVec2f target);
    
    void flock(vector<Boid> &boids);
    
    ofVec2f steer(ofVec2f target, bool slowdown);
    
    ofVec2f separate(vector<Boid> &boids);
    ofVec2f align(vector<Boid> &boids);
    ofVec2f cohesion(vector<Boid> &boids);
    
    ofVec2f location,direction
    
    ,acceleration;
    
    float r;
    float attraction;
    float maxspeed;
    };
    

    构造函数:
     //---Constructors(overload)-----------------------------------------
    Boid::Boid() {
    location.set(ofRandomWidth(),ofRandomHeight());
    direction.set(0,0);
    acceleration.set(0,0);
    r = 3.0;
    maxspeed = 4;
    attraction = 0.05;
    }
    
    Boid::Boid(int x, int y) {
    location.set(x,y); //initial location
    direction.set(0,0); //initial direction
    acceleration.set(0,0); //initial acceleration
    r = 3.0;
    maxspeed = 4; // initial max speed
    attraction = 0.1; // initial max force
    }
    

    子类:
    class Team1 : public Boid {
    public:
    
    Team1(): Boid() {};
    Team1(int x, int y): Boid(x,y) {};
    
    
    
    void draw()
    {
        // Draw a triangle rotated in the direction of direction
        float angle = (float)atan2(-direction.y, direction.x);
        float theta =  -1.0*angle;
        float heading2D = ofRadToDeg(theta)+90;
    
        ofPushStyle();
        ofFill();
    
    
        ofPushMatrix();
        ofTranslate(location.x, location.y);
    
        ofRotateZ(heading2D);
        ofSetColor(255,255,255,80);
    
        ofEllipse(0, -r*2, 7, 12);
        ofBeginShape();
        ofVertex(0, -r*2);
        ofVertex(-r, r*2);
        ofVertex(r, r*2);
        ofEndShape(true);
        ofPopMatrix();
        ofPopStyle();
    }
    };
    
    class Team2 : public Boid {
    public:
    
    Team2(): Boid() {};
    Team2(int x, int y): Boid(x,y) {};
    
    
    void draw()
    {
    
    
    }
    
    };
    
    Methods:
    
    // Method to update location
    void Boid::update(vector<Boid> &boids) {
    
    flock(boids);
    
    direction += acceleration;   // Update direction
    direction.x = ofClamp(direction.x, -maxspeed, maxspeed);  // Limit speed
    direction.y = ofClamp(direction.y, -maxspeed, maxspeed);  // Limit speed
    location += direction;
    acceleration = 0;  // Reset accelertion to 0 each cycle
    
    if (location.x < -r) location.x = ofGetWidth()+r;
    if (location.y < -r) location.y = ofGetHeight()+r;
    
    if (location.x > ofGetWidth()+r) location.x = -r;
    if (location.y > ofGetHeight()+r) location.y = -r;
    }
    
    //SEEK
    void Boid::seek(ofVec2f target) {
    acceleration += steer(target, false);
    }
    
    
    
    // A method that calculates a steering vector towards a target
    // Takes a second argument, if true, it slows down as it approaches the target
    ofVec2f Boid::steer(ofVec2f target, bool slowdown) {
       ofVec2f steer;  // The steering vector
       ofVec2f desired = target - location;  // A vector pointing from the location to the target
    
    float d = ofDist(target.x, target.y, location.x, location.y); // Distance from the target is the magnitude of the vector
    
    
    // If the distance is greater than 0, calc steering (otherwise return zero vector)
    if (d > 0) {
    
        desired /= d; // Normalize desired
    
        // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
        if ((slowdown) && (d < 100.0f)) {
            desired *= maxspeed * (d/100.0f); // This damping is somewhat arbitrary
        } else {
            desired *= maxspeed;
        }
        // Steering = Desired minus direction
        steer = desired - direction;
        steer.x = ofClamp(steer.x, -attraction, attraction); // Limit to maximum steering force
        steer.y = ofClamp(steer.y, -attraction, attraction);
    
    }
    return steer;
    }
    
    
    
    //----------FLOCKING-BEHAVIOUR-------------------------------------------
    
    void Boid::flock(vector<Boid> &boids) {
    ofVec2f Seperation = separate(boids);
    ofVec2f Alignment = align(boids);
    ofVec2f Cohesion = cohesion(boids);
    
    // Arbitrarily weight these forces
    Seperation *= 1.5;
    Alignment *= 1.0;
    Cohesion *= 1.0;
    
    acceleration += Seperation + Alignment + Cohesion;
    }
    
    //--SEPERATION--
    // Method checks for nearby boids and steers away
    ofVec2f Boid::separate(vector<Boid> &boids) {
    float desiredseparation = 30.0;
    ofVec2f steer;
    int count = 0;
    
    // For every boid in the system, check if it's too close
    for (int i = 0 ; i < boids.size(); i++) {
        Boid &other = boids[i];
    
        float d = ofDist(location.x, location.y, other.location.x, other.location.y);
    
        // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
        if ((d > 0) && (d < desiredseparation)) {
            // Calculate vector pointing away from neighbor
            ofVec2f diff = location - other.location;
            diff /= d;          // normalize
            diff /= d;        // Weight by distance
            steer += diff;
            count++;            // Keep track of how many
        }
    }
    // Average -- divide by how many
    if (count > 0) {
        steer /= (float)count;
    }
    
    
    // As long as the vector is greater than 0
    //float mag = sqrt(steer.x*steer.x + steer.y*steer.y);
    
    float mag = sqrt(steer.x*steer.x + steer.y*steer.y);
    if (mag > 0) {
        // Steering = Desired - direction
        steer /= mag;
        steer *= maxspeed;
        steer -= direction;
        steer.x = ofClamp(steer.x, -attraction, attraction);
        steer.y = ofClamp(steer.y, -attraction, attraction);
    }
    return steer;
    }
    
    //--ALIGNMENT--
    // For every nearby boid in the system, calculate the average direction
    ofVec2f Boid::align(vector<Boid> &boids) {
    float neighbordist = 60.0;
    ofVec2f steer;
    int count = 0;
    for (int i = 0 ; i < boids.size(); i++) {
        Boid &other = boids[i];
    
        float d = ofDist(location.x, location.y, other.location.x, other.location.y);
        if ((d > 0) && (d < neighbordist)) {
            steer += (other.direction);
            count++;
        }
    }
    if (count > 0) {
        steer /= (float)count;
    }
    
    // As long as the vector is greater than 0
    float mag = sqrt(steer.x*steer.x + steer.y*steer.y);
    if (mag > 0) {
        // Implement Reynolds: Steering = Desired - direction
        steer /= mag;
        steer *= maxspeed;
        steer -= direction;
        steer.x = ofClamp(steer.x, -attraction, attraction);
        steer.y = ofClamp(steer.y, -attraction, attraction);
    }
    return steer;
    }
    
    //--COHESION--
    // For the average location (i.e. center) of all nearby boids, calculate steering vector towards     that location
    ofVec2f Boid::cohesion(vector<Boid> &boids) {
    float neighbordist = 50.0;
    ofVec2f sum;   // Start with empty vector to accumulate all locations
    int count = 0;
    for (int i = 0 ; i < boids.size(); i++) {
        Boid &other = boids[i];
        float d = ofDist(location.x, location.y, other.location.x, other.location.y);
        if ((d > 0) && (d < neighbordist)) {
            sum += other.location; // Add location
            count++;
        }
    }
    if (count > 0) {
        sum /= (float)count;
        return steer(sum, false);  // Steer towards the location
    }
    return sum;
    }
    
    //--------------------------------------------------------------
    bool isMouseMoving() {
    static ofPoint pmouse;
    ofPoint mouse(ofGetMouseX(),ofGetMouseY());
    bool mouseIsMoving = (mouse!=pmouse);
    pmouse = mouse;
    return mouseIsMoving;
    }
    

    vector 初始化:
    std::vector<Boid*> boids;
    

    --
    //--------------------------------------------------------------
    void testApp::setup() {
    ofSetBackgroundAuto(false);
    ofBackground(0,0,0);
    ofSetFrameRate(60);
    ofEnableAlphaBlending();
    for(int i=0; i<10; i++)
    {
        boids.push_back(new Team1());
        //boids.push_back(Boid());
    }
    }
    
    //--------------------------------------------------------------
    void testApp::update() {
    
    
        for(int i=0; i<boids.size(); i++) {
            boids[i]->seek(ofPoint(mouseX,mouseY));
        }
    
    
    
        for(int i=0; i<boids.size(); i++) {
            boids[i]->update(boids);
        }
    
    }
    
    //--------------------------------------------------------------
    void testApp::draw() {
    
    ofSetColor(0,0,0,20);
    ofRect(0,0,ofGetWidth(),ofGetHeight());
    
    for(int i=0; i<boids.size(); i++)
    {
        boids[i]->draw();
    }
    }
    
    //--------------------------------------------------------------
    void testApp::mouseDragged(int x, int y, int button) {
    
    
    boids.push_back(new Team1(x,y));
        ////boids.push_back(Boid());
        //boids.push_back(Boid(x,y));
    }
    

    最佳答案

    从错误看来,您似乎有一个std::vector<Boid>。您需要多态地持有Boids,因此您的 vector 应持有(最好是聪明的)指向Boid的指针:

    std::vector<Boid*> boids;
    

    或者
    std::vector<std::unique_ptr<Boid>> boids;
    

    然后您可以像这样填充:
    boids.push_back(new Team1());
    

    或者
    boids.push_back(std::unique_ptr<Boid>(new Team1()));
    

    分别。

    注意std::unique_ptr需要C++ 11支持。有关smart pointers here的更多信息。

    08-25 08:23