Issue with clear()

I am trying to make it so the canvas clears when I click, but it always just comes back right away. Any Ideas? Here is my code:

global cWidth
global cHeight
cWidth=600
cHeight=600
class character(object):
    def __init__(self):
          self.x=100
          self.y=100
          self.up=0
          self.down=0
          self.left=0
          self.right=0
          self.speed=4
          self.w = 20
          self.h = 20
    def show(self):
            fill(200);
            rect(100, 100, 400, 400);
            fill(0,0,255);
            rect(439,465,60,35);
            fill(0,0,255);
            rect(100,100,60,35);
            fill(0,0,255);
            rect(100,100,60,35);
            fill(255,0,0);
            rect(200,100,20,350);
            fill(255,0,0);
            rect(275,150,20,350);
            fill(255,0,0);
            rect(350,100,20,350);
            fill(0);
            rect(self.x,self.y,self.w,self.h)
                            
    def update(self):
        self.x = self.x + (self.right - self.left)*self.speed
        self.y = self.y + (self.down - self.up)*self.speed
        if not(self.x >= 100):
            self.x=100
        if not(self.y >= 100):
            self.y=100
        if not(self.x <= 500-self.w):
            self.x=500-self.w
        if not(self.y <= 500-self.h):
            self.y=500-self.h
        if self.x>200-self.w and self.x<218 and self.y<450:
            self.x=100
            self.y=100
        if self.x>279-self.w and self.x<295 and self.y>131:
            self.x=100
            self.y=100
        if self.x>350-self.w and self.x<368 and self.y<450:
            self.x=100
            self.y=100
        if self.x>=385 and self.x<=390 and self.y>131:
            self.x=385
            textSize(25);
            text("invisible wall?", 150, 300); 
            fill(0, 102, 153);
        #if self.x>=440-self.w and self.y>=465-self.h:
            
            

def mouseClicked():
    clear()        


                            
                                                                                    
def setup():
    size(cWidth,cHeight)
    global c
    c=character()

def draw():
    background(100)
    c.show()
    c.update()
        

def keyPressed():
    if keyCode == UP:
        c.up = 1
    if keyCode == DOWN:
        c.down = 1
    if keyCode == RIGHT:
        c.right = 1
    if keyCode == LEFT:
            c.left = 1

        
def keyReleased():
    if keyCode == UP:
        c.up = 0
    if keyCode == DOWN:
        c.down = 0
    if keyCode == RIGHT:
        c.right = 0
    if keyCode == LEFT:
            c.left = 0
1 Like

Hi, honestly i have no experience with python, and don’t understand much of your code, but probably what is happening is that the function mouseClicked only executes once, so, in the next iteration of the draw function you show again the image (sorry if i’m not clear). what you can do ( i’ll write it in java version) is use a boolean variable instead.

Java version:

boolean clearFrame = false;

void mouseCliked(){
  clearFrame =! clearFrame;
}

void draw(){
  if(clearFrame == true){
    clear();
  } else { 
    c.show();
    c.update();
  }
}
1 Like

To express @bryan’s solution in Python:

Carefully review how the global keyword works – using it outside the function is not necessary; using it inside is required.

If you wish to modify or create a global variable from within a function, you must use the global Python statement. Globals \ Language (API)

Then try this sketch that flips a global boolean with the mouse, using it to control the display state:

clearFrame=False

def setup():
    pass

def mouseClicked():
    global clearFrame
    clearFrame = not clearFrame

def draw():
    if(clearFrame):
        clear()
    else:
        background(255,0,0)
2 Likes

Python looks more easy to use. I’ll try to learn it :slight_smile:

Python syntax can feel very easy compared to Java – although if you are not used to duck-typing it can take some getting used to after Java. In Processing.py specifically it also has some limitations. It is transpiled to JVM, so you are writing a kind of Python-in-emulation. That adds an extra layer of indirection that can occasionally make things more difficult. Also, PDE does not give the same level of live debugging feedback that you get in Java mode.

All that said, I love writing Python. It is one of my favorite languages for creative coding.

1 Like

