Event flow (Boolean values)

The following code works exactly as it should, but I want to understand the event flow. The change to varH should happen when the key is pressed and only happen once.

Under void keyPressed()
When the H or h key is pressed I have

changeH = true;

BUT, and here is my question, why is

changeH = true;

not needed for when the G or g key is pressed?? Everything works fine whether I include the switch for the G\g key or not. Can someone please explain this to me?


boolean changeH = true;
int varH = 204;

void setup() {
  size(800, 400, P2D);
  noStroke();
  colorMode(HSB, 360, 360, 360);
} 

void draw() {

  fill(204, 360, 360);
  rect(0, 0, 400, 400);

  fill(varH, 360, 360);
  rect(400, 0, 400, 400);
}

void keyPressed() {

  if ((key == 'H') || (key == 'h')) {
    changeH = true; // why only here?
    varH = varH + 1;
  } else if ((key == 'G') || (key == 'g')) {
    
    //changeH = true; // why not here?
    varH = varH - 1;
  }
  println(varH+" "+changeH);
}

void keyReleased() {
  changeH = false;
}
1 Like

The changeH variable is never used, so it doesn‘t do anything apart from being Printed…

If you were to remove the println() you could basically also delete the changeH variable.

For this variable to be a „Switch“ you‘d Need to include it in an if statement. Else it‘s just like declaring anywhere in the code something like : Int nothing = 23 and never using that Int…

This in connection with keyReleased saying changeH=false;

makes sense only when you evaluate changeH in draw()

In draw () you could say

if(changeH) varH = varH + 1;

That would give you a code that would increase varH as long as you hold the key down.

I always use a similar approach when I drag and drop with the mouse (as long as you hold the mouse key down)?

@Lexyth @Chrisir sorry,
Now I have provided my full sketch. I was trying to strip it down to understand the event flow. So, there are really two questions.

  1. Why does my script work exactly as intended whether or not I include the

