Processing: How do you give a shape a value based on the mouse button clicked?

Tags: ,



I’m trying to make a program on Processing that draws either a Rectangle or an Ellipse based on the button thats clicked (Left or Right button) and I’m struggling with how to save the value in the variable currentShape in the class mousePressed. I’m supposed to get a value when the mouse is pressed and save it into currentShape and then use the value in mouseDragged to drag and mess with the shapes size. This is the code I have:

int startX;
int startY;
int currentColor;
float currentShape;

float[] firstcornerX = {};
float[] firstcornerY = {};
float[] secondcornerX = {};
float[] secondcornerY = {};
color[] colors = {};
float[] shapes = {};

void setup() {
    size(500, 500);
    rectMode(CORNERS);
    ellipseMode(CORNERS);
}

void draw() {}

void mousePressed() {
    startX = mouseX;
    startY = mouseY;
    currentColor = color(random(255), random(255), random(255));
    if (mouseButton == LEFT) {
        ellipse(mouseX, mouseY, 100, 100);
    } else if (mouseButton == RIGHT) {
        rect(mouseX, mouseY, 100, 100);
    }
}

void mouseReleased() {
    firstcornerX = append(firstcornerX, startX);
    firstcornerY = append(firstcornerY, startY);
    secondcornerX = append(secondcornerX, mouseX);
    secondcornerY = append(secondcornerY, mouseY);
    colors = append(colors, currentColor);
    shapes = append(shapes, currentShape);
}

void mouseDragged() {
    background(255);
    for (int i = 0; i < firstcornerX.length; i++) {
        fill(colors[i]);
        rect(firstcornerX[i], firstcornerY[i], secondcornerX[i], secondcornerY[i]);
    }

    fill(currentColor);
    rect(startX, startY, mouseX, mouseY);
}

Answer

You are indeed appending currentShape, however you’re not changing the shape type between ellipse and rectangle in mousePressed(), hence currentShape will always be 0.0 in your code. Additionally you need to use the shape type to check what shape you’ll render on screen (everywhere in your code where you directly use rect() and ellipse())

Personally I would’ve used an integer and a couple of constants for the shape type (or an enum), however float currentShape; will do. Let’s say 0.0 represents an ellipse and 1.0 represents a rectangle. You can store these constants so it’s easy to remember which one’s which:

final float SHAPE_TYPE_ELLIPSE = 0.0;
final float SHAPE_TYPE_RECT    = 1.0;

Since you need to render the shapes in draw(), but also while mouseDragged(), you can encapsulate a functionality into a reusable function (instead of duplicating code):

void drawShape(float x1, float y1, float x2, float y2, float shapeType){
  if(shapeType == SHAPE_TYPE_ELLIPSE){
    ellipse(x1, y1, x2, y2);
  }
  if(shapeType == SHAPE_TYPE_RECT){
    rect(x1, y1, x2, y2);
  }
}

The conditions could’ve been if(shapeType == 0.0) ... else ..., however the above is easier to read/understand and can be expanded to support more shapes in the future.

That leaves 3 left to double check:

  1. update the shape type in mousePressed() based on the mouse button
  2. append the shape type in mouseReleased() (which you already do)
  3. calling drawShape() accordingly in mouseDragged() and draw()

The full code listing:

int startX;
int startY;
int currentColor;
float currentShape;
// constants for the supported shape types 
final float SHAPE_TYPE_ELLIPSE = 0.0;
final float SHAPE_TYPE_RECT    = 1.0;

float [] firstcornerX = {};
float [] firstcornerY = {};
float [] secondcornerX = {};
float [] secondcornerY = {};
color [] colors = {};
float [] shapes = {};

void setup () {
  size(500, 500);
  rectMode(CORNERS);
  ellipseMode(CORNERS);
}

void draw() {
  background (255);
  for (int i=0; i < firstcornerX.length; i++) {
    fill(colors[i]);
    // draw the shape from memory
    drawShape(firstcornerX[i], firstcornerY[i], secondcornerX[i], secondcornerY[i], shapes[i]);
  }
}

void drawShape(float x1, float y1, float x2, float y2, float shapeType){
  if(shapeType == SHAPE_TYPE_ELLIPSE){
    ellipse(x1, y1, x2, y2);
  }
  if(shapeType == SHAPE_TYPE_RECT){
    rect(x1, y1, x2, y2);
  }
}

void mousePressed () {
  startX = mouseX;
  startY = mouseY;
  currentColor = color(random(255), random(255), random(255));
  if(mouseButton == LEFT) {
   currentShape = SHAPE_TYPE_ELLIPSE; 
  }else if(mouseButton == RIGHT) {
   currentShape = SHAPE_TYPE_RECT; 
  }
}

void mouseReleased () {
  firstcornerX = append(firstcornerX, startX);
  firstcornerY = append(firstcornerY, startY);
  secondcornerX = append(secondcornerX, mouseX);
  secondcornerY = append(secondcornerY, mouseY);
  colors = append(colors, currentColor);
  shapes = append(shapes, currentShape);
}

void mouseDragged () {
  fill(currentColor);
  // preview the shape live
  drawShape(startX, startY, mouseX, mouseY, currentShape);
}

I’m using an older version of Processing and experiencing some flickering with mouseDragged(). Alternatively the mousePressed boolean can be used in draw():

int startX;
int startY;
int currentColor;
float currentShape;
// constants for the supported shape types 
final float SHAPE_TYPE_ELLIPSE = 0.0;
final float SHAPE_TYPE_RECT    = 1.0;

float [] firstcornerX = {};
float [] firstcornerY = {};
float [] secondcornerX = {};
float [] secondcornerY = {};
color [] colors = {};
float [] shapes = {};

void setup () {
  size(500, 500);
  rectMode(CORNERS);
  ellipseMode(CORNERS);
}

void draw() {
  background (255);
  for (int i=0; i < firstcornerX.length; i++) {
    fill(colors[i]);
    // draw the shape from memory
    drawShape(firstcornerX[i], firstcornerY[i], secondcornerX[i], secondcornerY[i], shapes[i]);
  }
  // preview the shape live if mouse is dragged:
  if(mousePressed){
    fill(currentColor);
    drawShape(startX, startY, mouseX, mouseY, currentShape);
  }
}

void drawShape(float left, float top, float right, float bottom, float shapeType){
  if(shapeType == SHAPE_TYPE_ELLIPSE){
    ellipse(left, top, right, bottom);
  }
  if(shapeType == SHAPE_TYPE_RECT){
    rect(left, top, right, bottom);
  }
}

void mousePressed () {
  startX = mouseX;
  startY = mouseY;
  currentColor = color(random(255), random(255), random(255));
  if(mouseButton == LEFT) {
   currentShape = SHAPE_TYPE_ELLIPSE; 
  }else if(mouseButton == RIGHT) {
   currentShape = SHAPE_TYPE_RECT; 
  }
}

void mouseReleased () {
  firstcornerX = append(firstcornerX, startX);
  firstcornerY = append(firstcornerY, startY);
  secondcornerX = append(secondcornerX, mouseX);
  secondcornerY = append(secondcornerY, mouseY);
  colors = append(colors, currentColor);
  shapes = append(shapes, currentShape);
}


Source: stackoverflow