Shorter version: :joy_cat:

def draw():
    clear() if clearFrame else background(255, 0, 0)

Python’s ternary is indeed concise! It can be neat, but I personally wouldn’t recommend using it – especially for learners, maybe not for most programmers. It has a lot of gotchas, including being expression-based and having some surprising order of operation effects. One discussion of drawbacks here:

There is also a tuple-index ternary form (falseVal, trueVal)[test] that is even shorter, and even harder to read / use / debug correctly – as one will probably see if attempting to use it on the above example. Please never do this to save 4 characters.

I fail to see any problems w/ those 2 “gotchas”!

… including being expression-based…

Almost anything in C, Java, JavaScript, etc. is an expression! :nerd_face: AFAIK, we’ve survived so far! :triumph:

… having some surprising order of operation effects.

If we read it out loud, it becomes very clear the full order of its evaluation: :loudspeaker:
clear() if clearFrame else background(255, 0, 0)

  1. The expression between if & else is evaluated 1st. That expression is variable clearFrame.
  2. If that’s evaluated as “truthy”, the expression before if is evaluated. In our case, clear().
  3. Otherwise, if it is evaluated as “falsy”, the expression after else is evaluated instead. That is, background(255, 0, 0).

Actually, I’ve 1st learnt about this particular “ternary” style when I was using CoffeeScript via Processing’s CS Mode: :coffee: CoffeeScript

B/c it instantiates a temporary Tuple, I’d never use it. :sneezing_face:

But my all-time fav is instead: condition and when_true or when_false. :smiling_face_with_three_hearts:
In JS too: condition && when_true || when_false.

However, we can only use this better performance style only when when_true always evaluates as “truthy”. :warning:

Interesting!

By “expression-based,” I meant for example that if someone tries to cut-paste this:

if x > y:
    print x
else:
    y = 10

…into this:

print x if x > y else y = 10

…they get a potentially confusing error message:

mismatched input ‘=’ expecting NEWLINE

The difference between how you can use if with statements and if with expressions in ternary could be subtle for a learner here – it isn’t just a compact reordering of the statement form, even though the keywords are the same, and that can mislead.

By order of operations, I didn’t mean the fact that Java, JavaScript, C, Ruby etc. are condition-true-false and Python is true-condition-false, or the order of their evaluation – although that could be confusing too! Instead I meant the operator precedence, and the fact that conditional expressions have the lowest, and that someone may be unsure whether if is stronger or weaker than, say, = or + when reading/writing code:

x = 2
y = 1
z = 3 + x if x < y else y
# is this equivalent to...?
#    z = 3 + (x if x < y else y)
#    z = (3 + x if x < y else y)
#   (z = 3 + x) if x < y else y
print z  # = 1 -- so the middle one
# vs:
z = 3 + (x if x < y else y)
print z  # = 4

If those 3 variables are already declared, the corresponding code for both Java & JS would be: :coffee:

x = 2;
y = 1;
z = x < y? 3 + x : y;

We could also go w/ this instead in Python:

x = 2
y = 1
z = x < y and 3 + x or y

And like this for JS:

x = 2
y = 1
z = x < y && 3 + x || y

However, it’d fail when the expression 3 + x would evaluate as “falsy”, like for example if variable x is -3. :fearful:

In such case, variable z would always be equal to y instead, no matter whether the x < y condition is “truthy” or “falsy”. :ghost:

1 Like

IMO, the decision to make the “ternary” operator 1 of the lowest 1s for precedence hit the jackpot! :slot_machine:

Writing z = x < y? 3 + x : y; rather than something boilerplate as z = (x < y)? (3 + x) : y; is a big plus! :heavy_plus_sign:

Notice though that the assignment = operator has an even lower precedence than the “ternary” 1! :arrow_lower_right:

Otherwise we’d have to wrap the whole “ternary” operator w/ parentheses when assigning it to a variable: :crazy_face:
z = ( x < y? 3 + x : y );

Of course that’s not relevant to Python, b/c its assignment operator can’t be used in the middle of an expression as it is in C, JS, Java, etc… :snake: