How to apply changes to a particular object of the class in Processing?

Hi! I am a little confused with the handling of objects. I have created class “Stone” and then I have created 3 objects Stone stone1, stone2, stone3 in the main scetch. What I need is to make a stone transparent when user moves it. The problem is that when the stone is moved, all 3 stones that I have created become transparent, not the particular stone that was moved. Can you please give me a hint, how can I apply transparency just for the moved stone?
My “Stone” class:

   class Stone {
    Playfield p;
    PImage stone;
    boolean overStone = false;
    boolean locked = false;
    boolean stoneMoved;
    int positionX;
    int positionY;
    int stoneXOld;
    int stoneYOld;
    int stoneSize;
    boolean transparencyOn;

    Stone(int stoneXtemp, int stoneYtemp, int stoneSizeTemp, Playfield pf) {
        stone = loadImage("stone.png");

        positionX = stoneXtemp;
        positionY = stoneYtemp;
        stoneXOld = positionX;
        stoneYOld = positionY;

        imageMode(CENTER);
        stoneSize = stoneSizeTemp;
        p = pf;
    }

    void display() {
        if (transparencyOn == true) {
            tint(255, 126);
        } else {
            noTint();
        }
        image(stone, positionX, positionY, stoneSize, stoneSize);
    }

    void update() {
        if (mouseX > positionX - stoneSize / 2 && mouseX < positionX + stoneSize / 2 &&
                mouseY > positionY - stoneSize / 2 && mouseY < positionY + stoneSize / 2) {
            overStone = true;
            if (!locked) {
                tint(160);
            }
        } else {
            noTint();
            overStone = false;
        }
    }

    void interact() {
        if (overStone && mousePressed) {
            locked = true;
            tint(230);
            positionX = mouseX;
            positionY = mouseY;
        } else {
            locked = false;
            noTint();
        }
    }
    
    boolean stoneMoved() {
        return stoneMoved = (!overStone && !locked && positionX > stoneXOld + 100 && positionY > stoneYOld + 100);
    }

    void afterMove() {
           transparencyOn = true;  

    }
}

My main scetch:

import processing.video.*;
Movie water;
Stone stone1,stone2,stone3;
PImage img;

void setup()
{
size(800,800);
water=new Movie(this,"Water.mp4");
water.loop();

stone1=new Stone(70,70,100,this);
stone2=new Stone(180,70,80,this);
stone3=new Stone(270,70,60,this);

}

void draw(){
background(water);

stone1.display();
stone2.display();
stone3.display();

stone1.update();
stone2.update();
stone3.update();

stone1.interact();
stone2.interact();
stone3.interact();
}

void movieEvent(Movie m){
m.read();
}

void mouseReleased(){
stone1.afterMove();
stone2.afterMove();
stone3.afterMove();
}

Hello,

Please provide a minimal example that we can work with.

I was interested but… try the sketch you posted and you will see why.

:)

You can’t rely on tint() outside display()

Instead

  • set transparencyOn correctly everywhere and
  • evaluate it in display() to set tint / noTint
1 Like

That’s my bad. I tried to delete code that is irrelevant for the issue and didn’t see that some things don’t match. I edited post, thanks

1 Like

As said above only use tint() when you are actually rendering the object. Also you can isolate changes in drawing style using push/pop style like this

    void display() {
        pushStyle();
        if (transparencyOn == true) {
            tint(255, 126);
        } else {
            noTint();
        }
        image(stone, stoneX, stoneY, stoneSize, stoneSize);
        popStyle();
    }
2 Likes

You still have a call to tint() inside the interact and update methods which is not good. Create an attribute in the Stone class to store the tint level you want during interaction etc then use it in display method

3 Likes

got it, I’m going to try it now

I added 2 attributes:

int tintLevel;
int base;

initialise them in constructor:

base = 255;
tintLevel = 255;

in display() I use tint() with base, tintLevel

tint(base,tintLevel);

and then in code instead of tint(), I change just tintLevel value
e.g: tintLevel=126;

should it be something like that?

Yes and don’t forget the push popStyle calls this will ensure that each stone is rendered without regard to the others.

1 Like

What did you intend your variable transparencyOn for?

Firstly I wanted to use it to mark when I need the stone to be transparent and when I do not need it. Now I think I would better create method to set transparency, not sure

Well yeah… you made 2 new attributes now, ignoring transparencyOn which already had the job in the first place…

just reread my first post

1 Like

more complicate than I thought it was

I made a global var drag that tells us when ANY stone is dragged, then the others are ignored.

(bit of house cleaning might be required)



import processing.video.*;

// Movie water;

Stone stone1, stone2, stone3;

PImage img;

boolean drag=false; 

void setup()
{
  size(800, 800);
  //water=new Movie(this,"Water.mp4");
  //water.loop();

  stone1=new Stone(70, 70, 100 );
  stone2=new Stone(180, 70, 80 );
  stone3=new Stone(270, 70, 60 );
}

void draw() {
  background(0); // water 

  stone1.display();
  stone2.display();
  stone3.display();

  stone1.update();
  stone2.update();
  stone3.update();

  stone1.interact();
  stone2.interact();
  stone3.interact();
}

void mousePressed() {
  stone1.initMove();
  stone2.initMove();
  stone3.initMove();
}

void mouseReleased() {

  drag=false; 
  stone1.afterMove();
  stone2.afterMove();
  stone3.afterMove();
}

// ===========================================================================================

class Stone {
  // Playfield p;
  PImage stone;

  boolean overStone = false;
  boolean locked = false;
  boolean stoneMoved;
  int positionX;
  int positionY;
  int stoneXOld;
  int stoneYOld;
  int stoneSize;
  boolean transparencyOn;

  Stone(int stoneXtemp, int stoneYtemp, 
    int stoneSizeTemp) {
    stone = loadImage("stone.jpg");

    positionX = stoneXtemp;
    positionY = stoneYtemp;
    stoneXOld = positionX;
    stoneYOld = positionY;

    imageMode(CENTER);
    stoneSize = stoneSizeTemp;
    //p = pf;
  }

  void display() {
    if (transparencyOn == true) {
      tint(255, 126);
    } else {
      noTint();
    }
    image(stone, 
      positionX, positionY, 
      stoneSize, stoneSize);
  }

  void update() {
    if (mouseX > positionX - stoneSize / 2 &&
      mouseX < positionX + stoneSize / 2 &&
      mouseY > positionY - stoneSize / 2 && 
      mouseY < positionY + stoneSize / 2) {
      overStone = true;
      if (!locked&&!drag) {
        transparencyOn=true;
      }
    } else {
      transparencyOn=false; 
      overStone = false;
    }
  }

  void initMove() {
    if (drag)
      return; // leave

    if (overStone && mousePressed) {
      locked = true;
      drag=true;
    } else {
      locked = false;
    }
  }

  void interact() {
    if (drag&&locked) {
      positionX = mouseX;
      positionY = mouseY;
    }
  }

  boolean stoneMoved() {
    return stoneMoved = (!overStone && !locked && positionX > stoneXOld + 100 && positionY > stoneYOld + 100);
  }

  void afterMove() {
    transparencyOn = true;
    locked = false;
  }
}

1 Like

Oh, Thanks a lot, I’ll try it now!

Oh! so I can use drag from all the classes in project! That is astonishing!

1 Like

This is top! I have added some more things that I need, and it seems to be working perfectly!

1 Like