How to make ball not go through walls?

//Varaibles for images
PImage frankenstein, ghost;
//Variables for walls
wall[] walls; 
//circle variables
float x=180;
float y=60;
float start=30;
float stop=30;
color colorOfWall = color(255);
color c;



//Sets the enviroment for the code
void setup() {
  //background setup
  size(1200, 790);
  //calling images from the data file
  //frankenstein = loadImage("frankenstein.png");
  //ghost = loadImage("ghost.png");
  //walls setup
  walls=new wall[16];//creates an array(list) for the walls array starts at 0
  walls[0]=new wall(150, 30, 10, 730);
  walls[1]=new wall(200, 250, 750, 10);
  walls[2]=new wall(250, 150, 10, 500);
  walls[3]=new wall(200, 250, 10, 300);
  walls[4]=new wall(150, 30, 850, 10);
  walls[5]=new wall(150, 750, 860, 10);
  walls[6]=new wall(300, 450, 10, 300);
  walls[7]=new wall(200, 650, 80, 10);
  walls[8]=new wall(300, 300, 80, 10);
  walls[9]=new wall(370, 250, 10, 300);
  walls[10]=new wall(400, 450, 10, 300);
  walls[10]=new wall(370, 630, 300, 10);
  walls[11]=new wall(370, 700, 300, 10);
  walls[12]=new wall(370, 500, 300, 10);
  walls[13]=new wall(400, 380, 10, 300);
  walls[14]=new wall(1000, 30, 10, 720);
  walls[15]=new wall(750, 100, 10, 500);
}


void draw() {
  //for background 
  background (225, 225, 225);//refreshing the background
  background(255,116,0);
  //image(frankenstein, 1050, 650, 150, 150);
  //image(ghost, 20, 20, 120, 120);
  textSize(32);
  fill(0);
  text(millis()/1100, 1100, 30);//sets up a timer in millaseconds so divided by 1000 to get it in seconds
  Circle();//cirlce function
  //for walls
  for (int i = 0; i < walls.length; i++) {
    walls[i].draw();
  }
}


//creats a class for the walls of the maze
class wall {
  float x;
  float y;
  float w;
  float h;
wall(float x1, float y1, float w1, float h1) {
    x = x1;
    y = y1;
    w = w1;
    h = h1;
  }


//draws the walls
void draw() {
    fill(0);
    rect(x, y, w, h);
  }
}


//user defined function for Circle
void Circle(){
  fill(255);
  ellipse(x, y, start, stop);
if (keyPressed == true) {
  if (keyCode == LEFT || key == 'a') {
    x += -2;
  }
    else if (c==colorOfWall){
      x+=0;
      
  }

  if (keyCode == RIGHT || key == 'd') {
  x += 2;
}
if (keyCode == UP || key == 'w') {
  y += -2;
}
if (keyCode == DOWN || key == 's') {
  y += 2;
}}}

Trying to get it to detect if it hits the color of the walls (black) the ball will not move.

Firstly, you have to use the variable colorOfWall to when you set the color of your wall.
Secondly, you have to use get() to set the variable c to the color of the pixel you want to analyze.
You are not far from the sollution. If you look at you current code, (in circle-class) you basically say:

if(trying to move left){
  Move left;
} Else if (c matches the color of the wall){
  Don't move;
}

What you need to do is this:

if(trying to move left){ //like before
  assign c the value of a pixel to the left of current position; //use get()
  if (c is equal to the value of the wall){ // like before
    don't move; //like before
  } else move; //like before
}
//Varaibles for images
PImage frankenstein, ghost;
//Variables for walls
wall[] walls; 
//circle variables
float x=180;
float y=60;
float start=30;
float stop=30;
color colorOfWall=color(0);
color c;





//Sets the enviroment for the code
void setup() {
  //background setup
  size(1200, 790);
  
  //calling images from the data file
  //frankenstein = loadImage("frankenstein.png");
  //ghost = loadImage("ghost.png");
  //walls setup
  walls=new wall[16];//creates an array(list) for the walls array starts at 0
  walls[0]=new wall(150, 30, 10, 730);
  walls[1]=new wall(200, 250, 750, 10);
  walls[2]=new wall(250, 150, 10, 500);
  walls[3]=new wall(200, 250, 10, 300);
  walls[4]=new wall(150, 30, 850, 10);
  walls[5]=new wall(150, 750, 860, 10);
  walls[6]=new wall(300, 450, 10, 300);
  walls[7]=new wall(200, 650, 80, 10);
  walls[8]=new wall(300, 300, 80, 10);
  walls[9]=new wall(370, 250, 10, 300);
  walls[10]=new wall(400, 450, 10, 300);
  walls[10]=new wall(370, 630, 300, 10);
  walls[11]=new wall(370, 700, 300, 10);
  walls[12]=new wall(370, 500, 300, 10);
  walls[13]=new wall(400, 380, 10, 300);
  walls[14]=new wall(1000, 30, 10, 720);
  walls[15]=new wall(750, 100, 10, 500);
}


