I have no clue how to change this into p5.js. Just trying to work on conversions. Please help me get this code to work in p5.js.
I know that this is old code and p5.js have different rules. Maybe the array isn't working. I have no clue.
Myself myself;
ArrayList<Enemy> enemies;
`enter code here`ArrayList<Enemy> enemies;
ArrayList<Bullet> myBullets;
ArrayList<Bullet> eneBullets;
void setup(){
size(640, 640);
rectMode(CENTER);
myself = new Myself();
enemies = new ArrayList<Enemy>();
myBullets = new ArrayList<Bullet>();
eneBullets = new ArrayList<Bullet>();
}
void draw(){
background(0);
myself.display();
for(Enemy enemy: enemies){
enemy.display();
}
for(Bullet bullet: myBullets){
bullet.display();
}
for(Bullet bullet: eneBullets){
bullet.display();
}
myself.update();
ArrayList<Enemy> nextEnemies = new ArrayList<Enemy>();
for(Enemy enemy: enemies){
enemy.update();
if(!enemy.isDead){
nextEnemies.add(enemy);
}
}
enemies = nextEnemies;
ArrayList<Bullet> nextMyBullets = new ArrayList<Bullet>();
for(Bullet bullet: myBullets){
bullet.update();
if(!bullet.isDead){
nextMyBullets.add(bullet);
}
}
myBullets = nextMyBullets;
ArrayList<Bullet> nextEneBullets = new ArrayList<Bullet>();
for(Bullet bullet: eneBullets){
bullet.update();
if(!bullet.isDead){
nextEneBullets.add(bullet);
}
}
eneBullets = nextEneBullets;
if(random(1) < 0.02){
enemies.add(new Enemy());
}
}
class Myself{
PVector loc;
float size;
int coolingTime;
boolean isDead;
Myself(){
size = 25;
loc = new PVector(width / 2, height - size / 2 - 10);
coolingTime = 0;
isDead = false;
}
void display(){
if(isDead){
fill(255, 255, 0);
stroke(0, 255, 0);
} else {
noFill();
stroke(0, 255, 0);
}
rect(loc.x, loc.y, size, size);
}
void update(){
isDead = false;
float dmx = mouseX - loc.x;
dmx = constrain(dmx, -5, 5);
loc.x += dmx;
coolingTime++;
if(mousePressed && coolingTime >= 10){
myBullets.add(new Bullet());
coolingTime = 0;
}
for(Bullet b: eneBullets){
if((loc.x - size / 2 <= b.loc.x && b.loc.x <= loc.x + size / 2)
&& (loc.y - size / 2 <= b.loc.y && b.loc.y <= loc.y + size / 2)){
isDead = true;
b.isDead = true;
break;
}
}
for(Enemy e: enemies){
if(abs(loc.x - e.loc.x) < size / 2 + e.size / 2 && abs(loc.y - e.loc.y) < size / 2 + e.size / 2){
isDead = true;
e.isDead = true;
break;
}
}
}
}
class Bullet{
PVector loc;
float vel;
boolean isMine;
boolean isDead;
Bullet(){
loc = new PVector(myself.loc.x, myself.loc.y);
vel = -10;
isMine = true;
}
Bullet(Enemy enemy){
loc = new PVector(enemy.loc.x, enemy.loc.y);
vel = 5;
isMine = false;
}
void display(){
if(isMine){
stroke(0, 255, 0);
} else {
stroke(255, 0, 0);
}
line(loc.x, loc.y, loc.x, loc.y + vel);
}
void update(){
loc.y += vel;
if((vel > 0 && loc.y > height) || (vel < 0 && loc.y < 0)){
isDead = true;
}
}
}
class Enemy{
PVector loc;
float vel;
float size;
int coolingTime;
boolean isDead;
Enemy(){
size = 25;
loc = new PVector(random(size / 2, width - size / 2), -size / 2);
vel = 3;
coolingTime = int(random(60));
isDead = false;
}
void display(){
noFill();
stroke(255, 0, 0);
rect(loc.x, loc.y, size, size);
}
void update(){
loc.y += vel;
if(loc.y > height){
isDead = true;
}
coolingTime++;
if(coolingTime >= 60){
eneBullets.add(new Bullet(this));
coolingTime = 0;
}
for(Bullet b: myBullets){
if((loc.x - size / 2 <= b.loc.x && b.loc.x <= loc.x + size / 2)
&& (loc.y - size / 2 <= b.loc.y && b.loc.y <= loc.y + size / 2)){
isDead = true;
b.isDead = true;
break;
}
}
}
}
If you could just tell me what parts i need to change or fix it it would help me a lot thankyou.
You shouldn't try to translate code line-by-line. Instead, you need to take a step back and understand what the program does, and then you implement that in the target language.
They syntax for Processing (which is based on Java) is very different from the syntax for p5.js (which is based on JavaScript).
Instead of trying to "convert" the code, you need to think in terms of what the code actually does. And then start with a new program in p5.js and do that using p5.js. It's not always going to be a line-by-line conversion.
here's your code:
class myself{
constructor()
{
this.x = 0;
this.y = height-35;
this.size = 25;
this.health = 25;
this.cooldown = 0;
this.plrBullets = [];
}update(){this.cooldown++;
if (mouseIsPressed && this.cooldown>10)
{
this.cooldown = 0;
this.plrBullets.push(new Bullet(true,this.x,this.y));
}
let nextPlrBullets = [];
for (let i = 0; i<this.plrBullets.length; i++)
{
this.plrBullets[i].update();
if (this.plrBullets[i].alive)
{
nextPlrBullets.push(this.plrBullets[i]);
}
}
this.plrBullets = nextPlrBullets;
this.x += constrain(mouseX - this.x, -10, 10);
for (let i = 0; i<eneBullets.length; i++)
{
let c = eneBullets[i];
if (c.x > this.x && c.x < this.x + 25 && c.y > this.y && c.y < this.y + 25)
{
this.health--;
c.alive = false;
if (this.health<=0)
{
print("you lost")
}
}
}
noFill();
stroke(0,255,0);
rect(this.x,this.y,this.size,this.size);
}
}
class enemy{
constructor()
{
this.x = random(15,width-15);
this.y = random(-100,0);
this.size = 25;
this.cooldown = 0;
this.alive = true;
}
update()
{
this.y+=2.5;
this.cooldown++;
if (this.cooldown>20)
{
this.cooldown = 0;
eneBullets.push(new Bullet(false,this.x,this.y));
}
let nextEneBullets = [];
for (let i = 0; i<eneBullets.length; i++)
{
eneBullets[i].update();
if (eneBullets[i].alive)
{
nextEneBullets.push(eneBullets[i]);
}
}
eneBullets = nextEneBullets;
for (let i = 0; i<my_self.plrBullets.length; i++)
{
let c = my_self.plrBullets[i];
if (c.x > this.x && c.x < this.x + 25 && c.y > this.y && c.y < this.y + 25)
{
this.alive = false
c.alive = false;
}
}
if (this.y>height+35)
{
this.y = random(-100,0);
}
noFill();
stroke(255,0,0);
rect(this.x,this.y,this.size,this.size);
}
}
class Bullet{
constructor(dir,x,y)
{
this.x = x;
this.speed = 5;
this.dir = dir;
this.alive = true;
this.y = y;
}
update()
{
if (this.dir)
{
this.y -= this.speed;
}else{
this.y += this.speed;
}
if (this.y<-20)
{
this.alive = false;
}//this.y = -25;
if(this.dir)
{
stroke(0,255,0);
}else{
stroke(255,0,0);
}
line(this.x,this.y,this.x,this.y+25);
}
}
let my_self;
let eneBullets = [];
let enemies = [];
function setup()
{
createCanvas(640,640);
rectMode(CENTER);
my_self = new myself();
for (let i = 0; i<10; i++)
{
enemies.push(new enemy());
}
}
function draw()
{
background(0);
if(random(1) < 0.02 && enemies.length<15){
enemies.push(new enemy());
}
my_self.update();
let newEnimies = [];
for (let i = 0; i<enemies.length; i++)
{
enemies[i].update();
if (enemies[i].alive)
{
newEnimies.push(enemies[i]);
}
s}
enemies = newEnimies;
if (enemies.length == 0)
{
print("you win");
}
}
Sorry that the collisions are a bit wacky but when converting processing to p5 here are some tips:
1: don’t use array lists use arrays with push instead of add
2: no data types only LET
3: print not println
4: class constructors are declared as “constructor” instead of class name
5: use “function” before function declaration instead of void
6: pvector is vector
7: google is your friend
8: the p5 documentation
I am currently just messing around with some code and I keep running into an issue. I want to create ten circles and simply have them bounce around the window. I've had a couple of problems (like when I want the circles to bounce off the wall, for some reason the 400,400 window isn't actually that size. I have the circles collide on the right by checking if x + width >= 400, but it bounces outside the screen unless I change the 400 to 380?), but my main issue is that when I create the circles, I want them to be in different locations (so they aren't colliding before they can even move). I am trying to get it so that if a circle is going to be 'inside' another circle then instead create random x and y coordinates again until it isn't inside another circle. But for some reason, if I put r.nextInt() inside the while loop it keeps giving me the same values. Can anyone help?
p.s. I wouldn't mind advice on any other mistakes I have made.
package practicedots;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PracticeDots extends JPanel {
float dots[][] = new float[10][7];
Random r = new Random();
boolean first = true;
float x = 0;
float y = 0;
float xAccel = 0;
float yAccel = 0;
int wall = 380;
int width = 50;
float radius = 0;
float centreX = 0;
float centreY = 0;
boolean collision;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new PracticeDots());
f.setPreferredSize(new Dimension(400, 400));
f.setResizable(true);
f.pack();
f.setVisible(true);
}
/**
*
* #return
*/
public float[][] CreateDots() {
if (first == true) {
for (int i = 0; i < 10; i++) {
while(collision == true){
x = r.nextInt(300);
y = r.nextInt(300);
xAccel = r.nextFloat() / 2;
yAccel = r.nextFloat() / 2;
radius = width/2;
centreX = x + radius;
centreY = y + radius;
dots[i][0] = x;
dots[i][1] = y;
dots[i][2] = xAccel;
dots[i][3] = yAccel;
dots[i][4] = radius;
dots[i][5] = centreX;
dots[i][6] = centreY;
bounce();
}
}
first = false;
} else if (first == false) {
for (int i = 0; i < 10; i++) {
dots[i][0] = dots[i][0] + dots[i][2];
dots[i][1] = dots[i][1] + dots[i][3];
if (dots[i][0] >= wall - width) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] >= wall - 20 - width) {
dots[i][3] = -dots[i][3];
}
if (dots[i][0] < 0) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] < 0) {
dots[i][3] = -dots[i][3];
}
bounce();
}
}
repaint();
return dots;
}
//(x2-x1)^2 + (y1-y2)^2 <= (r1+r2)^2
public void bounce() {
for (int i = 0; i < 10; i++) {
for (int a = 0; a < 10; a++) {
if (a != i) {
System.out.println((dots[i][0] - dots[a][0])*(dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1])*(dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]));
collision = (dots[i][0] - dots[a][0])*(dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1])*(dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]);
}
}
}
}
/**
*
* #param g
*/
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < 10; i++) {
CreateDots();
g.drawOval((int) dots[i][0], (int) dots[i][1], width, width);
g.fillOval((int) dots[i][0], (int) dots[i][1], width, width);
}
}
}
<!-- end snippet -->
There were a couple of problems:
During bounce you should return the first time you find a collision, otherwise the collision will be set to true, but then could be set back to false on the next iteration in the for-loop.
In the first == true condition, you should initialize collision to true or it will never do the while loop at all. Either that or change it to a do-while.
During paintComponent you should not call CreateDots within the for-loop since it loops over all dots itself. Just call it before.
The code seems to work with these changes (including width of 400 not 380):
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PracticeDots extends JPanel {
float dots[][] = new float[10][7];
Random r = new Random();
boolean first = true;
float x = 0;
float y = 0;
float xAccel = 0;
float yAccel = 0;
int wall = 400;
int width = 50;
float radius = 0;
float centreX = 0;
float centreY = 0;
boolean collision;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new PracticeDots());
f.setPreferredSize(new Dimension(400, 400));
f.setResizable(true);
f.pack();
f.setVisible(true);
}
public float[][] CreateDots() {
if (first == true) {
for (int i = 0; i < 10; i++) {
do {
x = r.nextInt(300);
y = r.nextInt(300);
xAccel = r.nextFloat() / 2;
yAccel = r.nextFloat() / 2;
radius = width / 2;
centreX = x + radius;
centreY = y + radius;
dots[i][0] = x;
dots[i][1] = y;
dots[i][2] = xAccel;
dots[i][3] = yAccel;
dots[i][4] = radius;
dots[i][5] = centreX;
dots[i][6] = centreY;
bounce();
} while (collision == true);
}
first = false;
} else {
for (int i = 0; i < 10; i++) {
dots[i][0] = dots[i][0] + dots[i][2];
dots[i][1] = dots[i][1] + dots[i][3];
if (dots[i][0] >= wall - width) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] >= wall - 20 - width) {
dots[i][3] = -dots[i][3];
}
if (dots[i][0] < 0) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] < 0) {
dots[i][3] = -dots[i][3];
}
bounce();
}
}
repaint();
return dots;
}
public void bounce() {
collision = false;
for (int i = 0; i < 10; i++) {
for (int a = 0; a < 10; a++) {
if (a != i && !(dots[a][0] == 0 && dots[a][1] == 0)) {
boolean thisCollision = (dots[i][0] - dots[a][0]) * (dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1]) * (dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]);
// System.out.println("collision: "+collision+" i="+i+" a="+a);
if (thisCollision) {
collision = true;
return;
}
}
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
CreateDots();
for (int i = 0; i < 10; i++) {
g.drawOval((int) dots[i][0], (int) dots[i][1], width, width);
g.fillOval((int) dots[i][0], (int) dots[i][1], width, width);
}
}
}
Table t1;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
int stickColR=0;
int stickColG=0;
int stickColB=0;
int counter=0;
//--------------
void setup(){
size(1000,600);
smooth();
t1 = new Table(1000,600);
t1.startGame();
//sound player setup
minim= new Minim(this);
player=minim.loadFile("ballsound.mp3");
}
//--------------
void draw(){
strokeWeight(10);
stroke(255,0,0);
fill(26, 218, 35);
rect(0, 0, 1000, 600);
fill(0);
noStroke();
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
t1.updatePos(); //calling the function to update the position of the balls
t1.visualize(); // Function responsible for drawing the balls
}
//--------------
void mousePressed(){
t1.mousePressed(mouseX-t1.x,mouseY-t1.y);
}
//--------------
void mouseReleased(){
t1.mouseReleased(mouseX-t1.x,mouseY-t1.y);
}
//=============================
class Table{
boolean GameIsOver=false;
float drag = 0.99;
float bounce = 0.4;
float wallBounce = 0.3;
float pushFactor = 0.4;
float maxPush = 20;
color[] ballColors = new color[]{color (255), color (216,7,17),color(17,242,225), color ( #45B4CE) , color ( #6A6347) , color (#E80909) ,color (#CEA9A9)};
Ball[] balls;
Ball selectedBall;
int x,y,width,height;
//--------------
Table(int w, int h){
width = w;
height = h;
}
//--------------
void startGame(){
buildBalls(5);
}
//--------------
void buildBalls(int count){
balls = new Ball[2*count+1];
int x_coor_red=600;
int y_coor_red=300;
int x_coor_green=626;
int y_coor_green=313;
for(int i=0;i<count;i++)
{
balls[i] = new Ball(x_coor_red, y_coor_red,i+1, this);
x_coor_red+=26;
y_coor_red-=13;
if(i>=3)
{
x_coor_red-=26;
y_coor_red+=26;
}
}
for(int i=0;i<count;i++)
{
balls[count+i] = new Ball( x_coor_green, y_coor_green,i+2, this);
x_coor_green+=26;
y_coor_green+=13;
if(i==1)
{
x_coor_green-=26;
y_coor_green-=20;
}
if(i==2)
{
y_coor_green-=20;
}
if(i==3)
{
x_coor_green-=45;
}
}
balls[2*count] = new Ball( 0.5*(width), 0.5*(height),0, this);
}
//--------------
void updatePos(){
//simulation
for(int i=0;i<balls.length;i++)
balls[i].update();
//collision detection
for(int i=0;i<balls.length;i++)
for(int j=i+1;j<balls.length;j++)
balls[i].collisionDetect(balls[j]);
}
//--------------
void visualize(){
translate(x,y);
noStroke();
//draw stick
if(mousePressed && selectedBall!= null && (mouseX<=26+selectedBall.x || mouseX>26-selectedBall.x) && selectedBall.ballColor==color(255)){
stickColR+=2;
stickColB+=2;
strokeWeight(4);
stroke(stickColR, stickColG, stickColB);
line ( mouseX , mouseY , mouseX + cos (atan2 ( mouseY -selectedBall.y , mouseX - selectedBall.x) )*300 , mouseY + sin( atan2 ( mouseY - selectedBall.y , mouseX -selectedBall.x ))*300);
}
//drawing
for(int i=0;i<balls.length;i++){
balls[i].visualize();
//Balls"disappearing" in corners
if(balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550)){
player.rewind();
player.play();
if(balls[i].ballColor==color(255))
{
textSize(25);
text("Cue Ball Sunk. GAME OVER",350,560);
}
fill(0);
ellipse(0,0,100,100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
balls[i].x=1200;
balls[i].y=0;
counter++;
if (balls[i].ballColor != 255 && counter>=3)
{
textSize(25);
text("YOU WIN", 350,560);
}
}
}
}
//--------------
float kineticEnergy(){
float energy=0;
for(int i=0;i<balls.length;i++)
energy += mag( balls[i].vx, balls[i].vy );
return energy;
}
//--------------
void mousePressed(int mx, int my){
for(int i=0;i<balls.length;i++)
if( dist(balls[i].x,balls[i].y,mx,my) < balls[i].radius) {
selectedBall = balls[i];
break;
}
}
//--------------
void mouseReleased(int mx, int my){
if(selectedBall != null){
float px = (selectedBall.x-mx) * pushFactor;
float py = (selectedBall.y-my) * pushFactor;
float push = mag(px,py);
stickColR=0;
stickColB=0;
if( push > maxPush ){
px = maxPush*px/push;
py = maxPush*py/push;
}
selectedBall.push(px,py);
}
selectedBall = null;
}
}
class Ball{
float x,y,vx,vy,radius,diameter;
int type;
Table table;
color ballColor;
//--------------
Ball(float x, float y, int type, Table t){
this.x = x;
this.y = y;
this.type = type;
diameter = 26;
radius = diameter/2;
table = t;
ballColor = table.ballColors[type];
}
//--------------
void update(){
vx *= table.drag;
vy *= table.drag;
x += vx;
y += vy;
wallBounce();
}
//--------------
void wallBounce(){
if(x<=radius){
vx = -table.wallBounce*vx;
x = radius;
player.rewind();
player.play();
}
if(x>=t1.width-radius){
vx = -table.wallBounce*vx;
x = table.width-radius;
player.rewind();
player.play();
}
if(y<=radius){
vy = -table.wallBounce*vy;
y = radius;
player.rewind();
player.play();
}
if(y>=t1.height-radius){
vy = -table.wallBounce*vy;
y = table.height-radius;
player.rewind();
player.play();
}
}
//--------------
void visualize(){
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x,y,diameter,diameter);
}
//--------------
void push(float dx, float dy){
vx += dx;
vy += dy;
}
//--------------
void collisionDetect(Ball b){
float distance = dist(x,y,b.x,b.y);
if( distance < diameter && (b.x>50 && (b.y>50 || b.y<550) || b.x<950 &&(b.y>50 || b.y<550))){
float vxSum = 0.5*(vx + b.vx);
float vySum = 0.5*(vy + b.vy);
float forceMagnitude = ((b.x-x)*(vx-vxSum) + (b.y-y)*(vy-vySum));
float xForce = 0.25*(x-b.x)*forceMagnitude/distance;
float yForce = 0.25*(y-b.y)*forceMagnitude/distance;
vx = vx + table.bounce * xForce;
vy = vy + table.bounce * yForce;
b.vx = b.vx - table.bounce * xForce;
b.vy = b.vy - table.bounce * yForce;
b.x = x + (diameter+1)*(b.x-x)/distance;
b.y = y + (diameter+1)*(b.y-y)/distance;
player.rewind();
player.play();
}
}
}
Im making a pool game in processing and I'm almost done but I'm stuck here. I want to add a counter that counts when a ball has been in the corner, then once the counter equals ten, the number of balls, it will display the winning message. I think something is going wrong in that the counter is being reset each time since it's in draw? But I'm not sure where else to initialize it. Btw, right now I just have it >= 3 so that I can quickly see if it's working. Thanks all
due to my low reputation, I have to show you my solution even though I think I haven't fixed all the bugs in your code.
I think your bug stated in the question has little relationship with the counter variable. I ran your code and found that you tried to hide the "disappeared" ball by changing coordinates. It means that "disappeared" balls can still be qualified to the if statement below, and as the result, value of counter will keep increasing.
//Balls"disappearing" in corners
if(balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550))
So you can add a boolean field to the Ball class
class Ball{
float x,y,vx,vy,radius,diameter;
int type;
Table table;
color ballColor;
// add this variable.
boolean disappeared = false;
// your constructor, wallBounce(), push(), collisionDetect()
void visualize(){
// only draw the ball when it hasn't disappeared.
if(!this.disappeared) {
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x,y,diameter,diameter);
}
}
}
and then use it to avoid double counting.
// other code in visualize()
if(!balls[i].disappeared) {
counter++;
balls[i].disappeared = true;
}
// other code
Table t1;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
int stickColR=0;
int stickColG=0;
int stickColB=0;
float counter;
boolean isAllIn = false;
//--------------
void setup() {
counter=0;
size(1000, 600);
smooth();
t1 = new Table(1000, 600);
t1.startGame();
//sound player setup
minim= new Minim(this);
player=minim.loadFile("ballsound.mp3");
}
//--------------
void draw() {
strokeWeight(10);
stroke(255, 0, 0);
fill(26, 218, 35);
rect(0, 0, 1000, 600);
fill(0);
noStroke();
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
t1.updatePos(); //calling the function to update the position of the balls
t1.visualize(); // Function responsible for drawing the balls
}
//--------------
void mousePressed() {
t1.mousePressed(mouseX-t1.x, mouseY-t1.y);
}
//--------------
void mouseReleased() {
t1.mouseReleased(mouseX-t1.x, mouseY-t1.y);
}
//=============================
class Table {
float drag = 0.99;
float bounce = 0.4;
float wallBounce = 0.3;
float pushFactor = 0.4;
float maxPush = 20;
color[] ballColors = new color[]{color (255), color (216, 7, 17), color(17, 242, 225), color ( #45B4CE), color ( #6A6347), color (#E80909), color (#CEA9A9)};
Ball[] balls;
Ball selectedBall;
int x, y, width, height;
//--------------
Table(int w, int h) {
width = w;
height = h;
}
//--------------
void startGame() {
buildBalls(5);
}
void restart() {
t1 = new Table(1000, 600);
t1.startGame();
}
//--------------
void buildBalls(int count) {
balls = new Ball[2*count+1];
int x_coor_red=600;
int y_coor_red=300;
int x_coor_green=626;
int y_coor_green=313;
for (int i=0; i<count; i++)
{
balls[i] = new Ball(x_coor_red, y_coor_red, i+1, this);
x_coor_red+=26;
y_coor_red-=13;
if (i>=3)
{
x_coor_red-=26;
y_coor_red+=26;
}
}
for (int i=0; i<count; i++)
{
balls[count+i] = new Ball( x_coor_green, y_coor_green, i+2, this);
x_coor_green+=26;
y_coor_green+=13;
if (i==1)
{
x_coor_green-=26;
y_coor_green-=20;
}
if (i==2)
{
y_coor_green-=20;
}
if (i==3)
{
x_coor_green-=45;
}
}
balls[2*count] = new Ball( 0.5*(width), 0.5*(height), 0, this);
}
//--------------
void updatePos() {
//simulation
for (int i=0; i<balls.length; i++)
balls[i].update();
//collision detection
for (int i=0; i<balls.length; i++)
for (int j=i+1; j<balls.length; j++)
balls[i].collisionDetect(balls[j]);
}
//--------------
void visualize() {
translate(x, y);
noStroke();
//draw stick
if (mousePressed && selectedBall!= null && (mouseX<=26+selectedBall.x || mouseX>26-selectedBall.x) && selectedBall.ballColor==color(255)) {
stickColR+=2;
stickColB+=2;
strokeWeight(4);
stroke(stickColR, stickColG, stickColB);
line ( mouseX, mouseY, mouseX + cos (atan2 ( mouseY -selectedBall.y, mouseX - selectedBall.x) )*300, mouseY + sin( atan2 ( mouseY - selectedBall.y, mouseX -selectedBall.x ))*300);
}
//drawing
for (int i=0; i<balls.length; i++) {
balls[i].visualize();
//Balls"disappearing" in corners
if (balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550)) {
player.rewind();
player.play();
if (balls[i].ballColor==color(255))
{
textSize(25);
text("Cue Ball Sunk. GAME OVER. Press any key to restart.", 170, 560);
if (keyPressed == true) {
t1.restart();
}
}
/*
fill(0);
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
balls[i].x=1200;
balls[i].y=0;
*/
if (!balls[i].disappeared) {
counter++;
balls[i].disappeared=true;
}
if ( counter>=3) {
textSize(25);
text("YOU WIN. Press any key to restart.", 300, 560);
if (keyPressed == true) {
t1.restart();
}
}
}
}
}
//--------------
float kineticEnergy() {
float energy=0;
for (int i=0; i<balls.length; i++)
energy += mag( balls[i].vx, balls[i].vy );
return energy;
}
//--------------
void mousePressed(int mx, int my) {
for (int i=0; i<balls.length; i++)
if ( dist(balls[i].x, balls[i].y, mx, my) < balls[i].radius) {
selectedBall = balls[i];
break;
}
}
//--------------
void mouseReleased(int mx, int my) {
if (selectedBall != null) {
float px = (selectedBall.x-mx) * pushFactor;
float py = (selectedBall.y-my) * pushFactor;
float push = mag(px, py);
stickColR=0;
stickColB=0;
if ( push > maxPush ) {
px = maxPush*px/push;
py = maxPush*py/push;
}
selectedBall.push(px, py);
}
selectedBall = null;
}
}
class Ball {
boolean disappeared = false;
float x, y, vx, vy, radius, diameter;
int type;
Table table;
color ballColor;
//--------------
Ball(float x, float y, int type, Table t) {
this.x = x;
this.y = y;
this.type = type;
diameter = 26;
radius = diameter/2;
table = t;
ballColor = table.ballColors[type];
}
//--------------
void update() {
vx *= table.drag;
vy *= table.drag;
x += vx;
y += vy;
wallBounce();
}
//--------------
void wallBounce() {
if (x<=radius) {
vx = -table.wallBounce*vx;
x = radius;
player.rewind();
player.play();
}
if (x>=t1.width-radius) {
vx = -table.wallBounce*vx;
x = table.width-radius;
player.rewind();
player.play();
}
if (y<=radius) {
vy = -table.wallBounce*vy;
y = radius;
player.rewind();
player.play();
}
if (y>=t1.height-radius) {
vy = -table.wallBounce*vy;
y = table.height-radius;
player.rewind();
player.play();
}
}
//--------------
void visualize() {
if (!this.disappeared) {
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x, y, diameter, diameter);
}
}
//--------------
void push(float dx, float dy) {
vx += dx;
vy += dy;
}
//--------------
void collisionDetect(Ball b) {
float distance = dist(x, y, b.x, b.y);
if ( distance < diameter && (b.x>50 && (b.y>50 || b.y<550) || b.x<950 &&(b.y>50 || b.y<550))) {
float vxSum = 0.5*(vx + b.vx);
float vySum = 0.5*(vy + b.vy);
float forceMagnitude = ((b.x-x)*(vx-vxSum) + (b.y-y)*(vy-vySum));
float xForce = 0.25*(x-b.x)*forceMagnitude/distance;
float yForce = 0.25*(y-b.y)*forceMagnitude/distance;
vx = vx + table.bounce * xForce;
vy = vy + table.bounce * yForce;
b.vx = b.vx - table.bounce * xForce;
b.vy = b.vy - table.bounce * yForce;
b.x = x + (diameter+1)*(b.x-x)/distance;
b.y = y + (diameter+1)*(b.y-y)/distance;
player.rewind();
player.play();
}
}
}
I'm new to programming and I need to make ten or more bouncing objects that will bounce off of each other. Can someone give me an example of a program that will create this?
Edit:Here is the code that I'm currently working on.
//main program
float hue;
float alpha;
float scale = 50;
AnArray HmWd;
void setup(){
size(1000,1000);
colorMode(HSB, 360, 100, 100);
HmWd = new AnArray(scale,3);
}
void display(){
background(0,0,100);
HmWd.display();
}
AnArray class:
class AnArray{
Agent Gems1[];
Agent Gems2[];
Agent Gems3[];
Agent Gems4[];
Agent Gems5[];
float size;
int quant;
int ol = 1;
AnArray(float _size,int _quant){
size = _size;
quant = _quant;
for(int i=0; i<quant;i++){
Gems1[i]=new Agent(size,ol); //I'm getting a "NullPointerException" Error here
ol++;
Gems2[i]=new Agent(size,ol);
ol++;
Gems3[i]=new Agent(size,ol);
ol++;
Gems4[i]=new Agent(size,ol);
ol++;
Gems5[i]=new Agent(size,ol);
ol=1;
}
}
void display(){
for(int i=0; i<quant;i++){
Gems1[i].display();
Gems2[i].display();
Gems3[i].display();
Gems4[i].display();
Gems5[i].display();
}
}
}
Agent class:
class Agent{
PVector position, speed;
float r;
float highlightHue, basicHue;
Agent(float _r,int c){
position = new PVector((random(100,900)),(random(100,900)));
r = _r; ///radius is for test intersection
speed = new PVector(2,2);
highlightHue = 72+(5*c);
basicHue = 190+(5*c);
hue = basicHue;
}
PVector getCenter(){
PVector center = new PVector();
center.x = position.x ;
center.y = position.y ;
return center;
}
void highlight(){
hue = highlightHue;
}
void reverseSpeed(){
speed.x *= -1;
}
void display(){
colorMode(HSB);
fill(hue, 200,200,alpha);
stroke(50, alpha);
ellipse(position.x,position.y, 2*r,2*r);
hue= basicHue;
}
void move(){
if( position.x >width || position.x < 0){
speed.x *= -1;
}
if( position.y > height || position.y < 0){
speed.y *= -1;
}
position.add(speed);
}
void grow(){
if( r < 150){
r++;
alpha = alpha > 50? alpha -= 2: 50; //ternary assignment operator
}
}
void shrink(){
if( r>10){
r--;
alpha = alpha< 200? alpha +=2: 200;
}
}
boolean intersect( Agent a){
boolean isIntersect = false;
float d = PVector.dist(position,a.position);
if(d < this.r + a.r){
isIntersect= true;
}
return isIntersect;
}
}