PShape inside a class, or extend PShape

I was reading some examples and this, this and this.

I wanted to build something like this.

PShape s;
void setup() {
  size(400, 400);
  s = createShape();
  s.beginShape();
  s.vertex(10, 10);
  s.vertex(200, 200);
  s.endShape();
}
void draw() {
  background(200);
  s.setStroke(#FF0000);
  s.setVisible( (millis()/1000%2 == 1) ? true:false);
  shape(s);
}

but, with the PShape part of it inside of a class, such as in here:

Line ln;
void setup() {
  size(400, 400);
  ln = new Line();
}

void draw() {
  background(200);
  ln.setStroke(#FF0000);
  ln.setVisible( (millis()/1000%2 == 1) ? true:false);
  ln.draw();
}



class Line {
  PShape p;
  int strokeColor = #000000;
  boolean isVisible = true;
  Line() {
    p = createShape();
    p.beginShape();
    p.vertex(10, 10);
    p.vertex(200, 200);
    p.endShape();
  }
  void setStroke(int c) {
    p.setStroke(c);
  }
  void setVisible(boolean b) {
    p.setVisible(b);
  }
  void draw () {
    if (isVisible) {
      shape(p);
    }
  }
}

Because I would like to have access to some PShape methods, I copied it inside the class, but to avoid making it for every method, I thought of extending PShape class and use super(). But here lies some questions about how to make it right. PLUS, I believe I should NOT depend on passing PApplet to inside a class, right?

//this is not working because I am not sure how to initiate PShape without using PApplet.createShape(xxx);
Line ln;
void setup() {
  size(400, 400);
  PGraphics g = createGraphics(400, 400);
  ln = new Line(this,g); //???
}

void draw() {
  background(200);
  ln.setStroke(#FF0000);
  ln.setVisible( (millis()/1000%2 == 1) ? true:false);
  shape(ln);
}


class Line extends PShape {
  PApplet p;
  Line(PApplet p, PGraphics g) {
    super(g,GEOMETRY); //?
    this.p = p;

    this.beginShape(); //?
    this.vertex(10, 10);
    this.vertex(200, 200);
    this.endShape();
  }
}

Answers

  • Hey, yes, I checked that example you just posted, but I couldnt actually figure out how to proper call or build it.

    So I thought I could build a PShape without depending on the createShape. Plus, the thing of passing PApplet on parameters seems to be not recommend...

    I was reading about reflecting a method, or overriding. But I had never used it, i am looking for some examples.

  • edited December 2018 Answer ✓

    However, here's my successful experiment on subclassing PGraphics class: \m/
    https://forum.Processing.org/two/discussion/6884/question-about-pgraphics#Item_3

    Although it's a little rusty and won't work on P3. Just fixed it now: :bz

    Tab: "JAVA2D_Subclass.pde":


    /**
     * JAVA2D Subclass (v1.4.2)
     * by GoToLoop (2014/May)
     *
     * Forum.Processing.org/two/discussion/16314/
     * pshape-inside-a-class-or-extend-pshape#Item_4
     * 
     * Forum.Processing.org/two/discussion/5238/
     * creating-a-layer-class-that-extends-pgraphics#Item_5
     *
     * Forum.Processing.org/two/discussion/6884/
     * question-about-pgraphics#Item_3
     */
    
    CustomPGraph pg;
    int w, h;
    
    void setup() {
      size(800, 600, FX2D);
      frameRate(1);
      smooth(3);
      clear();
    
      println( pg = new CustomPGraph(width*3 >> 2, height*3 >> 2) );
      w = pg.width; 
      h = pg.height;
    
      pg.strokeWeight(3);
    }
    
    void draw() {
      final color c = (color) random(#000000);
    
      surface.setTitle("Frame: " + frameCount
        + "\t\tColor: #" + hex(c, 6));
    
      set(width-w >> 1, height-h >> 1, pg.script(c));
    }
    
    final class CustomPGraph extends Layer {
      CustomPGraph(int w, int h) {
        super(w, h);
      }
    
      CustomPGraph script(color c) {
        beginDraw();
    
        background(c);
        fill(~c | ALPHA_MASK);
        ellipse(width>>1, height>>1, random(width), random(height));
    
        fill(#FF0000);
        beginShape(TRIANGLES);
        vertex(0, 0);
        vertex(100, 0);
        vertex(0, 100);
        endShape();
    
        endDraw();
        return this;
      }
    }
    

    Tab: "Layer.java":


    import processing.core.PApplet;
    import processing.awt.PGraphicsJava2D;
    
    public class Layer extends PGraphicsJava2D {
      public Layer() {
      }
    
      public Layer(int w, int h) {
        PApplet p = getEnclosingPApplet();
        initialize(w, h, p, p.dataPath(""));
        ignite();
      }
    
      public Layer(int w, int h, PApplet p) {
        this(w, h, p, p.dataPath(""));
      }
    
      public Layer(int w, int h, PApplet p, String s) {
        initialize(w, h, p, s);
        ignite();
      }
    
      public void initialize(int w, int h, PApplet p, String s) {
        setParent(p);
        setPrimary(false);
        setPath(s);
        setSize(w, h);
      }
    
      public void ignite() {
        beginDraw();
        smooth(3);
        fill(-1);
        stroke(0);
        endDraw();
      }
    
      protected PApplet getEnclosingPApplet() {
        try {
          return (PApplet) getClass()
            .getDeclaredField("this$0").get(this);
        }
        catch (ReflectiveOperationException cause) {
          throw new RuntimeException(cause);
        }
      }
    
      @ Override public String toString() {
        return "Width: " + width + "\t Height: " + height
          + "\nPath:  " + path;
      }
    }
    

  • edited April 2016 Answer ✓

    @bontempos, the trick is doing what createShape() or loadShape() would do inside the hacked PShape class.

    That's exactly what I did for PGraphics. Its constructor initializes everything just like createGraphics() would. B-)

  • wow, at first I thought the problem was somehow a matter of my lack of understanding syntaxes, but I see it really needs a lot more hacking than expected lol

    I will take a look on it for sure!! thank you very much!! ^:)^

Sign In or Register to comment.