void draw() {

if (changeH == true) {

and

  1. why is

changeH = true;

not needed for when the G or g key is pressed??
Everything still works fine whether I include the switch for the G\g key or not.

boolean changeH = true;
int varH = 204;

void setup() {
  size(800, 400, P2D);
  noStroke();
  colorMode(HSB, 360, 360, 360);
} 

void draw() {

  if (changeH == true) { // apparently not needed

    fill(204, 360, 360);
    rect(0, 0, 400, 400);

    fill(varH, 360, 360);
    rect(400, 0, 400, 400);
  }
}

void keyPressed() {

  if ((key == 'H') || (key == 'h')) {
    changeH = true; // why only here?
    varH = varH + 1;
  } else if ((key == 'G') || (key == 'g')) {

    //changeH = true; // why not here?
    varH = varH - 1;
  }
  println(varH+" "+changeH);
}

void keyReleased() {
  changeH = false;
}
1 Like

If i got it right what you want, then no, your Code doesn‘t work correctly.

Try including background(255,0,0); at the beginning of draw() and you‘ll See that the rect() only shows while you press H If you include the if statement, but will always stay if you don‘t use it.

Also, not setting changeH to true if you press G, means that you‘ll not see the rect even if you hold the G key.

You can check it yourself by just adding the background(); function in draw().

1 Like

Yes, you got it right. Thank you. I tested with the background() outside the if (changeH == true) and this shows the problems, as you say. Is the following code both correct and working?


boolean changeH = true;
int varH = 204;

void setup() {
  size(800, 400, P2D);
  noStroke();
  colorMode(HSB, 360, 360, 360);
} 

void draw() {

  if (changeH == true) {
    background(255, 0, 0); // Marc
    fill(204, 360, 360);
    rect(0, 0, 400, 400);

    fill(varH, 360, 360);
    rect(400, 0, 400, 400);
  }
}

void keyPressed() {

  if ((key == 'H') || (key == 'h')) {
    changeH = true;
    varH = varH + 1;
  } else if ((key == 'G') || (key == 'g')) {

    changeH = true;
    varH = varH - 1;
  }
  println(varH+" "+changeH);
}

void keyReleased() {
  changeH = false;
}
1 Like

If you want the rects to always be seen, then this Code is correct and should work as far as i can tell. Else you‘ll just need to move the background() function at the beginning of draw(), so the keyPress will make the rects show.

But what does the //Marc stand for?

It is just so I can see what has been most recently added and trace the addition back to its source.

Ah… nevermind… just forgot that my name was in my Profile… thought it was a weird coincidence, that‘s why i was curious…:sweat_smile:

1 Like

Yes, the email notification comes from “Marc via Processing Foundation”.

Hello,

I understand that this sketch is a test case. Nevertheless:

In most cases we have background(0); or background(255, 0, 0); or so at the start of draw().

This gives you full control over your sketch:

  • Only the things are shown that we actually draw, we don’t have elements from previous running’s of draw() that might not be active or visible anymore seen on the screen.

In most cases we show rects etc. throughout and not only during we change them. We change the color and this is visible.

Remark 1

When changing the variable varH it can be useful to make sure it stays in its range.
You could add:

  if (varH<0)
    varH=0; 
  else if (varH>360)
    varH=360;

Remark 2

Also note that you have to hit g and h again and again to get changes. This is because keyPressed() is a function that registers only once.

You could use a variable keyPressed instead which registers throughout, when you hold down the key g or h:

Have this in draw:

  .....

  if (keyPressed) {  // using the variable keyPressed here ! 

    if ((key == 'H') || (key == 'h')) {
      changeH = true;
      varH = varH + 1;
    } else if ((key == 'G') || (key == 'g')) {
      changeH = true;
      varH = varH - 10;
    }
    if (varH<0)
      varH=0; 
    else if (varH>360)
      varH=360;
    println(varH+" "+changeH);

  }//if

}//draw

(you could put this in a function keyPressedRegisterThroughout() you have to call from draw())

Function keyPressed() and variable keyPressed have the same name but behave different.
Note that in the reference, the function keyPressed() is recognizable by the brackets whereas the variable keyPressed has no brackets.

Remark 3

if (changeH == true) { can be shortened to if (changeH) { because has the value true, the expression is true.

Regards, Chrisir

2 Likes

Thanks @Chrisir

Your remark 1
Yes, I agree. I do that in my full sketch but have stripped things down to the bare bones so that I could ask my question without you having to read too much code.

Your remark 2
Yes, that is exactly what I want (“to hit g and h again and again to get changes”). I like the use of the variable and will store that for future use. Also on my OS, keyPressed() does not only register once hence my use of P2D and keyIsReleased (below).

Your remark 3
Wow, I didn’t know that. Now tested and it works. I will try to understand what is going on there.

Your introductory comments
If I understand correctly, elements that do not change should not be in draw() and only elements such as colour changes should be in draw(). Please will you show how to do this? I did things as they are because I wanted different colours for different rectangles

But before I go further, I have an approach (courtesy of @benja though any subsequent errors are my own) that relies on keyIsReleased instead of keyPressed. My aim is that the change should happen when the key is pressed and only happen once.

Is this code complete and correct? I suspect not.

int varH = 204;
boolean keyIsReleased = true;

void setup() {
  size(100, 100);
  noStroke();
  colorMode(HSB, 360, 360, 360);
}


void draw() {
  background(255, 0, 0);
  fill(varH, 360, 360);
  rect(35, 40, 30, 20);
  rect(15, 15, 20, 70);
  rect(65, 15, 20, 70);
}


void keyPressed() {
  if (keyIsReleased) {
    if ((key == 'H') || (key == 'h')) {
      varH = varH + 1;
    } else if ((key == 'G') || (key == 'g')) {
      varH = varH - 1;
    }
    println(varH);
    keyIsReleased = false;
  }
}


void keyReleased() {
  keyIsReleased = true;
}
1 Like

That’s not what I meant. Draw everything in draw, and delete everything at the start of draw, so the screen is always fresh and new.

I just see that keyPressed() does register multiple times [without using any special tricks like keyIsReleased]. Not sure if this was the case in ancient times. So what I wrote about this is totally wrong

Apologies