Trying to have mousePressed 'graffiti' with a news ticker running behind - cannot stop fill.

edited January 2016 in Library Questions

Hello.

I am trying to create a news ticker running across the screen but with the function of

if (mousePressed == true) {
    line (mouseX, mouseY, pmouseX, pmouseY);
  }

I have the ticker working almost correctly OR the graffiti, but not both. I know that it is because the background is being re-drawn over the graffiti, but cannot for the life of me, work out how to adjust my code.

The full code (although I have removed some of the text array) is

String[] tickerText =
{
  "children were some of the greatest victims", "I was a child soldier", 
};


color black;
color white;
int SZ; // initiate variables

PFont font;  // Global font variable
float x;  // horizontal location of headline
int index = 0;


void setup() {
  // sound 
  minim = new Minim(this); //define construction
  sound = minim.loadFile("Children_Playing_Sound.mp3");
  sound.loop(); // is looped
  black = (0); 
  white = (255);
  SZ = 800; //asign variables for colours and screen size

  size(SZ, SZ); // set size of screen
  font = createFont("CourierNewPS-BoldMT-48", 16, true);  
  x = 0; // ticker text enters screen from the right

  background(black);
  // fill(white);
}

void draw() {
  background(black);
  fill(white);

  // Display headline 
  textFont(font, 16);        
  textAlign(LEFT);
  text(tickerText[index], x, 180); 

  x = x - 3; 
  float w = textWidth(tickerText[index]); // takes length of text in tickerText to determine when the text is off-screen
  if (x < -w) {
    x = width; 
    index = (index + 1) % tickerText.length;

    stroke (white);
    strokeWeight (20); // set thickness of 'paint'

    if (mousePressed == true) {
      line (mouseX, mouseY, pmouseX, pmouseY);
    }
  }
}

I have different code which creates the graffiti effect I want. Very basic mousePressed - draw. It's trying to combine the two that I've come unstuck.

Many thanks to anyone who can help me.

