Hey everyone,
I am trying to create a sketch, using the ofxBox2d addon, in which I can draw static lines (ofxBox2dEdge) across the screen which cause an ofxBox2dCircle to repel from them. After drawing the lines, I want to store them into an array and access them in draw() so that they remain on the screen, which is the part of the code I am struggling with. I managed to successfully store the previously drawn edges in a vector. However, I get an error message (“Need to update shape first”) when trying to loop through the vector in draw(). I have tried multiple ways to work around this, although nothing has worked.
If anyone could point me in a better direction or offer any advice, I would appreciate it.
Thank you in advance!
App.h
#pragma once
#include "ofMain.h"
#include "ofxBox2d.h"
// -------------------------------------------------
class ofApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
ofxBox2d box2d;
ofPolyline line;
ofxBox2dEdge edge;
vector <ofxBox2dEdge> savedEdges;
vector <shared_ptr<ofxBox2dCircle>> circles;
};
App.cpp
Setup()
void ofApp::setup() {
ofSetVerticalSync(true);
ofSetLogLevel(OF_LOG_NOTICE);
box2d.init();
box2d.setGravity(0, 10);
box2d.createGround();
box2d.setFPS(60.0);
}
Update()
void ofApp::update() {
box2d.update();
ofRemove(circles, ofxBox2dBaseShape::shouldRemoveOffScreen);
cout << savedEdges.size() << endl;
}
Draw()
This is where I am trying to access the vector and loop through the previous edges.
void ofApp::draw() {
ofSetColor(ofColor::black);
for(auto &circle:circles) {
ofFill();
circle->update();
circle->draw();
}
for(auto savedEdges:savedEdges){
savedEdges.draw();
}
edge.draw();
line.draw();
}
keyPressed()
void ofApp::keyPressed(int key) {
if(key == ' ') {
auto circle = make_shared<ofxBox2dCircle>();
circle->setPhysics(3.0, 0.53, 0.1);
circle->setup(box2d.getWorld(), ofRandom(400,600), 100, 20);
circles.push_back(circle);
}
}
mousePressed()
void ofApp::mousePressed(int x, int y, int button) {
if(edge.isBody()){
line.clear();
edge.destroy();
}
}
mouseDragged()
void ofApp::mouseDragged(int x, int y, int button) {
line.addVertex(x, y);
}
mouseReleased()
This is where I convert the polyline to an edge before pushing it into the vector, which I want to access in draw().
void ofApp::mouseReleased(int x, int y, int button) {
line.simplify();
edge.addVertexes(line);
edge.setPhysics(0.0, 0.5, 0.5);
edge.create(box2d.getWorld());
savedEdges.push_back(edge);
}