How to use callback function in processing? - arrays

How do i call my array after a certain amount of time so it creates an object at certain intervals. I want my array to create a sphere every 3 seconds.
Ball [] ball;
void setup()
{
size(600,600,P3D);
ball = new Ball[3];
ball[0] = new Ball();
ball[1] = new Ball();
ball[2] = new Ball();
}
void draw()
{
background(255);
for (int i = 0; i < ball.length; i++) {
ball[i].drawBall();
}
}
class Ball
{
float sphereSize = random(30, 90);
float sphereX = random(-2200, 2800);
float sphereY = 0;
float sphereZ = random(-2200, 2800);
void drawBall()
{
translate(sphereX, sphereY, sphereZ);
sphere(sphereSize);
sphereY +=1;
}
}

Easiest way is to store the time in a variable using a time keeping function like millis().
The idea is simple:
store a previous time and a delay amount
keep track of time continuously
if the current time is greather than the previously stored time and the delay, then that delay interval has passed.
Here's a simple sketch to illustrate the idea:
int now,delay = 1000;
void setup(){
now = millis();
}
void draw(){
if(millis() >= (now+delay)){//if the interval passed
//do something cool here
println((int)(frameCount/frameRate)%2==1 ? "tick":"tock");
background((int)(frameCount/frameRate)%2==1 ? 0 : 255);
//finally update the previously store time
now = millis();
}
}
and integrated with your code:
int ballsAdded = 0;
int ballsTotal = 10;
Ball [] ball;
int now,delay = 1500;
void setup()
{
size(600,600,P3D);sphereDetail(6);noStroke();
ball = new Ball[ballsTotal];
now = millis();
}
void draw()
{
//update based on time
if(millis() >= (now+delay)){//if the current time is greater than the previous time+the delay, the delay has passed, therefore update at that interval
if(ballsAdded < ballsTotal) {
ball[ballsAdded] = new Ball();
ballsAdded++;
println("added new ball: " + ballsAdded +"/"+ballsTotal);
}
now = millis();
}
//render
background(255);
lights();
//quick'n'dirty scene rotation
translate(width * .5, height * .5, -1000);
rotateX(map(mouseY,0,height,-PI,PI));
rotateY(map(mouseX,0,width,PI,-PI));
//finally draw the spheres
for (int i = 0; i < ballsAdded; i++) {
fill(map(i,0,ballsAdded,0,255));//visual cue to sphere's 'age'
ball[i].drawBall();
}
}
class Ball
{
float sphereSize = random(30, 90);
float sphereX = random(-2200, 2800);
float sphereY = 0;
float sphereZ = random(-2200, 2800);
void drawBall()
{
pushMatrix();
translate(sphereX, sphereY, sphereZ);
sphere(sphereSize);
sphereY +=1;
popMatrix();
}
}

Related

Looping a mouse movement in Processing

