Place objects by clicking a canvas - arrays

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.

Related

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");
}

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;
}

Append does not work with mousepressed?

I am having an issue with my project, and cannot figure it out. Processing is telling me what I have is not an array, but I do not see how it is not. Also, this issue only occurs when I click the mouse in an attempt to make something else appear.
int numParticles = 200;
GenParticle [] p = new GenParticle[numParticles];
float r=170;
float g=150;
float b=85;
float velX;
float velY;
void setup(){
size(500,500);
noStroke();
smooth();
frameRate(30);
for (int i=0; i<p.length; i++){
velX = random(-1,1);
velY = -i;
p[i]=new GenParticle(width/2,height/2,velX,velY,5.0,width/2,height/2);
}
}
void draw(){
fill(0,20);
rect(0,0,width,height);
fill(255,60);
for(int i=0; i<p.length; i++){
p[i].update();
p[i].regenerate();
p[i].display();
}
}
void mousePressed() {
GenParticle gp = new GenParticle(mouseX,mouseY, velX, velY,5.0,mouseX,mouseY);
p = (GenParticle[]) append(gp,p);
}
class GenParticle extends Particle{
float originX,originY;
GenParticle(int xIn,int yIn,float vxIn,float vyIn,float r,float ox,float oy){
super(xIn, yIn, vxIn, vyIn, r);
originX=ox;
originY=oy;
}
void regenerate(){
if ((x>width+radius) || (x<-radius) || (y>height+radius) || (y<-radius)){
x=originX;
y=originY;
vx=random(-1.0,1.0);
vy=random(-4.0,-2.0);
}
}
}
class Particle{
float x, y;
float vx,vy;
float radius;
float gravity=0.1;
float r=0;
float g=0;
float b=0;
Particle(int xpos,int ypos,float velx,float vely,float r){
x=xpos;
y=ypos;
vx=velx;
vy=vely;
radius=r;
}
void update(){
vy=vy+gravity;
y += vy;
x += vx;
}
void display(){
fill(r,g,b);
ellipse(x, y, radius*3,radius*3);
if(mouseX>width/2){
r=r+9;
}else{
g=g+6;
}
if(mouseY>height/2){
b=b+7;
}else{
b=b-3;
}
if(keyPressed) {
g=g+1;
}else{
g=g-5;
}
r=constrain(r,0,255);
g=constrain(g,0,255);
b=constrain(b,0,255);
}
}
Syntax error: the array is the first parameter and the object you want to append is the second parameter of the append() function
Your mousePressed should look like this:
void mousePressed() {
GenParticle gp = new GenParticle(mouseX,mouseY, velX, velY,5.0,mouseX,mouseY);
p = (GenParticle[]) append(p,pg);
}
Notice the array p goes first, then the object (append to array p object pg).

How to use callback function in processing?

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();
}
}

Get value from an Arraylist of Objects - processing

I'm making a virtual pet game, and I am now trying to include hunger, however I'm not sure how to make the eat function work. I am trying to make it decrease through the addition of the nutrition value of an item of food. This value is in an object that is stored in an arraylist.
Is there a way to reference
int nutrition(int eaten) {
nutrition = nutrition - eaten;
return nutrition;
(int eaten will be passed in later)
inside
ArrayList items;
void setup() {
items = new ArrayList();
}
void draw() {
for (int i = items.size() - 1; i >=0; i --) {
Food food = (Food) items.get(i);
food.display();
if (food.finished()) {
items.remove(i);
}
}
}
void mouseClicked() {
items.add(new Food(mouseX, mouseY, 1));
}
((Food)items.get(i)).nutrition();
http://www.java-forums.org/new-java/2370-how-return-object-arraylist.html
I've tried to use this, but Processing is unable to find i. I believe this to be because i does not exist in the class, only in the main sketch. If this is so, I will find a way to place i into the method. Maybe using return.
I would appreciate the knowledge if someone was aware of a better way to do this.
CODE
Creature creature;
ArrayList items;
Hand hand;
String data[];
int gameInfo[];
int tempData[];
boolean haveFood;
void setup() {
size(100, 100);
smooth();
noCursor();
String data[] = loadStrings("save.txt");
String[] tempData = split(data[0], ',');
gameInfo = int(tempData);
for (int i = 0; i < data.length; i++) {
creature = new Creature(gameInfo[0], gameInfo[1], gameInfo[2], gameInfo[3]);
haveFood = false;
hand = new Hand();
items = new ArrayList();
}
}
void draw() {
background(255);
for (int i = items.size() - 1; i >=0; i --) {
Food food = (Food) items.get(i);
food.display();
if (food.finished()) {
items.remove(i);
}
}
creature.whatWant();
creature.whatDo(haveFood);
hand.draw();
}
void mouseClicked() {
items.add(new Food(mouseX, mouseY, 1));
haveFood = true;
}
class Creature {
int hunger;
int age;
int gender;
int asleep;
boolean idle;
char want;
char request;
Creature(int _gender, int _age, int _hunger, int _asleep) {
gender = _gender;
age = _age;
hunger = _hunger;
asleep = _asleep;
idle = true;
}
void whatWant() {
if (hunger == 50) {
want = 'H';
}
}
void whatDo(boolean food) {
if (idle == true) {
switch(want) {
case 'H':
if (food == true) {
creature.eat();
}
else
request = 'F';
ask();
}
}
else
{
println("IDLE");
}
}
void ask() {
if (request == 'F') {
println("HUNGRY");
}
}
void eat() {
println("EAT");
((Food)items.get(i)).nutrition();
}
}
class Food {
float posX;
float posY;
int nutrition;
Food(float _posX, float _posY, int rating) {
posX = _posX;
posY = _posY;
nutrition = rating;
}
void display() {
rect(posX, posY, 10, 10);
}
boolean finished() {
if (nutrition < 0) {
return true;
}
else {
return false;
}
}
int nutrition(int eaten) {
nutrition = nutrition - eaten;
return nutrition;
}
}
class Hand {
int posX;
int posY;
Hand() {
posX = mouseX;
posY = mouseY;
}
void draw() {
rectMode(CENTER);
point(mouseX, mouseY);
}
}
Where save.txt is a txt file with 1,1,50,1,1.
Unfortunately I can't provide a nice detailed answer. There are quite a few confusing things with the structure of your project and it's code.
In the meantime, you had a syntax error in the Creature's eat() function.
Try this:
void eat() {
println("EAT");
//((Food)items.get(i)).nutrition();
for(int i = 0 ; i < items.size(); i++){
Food yummy = (Food)items.get(0);
yummy.nutrition(hunger);
}
}
The above works because items is declared at the top and therefore visible through out the scope of the whole sketch(global in other words). I'm not sure if this is intentional or what relationship you plan between creatures and food.
The above can be written in a lazier(but less common/obvious) way like so:
void eat() {
println("EAT");
//((Food)items.get(i)).nutrition();
for(Object yummy : items) ((Food)yummy).nutrition(hunger);
}
I assume the creature will be fed based on how hungry it.
At some point the creature should be full I suppose,
so you would also update the creature's hungry property based on the nutrition
it gets from food, etc.
Also, just to test, I've added very nutritious food :P
items.add(new Food(mouseX, mouseY, 10000));

Resources