Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

  • Collision between object moved by keys and random object

    You could need more luck when it comes to naming variables.

    better use streetLine1, streetLine2... instead of a,b,... or use an array. You might need a bit longer to type but you can read your code faster and find errors later on (like the collision problem you just had which was in fact a naming issue).

    Also say obstacleX and obstacleY instead of j,z

  • Collision between object moved by keys and random object

    Instead of noLoop() you could have a lives counter and say lives=lives-1; in case of a collision

    Starting with int lives=3; we would see game over after 3 collisions

  • Collision between object moved by keys and random object

    Hello, I'm having problems with this collision thingy between the 2 rectangles, I know I'm supposed to use dist(), It worked when my object was controlled by mouse, but I can't make it work now with keys, any help would be appreciated! :)

    Ship myShip;
    int a=1;
    int b=100;
    int c=200;
    int d=300;
    int e=400;
    int f=500;
    int z=10;
    int j=160;
    boolean [] keys = new boolean[128];
    
    
    void setup() {
      size(500, 600); 
      smooth();
      myShip = new Ship();
    }
    void gameOver() {
        textAlign(CENTER);
        text("GAME OVER", width / 2, height / 2);
    
        }
    
    void draw() {
      background(0);
      a=a+3;
      b=b+3;
      c=c+3;
      d=d+3;
      e=e+3;
      f=f+3;
      z=z+4;
      rect(j,z+3,25,25);
      rect(270,a+3,5,30);
      rect(270,b,5,30);
      rect(270,c,5,30);
      rect(270,d,5,30);
      rect(270,e,5,30);
      rect(270,f,5,30);
      rect(80,0,5,1500);
      if (a>=600)
      a=-10;
      if (b>=600)
      b=-10;
      if (c>=600)
      c=-10;
      if (d>=600)
      d=-10;
      if (e>=600)
      e=-10;
      if (f>=600)
      f=-10;
      myShip.run();
    }
    
    void keyPressed() {
      keys[key] = true;
    }
    
    void keyReleased() {
      keys[key] = false;
    }
    
    
    class Ship {  
      PVector pos, vel;
      float rotation;
    
    
      Ship() {
        pos = new PVector(160, height/2);
        vel = new PVector(5, 5);
        rotation = 0;
      }
    
      void run() {    //generic function container
        display();
        move();
      }
    
    
      void display() {
        pos.x=constrain(pos.x, 25, width);
        pos.y=constrain(pos.y, 25, height);
        pushMatrix();
        translate(pos.x, pos.y);
        rect(0, 0, 50, 50);
        popMatrix();
       if (pos.x>=260) 
      noLoop();
      if (pos.x<=60) 
      noLoop();
      if (pos.x>=260)
      gameOver();
        if (pos.x<=60)
      gameOver();
      if (dist(pos.x,pos.y,50,a+1)<25)
      noLoop();
    
    
      }
    
    
      void move() {
        if (keys['a']) //move left 
          pos.x -= vel.x;
        if (keys['d']) //move right
          pos.x += vel.x;
        if (keys['w']) //move up
          pos.y -= vel.y;
        if (keys['s']) //move down
          pos.y += vel.y;
    
      }
    
    }
    
  • How to connect two or more things in one array

    You store your circles in an array. You are not comparing the circles against each other. So you have:

      for (int j, i = 0; i < p.length; i++) {
        p[i].display();
        p[i].mouseOver();
      }
    

    You need instead

    void draw() {
      background(0);
    
      if(p.length>1){  //Need to have more than 1 to check overlap
        for (int i = 0; i < p.length; i++) {   
          for (int other = i; other < p.length; other++) {
            boolean res=p[i].overlapOtherCircle(p[other]);  
    
             if(res==true){
                  //Overlap happened: Change the color of both the 'i' and 'other' object
             }
            else{
                //Update the field of only i object with a non-overlapping color
            }
          }  
        }
      }
    
      for (int i = 0; i < p.length; i++) {
        p[i].display();    
      }
    }
    

    and inside your class you need to define:

    boolean overlapOtherCircle(Postac  otherObj){
       return dist(x,y,otherObj.x,otherObj.y)  >  (radius/2.0 + otherObj.radius/2.0);
    }
    

    Check this

    www.jeffreythompson.org/collision-detection/index.php
    https://forum.processing.org/two/discussion/24966/bouncing-balls-collision#latest

    Notice there is a new forum at https://discourse.processing.org

    Kf

  • LiquidFun box2d textures?

    LiquidFun can be found in the Add Library listing, it seems to be the best implementation of box2d for processing. Much higher and smoother framerates than the other two listed.

    For a start I would point to the included example box2d_BrickWall and seeing if you can draw the bricks with a rect in place of the box2d rendering.

    Here's my attempt. But this example doesn't move the box2d camera, the box2d_car example does and might be better, that's the part I was having problems with. Basically my scale settings are just tuned by hand to match, can't find a way to get it spot on. I've edited this to draw the bricks with rects instead of the box2d renderer

    edit: I seem to have it kinda figured out enough

     /**
     * 
     * LiquidFunProcessing | Copyright 2017 Thomas Diewald - www.thomasdiewald.com
     * 
     * https://github.com/diwi/LiquidFunProcessing.git
     * 
     * Box2d / LiquidFun Library for Processing.
     * MIT License: https://opensource.org/licenses/MIT
     * 
     */
    
    
    import com.thomasdiewald.liquidfun.java.DwWorld;
    
    import org.jbox2d.collision.shapes.CircleShape;
    import org.jbox2d.collision.shapes.PolygonShape;
    import org.jbox2d.common.Vec2;
    import org.jbox2d.dynamics.Body;
    import org.jbox2d.dynamics.BodyDef;
    import org.jbox2d.dynamics.BodyType;
    import org.jbox2d.dynamics.FixtureDef;
    
    import processing.core.*;
    import processing.opengl.PGraphics2D;
    
    
      //
      // Simple stacking demo.
      //
      //
      // Controls:
      //
      // LMB         ... drag bodies
      // LMB + SHIFT ... shoot bullet
      // MMB         ... add particles
      // RMB         ... remove particles
      // 'r'         ... reset
      // 't'         ... update/pause physics
      // 'f'         ... toggle debug draw
      //
    
    
      int viewport_w = 1280;
      int viewport_h = 720;
      int viewport_x = 230;
      int viewport_y = 0;
    
      boolean UPDATE_PHYSICS = true;
      boolean USE_DEBUG_DRAW = false;
    
      DwWorld world;
      ArrayList<Body> bricks = new ArrayList<Body>();
    
      public void settings(){
        size(viewport_w, viewport_h, P2D);
        smooth(8);
      }
    
      public void setup(){ 
        surface.setLocation(viewport_x, viewport_y);
        reset();
        world.setGravity(new Vec2(0,-32.0));
        frameRate(60);
      }
    
    
      public void release(){
        if(world != null) world.release(); world = null;
      }
    
      public void reset(){
        // release old resources
        release();
    
        world = new DwWorld(this, 20);
    
        // create scene: rigid bodies, particles, etc ...
        initScene();
      }
    
    
      PVector pos = new PVector(0,0);
      public void draw(){
         pos = new PVector(22,32);
         world.transform.setCamera(pos.x, pos.y/2);
    
        if(UPDATE_PHYSICS){
          world.update();
        }
    
    
        PGraphics2D canvas = (PGraphics2D) this.g;
    
        canvas.background(32);
        canvas.pushMatrix();
        world.applyTransform(canvas);
        world.drawBulletSpawnTrack(canvas);
    
        if(USE_DEBUG_DRAW){
          world.displayDebugDraw(canvas);
          // DwDebugDraw.display(canvas, world);
        } else {
         world.bodies.display(canvas);
          world.particles.display(canvas);
        }
        canvas.popMatrix();
    
        pushMatrix();
        scale(20,20);
        //world.transform
        translate(pos.x/-1.0,( pos.y/2 + -18));
         for (Body b : bricks){
           //Vec2 t = b.getTransform();
           pushMatrix();
           // Vec2 l = b.getWorldCenter();
              Vec2 l = b.getWorldCenter();
           translate(32+l.x,36-l.y);
           rotate(-b.getAngle());
           rect(-0.5, 0, 1.00,0.25);
           //println( b.getContactList());
           popMatrix();
         }
        popMatrix();   
    
    
        int num_bodies    = world.getBodyCount();
        int num_particles = world.getParticleCount();
        String txt_fps = String.format(getClass().getName()+ " [bodies: %d]  [particles: %d]  [fps %6.2f]", num_bodies, num_particles, frameRate);
        surface.setTitle(txt_fps);
      }
    
      //////////////////////////////////////////////////////////////////////////////
      // User Interaction
      //////////////////////////////////////////////////////////////////////////////
    
      public void keyReleased(){
        if(key == 'r') reset();
        if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
        if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
      }
    
    
    
      //////////////////////////////////////////////////////////////////////////////
      // Scene Setup
      //////////////////////////////////////////////////////////////////////////////
    
      public void initScene() {
    
        float screen_scale = world.transform.screen_scale;
        float b2d_screen_w = world.transform.box2d_dimx;
        float b2d_screen_h = world.transform.box2d_dimy;
        float b2d_thickness = 20 / screen_scale;
    
        {
    
          float radius = 25 / screen_scale;
          CircleShape circle_shape = new CircleShape();
          circle_shape.setRadius(radius);
    
          FixtureDef fixture_def = new FixtureDef();
          fixture_def.shape = circle_shape;
          fixture_def.density = 10f;
          fixture_def.friction = 0.30f;
          fixture_def.restitution = 0.30f;
    
          BodyDef body_def = new BodyDef();
          body_def.type = BodyType.DYNAMIC;
          body_def.angle = 0.0f;
          body_def.position.x = -1/screen_scale;
          body_def.position.y = b2d_screen_h - 10;
          body_def.bullet = true;
    
          Body circle_body = world.createBody(body_def);
          circle_body.createFixture(fixture_def);
    
          world.bodies.add(circle_body, true, color(64, 125, 255), true, color(0), 1f);
        }
    
        { // Walls
          BodyDef bd = new BodyDef();
          bd.position.set(0, 0);
    
          Body ground = world.createBody(bd);
          PolygonShape sd = new PolygonShape();
    
          float x, y, w, h;
    
          // BOTTOM
          x = 0;
          y = 0;
          w = b2d_screen_w;
          h = b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          // TOP
          x = 0;
          y = b2d_screen_h;
          w = b2d_screen_w;
          h = b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          // LEFT
          x = -b2d_screen_w/2;
          y = +b2d_screen_h/2;
          w = b2d_thickness;
          h = b2d_screen_h - b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          // RIGHT
          x = +b2d_screen_w/2;
          y = +b2d_screen_h/2;
          w = b2d_thickness;
          h = b2d_screen_h - b2d_thickness;
          sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
          ground.createFixture(sd, 0f);
    
          world.bodies.add(ground, true, color(0), !true, color(0), 1f);
        }
    
        createWall(10, 20, 40, 20, 0, 10);
    
      }
    
    
      public void createWall(int numx, int numy, float dimx, float dimy, float tx, float ty){
    
        float scree_scale = world.transform.screen_scale;
    
    
        dimx /= scree_scale;
        dimy /= scree_scale;
    
        tx /= scree_scale;
        ty /= scree_scale;
    
        PolygonShape brick_shape = new PolygonShape();
        brick_shape.setAsBox(dimx*0.5f, dimy*0.5f);
    
        PolygonShape brick_shape2 = new PolygonShape();
        brick_shape2.setAsBox(dimx*0.25f, dimy*0.5f);
    
        FixtureDef fixture_def = new FixtureDef();
        fixture_def.shape = brick_shape;
        fixture_def.density = 40;
        fixture_def.friction = 0.7f;
        fixture_def.restitution = 0.00f;
    
        BodyDef body_def = new BodyDef();
        body_def.type = BodyType.DYNAMIC;
        body_def.angle = 0.0f;
        body_def.allowSleep = true;
    
    
        int scol = color(0);
        int fcol = color(224,128,64);
    
        colorMode(HSB, 360,100,100);
    
        randomSeed(1);
    
        float ox = 0;
        float oy = dimy/2;
        for(int y = 0; y < numy; y++){
    
          float off = 0.5f;
    
          for(int x = 0; x < numx; x++){
            boolean odd_row = (y & 1) == 1;
    
            ox = -numx * dimx * 0.5f;
            ox += odd_row ? dimx * off : 0;
    
            fixture_def.shape = brick_shape;
            if(!odd_row && x == 0){
              fixture_def.shape = brick_shape2;
              ox += dimx * 0.25;
            }
            else if(odd_row && x == (numx-1)){
              fixture_def.shape = brick_shape2;
              ox -= dimx * 0.25;
            }
    
            body_def.position.x = tx + ox + x * (dimx);
            body_def.position.y = ty + oy + y * (dimy);
    
            Body brick = world.createBody(body_def);
            brick.createFixture(fixture_def);
            bricks.add(brick);
            float hsb_h = 20 + random(-3, 3);
            float hsb_s = random(70,60);
            float hsb_b = random(70,100);
            fcol = color(hsb_h, hsb_s, hsb_b);
            world.bodies.add(brick, true, fcol, true, scol, 0.5f);
    
          }
        }
    
        colorMode(RGB, 255);
    
      }
    
  • Help with spheres bouncing off each other

    There is example for 2D collision with vectors

  • Help with spheres bouncing off each other

    Please edit your post above and format your code so that people can run it and help you!

    This is a collision detection question -- please see a basic introduction to collision detection:

    Finally, you are talking about sphere / sphere collision detection. That is circle-circle collision detection with an added z axis.

    Is the distance between x,y,z and a,b,c less than the sum of their radii? If so, they are colliding, and they should alter direction.

    Notice that PVector has some built-in methods that can help -- e.g. for calculating the distance between two 3D points.

  • texture

    i whant to put an image in to the shape but its coming out white can anyone help

    `class astroid {`
      // An astroid angle, speed, size, rotation
      float angle, speed, size, rotSpeed;
      float position;
      float rotation;
      float xoff, yoff;
      float x, y;
      PShape s;  // The PShape object - Keeps the astroid shape
      float i;
      int id;
    
    
      // Constructor  
    
      astroid(float _angle, float _speed, float _size, float _rotSpeed, float _xoff, float _yoff, int _id) {
        angle = _angle;
        speed = _speed;
        size = _size;
        rotSpeed = _rotSpeed;
        xoff = _xoff;
        yoff = _yoff;
        id = _id;
        if (xoff<1000) {
          x = 250+500*cos(angle)+xoff;
          y = 250+500*sin(angle)+yoff;
    
        } else {
          x = _xoff-2000;
          y = _yoff-2000;
        }
        rotation = 0; 
        // Generate the shape of the astroid - Some variations for all
        s = createShape();
    
        s.beginShape();
        //s.fill(2        55, 255, 170);
        //s.setTexture(
        s.setTexture(ast);
        s.noStroke();
        for (i=0; i<TWO_PI; i=i+PI/(random(4, 11))) {
          s.vertex(random(ast_size*0.8, ast_size*1.2)*cos(i), random(ast_size*0.8, ast_size*1.2)*sin(i));
        }
        s.endShape(CLOSE);
      }
    
      // Increases the speed. Used in the end of the game to clear screen of astroids
      void incSpeed() {
        speed = speed * 1.02;
      }
    
      // Update position, return true when out of screen
      boolean update() {
        int i;
        x = x - cos(angle)*speed;
        y = y - sin(angle)*speed;
        rotation = rotation + rotSpeed; 
    
        // Check for astroid vs astroid collision
        for (i = 0; i<astroids.size(); i++) {
          astroid a = astroids.get(i);
          if ((a != this) && (a.coll(x, y, ast_size*size, id))) {
            if (size > 1) {
              astroids.add(new astroid(angle-random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id));
              astroids.add(new astroid(angle+random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id));    
              ast_id++;
            }
            astroids.remove(i);
          }
        }
    
        pushMatrix();
        // Set position as the new 0,0 
        translate(x, y);
        // Rotate screen "angle" 
        rotate(rotation);
        // Draw astroid
        scale(size);
        shape(s);
        texture(ast);
        // Bring back normal perspektive
        popMatrix();
    
        if (x<-300 || x>800 || y<-300 || y>800) {
          return true;
        } else {
          return false;
        }
      }
    
      //
      boolean coll(float _x, float _y, float _size, int _id) {
        float dist;
    
        dist = sqrt ((x-_x)*(x-_x) + (y-_y)*(y-_y));
    
        // Check if distance is shorter than astroid size and other objects size
        if ((dist<(_size+ast_size*size)) && (id!=_id)) {
          // Collision, 
          if (_id>0) id = _id;
          if (size > 1) {
            // If the astroid was "large" generate two new fragments
            astroids.add(new astroid(angle-random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id));
            astroids.add(new astroid(angle+random(PI/5, PI/7), speed+random(0, speed/2), size/2, rotSpeed, 2000+x, 2000+y, id));
          }
          return true;
        } else { 
          return false;
        }
      }
    }
    
  • Help for code optimization

    @Tushar - first things first: set up some way to properly measure performance. E.g. something that displays a framerate (actually even that is fairly crude) so you can make a more objective decision on whether your 'optimisation' is actually effective ;)

    Then here are some things to try:

    Cache calculated values where possible

    As TfGuy44 said, avoid repeating calculations - store these as soon as possible:

    For example anything referencing fractions of width or height can be calculated and stored in setup() (just make sure you use a variable that's available in draw) - e.g.

    const halfWidth = width /2;
    const blockHeight = height * -5/6;
    

    It also used to be the case that you should set variables used in loops outside the loop - e.g.:

    const limit = trails.length -1
    for (let i = limit; i > -1; i--) {
    

    avoid iterating over the same loop multiple times

    for (let trail of trails) {
        trail.move();
    }
    
    for (let block of blocks) {
        block.move();
    }
    
    arrow.update();
    
    for (let trail of trails) {
        trail.show();
    }
    
    for (let block of blocks) {
        block.show();
    }
    
    arrow.show();
    

    You could combine move/update and show methods and get:

    for (let trail of trails) {
        trail.moveAndShow();
    }
    
    for (let block of blocks) {
        block.moveAndShow();
    }
    
    arrow.updateAndShow();
    

    Avoid expensive array operations

    splice() is a relatively slow array operation. If you splice an element from an array that you're also pushing new objects to; then you should consider fixing the size of the array to the maximum number of objects you'll require and just hide unused elements from view when they're not needed. You should definitely be able to re-cycle your trails objects and probably the blocks too...

    For a technical perspective see this


    BTW - I haven't run your code - so maybe this is deliberate - but your collision detection appears to only check one block (block[0]) for a hit. If the arrow can hit any of the visible blocks then you need to do that check in a loop (which could slow things down even more)

    If things start getting really laggy then you might want to use time-based animation: that allows you to essentially drop frames so the animation always runs at the same speed.

  • Per-pixel collision with arrays

    Ok, you need to take the code you provide above and merge it into a single tab, the main tab. Then, using the code you provided, review it and make sure it runs as I can still find some pieces missing. Either you reduce your code to an MCVE or you make sure the code you provide runs. Please keep in mind we do not have your images so you can provide some information about your images and reduce the number of images used to a minimum. If you can access the images via urls, please provide them.

    Kf

    Got it kfrajer , * UPDATED* so I simplified it a bit leaving just the essential parts to emphasize what im trying to do. Id like to detect collision between the ghost and the pillars but neglecting the transparencies that is. As the obstacles are arrays that're linked i dont know how to do this effectively

    Took the code a lot further, it runs multiple pipes and the collision pgraphic is minimally sized for speed.

    Excellent, Thanks Imccandles your code is exactly what i may be thinking about, However, there's only one issue, I can't use any stored images with it for whatever reason.

    edit: I got it to work this time loading the PImages from the data folder in setup...doing that didn't work with the previous code...but it works now smh.

  • Per-pixel collision with arrays

    Took the code a lot further, it runs multiple pipes and the collision pgraphic is minimally sized for speed.

    For me, I go from 1000fps to ~600fps when checking for collision;

    FX2D runs much faster but is more limited, holds at 1000fps for me. To convert replace P2D with FX2D on line 12 and remove the P2D 3rd argument entirely on line 53.

    color blue = color(0, 0, 255, 255), 
      transparent = color(0, 0, 0, 0);
    
    PImage pipe = loadImage("http://" + "flappycreator.com/default/tube2.png");
    PImage bird = loadImage("http://" + "flappycreator.com/default/bird_sing.png");
    
    Sprite sbird;
    ArrayList<Sprite> spipes;
    float fps = 0;
    
    void setup() {
      size(800, 800, P2D);
      //bird.resize((int)(bird.width*2), ((int)bird.height*2));
      spipes = new ArrayList<Sprite>();
      for (int i = 0; i < 6; i++) {
        Sprite sPipe = new Sprite(pipe, color(255, 0, 0, 200));
        sPipe.loc = new PVector(i*120+50, 500+random(250));
        spipes.add(sPipe);
      }
      sbird = new Sprite(bird, color(0, 255, 0, 200));
      frameRate(1000);
      noCursor();
    }
    
    void draw() {
      clear();
      sbird.loc = new PVector(mouseX,mouseY);
      sbird.draw();
      for (Sprite s : spipes) {
        s.draw();
        PixelCollision check = sbird.pixelCollision(s);
        if (check!=null) {
          image(check.pg, check.loc.x, check.loc.y);
          stroke(0,255,0,255);
          noFill();
          rect( check.loc.x, check.loc.y, check.pg.width, check.pg.height);
          noStroke();
          stroke(255);
          fill(255,0,255,255);
          ellipse(check.hit.x, check.hit.y, 5, 5);
        }
      }
      fill(255);
      fps = (fps*119 + frameRate)/120.0;
      text((int)fps + " fps", 10, 10);
    }
    
    class PixelCollision {
      PGraphics pg;
      PVector loc;
      PVector hit;
      PixelCollision(int w, int h, PVector nloc) {
        pg = createGraphics(w, h, P2D);
        loc = nloc.copy();
      }
    }
    
    class Sprite {
      PImage img;
      PVector loc = new PVector(0, 0);
      color tint;
      Sprite(PImage pimg, color colTint) {
        img = pimg;
        tint = colTint;
      }
    
      void draw() {
        draw(g);
      }
    
     boolean overlap(Sprite s) {
        if ((loc.x < s.loc.x+s.img.width) && (loc.x+img.width > s.loc.x) &&
          (loc.y < s.loc.y+s.img.height) && (loc.y+img.height > s.loc.y)) {
          return true;
        }
        return false;
      }
    
      void draw(PGraphics pg) {
        pg.pushMatrix();
        pg.translate(loc.x, loc.y);
        pg.image(img, 0, 0);
        //pg.rect(0, 0, bird.width, bird.height);
        pg.popMatrix();
      }
    
      PixelCollision pixelCollision(Sprite s) {
        PixelCollision pc = null;
        if (overlap(s)) {
    
          float x = max(loc.x, s.loc.x);
          float y = max(loc.y, s.loc.y);
          float w =  min(loc.x+img.width, s.loc.x+s.img.width);
          float h =  min(loc.y+img.height, s.loc.y+s.img.height);
    
          pc = new PixelCollision( ceil(w-x), ceil(h-y), new PVector(x, y));
          PGraphics pg = pc.pg;
          pg.beginDraw();
          pg.clear();
    
          pg.tint(tint);
          pg.image(img, -(x-loc.x), -(y-loc.y));
    
          pg.tint(s.tint);
          pg.image(s.img, -(x-s.loc.x), -(y-s.loc.y));
    
          pg.endDraw();
          pg.loadPixels();
          int i = 0;
          for (; i < pg.width*pg.height-1; i++) {
            color c = pg.pixels[i];
            if ((red(c)>0)&&(green(c)>0)) {
              //pg.pixels[i] = blue;
              break;
            }
          }
          if (i== pg.width*pg.height-1) pc.hit = null;
          else pc.hit = new PVector(x+ (i%pg.width), y + floor((i-(i%pg.width))/pg.width));
          /* for (; i < pg.width*pg.height; i++) { // uncomment this and above to show collisions, slows code
           color c = pg.pixels[i];
           if ((red(c)>0)&&(green(c)>0)) {
           pg.pixels[i] = blue;
           }
           }
           pg.updatePixels(); */
        }
        if ((pc != null) && (pc.hit == null)) return null;
        return pc;
      }
    }
    
  • Per-pixel collision with arrays

    Here's an example of some pixel based collision. Perhaps I should point out this way of doing it on the CPU is very slow and not really good for a commercial game, needs to be done in shaders.

    A solution to this might be to check for bounding box collisions, create a collision pgraphics that is only the size of the overlap (far less pixels), and draw your images there offset.

    Basically, you draw your image twice. Once to the screen, once tinted and transparent to a collision pgraphics. Then we check all the pixels in the collision pgraphics for pixels that contain both the bird(tinted to be only red) and the pipe(tinted to be only green).

    PGraphics pgCollision;
    color blue = color(0, 0, 255, 255),
          transparent = color(0,0,0,0);
    
    
    PImage pipe = loadImage("http://" + "flappycreator.com/default/tube2.png");
    PImage bird = loadImage("http://" + "flappycreator.com/default/bird_sing.png");
    
    void setup() {
      size(800, 800, P2D);
      pgCollision = createGraphics(width, height, P2D);
    }
    
    void draw() {
      clear();
    
      // draw tinted semi-transparent images
      pgCollision.beginDraw();
      pgCollision.clear();
      pgCollision.tint(255, 0, 0, 200); // draw bird as transparent red
      drawBird(pgCollision);
      pgCollision.tint(0, 255, 0, 200); // pipes as transparent green
      drawPipe(pgCollision);
      pgCollision.endDraw();
      noTint();
    
      // check all pixels for ones that contain both red and green
      pgCollision.loadPixels();
      for (int i = 0; i < width*height; i++) {
        color c = pgCollision.pixels[i];
        if ((red(c)>0)&&(green(c)>0))
          pgCollision.pixels[i] = blue; // collision detected
          else pgCollision.pixels[i] = transparent; // optional, slow
      }
      pgCollision.updatePixels();  
    
      drawPipe(g);
      drawBird(g);
      image(pgCollision, 0, 0);
    }
    
    void drawPipe(PGraphics pg) {
      pg.image(pipe, 200, 600);
    }
    
    void drawBird(PGraphics pg) {
      pg.image(bird, mouseX, mouseY);
    }
    
  • Per-pixel collision with arrays

    I'm fairly new to processing but I've been progressing well with learning how to use it. I've been working on a simple flappy bird esque game and what I want to do is to have the bird and "pipes" collisions be recognized on a pixel-level, ive seen Peter Lagers code for pp_collision but i can't seem to get it to work for the obstacles. can someone tell me how to incorporate the classes into pp_collision(PImage imgA, float aix, float aiy, PImage imgB, float bix, float biy)

    for souls https://i.imgur.com/PZm7ivN.png and https://i.imgur.com/wvOkeEZ.png . I would love to know how to get collisions on a pixel level for animated sprites (ie. the souls array) as well but its secondary which is why i commented its code out.

    //int numFrames = 2;  // The number of frames in the animation
    //int currentFrame = 0;
    //PImage[] souls = new PImage[numFrames];
    
    
    int gameState; //0 = startscreen, 1 = in-game, 2 = game over, 3 = restart-screen
    int o = 240;
    
    
    Ghost ghost;
    Obstacle[] obstacles = new Obstacle[2];
    Score score;
    // Game states
    boolean gameStarted = false;
    boolean gameOver = false;
    boolean gameRestart = false;
    
    
    void setup() {
      //frameRate(30);
      fullScreen(FX2D);
      //size(1280, 720, FX2D);
    
      ghost = new Ghost(width/2, height/2);
      obstacles[0] = new Obstacle(width, random(100, height-100));
      obstacles[1] = new Obstacle(width*1.5+25, random(100, height-100));
      score = new Score();
    
      //startTimer = new Timer (0);
    
      //for (int k = 0; k < numFrames; k++) {
       // String imageName = "Soul_" + nf(k, 2) + ".png";
       // souls[k] = loadImage(imageName);
      //}
    }
    
    
    void draw() {
      background(175); 
    
      if (gameState==0) {
        gameRestart = true;
        drawMenuScreen();
        score.highscores();
        //startTimer.countUp();
        //fill (255);
        //text (startTimer.getTime(), 60, 60);
      } 
      if (gameState==0 && mousePressed) {
        if (gameRestart == true)
          //timerReset();
        score.reset();
        gameState = 1;
      }
    
    
      if (gameState==1) { 
        gameStarted = true;
        gameRestart = false;
        ghost.draw();
        for (Obstacle o : obstacles) { 
          o.draw();
          //Souls();
        }
        score.draw();
        detectCollision();
    
        if (gameState==1 && mousePressed) {
          //startTimer.countUp();
          //fill (255);
          //text (startTimer.getTime(), 60, 60);
        }
        if (gameState==1 && mousePressed) {
          ghost.jump();
        }
      }
    
    
      if (gameState==2) {
        //startTimer.countUp();
        //fill (255);
        //text (startTimer.getTime(), 60, 60);
        gameStarted = false;
        gameRestart = false;
        drawGameOver();
        ghost.reset();
        for (Obstacle obs : obstacles) { 
          obs.reset();
        }
      }
      //if (gameState==2 && startTimer.getTime()>=3.5) {
      if (gameState==2 && mousePressed) {
        if (gameStarted == false && gameRestart == false);
        //timerReset();
        gameState=3;
      }
    
    
      if (gameState==3) {
        gameRestart = true;
        drawMenuScreen();
        score.highscores();
      } 
      if (gameState==3 && mousePressed) {  
        if (gameRestart == true)
          score.reset();
        gameState = 1;
      }
    }
    
    
    
    
    
    
     class Score {
      private int score = 0;
      private int highscore;
      private boolean scoreIncreased = false;
    
    // Methods for increasing scores. If score is NOT increased
    
      void highscores(){
        if (score>highscore)
          highscore=score;
          else if (gameState==0 || gameState==3) {
          textAlign(CENTER);
          fill(255);
          textSize(width/60);
          text("HIGHSCORE: " + highscore, width/2, height/2 + height/8.25);
        }  
      }
    
      void increase() {
        if (!scoreIncreased) {
          score += 1;
          scoreIncreased = true;
        }
      }
    
      void reset() {
        score = 0;
        scoreIncreased = false;
      }
    
      void allowScoreIncrease() {
        scoreIncreased = false;
      }
    
    
      void draw() {
        pushStyle();
        if (gameState==2) {
          textAlign(CENTER);
          fill(0);
          textSize(width/60);
          text("SCORE: " + score, width/2, height/2 + 65);
        } 
          else if (gameState==1) {
          //rectMode(CORNER);
          textAlign(CENTER);
          fill(255);
          textSize(width/60);
          text("Score: " + score, width/2, 40);
        }
        popStyle();
      }
    }
    
    
    
     class Obstacle {
      float initX;
      float topX;
      float topY;
      float w = 120; // original was 50
      PImage obstacle1, obstacle2;
    
      Obstacle(float initialTopX, float initialTopY) {
        initX = initialTopX;
        topX = initialTopX;
        topY = initialTopY;
        obstacle1 = loadImage("https://" + "i.imgur.com/9Dnn4sI.png");
        obstacle2 = loadImage("https://" + "i.imgur.com/d83OfMi.png");
      }
    
    
      void draw() {
        pushStyle();
        imageMode(CORNERS);
        image(obstacle1, topX, topY, topX+w, height-1);
        image(obstacle2, topX, 0, topX+w, topY - 180);
        popStyle();
    
         // Controls speed of object x movements (namely for obstacles)
        // topX -= 4.25;
        topX -= 9.5;
      }
    
      void reset() {
        topX = initX;
        topY = random(100, height-100);
      }
    
      void reposition() {
        topX = width;
        topY = random(100, height-100);
      }
     } 
    
    
    
    
    class Ghost {
      float x;
      float y;
      float size = 85;
      float vy = 0;
      float ay = 0.63;
      PImage ghost;
    
      Ghost(float initialX, float initialY) {
        x = initialX;
        y = initialY;
        ghost = loadImage("https://" + "i.imgur.com/GPRyMO7.png");
      }
    
      void draw() {
        pushStyle();
        imageMode(CENTER);
        image(ghost, x, y, size, size);
        popStyle();
    
    
        y += vy;
        vy += ay;
      }
    
      void reset() {
        y = 200;
        vy = 0;
      }
    
      void jump() {
        vy = -9.5;
      }
    }
    
    
    
    
    
    
    // void Souls(){   
    //   currentFrame = (currentFrame+1) % numFrames;  // Use % to cycle through frames
    //   image(souls[(currentFrame) % numFrames], width/2, height/2);
    //}
    
    
    
    
    void drawGameOver() {
      pushStyle();
      fill(200, 200, 200, 200);
      noStroke();
      rect(-20, -20, width + 40, height + 40);
      score.draw ();
      popStyle();
    }
    
    void drawMenuScreen() {
      fill(0);
      noStroke();
      rect(-20, -20, width + 40, height + 40);
      ;
    }
    
    
    
    void detectCollision() {
      // Did the ghost come out of the screen?
      if (ghost.y > height || ghost.y < 0) {
        gameState=2;
      }
    
      for (Obstacle obstacle : obstacles) {
        if (ghost.x - ghost.size/2.0 > obstacle.topX + obstacle.w) {
          score.increase();
        }
    
        if (obstacle.topX + obstacle.w < 0) {
          obstacle.reposition();
          score.allowScoreIncrease();
        }
    
        //if (obstacle.detectCollision(ghost)) {
          //gameState=2;
        //}
      }
    }
    

    Can you help with incorporating the collision detection method below to the work on the ghost class and the obstacles array in my code

      obstacle2 = loadImage("up2.png");
      obstacle1x = (width - obstacle1.width)/2;
      obstacle1y = (height/3 - obstacle1.height)/2;
    //  obstacle2x = (width - obstacle2.width)/4;
    //  obstacle2y = (height - obstacle2.height)/4;
    //    f2x = (width - ghost.width)/2;
    //      f2y = (height - ghost.height)/2;
    }
    
    void draw(){
      background(0);
      image(obstacle1,obstacle1x,obstacle1y);
      obstacle1x = obstacle1x-2;
      if (obstacle1x <= -150){
        obstacle1x = 900;}
      image(ghost,mouseX,mouseY);
      if(pp_collision(obstacle1,obstacle1x,obstacle1y,ghost,mouseX,mouseY)){
        stroke(255,64,64);
        strokeWeight(1);
        noFill();
        rect(obstacle1x,obstacle1y,obstacle1.width,obstacle1.height);
        rect(mouseX,mouseY,ghost.width,ghost.height);
      }
    }
    
    final int ALPHALEVEL = 20;
    
    boolean pp_collision(PImage imgA, float aix, float aiy, PImage imgB, float bix, float biy) {
      int topA, botA, leftA, rightA;
      int topB, botB, leftB, rightB;
      int topO, botO, leftO, rightO;
      int ax, ay;
      int bx, by;
      int APx, APy, ASx, ASy;
      int BPx, BPy; //, BSx, BSy;
    
      topA   = (int) aiy;
      botA   = (int) aiy + imgA.height;
      leftA  = (int) aix;
      rightA = (int) aix + imgA.width;
      topB   = (int) biy;
      botB   = (int) biy + imgB.height;
      leftB  = (int) bix;
      rightB = (int) bix + imgB.width;
    
      if (botA <= topB  || botB <= topA || rightA <= leftB || rightB <= leftA)
        return false;
    
      // If we get here, we know that there is an overlap
      // So we work out where the sides of the overlap are
      leftO = (leftA < leftB) ? leftB : leftA;
      rightO = (rightA > rightB) ? rightB : rightA;
      botO = (botA > botB) ? botB : botA;
      topO = (topA < topB) ? topB : topA;
    
    
      // P is the top-left, S is the bottom-right of the overlap
      APx = leftO-leftA;   
      APy = topO-topA;
      ASx = rightO-leftA;  
      ASy = botO-topA-1;
      BPx = leftO-leftB;   
      BPy = topO-topB;
    
      int widthO = rightO - leftO;
      boolean foundCollision = false;
    
      // Images to test
      imgA.loadPixels();
      imgB.loadPixels();
    
      // These are widths in BYTES. They are used inside the loop
      //  to avoid the need to do the slow multiplications
      int surfaceWidthA = imgA.width;
      int surfaceWidthB = imgB.width;
    
      boolean pixelAtransparent = true;
      boolean pixelBtransparent = true;
    
      // Get start pixel positions
      int pA = (APy * surfaceWidthA) + APx;
      int pB = (BPy * surfaceWidthB) + BPx;
    
      ax = APx; 
      ay = APy;
      bx = BPx; 
      by = BPy;
      for (ay = APy; ay < ASy; ay++) {
        bx = BPx;
        for (ax = APx; ax < ASx; ax++) {
          pixelAtransparent = alpha(imgA.pixels[pA]) < ALPHALEVEL;
          pixelBtransparent = alpha(imgB.pixels[pB]) < ALPHALEVEL;
    
          if (!pixelAtransparent && !pixelBtransparent) {
            foundCollision = true;
            break;
          }
          pA ++;
          pB ++;
          bx++;
        }
        if (foundCollision) break;
        pA = pA + surfaceWidthA - widthO;
        pB = pB + surfaceWidthB - widthO;
        by++;
      }
      return foundCollision;
    }
    
  • Help for code optimization

    I quickly threw together my version of a popular mobile game called "Sine Line".

    Links to my code (whichever you prefer): https://pastebin.com/FfxhJs6s https://hastebin.com/jekezecawu.js

    The code seems to work fine on both PC and Mobile. But, I think it slowed down considerably after I added the Collision checking (Line 59) in my draw loop, especially on mobile.

    Here's a link for quick testing: http://random-codes.000webhostapp.com/sineline.html

    I'd like to optimize it further as I do think there's room for it, but I can't seem to find any way. Any help would be appreciated :')

  • How to move my objects
    int drawShot=0;
    
    color c;
    
    int xShotfired = 0;
    
    int drawAsteroid;
    
    int asX;
    int asY;
    int asSpeed;
    
    int shot1X=60;
    int shot1Y=300;
    int shot1SpeedX=1;
    int shot1SpeedY=-1;
    
    boolean collision = false;
    
    void setup() {
      size(600, 600);
      background(0);
      asX=300;
      asSpeed =10;
      frameRate(44);
    }
    
    void draw() {
      background(0); 
    
      drawTurret(10, color(255, 0, 0), true);
      drawTurret(540, color(0, 0, 255), true);
    
      drawShot(shot1X, shot1Y, true);
      drawShot(540, 300, true);
    
      shot1X+=shot1SpeedX;
      shot1Y+=shot1SpeedY;
    
      drawAsteroid(asX, asY, asSpeed);
    }
    
    
    void drawTurret(int x, color cVal, boolean rightTurret) {
      fill(cVal);
      rect(x, 10, 50, 580);
    }
    
    void drawShot(int xShot, int yShot, boolean rightShot) {
      fill(255, 0, 0);
      ellipse(xShot, yShot, 20, 20);
      // return drawShot = drawShot - 4;
    }
    
    
    void drawAsteroid(int x, int y, int speed) {
      fill(255);
      ellipse(x, y, 100, 100);
      asY= asY + speed;
    }
    
    boolean collision(int xAsteroid, int yAsteroid, 
      int xBolt, int yBolt) {
      return false;
    }
    //
    
  • Eggs disappearing in mid-air as they are going down

    I added the class pan and changed it to the revised one you gave, but it is now giving me errors that there are things that do not exist such as Pan(int), collision(Normal), variables x,y and r

  • Eggs disappearing in mid-air as they are going down

    I don't know what happened to the other discussion I was writing a reply to. Some of what I wrote applies here too. Here's what I had:


    Well, your code has some problems.

    The biggest issue I see is a lack of nice formatting. Press Ctrl + t in the editor to automagically format your code.

    If you do that, then it should immediately become apparent that you are missing a stray closing brace. In fact, your Timer class is getting defined inside your Pan class! Add this closing brace in so your Pan class ends before your Timer class.

    The next issue I see is that you are loading the images inside the class definitions. Don't do this. To make sure that the images are only ever loaded once, put them inside the function that only ever runs once: setup().

    The display() method inside the normalEgg class has a loop in it. I have no idea why. You don't need a loop to draw the same image in the same place ten times. Just draw the image once?

    Anyway, actually looking at the collision method, it appears you have a pair of stray opening and closing braces in there that you don't need. Remove those.

    Looking at the collision method some more, we see that it looks fine! You are getting the distance from the center of the pan to the center of an egg. If that distance is less than some value, then there is a collision. That sounds good. There's no problem with it.

    But there is a problem. Your code has a bug. A bug happens when you have assumed your code does something that it dosen't actually do.

    This is a really sneaky bug too, and I suggest you take a minute here to try to find it yourself again before I clue you in to the problem.

    Last chance to solve it yourself. Here's a hint: Where is your pan? No really, where is your pan?

    The problem is that your code assumes your pan is at (pan.x, pan.y). But it isn't. It's drawn at (mouseX, 450), so where it appears to be has nothing to do with the x and y variables in the pan class! That is, even though the pan moves like you would like, if you use pan.x and pan.y as it's position, well, that position is always (0,0)!

    The best way to fix this is to modify the Pan class:

    class Pan {
      float x, y, r;
    
      Pan() {
        r = 30;
        x = mouseX;
        y = 450;
      }
    
      void display() {
        x = mouseX;
        image(pan, x, y);
      }
    }
    

    Now pan.x and pan.y are updated when they need to be, and the collision function should work properly. Try it! Does it?

  • Eggs disappearing in mid-air as they are going down

    eggs disappear midway as they are going down, please send help! idk if its the timer or array problem, but if anyone can detect why it disappears at random times, then please send the correct code

     PImage pan;
     PImage egg;
     PImage goldegg;
     PImage rottenegg;
    
     Pan catcher;
     Timer timer;
     Normal[] normal; 
     Golden[] golden;
     Rotten[] rotten;
     int totalNormal = 0;
     int totalGolden = 0;
     int totalRotten = 0;
    
     void setup() {
       size(500, 500);
       imageMode(CENTER);
    
       catcher = new Pan(20); 
       normal = new Normal[10];
       golden = new Golden[5];
       rotten = new Rotten[5];
       timer = new Timer(3000);
       timer.start();
     }
    
     void draw() {
       background(250, 237, 235);
    
       catcher.setLocation(mouseX, 450); 
       catcher.display(); 
    
    
       if (timer.isFinished()) {
    
         normal[totalNormal] = new Normal();
         totalNormal++ ;
    
         golden[totalGolden] = new Golden();
         totalGolden++;
    
         rotten[totalRotten] = new Rotten();
         totalRotten++;
    
         if (totalNormal >= normal.length) {
           totalNormal = 0; 
         }
    
         if (totalGolden >= golden.length) {
          totalGolden = 0;
         }
    
         if (totalRotten >= rotten.length) {
           totalRotten = 0;
         }
    
         timer.start();
       }
    
    
       for (int i = 0; i < totalNormal; i++ ) {
         normal[i].move();
         normal[i].display();
    
         if (catcher.collision(normal[i])) {
           normal[i].caught();
         }
       }
    
       for (int i = 0; i < totalGolden; i++) {
        golden [i].move();
        golden[i].display();
    
        if(catcher.collision(golden[i])) {
          golden[i].caught();
        }
       }
    
       for (int i = 0; i <totalRotten; i++){
         rotten[i].move();
         rotten[i].display();
    
         if(catcher.collision(rotten[i])) {
           rotten[i].caught();
         }
       }
     }
     class Golden {
       float x, y, r;
       float speed;
    
       Golden() {
         r = 10;
         x = random(width);
         y = -20;
         speed = 4;
       }
    
       void move() {
         y += speed;
       }
    
    
     //  boolean atBottom() {
    
     //    if (y > height + r) { 
     //      return true;
     //    } else {
     //      return false;
     //    }
     //  }
    
    
       void display() {
         goldegg = loadImage ("GoldenEgg.png");
    
         for (int i = 2; i < r; i++ ) {
         image(goldegg, x, y);
         }
       }
    
    
       void caught() {
        speed = 0; 
        y = -1000;
       }
     }
     class Normal {
       float x, y, r;
       float speed;
    
       Normal() {
         r = 10;
         x = random(width);
         y = -20;
         speed = random(1, 2);
       }
    
       void move() {
         y += speed;
       }
    
    
       //boolean atBottom() {
    
       //  if (y > height + r) { 
       //    return true;
       //  } else {
       //    return false;
       //  }
       //}
    
    
       void display() {
         egg = loadImage ("RegularEgg.png");
    
         for (int i = 2; i < r; i++ ) {
         image(egg, x, y);
         }
       }
    
    
       void caught() {
        speed = 0; 
        y = -1000;
       }
     }
     float r; 
       float x, y; 
    
       Pan(float tempR) {
         r = tempR;
         x = 0;
         y = 0;
       }
    
       void setLocation(float tempX, float tempY) {
         x = tempX;
         y = tempY;
       }
    
       void display() {
        pan = loadImage ("Pan.png");
        image(pan, x, y);
    
       }
    
    
       boolean collision(Normal n) {
        float d = dist(x, y, n.x, n.y); 
    
         if (d < r + n.r) { 
           return true;
         } else {
           return false;
         }
       }
    
       boolean collision(Golden g) {
        float d = dist(x, y, g.x, g.y);
    
         if (d < r + g.r) {
           return true;
         } else {
           return false;
        }
       }
    
       boolean collision(Rotten o) {
         float d = dist(x, y, o.x, o.y);
    
         if (d < r + o.r) {
           return true;
         } else {
           return false;
         }
       }
      }
     class Rotten {
       float x, y, r;
       float speed;
    
       Rotten() {
         r = 10;
         x = random(width);
         y = -20;
         speed = 3;
       }
    
       void move() {
         y += speed;
       }
    
    
       //boolean atBottom() {
    
       //  if (y > height + r) { 
       //    return true;
       //  } else {
       //    return false;
       //  }
       //}
    
    
       void display() {
         rottenegg = loadImage ("RottenEgg.png");
    
         for (int i = 2; i < r; i++ ) {
         image(rottenegg, x, y);
         }
       }
    
       void caught() {
        speed = 0; 
        y = -1000;
       }
     }
     class Timer {
    
       int savedTime; 
       int totalTime; 
    
       Timer(int tempTotalTime) {
         totalTime = tempTotalTime;
       }
    
    
       void start() {
    
         savedTime = millis();
       }
    
    
       boolean isFinished() { 
    
         int passedTime = millis()- savedTime;
         if (passedTime > totalTime) {
           return true;
         } else {
           return false;
         }
       }
     }
    
  • [LEAP motion used] Elipse react to hand position (and the physics add on of punktierd)

    I have been playing with the Leap Motion for the last couple of days ever since I discovered the "Leap Motion for Processing" library.

    The biggest problem that you have is that sometimes the Leap Motion library does not immediately provide data. To demonstrate this I modified example sketch "LM_1_Basics". It can take up to 99 msecs for the Leap Motion to connect, that's a really long time from the sketches point of view.

    In your original code you were assuming the the right-hand's position data was available from the very first iteration of the draw(). Unfortunately, initially it isn't, I modified your code to illustrate this problem:

    import de.voidplus.leapmotion.*; 
    import processing.sound.*; 
    import punktiert.math.Vec; 
    import punktiert.physics.*;
    
    LeapMotion leap; 
    SinOsc sine; 
    Hand leftHand; 
    Hand rightHand;
    
    float freq; 
    float amp; 
    float pos; 
    PVector hL; 
    PVector hR;
    
    int teller = 0; 
    int amount = 100;
    
    // world object
    VPhysics physics;
    
    // attractor
    BAttraction attr;
    
    void setup() { 
      //size(displayWidth, 700);
      size(1280, 720); // HD 720P
    
      leap = new LeapMotion(this); 
      sine = new SinOsc(this);
    
      //Start the Sine Oscillator.
      sine.play();
      sine.amp(amp);
    
      noStroke(); 
      background(#57385c); 
      //frameRate(30); 
      smooth();
    
      //set up physics
      physics = new VPhysics();
      physics.setfriction(0.4f);
    
      // new AttractionForce: (Vec pos, radius, strength)
      attr = new BAttraction(new Vec(width * .5f, height * .5f), 400, .01f);
      physics.addBehavior(attr);
      //
      // val for arbitrary radius
      float rad = attr.getRadius()/4;
      // vector for position
      Vec pos = new Vec (random(rad, width/2 - rad), random(rad, height/2 - rad));
      // create particle (Vec pos, mass, radius)
      VParticle particle = new VParticle(pos, 9, rad);
      // add Collision Behavior
      particle.addBehavior(new BCollision());
      // add particle to world
      physics.addParticle(particle);
    
      for (int i = 1; i < amount; i++) {
        // val for arbitrary radius
        float rad2 = random(2, 20);
        // vector for position
        Vec pos2 = new Vec(random(rad2, width - rad2), random(rad2, height - rad2));
        // create particle (Vec pos, mass, radius)
        VParticle particle2 = new VParticle(pos2, 8, rad2);
        // add Collision Behavior
        particle2.addBehavior(new BCollision());
        // add particle to world
        physics.addParticle(particle2);
      }
    }
    
    void draw() { 
      background(255); 
      smooth();
    
      for (Hand hand : leap.getHands()) { 
        boolean handIsLeft = hand.isLeft(); 
        boolean handIsRight = hand.isRight();
    
        leftHand = leap.getLeftHand(); 
        hL = leftHand.getPosition();
        if (hL == null) println("No LH data!");
    
        rightHand = leap.getRightHand(); 
        hR = rightHand.getPosition();
        if (hR == null) println("No RH data!");
    
        //----------------------- LEFT HAND ----------------------------------
        if (handIsLeft) {
          text("leftHand-X=" + hL.x, 10, 15); //shows hL.x in sketch
          text("leftHand-Y=" + hL.y, 10, 30); //shows hL.y in sketch
          text("leftHand-Z=" + hL.z, 10, 45); //shows hL.z in sketch
          text("volume(in %)= " + nf(amp*100, 1, -3), 10, 60);
    
          leftHand.draw();
          // Map leftHandY van 0.0 to 1.0 voor amplitude (volume)
          amp = map(hL.y, 0, height, 1.0, 0.0);
        } 
    
        sine.amp(amp);
    
        //----------------------- RIGHT HAND ----------------------------------  
        if (handIsRight) {
          text("rightHand-X= " + hR.x, width-160, 15); // shows hL.x in sketch
          text("rightHand-Y= " + hR.y, width-160, 30); // shows hL.y in sketch
          text("rightHand-Z= " + hR.z, width-160, 45); // shows hL.z in sketch
          text("freq(in Hz)= " + nf(freq, 3, -3), width-160, 60);
    
          rightHand.draw();
          // Map rightHandX van 100Hz to 800Hz voor frequency
          freq = map(hR.x, 0, width, 100.0, 800.0);
        }
    
        if (!handIsLeft && handIsRight) {
          amp = 0;
        }
    
        sine.freq(freq);
      } // end for - hand
    
      physics.update();
    
      noFill(); 
      stroke(200, 0, 0);
    
      // set pos to mousePosition
      Vec mousePos;
    
      // Deal with right-hand position not yet ready?
      // Note: The Leap Motion can take a fraction of a second to start providing data and
      //       this code is outside the "for (Hand hand : leap.getHands())" for-loop ;-)
      if (hR == null) {
        println("hR is null!");
        mousePos = new Vec(mouseX, mouseY); // Added by Niels
      } else {
        println("hand x,y = " + hR.x + "," + hR.y);
        mousePos = new Vec(hR.x, hR.y); // Added by Niels
      }
    
      attr.setAttractor(mousePos);
    
      //ellipse(attr.getAttractor().x, attr.getAttractor().y, attr.getRadius(), attr.getRadius());
    
      noStroke(); 
      fill(0, 125);
    
      teller = 0; 
      for (VParticle p : physics.particles) { 
        //println("teller= " + teller);
    
        if (teller == 0) {
          p.set(mouseX, mouseY);
          ellipse(p.x, p.y, p.getRadius() * 2, p.getRadius() * 2);
          teller++;
        }
    
        if (teller == 1); {
          ellipse(p.x, p.y, p.getRadius() * 2, p.getRadius() * 2);
        }
      } // end for - p
    }
    

    With no call to frameRate() specified Processing will call draw() as quickly as it can. When I run the modified sketch I see the following in the console window:

    # Leap Motion Library v2.3.1.6 - Leap Motion SDK v2.3.1+31549 - https://github.com/nok/leap-motion-processing hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! hR is null! translate(), or this particular variation of it, is not available with this renderer. hand x,y = 647.9134,592.4121 hand x,y = 786.3234,530.3577 hand x,y = 767.5345,525.84015 hand x,y = 745.8991,519.5922

    So you see you need to handle the situation where you don't immediately get data from the Leap Motion.