I am trying to de-pixellate an image over time, which is working. However when this has finished, I want the mouse to go back to its original point and start again, forever. I have tried loop commands with no luck.
I can only get this code to work in version 2.2.1
import java.awt.Robot;
PImage img;
int pixls = 0;
int x, y, yinc;
int XOffset = 0;
int YOffset = 30;
int counter = YOffset;
Robot robot;
void setup() {
size(900, 900);
//noCursor();
noStroke();
img = loadImage("p.jpg");
img.resize(900, 900);
//surface.setLocation(XOffset, YOffset);
}
void draw() {
loadPixels();
frameRate(14);
pixls = (int)map(mouseY, height, 20, 250, 20); //pixellation
for (int i = 0; i < pixls; i++) {
for (int j = 0; j < pixls; j++) {
float r = red(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float g = green(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float b = blue(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
fill(r, g, b);
rect((width/pixls)*i, (height/pixls)*j, width/pixls, height/pixls);
yinc = (height/pixls)*j;
}
}
try {
robot = new Robot();
robot.mouseMove(XOffset*2, counter); //counter is start of mouse
if (counter > height + YOffset)
{
counter = YOffset + 30; // +30 for menubar
}
}
catch (Exception e) {
//println("error = ", e);
}
counter++;
}
The following should work in Processing 2.2.1. It uses an old method for finding the XOffset and YOffset of the app's window.
/*
Will work in Processing 2.2.1
*/
import java.awt.Robot;
Robot robot;
PImage img;
int pixls = 0;
int x, y, yinc;
int XOffset = 0;
int YOffset = 0;
int counter = 0;
void setup() {
size(710, 710);
// noCursor();
noStroke();
img = loadImage("myImage.jpg");
img.resize(710, 710);
}
void draw() {
int XOffset = frame.getLocationOnScreen().x;
int YOffset = frame.getLocationOnScreen().y;
pixls = (int)map(mouseY, 0, height, 5, 350);
for (int i = 0; i < pixls; i++) {
for (int j = 0; j < pixls; j++) {
float r = red(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float g = green(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
float b = blue(img.pixels[(height/pixls)*j*width+(width/pixls)*i]);
fill(r, g, b);
rect((width/pixls)*i, (height/pixls)*j, width/pixls, height/pixls);
yinc = (height/pixls)*j;
}
}
try {
robot = new Robot();
robot.mouseMove(XOffset + 10, counter);
if (counter > height + YOffset + 30) {
counter = YOffset + 30; // + 30 for menubar
}
} catch (Exception e) {
println("error = ", e);
}
counter++;
}

How do I make my object disappear when it hits my character in my game? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm trying to make a game where my character (Homer Simpson) has to collect falling objects (donuts) and avoid falling toxic-tanks. Right now my score increments every time he gets a donut, but I wish to make the donut disappear afterwards. Can anyone help me with that?
This is my code so far:
PImage bg2; //background image
PImage homer; //image of homer
homer homer1;
int numberOfToxic = 3; //number of falling toxic tanks
int numberOfDonut = 3; //number of falling donuts
int score; //the score
Toxic[] toxic; //array for the toxic that will fall
PImage t;
Donut[] donut; //array for the donuts that will fall
PImage d;
void setup() {
size(600,500); //size of the window
bg2 = loadImage("bg2.jpg"); //uploading the background image
homer = loadImage("homer.gif"); //uploading the character image
t = loadImage("toxictank.png");
d = loadImage("donut.png");
PFont louiseFont;
louiseFont = loadFont("chalk.vlw"); //loading the font I've chosen
textFont(louiseFont); //the current font being used in the game
toxic = new Toxic[numberOfToxic];
for (int i = 0; i < numberOfToxic; i++) {
toxic[i] = new Toxic();
}
donut = new Donut[numberOfDonut];
for(int i = 0; i < numberOfDonut; i++) {
donut[i] = new Donut();
}
score = 0; //the score starts at 0
}
void draw() {
background(bg2);
homer1 = new homer(mouseX-70, 350, 140, 150, homer); //mouseX makes the hero move on the x axis and 350 defines where it is on the y axis. -70 center the mouse on the image/hero
homer1.drawHomer(); //call the function homer(hero)
//Making the taxictanks fall
for(int i = 0; i < toxic.length; i++) {
toxic[i].update();
toxic[i].drawToxic();
if(toxic[i].position.y > 500) {
toxic[i].reset();
}
}
//Making the donuts fall
for(int i = 0; i < donut.length; i++) {
donut[i].update2();
donut[i].drawDonut();
if(donut[i].position2.y > 500) {
donut[i].reset2();
}
//Collecting points if Homer eats donuts
if(abs(donut[i].position2.y - homer1.y) <= 2 && abs(donut[i].position2.x-40 - homer1.x)<=40) {
score ++;
println("ok");
}
}
fill(#0D128B); //color of text
textSize(20); //size of text
text("SCORE: " + nf(score, 1), 20, 40); //score points - tells how to use the text in the game
}
//class with height, width x, y positions and the hero image
class homer {
int x;
int y;
int hWidth;
int hHeight;
PImage homer;
homer(int x, int y, int hWidth, int hHeight, PImage homer) {
this.x = x;
this.y = y;
this.hWidth = hWidth;
this.hHeight = hHeight;
this.homer = homer;
}
void drawHomer() {
image(this.homer, this.x, this.y, this.hWidth, this.hHeight);
}
}
class Toxic { //all the variables for toxic
PImage t;
PVector position;
float speed;
float size;
//constructor of toxic
Toxic() {
t = loadImage("toxictank.png");
position = new PVector(random(width), random(height));
speed = 4;
size = 20;
}
void update() {
position.y += speed;
}
void drawToxic() {
for(int i = 1; i < 3; i++) {
image(t, position.x, position.y);
}
}
void reset() {
position.x = random(width);
position.y = 0 - 50;
speed = 4;
size = 20;
}
}
class Donut { //all variables for donut
PImage d;
PVector position2;
float speed2;
float size2;
boolean falling;
int timeToDisplay;
int fallingSpeed;
Donut() { //constructor of donut
d = loadImage("donut.png");
position2 = new PVector(random(width), random(height));
speed2 = 4;
size2 = 40;
falling = false;
timeToDisplay = (int)random(2.60);
fallingSpeed = (int)random(2.5);
}
void update2() {
position2.y += speed2;
}
void drawDonut() {
for(int i = 1; i < 3; i++) {
image(d, position2.x, position2.y);
}
}
void reset2() {
position2.x = random(width);
position2.y = 0 - 50;
speed2 = 4;
size2 = 20;
}
}
Just set the variables in the instance of Donut so that it goes back to the top of the screen, or isn't drawn at all. You already have a reset2() function that does that. Something like this:
if(abs(donut[i].position2.y - homer1.y) <= 2 && abs(donut[i].position2.x-40 - homer1.x)<=40) {
score ++;
donut[i].reset2();
println("ok");
}

Processing - Flock Boids avoid draggable objects

I'm working on a boids flocking project.
My goal is to have several draggable objects which have to be avoided by the boids.
There are several different flocks with a different starting position.
I managed to get the boids to avoid one draggable object. But I can't seem to make them avoid all. (using a for loop)
I really can't figure out why this won't do the trick..
I hope you could give me some suggestions.
the code:
int initBoidNum = 100; //amount of boids to start the program with
BoidList flock1, flock2, flock3;
Draggable draggable;
NullDraggableObject nullDraggableObject;
ArrayList draggables;
int id;
float[] xposs= new float[10];
float[] yposs= new float[10];
String turn;
void setup() {
size(1000, 700);
//create and fill the list of boids
flock1 = new BoidList(150, 0, 10, 100);
flock2 = new BoidList(150, 255, 10, 200);
flock3 = new BoidList(150, 150, 10, 300);
turn = "turn";
nullDraggableObject = new NullDraggableObject();
draggables = new ArrayList();
for (int i = 0; i < 10; i++) {
draggables.add(new DraggableObject(random(width), random(height/2)));
}
}
void draw() {
background(100, 60);
flock1.run();
flock2.run();
flock3.run();
stroke(255);
noFill();
draggable = nullDraggableObject;
for (id = 0; id < draggables.size (); id++) {
Draggable d = (Draggable)draggables.get(id);
d.draw();
if (d.isBeingMouseHovered()) {
draggable = d;
}
}
}
void mousePressed() {
draggable.mousePressed();
}
void mouseDragged() {
draggable.mouseDragged();
}
void mouseReleased() {
draggable.mouseReleased();
}
interface Draggable {
boolean isBeingMouseHovered();
boolean inside(float ix, float iy);
void draw();
void mousePressed();
void mouseDragged();
void mouseReleased();
}
class NullDraggableObject implements Draggable {
boolean isBeingMouseHovered() {
return false;
}
boolean inside(float ix, float iy) {
return false;
}
void draw() {
}
void mousePressed() {
}
void mouseDragged() {
}
void mouseReleased() {
}
}
public class DraggableObject implements Draggable {
float XX, YY;
float radius;
boolean drag;
float dragX, dragY;
DraggableObject(float _x, float _y) {
XX = _x;
YY = _y;
radius = 50;
drag = false;
dragX = 0;
dragY = 0;
}
boolean isBeingMouseHovered() {
return inside(mouseX, mouseY);
}
boolean inside(float ix, float iy) {
return (dist(XX, YY, ix, iy) < radius);
}
void draw() {
ellipseMode(CENTER);
ellipse(XX, YY, 2*radius, 2*radius);
String space = "__";
println(id);
println(XX);
println(YY);
xposs[id] = XX;
yposs[id] = YY;
}
void mousePressed() {
drag = inside(mouseX, mouseY);
if (drag) {
dragX = mouseX - XX;
dragY = mouseY - YY;
}
}
void mouseDragged() {
if (drag) {
XX = mouseX - dragX;
YY = mouseY - dragY;
}
}
void mouseReleased() {
drag = false;
}
}
class Boid {
//fields
PVector pos, vel, acc, ali, coh, sep; //pos, velocity, and acceleration in a vector datatype
float neighborhoodRadius; //radius in which it looks for fellow boids
float maxSpeed = 1; //maximum magnitude for the velocity vector
float maxSteerForce = .05; //maximum magnitude of the steering vector
float sMod, aMod, cMod; //modifiers for the three forces on the boid
float h; //hue
Boid(PVector inPos) {
pos = new PVector();
pos.set(inPos);
vel = new PVector(random(-1, 1), random(-1, 1));
acc = new PVector(0, 0);
neighborhoodRadius = 20;
sMod = 1;
aMod = 1;
cMod = 4;
}
Boid(PVector inPos, PVector inVel, float r) {
pos = new PVector();
pos.set(inPos);
vel = new PVector();
vel.set(inVel);
acc = new PVector(0, 0);
neighborhoodRadius = r;
}
void run(ArrayList bl) {
for (int i =0; i < 10; i++) {
acc.add(attract(new PVector(width/2, height/2), true));
acc.add(avoid(new PVector(xposs[i], yposs[i]), true));
if (i == 10) i = 0;
}
if (pos.x>width-10)acc.add(bounce(new PVector(width, pos.y), true));
if (pos.x<10) acc.add(bounce(new PVector(0, pos.y), true));
if (pos.y>height-10) acc.add(bounce(new PVector(pos.x, height), true));
if (pos.y<10) acc.add(bounce(new PVector(pos.x, 0), true));
ali = alignment(bl);
coh = cohesion(bl);
sep = seperation(bl);
for (int i =0; i < 10; i++) {
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)>180) {
acc.add(PVector.mult(ali, aMod));
acc.add(PVector.mult(coh, cMod));
acc.add(PVector.mult(sep, sMod));
}
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)<80) maxSpeed = 1000;
if (i == 10) i = 0;
}
if (PVector.dist(new PVector(width, height), pos)<60) maxSpeed = 1000;
if (PVector.dist(new PVector(0, 0), pos)<50) {
maxSpeed = 1000;
} else {
maxSpeed = 1;
}
move();
checkBounds();
render();
}
void move() {
vel.add(acc); //add acceleration to velocity
vel.limit(maxSpeed); //make sure the velocity vector magnitude does not exceed maxSpeed
pos.add(vel); //add velocity to position
acc.mult(0); //reset acceleration
}
void checkBounds() {
}
void render() {
pushMatrix();
translate(pos.x, pos.y);
rotate(atan2(vel.y, vel.x)); //rotate drawing matrix to direction of velocity
stroke(0);
noFill();
ellipse(0, 0, neighborhoodRadius/2, neighborhoodRadius/2);
noStroke();
fill(h);
//draw triangle
beginShape(TRIANGLES);
rect(0, 0, 6, 2);
endShape();
popMatrix();
}
//steering. If arrival==true, the boid slows to meet the target. Credit to Craig Reynolds
PVector steer(PVector target, boolean arrival) {
PVector steer = new PVector(); //creates vector for steering
if (!arrival) {
steer.set(PVector.sub(target, pos)); //steering vector points towards target (switch target and pos for avoiding)
steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
} else {
PVector targetOffset = PVector.sub(target, pos);
float distance=targetOffset.mag();
float rampedSpeed = maxSpeed*(distance/100);
float clippedSpeed = min(rampedSpeed, maxSpeed);
PVector desiredVelocity = PVector.mult(targetOffset, (clippedSpeed/distance));
steer.set(PVector.sub(desiredVelocity, vel));
}
return steer;
}
//avoid. If weight == true avoidance vector is larger the closer the boid is to the target
PVector avoid(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector attract(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(target, pos)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(target, pos)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector bounce(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector seperation(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector repulse;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
repulse = PVector.sub(pos, b.pos);
repulse.normalize();
repulse.div(d);
posSum.add(repulse);
}
}
return posSum;
}
PVector alignment(ArrayList boids) {
PVector velSum = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
velSum.add(b.vel);
count++;
}
}
if (count>0) {
velSum.div((float)count);
velSum.limit(maxSteerForce);
}
return velSum;
}
PVector cohesion(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector steer = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = dist(pos.x, pos.y, b.pos.x, b.pos.y);
if (d>0&&d<=neighborhoodRadius) {
posSum.add(b.pos);
count++;
}
}
if (count>0) posSum.div((float)count);
steer = PVector.sub(posSum, pos);
steer.limit(maxSteerForce);
return steer;
}
}
class BoidList {
ArrayList boids; //will hold the boids in this BoidList
float h; //for color
BoidList(int n, float ih, int xstart, int ystart) {
boids = new ArrayList();
h = ih;
for (int i=0; i<n; i++) {
boids.add(new Boid(new PVector(xstart, ystart)));
}
}
void run() {
for (int i=0; i<boids.size (); i++) {
Boid tempBoid = (Boid)boids.get(i); //create a temporary boid to process and make it the current boid in the list
tempBoid.h = h;
tempBoid.run(boids); //tell the temporary boid to execute its run method
}
}
}