void draw() {
  //for background 
  background (225, 225, 225);//refreshing the background
  background(255,116,0);
  //image(frankenstein, 1050, 650, 150, 150);
  //image(ghost, 20, 20, 120, 120);
  textSize(32);
  fill(0);
  text(millis()/1100, 1100, 30);//sets up a timer in millaseconds so divided by 1000 to get it in seconds
  Circle();//cirlce function
  //for walls
  for (int i = 0; i < walls.length; i++) {
    walls[i].draw();
  }
}


//creats a class for the walls of the maze
class wall {
  float x;
  float y;
  float w;
  float h;
wall(float x1, float y1, float w1, float h1) {
    x = x1;
    y = y1;
    w = w1;
    h = h1;
  }


//draws the walls
void draw() {
    fill(colorOfWall);
    rect(x, y, w, h);
  }
}


//user defined function for Circle
void Circle(){
  c=get(150,30);
  fill(255);
  ellipse(x, y, start, stop);
if(keyCode == LEFT || key == 'a'){
  c=get(190,70);
if (c==colorOfWall){
  x+=0;
}
else x+=-2;
}}

Now when i press left key ball just moves contiously left until another key is pressed.

That’s because you don’t have this line: if(keyPressed){}

One more comment before it should work fine, when you are using get(), you are currently using a fixed, hardcoded number. But you should use another variable. Because if you don’t you will always get the same result. You can for example use x-start and y. And for the right of the ball you can use x+start. But get() only takes integers as parameters. So you have to convert it to ints. you do this by simply saying int(x-start)

c = get(int(x-start),int(y));

Now you just have to do the same for the other directions

You have lost me again. I solved the problem of the ball continuously moving but the ball still goes through the wall.

Lets go vack to my analogy again. Youre in a maze and you want to know if there is a wall in front of you. When you say c = get(25,25);. It’s like youre having a piece of paper in you pocket that you check instead of looking at the actual ground. So when you ask yourself “am I facing a wall?” And you go to check, you pick up the paper and it is red. So you conclude: “yes, I am facing a wall”. But the paper doesn’t change. So even when you aren’t facing a wall, you conclude that you are.

If you say c = get(int(x-start),int(y));, it’s like looking at the actual ground. So when you want to know if youre facing a wall, you look at the ground in front of you and if you face a wall you determin that you are facing a wall. If you are not facing a wall, you won’t falsly determin that you are facing a wall. Unless something is wrong.

Did you put that in?

//Varaibles for images
PImage frankenstein, ghost;
//Variables for walls
wall[] walls; 
//circle variables
float x=180;
float y=60;
float start=30;
float stop=30;
color colorOfWall=color(0);
color c;





//Sets the enviroment for the code
void setup() {
  //background setup
  size(1200, 790);
  
  //calling images from the data file
  //frankenstein = loadImage("frankenstein.png");
  //ghost = loadImage("ghost.png");
  //walls setup
  walls=new wall[16];//creates an array(list) for the walls array starts at 0
  walls[0]=new wall(150, 30, 10, 730);
  walls[1]=new wall(200, 250, 750, 10);
  walls[2]=new wall(250, 150, 10, 500);
  walls[3]=new wall(200, 250, 10, 300);
  walls[4]=new wall(150, 30, 850, 10);
  walls[5]=new wall(150, 750, 860, 10);
  walls[6]=new wall(300, 450, 10, 300);
  walls[7]=new wall(200, 650, 80, 10);
  walls[8]=new wall(300, 300, 80, 10);
  walls[9]=new wall(370, 250, 10, 300);
  walls[10]=new wall(400, 450, 10, 300);
  walls[10]=new wall(370, 630, 300, 10);
  walls[11]=new wall(370, 700, 300, 10);
  walls[12]=new wall(370, 500, 300, 10);
  walls[13]=new wall(400, 380, 10, 300);
  walls[14]=new wall(1000, 30, 10, 720);
  walls[15]=new wall(750, 100, 10, 500);
}


void draw() {
  //for background 
  background (225, 225, 225);//refreshing the background
  background(255,116,0);
  //image(frankenstein, 1050, 650, 150, 150);
  //image(ghost, 20, 20, 120, 120);
  textSize(32);
  fill(0);
  text(millis()/1100, 1100, 30);//sets up a timer in millaseconds so divided by 1000 to get it in seconds
  Circle();//cirlce function
  //for walls
  for (int i = 0; i < walls.length; i++) {
    walls[i].draw();
  }
}


