4

現在、私は異なる振る舞いをする異なるサブクラスで群れを作るシステムを作らなければならない課題に取り組んでいます。私はOpenFrameworksとC++で作業しています。私はOpenFrameworksとC++にかなり慣れていません。

基礎として、私はこのコードを使用します: https ://sites.google.com/site/ofauckland/examples/ofxflocking-example

ただし、このコードの構造は、私が慣れているものとは異なります。'new...'で新しいクラスオブジェクトを作成する

私の質問は、2つの群れのクラスをどのように使用できるかということです。まず、たとえば別の色だけを使用します。

これまでに追加したサブクラスの1つは、次のとおりです。

class Team1 : public Boid {
public:

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



   void draw()
    {

    }
};

スーパークラスBoidのボイド描画に仮想ボイド描画を使用し、boids.push_back(* new Team1());を使用しました。セットアップとマウスドラッグで。これにより、次のエラーが発生します。

  • 前に予想されるタイプ指定子Team1
  • )前に期待Team1
  • 呼び出しに一致する関数がありませんstd::vector<Boid, std::allocator<Boid> >::push_back(int&)

コード全体:(リンクの問題を除外するために、すべてのコードが1つのtestapp.cppファイルに含まれています)

//number of boids
const int BoidAmount = 25;

スーパークラスボイド:

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;
}

ベクトル初期化:

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));
}
4

2 に答える 2

2

エラーから、あなたはを持っているようですstd::vector<Boid>Boids多形的に保持する必要があるため、ベクトルは次のポインタを保持する必要があります(できればスマート) 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のサポートが必要であることに注意してください。スマートポインタの詳細については、こちらをご覧ください。

于 2012-11-06T14:44:32.630 に答える
1

boids.push_back(*new Team1());より多くのコードを見ずに確認するのは難しいですが、コード呼び出しはの定義を見ることができないと思いますTeam1。使用するすべての.cppファイルで#include定義するヘッダーファイルを作成する必要があります。Team1

また、ポリモーフィズム(仮想関数)を使用できるようにするには、実際のオブジェクトではなく、ベクトルにポインターを格納する必要があります。したがって、ベクトルをとして入力する必要がありますstd::vector<Boid*>。または、できれば、などのスマートポインタを使用しますstd::vector<std::shared_ptr<Boid> >

于 2012-11-06T14:47:34.293 に答える