My program is storing my array backwards

I'm using a program called "Processing" to write this code. The code is supposed to record mouse coordinates in an array when u drag your mouse, and then when you release your mouse, it will show a circle following the path of the coordinates stored in the array, but right now it plays the circle from when I stopped dragging my mouse, to where i started dragging. This is supposed to be the other way around, but I've tried a lot of get it the reverse, but nothing I do seems to work :/
If you could show me it would be really helpful! I'm sure I missed something really obvious.
int num = 100;
int[] x = new int[num];
int[] y = new int[num];
boolean released = false;
int arrayIndex;
boolean drag = false;
void setup() {
size(600, 600);
noStroke();
smooth();
fill(255, 102);
}
void draw() {
background(0);
if (released==true){
arrayIndex= (arrayIndex+1)%100;
ellipse(x[arrayIndex],y[arrayIndex],20,20);
}
}
void mouseDragged(){
drag=true;
x[0] = mouseX;
y[0] = mouseY;
for (int i = num - 1; i > 0; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
}
void mouseReleased(){
released=true;
}
As pointed you add coordinates from end to begin and read form begin to end. So reverse the display iteration, eithr by using frameCount, or a intermediary var...
using frameCount:
int num = 100;
int[] x = new int[num];
int[] y = new int[num];
boolean released = false;
int arrayIndex;
boolean drag = false;
void setup() {
size(600, 600);
noStroke();
smooth();
fill(255, 102);
}
void draw() {
background(0);
if (released==true){
arrayIndex= (num-1) - (frameCount+1)%100;
ellipse(x[arrayIndex],y[arrayIndex],20,20);
}
}
void mouseDragged(){
drag=true;
x[0] = mouseX;
y[0] = mouseY;
for (int i = num - 1; i > 0; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
}
void mouseReleased(){
released=true;
}
using another var:
int num = 100;
int[] x = new int[num];
int[] y = new int[num];
boolean released = false;
int arrayIndex;
boolean drag = false;
void setup() {
size(600, 600);
noStroke();
smooth();
fill(255, 102);
}
void draw() {
background(0);
if (released==true){
arrayIndex= (arrayIndex+1)%100;
int reversed = (num-1) - arrayIndex;
ellipse(x[reversed],y[reversed],20,20);
}
}
void mouseDragged(){
drag=true;
x[0] = mouseX;
y[0] = mouseY;
for (int i = num - 1; i > 0; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
}
void mouseReleased(){
released=true;
}

Place objects by clicking a canvas

Hello. I am new to SO. I have an assignment, which requires me to allow a user to click on a canvas and place an object. The user is only allowed to place the object 100 times and anywhere on the canvas. The problem is I can only create one object and it always goes to the upper left corner.
Here is my code:
Food[] f;
void setup()
{
size(400,400);
background(206,172,26);
f = new Food[100];
for (int i = 0; i < 100; i++)
f[i] = new Food();
}
void draw()
{
for(int i=0; i<f.length; i++)
f[i].draw();
}
class Food
{
color c;
int xpos;
int ypos;
Food()
{
c = color(0,255,0);
xpos = mouseX;
ypos = mouseY;
}
void draw()
{
if (mousePressed == true)
{
fill(c);
ellipse(xpos,ypos,10,10);
}
}
}
What am I doing wrong?
I would go for an ArrayList, so you can easily add objects:
ArrayList<Dummy> d = new ArrayList<Dummy>();
void setup(){
size (400, 400);
smooth();
}
void draw(){
background(0);
for(Dummy dd:d){
dd.display();
}
}
void mouseReleased(){
if(d.size() < 100)
d.add(new Dummy(mouseX, mouseY));
println(d.size());
}
class Dummy{
int x, y;
Dummy(int _x, int _y){
x = _x;
y = _y;
}
void display(){
ellipse(x,y,10,10);
}
}
Your Food() constructor does not have parameters for the xpos and ypos of the mouse. You should change it to be:
Food(int mousePosX, int mousePosY)
{
xpos = mousePosX;
ypos = mousePosY;
}
Also, you should create a Food object only when you click. Then you can get the position of the mouse and pass that into the Food object constructor. You will need a counter to keep track of how many food objects you have created.
All that said, you should do homework on your own (unless you are REALLY stuck). You learn better.

Resources