//creats a class for the walls of the maze
class wall {
  float x;
  float y;
  float w;
  float h;
wall(float x1, float y1, float w1, float h1) {
    x = x1;
    y = y1;
    w = w1;
    h = h1;
  }


//draws the walls
void draw() {
    fill(colorOfWall);
    rect(x, y, w, h);
  }
}


//user defined function for Circle
void Circle(){
  c=get(150,30);
  fill(255);
  ellipse(x, y, start, stop);
  if (keyPressed==true){
if(keyCode == LEFT || key == 'a'){
  c = get(int(x-start),int(y));
if (c==colorOfWall){
  x+=0;
}
else x+=-2;
}}}

Aah, I see now that when I tried it myself I put the movement-stuff in the function keyPressed(), because I think that looks better. Apparently it does make a difference. Can’t explain why.

void keyPressed() {
  if (keyCode == LEFT || key == 'a') {
    c=get(int(x-start), int(y));
    if (c==colorOfWall) {
      x+=0;
    } else x+=-2;
  }
  if (keyCode == RIGHT || key == 'd') {
    x += 2;
  }
  if (keyCode == UP || key == 'w') {
    y += -2;
  }
  if (keyCode == DOWN || key == 's') {
    y += 2;
  }
}

Guys, I ran the code, fixed some stuff here and there and was able to make the ball stop using get (). The problem though is that for some reason the get() function is not able to get the color out of the wall. Infact if you move the ball to the timer or add some temporary black text somewhere, the ball stops. But the wall is unable to do so. It seems like the wall is on it’s own layer which is above the ball. You will also notice that the ball goes under the wall and the get function does not get the black pixel like it should.

//Varaibles for images
PImage frankenstein, ghost;
//Variables for walls
wall[] walls; 
//circle variables
float x=180;
float y=60;
float start=30;
float stop=30;
color colorOfWall=color(0);
color c;





//Sets the enviroment for the code
void setup() {
  //background setup
  size(1200, 790);
  
  //calling images from the data file
  //frankenstein = loadImage("frankenstein.png");
  //ghost = loadImage("ghost.png");
  //walls setup
  walls=new wall[16];//creates an array(list) for the walls array starts at 0
  walls[0]=new wall(150, 30, 10, 730);
  walls[1]=new wall(200, 250, 750, 10);
  walls[2]=new wall(250, 150, 10, 500);
  walls[3]=new wall(200, 250, 10, 300);
  walls[4]=new wall(150, 30, 850, 10);
  walls[5]=new wall(150, 750, 860, 10);
  walls[6]=new wall(300, 450, 10, 300);
  walls[7]=new wall(200, 650, 80, 10);
  walls[8]=new wall(300, 300, 80, 10);
  walls[9]=new wall(370, 250, 10, 300);
  walls[10]=new wall(400, 450, 10, 300);
  walls[10]=new wall(370, 630, 300, 10);
  walls[11]=new wall(370, 700, 300, 10);
  walls[12]=new wall(370, 500, 300, 10);
  walls[13]=new wall(400, 380, 10, 300);
  walls[14]=new wall(1000, 30, 10, 720);
  walls[15]=new wall(750, 100, 10, 500);
}


void draw() {
  //for background 
  background (225, 225, 225);//refreshing the background
  background(255,116,0);
  //image(frankenstein, 1050, 650, 150, 150);
  //image(ghost, 20, 20, 120, 120);
  textSize(32);
  fill(0);
  text(millis()/1100, 1100, 30);//sets up a timer in millaseconds so divided by 1000 to get it in seconds
  Circle();//cirlce function
  //for walls
  for (int i = 0; i < walls.length; i++) {
    walls[i].draw();
  }
}


//creats a class for the walls of the maze
class wall {
  float x;
  float y;
  float w;
  float h;
wall(float x1, float y1, float w1, float h1) {
    x = x1;
    y = y1;
    w = w1;
    h = h1;
  }


//draws the walls
void draw() {
    fill(colorOfWall);
    rect(x, y, w, h);
  }
}


//user defined function for Circle
void Circle(){
  c=get(150,30);
  fill(255);
  ellipse(x, y, start, stop);
}

