Problem removing a behaviour in toxi.physics2d

edited January 2018 in Library Questions

I'm using the standard attraction2D example to develop an interactive bee simulation program and having trouble with physics.removeBehaviour when I press key '2' in the following example. It just won't remove the attractor. almost identical code works for the mouse behaviour add/remove. I suspect it's because the 'keypressed' code is within the 'draw' loop while the mouse code is outside the draw loop. The whole program is below . Apologies that my first post was not properly presented. I'm using P3.6.6 under Win10.

/**
 * <p>This example demonstrates how to use the behavior handling
 * (new since toxiclibs-0020 release) and specifically the attraction
 * behavior to create forces around the current locations of particles
 * in order to attract (or deflect) other particles nearby.</p>
 *
 * <p>Behaviors can be added and removed dynamically on both a
 * global level (for the entire physics simulation) as well as for
 * individual particles only.</p>
 * 
 * <p>Usage: Click and drag mouse to attract particles</p>
 */

/* 
 * Copyright (c) 2010 Karsten Schmidt
 * Attraction2D  demo & library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; 
 */

import toxi.geom.*;
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;

int NUM_PARTICLES = 100;
int pSize = 15;
int width = 800;
int height = 680;
boolean target = false;
VerletPhysics2D physics;
AttractionBehavior mouseAttractor;
AttractionBehavior endAttractor;  //placed in centre of screen

Vec2D mousePos;
Vec2D endPos = new Vec2D(width/2, height/2); 

PImage img;  // Declare a variable of type PImage

//************************************************************************
void setup() {
  size(800, 680, P3D);
  background(0);
  smooth();  
  // Make a new instance of a PImage by loading an image file
  // img = loadImage("blue-man.png");    //man is target for bees
  // setup physics with 10% drag
  physics = new VerletPhysics2D();
  physics.setDrag(0.05f);
  physics.setWorldBounds(new Rect(0, 0, width, height));
  // the NEW way to add gravity to the simulation, using behaviors
  // physics.addBehavior(new GravityBehavior(new Vec2D(0, 0.15f)));
}

void addParticle() {
  VerletParticle2D p = new VerletParticle2D(Vec2D.randomVector().scale(10).addSelf(0, height/2));

  //p.addForce(new Vec2D(random(-1.0, 1.0), random(-2.0, 1.0)));
  //p.setWeight(random(1, 3));

  physics.addParticle(p);
  // add a negative attraction force field around the new particle
  physics.addBehavior(new AttractionBehavior(p, 40, -1.2f, 0.01f));
}

//************
void draw() {
  fill(0, 12);
  rect(0, 0, width, height);
  fill(200, 200, 60, 90);
  if (physics.particles.size() < NUM_PARTICLES) { 
    addParticle();
  } else
  {
    for (int i = 0; i < NUM_PARTICLES; i++) 
    {
      VerletParticle2D p = ((VerletParticle2D)physics.particles.get(i));
      p.addForce(new Vec2D(random(-0.7, 0.7), random(-0.7, 0.7)));
      if (p.y >= height/2 -60 && p.x <= -width/2 -  50)
        p.addForce( new Vec2D(random(-0.4, -0.9), random(-0.1, -0.7)));
    }
  }

  physics.update();
  for (VerletParticle2D p : physics.particles) { 
    ellipse(p.x, p.y, pSize, pSize);
  }
  //  if (target) {image(img,mouseX-18,mouseY-20,30,60);}
  if (target) ellipse (mouseX, mouseY, 30, 30);

  if (keyPressed) {  
    if (key == '1') {        
      endAttractor = new AttractionBehavior(endPos, 250, 0.9f);
      physics.addBehavior(endAttractor);
    } else if (key == '2') {
      physics.removeBehavior(endAttractor);
    } else 
    exit();
  }
}

void mousePressed() {
  mousePos = new Vec2D(mouseX, mouseY);
  // create a new positive attraction force field around the mouse position (radius=250px)
  mouseAttractor = new AttractionBehavior(mousePos, 250, 0.9f);
  physics.addBehavior(mouseAttractor);
  target = true;
}

void mouseDragged() {
  // update mouse attraction focal point
  mousePos.set(mouseX, mouseY);
}

void mouseReleased() {
  // remove the mouse attraction when button has been released
  physics.removeBehavior(mouseAttractor);
  target = false;
}

Answers

  • Please format your code. Edit your post (gear on top right side of any of your posts), select your code and hit ctrl+o. Leave an empty line above and below your block of code. Details here: https://forum.processing.org/two/discussion/15473/readme-how-to-format-code-and-text

    Kf

  • Done - sorry about my first post. Geo

  • edited January 2018 Answer ✓

    Yes, that code all looks correct to me -- without understanding how toxi implements its behaviors.

    As a first test, have you tried simply moving your code to the void keyPressed() -- or voide keyReleased() if you want to ensure no repeat signals? That is what those built-in functions are for. Then your key and mouse code really will be perfectly parallel.

  • Yes, moving keyPressed etc outside the draw loop resolves it. Not sure why as a keyPressed action should only be seen once whether inside or outside. (?) Thanks for replying - Geo

  • One guess -- the answer might be in the toxi library -- it might be using pre-hooks or post-hooks in a specific way that causes this unexpected behavior.

Sign In or Register to comment.