class Pebble { boolean caught; private Particle p; private float px, py; private float rad; private color c; Pebble(Particle _p, color _c) { p = _p; rad = 10/p.mass(); c = _c; caught = false; } void update() { if ( y() > height + 50 || x() < -rad || x() > width + rad ) p.kill(); } void collide(Pebble peb) { if ( peb == this ) return; float ad = dist(x(), y(), peb.x(), peb.y()); float rd = (rad + peb.radius()); if ( ad == 0 ) { peb.moveTo(x() + rd/2, y() + rd/2); moveTo(x() - rd/2, y() - rd/2); } else if ( ad < rd ) { float dx = (peb.x() - x())/ad; float dy = (peb.y() - y())/ad; if ( dy <= 0 ) { peb.moveTo(x() + dx*rd, y() + dy*rd); //peb.addVelocity(dx, dy); } else { moveTo(x() - dx*rd, y() - dy*rd); //addVelocity(-dx, -dy); } if ( false ) { stroke(255); strokeWeight(1); line(x(), y(), peb.x(), peb.y()); noStroke(); } } } void kill() { p.kill(); } void makeFixed() { if ( p.isFree() ) p.makeFixed(); } void makeFree() { if ( p.isFixed() ) p.makeFree(); } void moveTo(float x, float y) { p.moveTo(x, y, 0); } void moveBy(float x, float y) { p.moveBy(x, y, 0); } void addVelocity(float vx, float vy) { p.addVelocity(vx, vy, 0); } void setVelocity(float vx, float vy) { p.setVelocity(vx, vy, 0); } void invertVelocity() { p.setVelocity(-vx(), -vy(), 0); } boolean isFixed() { return p.isFixed(); } boolean isFree() { return p.isFree(); } boolean isDead() { return p.isDead(); } float radius() { return rad; } float mass() { return p.mass(); } float x() { return p.position().x(); } float y() { return p.position().y(); } float px() { return px; } float py() { return py; } float vx() { return p.velocity().x(); } float vy() { return p.velocity().y(); } void render() { px = x(); py = y(); fill(c); ellipse(x(), y(), rad, rad); } }