void keyPressed() {
  if (keyCode == LEFT || key == 'a') {
    c=get(int(x-start), int(y));
    if (c==colorOfWall) {
      x+=0;
    } else x+=-2;
  }
  if (keyCode == RIGHT || key == 'd') {
    c=get(int(x+start), int(y));
    if (c==colorOfWall) {
      x+=0;
    } else x+=2;
    
  }
  if (keyCode == UP || key == 'w') {
    c=get(int(x-start), int(y));
    if (c==colorOfWall) {
      y+=0;
    } else y+=-2;
    
  }
  if (keyCode == DOWN || key == 's') {
    c=get(int(x-start), int(y));
    if (c==colorOfWall) {
      y+=0;
    } else y+=2;
  }}

Something isn’t working right sometimes the ball moves, other times it doesn’t. I can also go through the top of the lines.

Is there any way to fix that?

Yes, just fixed it. Firstly make sure that the wall is below the circle by drawing it before the circle.
Then in every keyCode if statement, add an &&(get(x,y)!=color(0,0,0)). This will make sure that the code runs(the x and y update) only if there is no wall. Now the final thing, while moving left get the pixel value of x-16, y; since that will be the first pixel left of the ball, while moving right use x+16 and y+16 when down and y-16 when up. Hope it helps.

Thanks any chance you can post that I have a jumbled mess on my screen now.

Yeah, sure. Here.

//Varaibles for images

PImage frankenstein, ghost;

//Variables for walls

wall[] walls; 

//circle variables

int x=180;

int y=60;

float start=30;

float stop=30;

color colorOfWall = color(255);

color c;







//Sets the enviroment for the code

void setup() {

  //background setup

  size(1200, 790);

  //calling images from the data file

  //frankenstein = loadImage("frankenstein.png");

  //ghost = loadImage("ghost.png");

  //walls setup

  walls=new wall[16];//creates an array(list) for the walls array starts at 0

  walls[0]=new wall(150, 30, 10, 730);

  walls[1]=new wall(200, 250, 750, 10);

  walls[2]=new wall(250, 150, 10, 500);

  walls[3]=new wall(200, 250, 10, 300);

  walls[4]=new wall(150, 30, 850, 10);

  walls[5]=new wall(150, 750, 860, 10);

  walls[6]=new wall(300, 450, 10, 300);

  walls[7]=new wall(200, 650, 80, 10);

  walls[8]=new wall(300, 300, 80, 10);

  walls[9]=new wall(370, 250, 10, 300);

  walls[10]=new wall(400, 450, 10, 300);

  walls[10]=new wall(370, 630, 300, 10);

  walls[11]=new wall(370, 700, 300, 10);

  walls[12]=new wall(370, 500, 300, 10);

  walls[13]=new wall(400, 380, 10, 300);

  walls[14]=new wall(1000, 30, 10, 720);

  walls[15]=new wall(750, 100, 10, 500);

}





void draw() {

  //for background 

  background (225, 225, 225);//refreshing the background

  background(255,116,0);
  
  //image(frankenstein, 1050, 650, 150, 150);

  //image(ghost, 20, 20, 120, 120);

  textSize(32);

  fill(0);

  text(millis()/1100, 1100, 30);//sets up a timer in millaseconds so divided by 1000 to get it in seconds

  for (int i = 0; i < walls.length; i++) {

    walls[i].draw();

  }
  Circle();//cirlce function

  

  

}





//creats a class for the walls of the maze

class wall {

  float x;

  float y;

  float w;

  float h;

wall(float x1, float y1, float w1, float h1) {

    x = x1;

    y = y1;

    w = w1;

    h = h1;

  }





//draws the walls

void draw() {

    fill(0);

    rect(x, y, w, h);

  }

}





//user defined function for Circle

void Circle(){

  fill(255);

  ellipse(x, y, start, stop);

if (keyPressed == true) {

  if ((keyCode == LEFT || key == 'a')&&get(x-16,y)!=color(0,0,0)) {

    x += -2;

  }

    else if (c==colorOfWall){

      x+=0;

      

  }



  if ((keyCode == RIGHT || key == 'd')&&get(x+16,y)!=color(0,0,0)) {

  x += 2;

}

if ((keyCode == UP || key == 'w')&&get(x,y-16)!=color(0,0,0)) {

  y += -2;

}

if ((keyCode == DOWN || key == 's')&&get(x,y+16)!=color(0,0,0)) {

  y += 2;

}}}


It should work. Couldn’t add comments.

Thank you for all your help I greatly appreciate it. @shubhamtewari @Eeyorelife @noahbuddy
You all helped me understand what it all means and how to do it, thanks!

1 Like

@ant No problem dude. I hope you understand how it worked and why it wasn’t working before.
Also snooping around the reference, I found the pixel[] array, which is a faster way to get pixel colour and with it you can easily get all the pixels around the ball instead of just one or any shape for that matter. Do look into that.

Interesting I’ll look into that.