I have a bit of a problem with a collision check loop

Hi there , I have been working (playworking), on this this P3D program and am confused as to why the collision check loop does not detect any of the posts other than the last in the array (which I have coloured red.) !

Could anyone please explain to me why this is so ?

//***BALL MAZE********NIGEL WOOLLARD

// *** KEY CONTROLS ***
//
// ‘,’ = LEFT
// ‘/’ = RIGHT
// ’ .’= FORWARD
// ‘x’ = BACK

float x=683;
float y=636; //sets initial ball position
float z=-282;
float s=3;
float altitude=1;
float py=600;

float d; // Ball to Post distance

int[]postx = new int[50];
int[]posty = new int[50]; // declare post coordinates
int[]postz = new int[50];

int bc=255; //background colour var

void setup(){
size(1200, 700, P3D);
//directionalLight(255,255,255, 0, 0,0);

for (int p=0;p<50;p++){

postx[p]= int (random(200,1160));
posty[p]= int (random(100,1100)); // Fill arrays with random post coordinates
postz[p]= int (random(-900,80));

}

}

void draw(){

shapeMode(CENTER);

background(bc);

//lights
directionalLight(251, 202, 226, -1, 0, 0);
spotLight (255,255,255,300,100,100,width/2,height/2,-100,PI/2,2);

//stage
pushMatrix();
translate(width/2,height-100,-400);
fill(#257C13);
box(1000,5,1000);
popMatrix();

//posts
for (int p=0;p<50;p++){
pushMatrix();
translate (postx[p],py,postz[p]);
fill(#BC9B20);
box( 20,100,20);
popMatrix();
}
pushMatrix();
translate (postx[49],py,postz[49]); // color last post in array red .(done this just to make sure it was the last one.)
fill(#D62B18);
box(20,100,20);
popMatrix();

// pointer sphere
pushMatrix();
translate(x,y,z);
fill(#FF0313);
noStroke();
sphere(10);
popMatrix();

// create backward forward movement

if (keyPressed){
if (key == ‘/’){x=x+s;} //RIGHT
if (key == ‘,’){x=x-s;} //LEFT
//if (key == ‘c’){y=y+altitude;} //ALTITUDE UP
//if (key == ‘z’){y=y-altitude;} //ALTITUDE DOWN
if (key == ‘x’){z=z+s;}
if (key == ‘.’){z=z-s;}
}

// position coordinates
fill(255);
textSize(32);
text (“x=”,25,40);
text ((x)-width/2,70,40);
text (“y=”,25,75);
text (-(y)+636,70,75);
text (“z=”,25,110);
text ((z)+282,70,110);
// text (“postx”,25,150);
// text ((postx[0]),120,150);

for (int p=0;p<50;p++){
d= dist(x,y,z,postx[p],y,postz[p]);

if (d<=20) {bc=0;}//else{bc=255;} // collision check
if (d>=20) {bc=255;}//else {bc=0;}
// text (d,100,200);
}
// (x>postx[0])-10)
}

What do you think should happen when you detect the collision?

Your code is computing the distance to each post and then setting the value of bc each time through the loop, over-writing it each time. Only the last value is preserved once the loop ends.

You could, instead, have a variable that remembers which post you are closest to and color that one – remember the post number and your distance to it and update both if you find a closer one.

3 Likes

Also not fully sure why you don’t use the y array for y

Back to the main issue

I agree to what has been said

Or make bc an array of colors so each wall has its own color

Thanks for your input scudly . I understand what you are saying , I thought that is what was happening and tried putting the background change within the loop but of course that just whitewashes everything ! I will try and have a go at what you are saying , thanks Chrisir.

Thanks for your input Chrisir . The reason why the Y array is incorperated is because the “game” took a somewhat unknown creative path , and earlier versions had the ball rising and falling on the Y axis and I simply didn’t change it .

hanks for your input scudly . I understand what you are saying , I thought that is what was happening and tried putting the background change within the loop but of course that just whitewashes everything ! I will try and have a go at what you are saying , thanks .

Can the player be near only ONE post or a few at the same time?

Yeah Hi Chrisir. I hadn’t actually defined a final aim of the program , I am just trying to progress in command use and program manipulation through online study ,trial and error really ! I discovered Processing about 8/9 years back , had a dabble , and then recently got reinterested in it . I learnt some BBC BASIC in the mid 80’s whilst at school , and wasn’t really ,i must say , 'impressed ’ when introduced to Object Oriented Programming in the form of C++ in late 90’s ! Aaaagh why can’t we just have line numbers and GOTO 's SUB’s I would say to myself ! conclusion ; parallel better than series execution I guess . I have just become aware of heuretics paths etc and I think I understand the whole reason why programming went oops ! I think , though I still like the idea of line number tracking and just documenting the program with REM’s . It seems a bit of a shame that there was no direct progression from 8 bit BBC BASIC to a 32 or 64 bit format enabling todays modern colour pallette and preprogrammed functons , 3D etc ! But hey ho , deciced to see what I can do with P3 as it seems to me to fairly a fairly concise JAVA derivative. (All that pre gl stuff in openGL ,couldn’t be doing with that . Anyhow thanks Chisir , back to the brain bashing programming lol.

1 Like

thanks for this great post!

I made a new version.

  • each post has its color to mark the nearest to sphere
  • sphere is on top of stage now
  • some function (three) added so code is better readable (showPosts() etc.)

Happy new year!



//***BALL MAZE********NIGEL WOOLLARD

// *** KEY CONTROLS ***
//
// ‘,’ = LEFT
// ‘/’ = RIGHT
// ’ .’= FORWARD
// ‘x’ = BACK

float x=683;
float y=570; //636; //sets initial ball position
float z=-282;
float s=3;
float altitude=1;
float py=600;

float d; // Ball to Post distance

int[]postx = new int[50];
int[]posty = new int[50]; // declare post coordinates
int[]postz = new int[50];
color[]postColor = new color[50];

color backgroundcolorvar=color(255); //background colour var

// -----------------------------------------------------

void setup() {
  size(1200, 700, P3D);
  //directionalLight(255,255,255, 0, 0,0);

  for (int p=0; p<50; p++) {

    postx[p]= int (random(200, 1160));
    posty[p]= int (random(100, 1100)); // Fill arrays with random post coordinates
    postz[p]= int (random(-900, 80));

    postColor[p]= #BC9B20;  //color(255, 0, 0);
  }
}

void draw() {
  background(backgroundcolorvar);

  shapeMode(CENTER);

  //lights
  directionalLight(251, 202, 226, -1, 0, 0);
  spotLight (255, 255, 255, 300, 100, 100, width/2, height/2, -100, PI/2, 2);

  //stage
  pushMatrix();
  translate(width/2, height-100, -400);
  fill(#257C13);
  box(1000, 5, 1000);
  popMatrix();

  showPosts(); 

  // pointer sphere
  pushMatrix();
  translate(x, y, z);
  fill(#FF0313);
  noStroke();
  sphere(10);
  popMatrix();

  readKeys(); 

  // position coordinates
  fill(255);
  textSize(32);
  text ("x=", 25, 40);
  text ((x)-width/2, 70, 40);
  text ("y=", 25, 75);
  text (-(y)+636, 70, 75);
  text ("z=", 25, 110);
  text ((z)+282, 70, 110);
  // text (“postx”,25,150);
  // text ((postx[0]),120,150);

  colorChecks();
}//draw

// ------------------------------------------------------------

void showPosts() {
  //posts
  for (int p=0; p<50; p++) {
    pushMatrix();
    translate (postx[p], py, postz[p]);
    // fill(#BC9B20);
    fill(postColor[p]);
    box( 20, 100, 20);
    popMatrix();
  }
  pushMatrix();
  translate (postx[49], py, postz[49]); // color last post in array red .(done this just to make sure it was the last one.)
  fill(#D62B18);
  box(20, 100, 20);
  popMatrix();
}

void readKeys() {
  // create backward / forward movement
  if (keyPressed) {
    if (key == '/') {
      x=x+s;
    } //RIGHT
    if (key == ',') {
      x=x-s;
    } //LEFT
    //if (key == ‘c’){y=y+altitude;} //ALTITUDE UP
    //if (key == ‘z’){y=y-altitude;} //ALTITUDE DOWN
    if (key == 'x') {
      z=z+s;
    }
    if (key == '.') {
      z=z-s;
    }
  }
}

void colorChecks() {
  // RESET colors 
  for (int p=0; p<50; p++) {
    postColor[p]=color(255, 0, 0);
  }

  float minDist=1000; // BIG
  int minDist_p=0; 

  for (int p=0; p<50; p++) {
    d= dist(x, 0, z, postx[p], 0, postz[p]);

    if (d<=30) {
      if (d<minDist) {
        // backgroundcolorvar=0;
        minDist=d; 
        minDist_p=p;
      }
    }//else{bc=255;} // collision check
    else if (d>30) { // placed else if here instead of if
      backgroundcolorvar=255;
    }//else {bc=0;}
    // text (d,100,200);
  }//for
  // (x>postx[0])-10)

  if (minDist<1000) {
    postColor[minDist_p]= color(0, 255, 0);
  }
}
//

Hey thanks for that Chrisir, thats excellent ! I’ve had a bit of a look at your changes and must admit that I am a bit confused ! mainly the if nesting bit and the min dist calculations . Readkeys is also new to me and I shall look into it , is it a preprogrammed function ? Clever stuff mate ,nice one ! I’m also struggling with syntax on setting up class , I keep thinking I’ve got it but when I go to apply it , I seem to lose track of what I am trying to do , like a programmers autism or something ,is there such a thing ? when I try to go off to a function that I’ve created out of draw with a VOID precedent using name(); I find it goes there and does stuff like draws a rectangle but it doesnt recognise variables announced within it , no matter how I declare it ! Is that kind of why we need class ? I shall study your improvements some more , thanks .

Hey cheers Chrisir , smart stuff , thanks very much for that and a Happy New Year to you . I’m still studying your brilliant changes ,admitidely somewhat perplexed, many thanks. .

1 Like

Just what scudly suggested above

And yeah you can define your own functions and call them by their names (nothing to do with oop). It just makes draw () shorter and the code better readable because one function per purpose. Nice.

And you’re right the variables are known only within a function. Variables declared before setup () are known everywhere though (they are declared OUTSIDE any function).

BUT you can declare a variable within a function with the same name as the variable before setup (bad idea) which will then overshadow the one before setup () (which is called a global variable).

(A variable within a function is a local variable)

Also we can pass parameters to a function which are in turn variables known only within the function

This all very confusing but it serves the modularization of a code / Sketch

1 Like

No it’s not inbuilt, I invented the name. Just to move the section of code out of draw()

Hi Chris , yeah it is a bit confusing I must say , but intersting non the less ! I now have another bit of a problem with a derivative of the BALLMAZE layout. I’ve wrote some notes in the progtext , cheers !

//BALLPLOTTER
// IDEA: to collect data for vertices of 3D shapes into array.

//************************* GLOBAL VARIABLES ************************************
int x=0;
int y=0;
int z=0;
int s=3;

int cx;
int cy;
int cz;

int[]bx = new int [10];
int[]by = new int [10]; // captured coordinates
int[]bz = new int [10];

int icap;
float bx_p;
int val=0;
//****************** SETUP **************************************8

void setup() {

size(1200, 700, P3D);
// frameRate(30);
}

//*********************** START DRAW ****************************

void draw() {

shapeMode(CENTER);

background(#4D1F98);

//lights
directionalLight(251, 202, 226, -1, 0, 0);
spotLight (255, 255, 255, 300, 100, 100, width/2, height/2, -100, PI/2, 2);

//stage
pushMatrix();
translate(width/2, height-100, -400);
fill(0);
box(1000, 5, 1000);
popMatrix();

keyGet();

// create backward forward movement

// position coordinates
textSize(32);
text (“x=”, 25, 40);
int bx=(x-width/2);
text (bx, 70, 40);

text (“y=”, 25, 75);
int by=(-y+591);
text (by, 70, 75);

text (“z=”, 25, 110);
int bz=(z+282);
text (bz, 70, 110);

pointer();

if (mousePressed) {

cx= bx;
cy= by;
cz= bz;

capture();

}
}

// ******** END OF DRAW ******************************************************************************

//******************** FUNCTIONS **********************

void keyGet() {
if (keyPressed) {
if (key == ‘/’) {
x=x+s;
}
if (key == ‘,’) {
x=x-s;
}
if (key == ‘c’) {
y=y+s;
}
if (key == ‘z’) {
y=y-s;
}
if (key == ‘x’) {
z=z+s;
}
if (key == ‘.’) {
z=z-s;
}
}
}

void pointer() {

pushMatrix();
translate(x, y, z);
fill(#FF0313);
noStroke();
sphere(10);
popMatrix();
}

void capture() {

noLoop();

bx[icap] = cx;
by[icap] = cy;
bz[icap] = cz;

text (bx[icap], 25, 150+35*icap) ;

text (by[icap], 25, 180+35*icap) ;

text (bz[icap], 25, 210+35*icap) ;

icap++;
if (icap>9){exit();}
//else {);} // HI Chrisir , this is where I want to return to the pointer (which I tried by declaring the function but didn’t work!

                       //   Also I realize that a VOID method  cannot return a value . Does this mean that the stored coordinates ie bx[icap] etc will be lost ?

}

General Remark

In processing you can hit ctrl-t to get auto-format. Do this before posting

Posting code: Hit ctrl-e and then paste Code between the two lines with the “```”

Remark PVector:

instead of using

int[]bx = new int [10];
int[]by = new int [10];  // captured coordinates
int[]bz = new int [10];

Please look at PVector which stores x,y,z

then you get:

PVector [] posPVector = new PVector[10]; // captured coordinates

see reference PVector

Remark WASD

Where I come from people use WASD keys for steering not , . x…

and maybe l (“L”) and p for up and down (y value)

Remark mousePressed

Distinguish between mousePressed as a variable as you had it and mousePressed() with the brackets() as function:

  • mousePressed as a variable registers multiple times
  • mousePressed() with the brackets() as function registers only ONCE (better in this case)

I changed this.

Remark

Quote:

HI Chrisir , this is where I want to return to the pointer (which I tried by declaring the function but didn’t work!

Also I realize that a VOID method cannot return a value . Does this mean that the stored coordinates ie bx[icap] etc will be lost ?

No, stored coordinates ie bx[icap] etc are stored, because the arrays are global arrays.


Full Sketch


// BALLPLOTTER
// IDEA: to collect data for vertices of 3D shapes into array.

//************************* GLOBAL VARIABLES ************************************
int x=333;
int y=333;
int z=-222;
int s=3;

float cx;
float cy;
float cz;

// captured coordinates
float[]bx = new float [10];
float[]by = new float [10]; 
float[]bz = new float [10];

float bx1, by1, bz1;

int icap=0;
float bx_p;
int val=0;

//****************** SETUP **************************************8

void setup() {
  size(1200, 700, P3D);
}

//*********************** DRAW ****************************

void draw() {
  background(#4D1F98);

  shapeMode(CENTER);

  //lights
  directionalLight(251, 202, 226, -1, 0, 0);
  spotLight (255, 255, 255, 300, 100, 100, width/2, height/2, -100, PI/2, 2);

  //stage
  pushMatrix();
  translate(width/2, height-100, -400);
  fill(0);
  box(1000, 5, 1000);
  popMatrix();

  // create backward forward movement
  keyGet();

  // position coordinates
  textSize(32);
  text ("x=", 25, 40);
  bx1=(x-width/2);
  text (bx1, 70, 40);

  text ("y=", 25, 75);
  by1=(-y+591);
  text (by1, 70, 75);

  text ("z=", 25, 110);
  bz1=(z+282);
  text (bz1, 70, 110);

  pointer();

  if (icap>=1) {
    textSize(12); 
    for (int i2=0; i2<icap; i2++) {
      text (bx[ i2], width-95, 20+135*i2) ;
      text (by[ i2], width-95, 40+135*i2) ;
      text (bz[ i2], width-95, 60+135*i2) ;
    }
    textSize(32);

    stroke(255);
    strokeWeight(1); 
    for (int i2=0; i2<icap-1; i2++) {
      line(bx[ i2], by[ i2], bz[ i2], 
        bx[ i2+1], by[ i2+1], bz[ i2+1]);
    }
    stroke(0);
  }//if
  //
}

// ******** END OF DRAW ******************************************************************************

//******************** FUNCTIONS **********************

void mousePressed() {
  bx1=x;//(x-width/2);  
  by1=y;//(-y+591);  
  bz1=z;//(z+282);

  cx= bx1;
  cy= by1;
  cz= bz1;

  capture();
}

void keyGet() {
  if (keyPressed) {
    if (key == '/') {
      x=x+s;
    }
    if (key == ',') {
      x=x-s;
    }
    if (key == 'c') {
      y=y+s;
    }
    if (key == 'z') {
      y=y-s;
    }
    if (key == 'x') {
      z=z+s;
    }
    if (key == '.') {
      z=z-s;
    }
  }
}

void pointer() {
  // ball 
  pushMatrix();
  translate(x, y, z);
  //  fill(#FF0313);
  fill(255, 0, 0); 
  noStroke();
  sphere(10);
  popMatrix();
}

void capture() {

  // noLoop();

  bx[icap] = cx;
  by[icap] = cy;
  bz[icap] = cz;

  printArray(bx);
  println();

  icap++;
  if (icap>9) {
    // exit();
  }
}
//

Thanks Chrisir , you’ve worked wonders with just a few additional lines and changes ! You are a good teacher.

1 Like

No need to return a value here since we change global variables which keep their value when we leave the function.

You can write a function that returns a variable. For example of type PVector:

PVector getPoint() {

PVector result=new PVector();

/// set result 
// ....
return result;

}

Hi Chrisir , but if it is a vector ie PVector p( x,y,z) , then does it not need a polar coordinate (heading) and an acceleration parameter ? and then in which case how is this different to original processing vertex(x, y, z, u, v) ? A bit confused , Nigel.

I think it’s primarily a 3D or 2D point

but just check the reference for it

Just thinking I might avoid the PVector pretext !