Elmpt
January 7, 2021, 10:29am
1
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();
}
glv
January 7, 2021, 10:56am
2
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
Elmpt
January 7, 2021, 11:16am
4
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
quark
January 7, 2021, 11:16am
5
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
quark
January 7, 2021, 11:20am
6
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
Elmpt
January 7, 2021, 11:25am
7
got it, I’m going to try it now
Elmpt
January 7, 2021, 12:33pm
8
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?
quark
January 7, 2021, 12:34pm
9
Yes and don’t forget the push popStyle calls this will ensure that each stone is rendered without regard to the others.
1 Like
Chrisir
January 7, 2021, 12:40pm
10
quark:
transparencyOn
What did you intend your variable transparencyOn
for?
Elmpt
January 7, 2021, 12:43pm
11
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
Chrisir
January 7, 2021, 12:45pm
12
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
Elmpt
January 7, 2021, 2:37pm
14
Oh, Thanks a lot, I’ll try it now!
Elmpt
January 7, 2021, 2:41pm
15
Oh! so I can use drag from all the classes in project! That is astonishing!
1 Like
Elmpt
January 7, 2021, 3:05pm
16
This is top! I have added some more things that I need, and it seems to be working perfectly!
1 Like