Answers

  • edited January 2016

    The problem is that your rely on the previous drawn frame's contents for the graffiti, but don't want the previous frame's news ticker text to remain. There are a few ways you can fix this.

    First, stop relying on the previous frame's contents entirely. Redraw all the lines of graffiti that have ever been drawn each time. This will require a lot of memory to store all the lines (since any previous line could be important), and might have a lot of wasted memory (since a prvious line could have been totally over-written). For this and other reasons, I would not suggest you take this approach.

    You could remember what the graffiti from the previous frame looked like by using get() before you draw the news ticker on top of it. The process would thus be 1) drawn previous graffiti 2) draw new graffiti 3) save graffiti for next frame 4) display news ticker. This will totally work, but can cause your sketch to lag as you're saving the whole sketch's contents before it gets displayed, every frame. Don't take this approach either.

    What you should do is use a separate PGraphics object for the graffiti: This gives you an off-screen canvas that you can draw on just like a normal sketch window, except for the fact that it's not visible anywhere until you draw it (or parts of it!) in the main sketch window.

    PGraphics pg;
    
    void setup(){
      size(400,400);
      pg = creatGraphics(with,height,P2D);
      pg.beginDraw();
      pg.background(0);
      pg.stroke(orWhatever);
      pg.endDraw();
      // ...
    }
    
    void draw()
      pg.beginDraw();
      pg.line(whatever);
      pg.endDraw();
      background( pg.get() );
      text( "newsticker", whatever);
    }
    

    Good luck! Post your attept at this for more help.

  • I'm afraid I don't understand what you've suggested I do.

    Can you point me in the direction of how to use PGraphics?

    Thanks for your reply TfGuy44

  • Sorry. You'll have to look in the reference for a better explanation of what a PGraphics object is, does, and can be used for. Or look for a tutorial on them. It's basically like an extra space that you can draw on without it showing up in the main sketch window.

    Maybe a working example will help you understand it better.

    PGraphics pg;
    
    void setup() {
      size(400, 400, P2D);
      pg = createGraphics(width, height, P2D);
      pg.beginDraw();
      pg.background(0);
      pg.stroke(0, 255, 0);
      pg.strokeWeight(2);
      pg.endDraw();
      textSize(20);
    }
    
    void draw() {
      if (mousePressed) {
        pg.beginDraw();
        pg.line(mouseX, mouseY, pmouseX, pmouseY);
        pg.endDraw();
      }
      background( pg.get() );
      text("TfGuy44", millis()/10%width, 200);
    }
    
  • Thank you for your help again. I've got my code working and understand what I've written but am stuck with a similar (I think) issue.

    In a previous version I have this code - the graffiti can be drawn and the background image fades.

    import ddf.minim.*;
    
    Minim minim;
    AudioPlayer sound;
    color black = (0);
    color white = (255);
    int x = (615);
    int y = (762);
    
    PImage background;
    
    void setup() {
    
      //display
      size(x, y);
      background = loadImage ("background_Text_Image.JPG");
      smooth();
      imageMode(CENTER);
      background (background);
      noStroke();
      frameRate(18);
    
      // sound
      minim = new Minim(this); //define construction
      sound = minim.loadFile("Children_Playing_Sound.mp3");
      sound.loop();
    }
    
    void draw (){
    stroke (black);
    strokeWeight (10);
    fill (0,0,0,1);
    rect(0,0,width,height);
    
    
    if (mousePressed == true) {
    line (mouseX, mouseY, pmouseX, pmouseY);
    
    }
    
    }
    

    However, trying to get the background image simply to display (let alone fade) in the new code below is failing.

    I assume it's to do with using a different canvas to display the ticker and the graffiti.

    I have this working code:

        import ddf.minim.*;
        // import necessary libraries to play sound effect
        String[] tickerText =
        {
          "children were some of the greatest victims", 
          "I was a child soldier", 
          // ........
    
        };
    
        Minim minim;
        AudioPlayer sound; // variable name
    
        PGraphics pg;
        PFont font; //declare PFont object called font
        float x; // location of text on x axis
    
        // color black;
        // color gray;
        // color white;
        int SZ = 900;
        int index = 0;
    
    
        void setup() {
          size(SZ, SZ, P2D);
    
          //sound setup
          minim = new Minim(this); //define construction
          sound = minim.loadFile("Children_Playing_Sound.mp3");
          sound.loop(); // is looped
    
    
          pg = createGraphics(width, height, P2D);
          pg.beginDraw();
          pg.background(129,129,129);
          pg.stroke(0, 255, 0);
          pg.strokeWeight(20);
          pg.endDraw();
    
          font = createFont("CourierNewPS-BoldMT-48", 44, true);
          x = 0;
    
        }
    
        void draw() {
          if (mousePressed) {
            pg.beginDraw();
            pg.line(mouseX, mouseY, pmouseX, pmouseY);
            pg.endDraw();
          }
          background( pg.get() );
    
          textFont(font);        
          text(tickerText[index], x, 180); 
    
          x = x - 2; 
          float w = textWidth(tickerText[index]); // calculates the width of the text string - necessary for knowing when the text leaves the screen
          if (x < -w) { // when x moves completely off the screen new text appears
            x = width; 
            index = (index + 1) % tickerText.length;
    
            stroke (0,33,44);
            strokeWeight (20); // set thickness of 'paint'
          }
        }
    

    and this failing code

    import ddf.minim.*;
    // import necessary libraries to play sound effect
    String[] tickerText =
    {
      "children were some of the greatest victims", 
      "I was a child soldier", 
     // ....
    };
    
    Minim minim;
    AudioPlayer sound; // variable name
    
    PGraphics pg;
    PFont font; //declare PFont object called font
    float x; // location of text on x axis
    PImage background;
    // color black;
    // color gray;
    // color white;
    int SZ = 900;
    int index = 0;
    
    
    void setup() {
      size(SZ, SZ, P2D);
    
      //sound setup
      minim = new Minim(this); //define construction
      sound = minim.loadFile("Children_Playing_Sound.mp3");
      sound.loop(); // is looped
    
    
      background = loadImage ("background_Text_Image.JPG");
    
      pg = createGraphics(width, height, P2D);
      pg.beginDraw();
      pg.background(background);
      pg.stroke(0, 255, 0);
      pg.strokeWeight(20);
      pg.endDraw();
    
      font = createFont("CourierNewPS-BoldMT-48", 44, true);
      x = 0;
    
    }
    
    void draw() {
      if (mousePressed) {
        pg.beginDraw();
        pg.line(mouseX, mouseY, pmouseX, pmouseY);
        pg.endDraw();
      }
      background( pg.get() );
    
      textFont(font);        
      text(tickerText[index], x, 180); 
    
      x = x - 2; 
      float w = textWidth(tickerText[index]); // calculates the width of the text string - necessary for knowing when the text leaves the screen
      if (x < -w) { // when x moves completely off the screen new text appears
        x = width; 
        index = (index + 1) % tickerText.length;
    
        stroke (0,33,44);
        strokeWeight (20); // set thickness of 'paint'
      }
    }
    

    Many thanks for your time and help!

  • edited January 2016

    How is it failing? What error were you getting? When I tried it with my own image, I got the error "Background image must be the same size as your sketch" or something, because my sample image was a different size from the PGraphics size. So instead of pg.background(), I used pg.image(), and it worked fine...

    PGraphics objects have all the same drawing methods that you're used too. If you want to initially have a background that fades, draw the background with image() (since background() is kind of picky (actually set a background color using background() first, then draw your image)), then each time draw() runs, draw the almost transparent rectangle over it again (pg.fill(), pg.rect(), and don't forget the pg.beginDraw() and pg.endDraw()!).

Sign In or Register to comment.