Can I combine object with trail and object with no trail?
Yes. The easiest way to leave a trail is to use a black rect with weak opaqueness (instead of background (0)
To leave no trail you can delete the item (the one you want to leave no trail) with a small rectangle just deleting the item before moving it
void setup() {
size (700,700); //set the size of the window
smooth();
}
void draw() {
background(255); // Draw a white background
//Set ellipses and rect to CENTER mode
ellipseMode(CENTER);
rectMode(CENTER);
//Draw Body
stroke(0);
fill(175);
rect(mouseX, mouseY, 20, 100);
//Draw Head
stroke(0);
fill(255);
ellipse(mouseX, mouseY-30, 60,60);
//Draw Zoog's eyes
fill(0);
ellipse(mouseX-18, mouseY-30,16,32);
ellipse(mouseX+18, mouseY-30,16,32);
// Draw legs
stroke(0);
line(mouseX+10, mouseY+50,mouseX+20, mouseY+60);
line(mouseX-10, mouseY+50,mouseX-20, mouseY+60);
}
I just want to make the legs leave trails and the others no trails. Can you teach me? sorry I’m a troublesome because I don’t really understand
Ah, do you mean trail like in footsteps?
yes, like in footsteps. sorry for the misunderstanding
Before you start with footprints I would create a separate function to draw Zoog like this
void setup() {
size (700, 700); //set the size of the window
smooth();
}
void draw() {
background(255); // Draw a white background
//Draw Zoog
drawZoog(mouseX, mouseY);
}
void drawZoog(float x, float y){
push();
//Set ellipses and rect to CENTER mode
ellipseMode(CENTER);
rectMode(CENTER);
//Draw Body
stroke(0);
fill(175);
rect(x, y, 20, 100);
//Draw Head
stroke(0);
fill(255);
ellipse(x, y-30, 60, 60);
//Draw Zoog's eyes
fill(0);
ellipse(x-18, y-30, 16, 32);
ellipse(x+18, y-30, 16, 32);
// Draw legs
stroke(0);
line(x+10, y+50, x+20, y+60);
line(x-10, y+50, x-20, y+60);
pop();
}
You can store the footprints positions
ArrayList<PVector> listFP = new ArrayList();
listFP.add(new PVector(mouseX+.., mouseY+..));
Example
ArrayList<PVector> listFootprints = new ArrayList();
void setup() {
size (700, 700); //set the size of the window
smooth();
noCursor();
}
void draw() {
background(255); // Draw a white background
// draw FootPrints
for (PVector pv : listFootprints) {
noFill();
ellipse(pv.x, pv.y, 7, 3);
}
//Draw Zoog
drawZoog(mouseX, mouseY);
}
void drawZoog(float x, float y) {
push();
//Set ellipses and rect to CENTER mode
ellipseMode(CENTER);
rectMode(CENTER);
//Draw Body
stroke(0);
fill(175);
rect(x, y, 20, 100);
//Draw Head
stroke(0);
fill(255);
ellipse(x, y-30, 60, 60);
//Draw Zoog's eyes
fill(0);
ellipse(x-18, y-30, 16, 32);
ellipse(x+18, y-30, 16, 32);
// Draw legs
stroke(0);
line(x+10, y+50, x+20, y+60);
line(x-10, y+50, x-20, y+60);
// store footprints
listFootprints.add(new PVector(x+20, y+60));
listFootprints.add(new PVector(x-20, y+60));
pop();
}
Hey, and welcome to the forum!
Great to have you here!
Chrisir
thank you so much for helping me do this!
thank you so much for helping me do this and thanks for the welcome!
here is an improved version where we check
whether the current footprint has already been stored (for example
when Zoog stands, we don’t want to record the same
footprint position over and over again…)
this can be improved of course
ArrayList<PVector> listFootprints = new ArrayList();
void setup() {
size (700, 700); //set the size of the window
smooth();
noCursor(); // hides mouse cursor
}
void draw() {
background(255); // Draw a white background
// draw FootPrints
drawFootPrints();
// show size of the list (for testing)
text(listFootprints.size(), 17, 17);
//Draw Zoog
drawZoog(mouseX, mouseY);
}
// ---------------------------------------------------------------------------------
void drawZoog(float x, float y) {
// draw Zoog
// store formatting
push();
//Set ellipses and rect to CENTER mode
ellipseMode(CENTER);
rectMode(CENTER);
//Draw Body
stroke(0);
fill(175);
rect(x, y, 20, 100);
//Draw Head
stroke(0);
fill(255);
ellipse(x, y-30, 60, 60);
//Draw Zoog's eyes
fill(0);
ellipse(x-18, y-30, 16, 32);
ellipse(x+18, y-30, 16, 32);
// Draw legs
stroke(0);
line(x+10, y+50, x+20, y+60);
line(x-10, y+50, x-20, y+60);
// store footprints (from legs position)
storeFootprints(x, y);
// restore formatting
pop();
}
void storeFootprints( float x, float y ) {
// first time we store the foot print
if (listFootprints.size()==0) {
listFootprints.add(new PVector(x+20, y+60));
listFootprints.add(new PVector(x-20, y+60));
return; // leave
}
// After the first time we check if the last position was the same,
// we store the foot print only when it's new:
// Second last position in list:
if (listFootprints.get(listFootprints.size()-2).x != x+20 || listFootprints.get(listFootprints.size()-2).y != y+60)
listFootprints.add(new PVector(x+20, y+60));
// last position
if (listFootprints.get(listFootprints.size()-1).x != x-20 || listFootprints.get(listFootprints.size()-1).y != y+60)
listFootprints.add(new PVector(x-20, y+60));
}
void drawFootPrints() {
for (PVector pv : listFootprints) {
noFill();
ellipse(pv.x, pv.y, 7, 3);
}
}
//
thank you so much! have a nice day
in this version
- we suppress the initial footprint (because it’s not connected to the trail)
- and we make a more catlike paw trail (with 3 dots)
ArrayList<PVector> listFootprints = new ArrayList();
void setup() {
size (700, 700); //set the size of the window
smooth();
noCursor(); // hides mouse cursor
//mouseX = width/2;
//mouseY = height/2;
}
void draw() {
background(255); // Draw a white background
// draw FootPrints
drawFootPrints();
// show size of the list (for testing)
text(listFootprints.size() +" " + mouseX, 17, 17);
//Draw Zoog
drawZoog(mouseX, mouseY);
}
// ---------------------------------------------------------------------------------
void drawZoog(float x, float y) {
// draw Zoog
// store formatting
push();
//Set ellipses and rect to CENTER mode
ellipseMode(CENTER);
rectMode(CENTER);
//Draw Body
stroke(0);
fill(175);
rect(x, y, 20, 100);
//Draw Head
stroke(0);
fill(255);
ellipse(x, y-30, 60, 60);
//Draw Zoog's eyes
fill(0);
ellipse(x-18, y-30, 16, 32);
ellipse(x+18, y-30, 16, 32);
// Draw legs
stroke(0);
line(x+10, y+50, x+20, y+60);
line(x-10, y+50, x-20, y+60);
// store footprints (from legs position)
if (mouseX>0 && mouseY>0) { // if mouse is there
storeFootprints(x, y);
}
// restore formatting
pop();
}
void storeFootprints( float x, float y ) {
// first time we store the foot print
if (listFootprints.size()==0) {
listFootprints.add(new PVector(x+20, y+60));
listFootprints.add(new PVector(x-20, y+60));
return; // leave
}
// After the first time we check if the last position was the same,
// we store the foot print only when it's new:
// Second last position in list:
if (listFootprints.get(listFootprints.size()-2).x != x+20 || listFootprints.get(listFootprints.size()-2).y != y+60)
listFootprints.add(new PVector(x+20, y+60));
// last position
if (listFootprints.get(listFootprints.size()-1).x != x-20 || listFootprints.get(listFootprints.size()-1).y != y+60)
listFootprints.add(new PVector(x-20, y+60));
}
void drawFootPrints() {
for (PVector pv : listFootprints) {
noFill();
ellipse(pv.x, pv.y, 2, 2);
ellipse(pv.x+3, pv.y+3, 2, 2);
ellipse(pv.x+3, pv.y-3, 2, 2);
}
}
//
Thank you so much! Sorry, may I ask again? What if the tracks were replaced with legs? like this
like here
(The small check if it’s new doesn’t work)
Explanation
Instead of PVector (the in-built type to store a point with x,y) that we used previously we define a new type “Line” that stores 2 PVectors (line from point 1 to point 2). To define a type, we made a class “Line”.
To store a line in our list we just say
listFootprints.add(new Line(new PVector(x1, y1), new PVector(x2, y2)));
As you can see we make a new line by passing 2 PVectors in it (that we make on the fly) and add the line to the list. (you have to read this from inside to outside: from x1,y1 to PVector, 2 PVectors needed to make a line, add the line to list)
- The nice thing of using a class is that we can place a function “display()” inside a class to work with one line.
Sketch
ArrayList<Line> listFootprints = new ArrayList();
void setup() {
size (700, 700); // set the size of the window
smooth();
noCursor(); // hides mouse cursor
}
void draw() {
background(255); // Draw a white background
// draw FootPrints
drawFootPrints();
// show size of the list (for testing)
text(listFootprints.size(), 17, 17);
//Draw Zoog
drawZoog(mouseX, mouseY);
}
// ---------------------------------------------------------------------------------
void drawZoog(float x, float y) {
// draw Zoog
// store formatting
push();
//Set ellipses and rect to CENTER mode
ellipseMode(CENTER);
rectMode(CENTER);
//Draw Body
stroke(0);
fill(175);
rect(x, y, 20, 100);
//Draw Head
stroke(0);
fill(255);
ellipse(x, y-30, 60, 60);
//Draw Zoog's eyes
fill(0);
ellipse(x-18, y-30, 16, 32);
ellipse(x+18, y-30, 16, 32);
// Draw legs
stroke(0);
line(x+10, y+50, x+20, y+60);
line(x-10, y+50, x-20, y+60);
// store footprints (from legs position)
if (mouseX>0 && mouseY>0) { // if mouse is there
storeFootprints(x+10, y+50, x+20, y+60);
storeFootprints(x-10, y+50, x-20, y+60);
}
// restore formatting
pop();
}
void storeFootprints( float x1, float y1,
float x2, float y2) {
// store the foot print
// The first 3 times we store the foot print
if (listFootprints.size()==0 || listFootprints.size()==1 || listFootprints.size()==2) {
listFootprints.add(new Line(new PVector(x1, y1), new PVector(x2, y2)));
return; // leave
}//if
// After the first time we check if the last position was the same,
// we store the foot print only when it's new:
// last position:
if ( listFootprints.get(listFootprints.size()-2).pv1.x != x1 || listFootprints.get(listFootprints.size()-2).pv1.y != y1 )
listFootprints.add(new Line(new PVector(x1, y1),
new PVector(x2, y2)));
} //func
void drawFootPrints() {
for (Line l1 : listFootprints) {
noFill();
l1.display();
}//for
}//func
// ============================================================================
class Line {
PVector pv1;
PVector pv2;
// constr
Line(PVector pv1_, PVector pv2_) {
pv1=pv1_.copy();
pv2=pv2_.copy();
}// constr
void display() {
line(pv1.x, pv1.y,
pv2.x, pv2.y);
}//method
//
}//class
//
Sorry for the late reply, thanks for the help! I’ll understand the code first. If I need further assistance, may I send you a message? if not, that’s fine
An alternative solution might be to use layers, drawing the trail in a transparent image that is drawn at each frame with the rest of the objects. This way you don’t have to store the steps in an ArrayList, and doing many steps doesn’t increase the computational cost.
push() saves the current state of formatting (for the rectMode()
etc.).
when you use rectMode(CENTER);
etc. the formatting changes.
at the end, pop() restores the formatting (push()
and pop()
always come together).
- So, by restoring the formatting, we are polite to the rest of the program, we don’t change the formatting for it.