How to make ball not go through walls?

I’m working on a maze game and ran into a problem. I’m not sure how to make the circle, not through the walls. I know you can probably do it with Boolean but I’m not really familiar with that. Is there a different way such as detecting the color change?

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


//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, 165, 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 _x, float _y, float _w, float _h) {
    x = _x;
    y = _y;
    w = _w;
    h = _h;
  }
//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 down,up,left,right keys are pressed circle will move 5 pixels 
void keyPressed(){
  if (keyCode==UP){
    y=y-5;
  }
  if (keyCode==DOWN){
    y=y+5;
  }
  if (keyCode==RIGHT){
    x=x+5;
  }
  if (keyCode==LEFT){
    x=x-5;
  }
}

1 Like

:cry: Can’t figure this out.

Could you post your implementation and describe what trouble you are having?

If it is a matter of “where to begin”, start with the keyPressed function.

In keyPressed, we know when a change is made and in which direction. So we could call a “collide” function from there or implement it in place.

For example, if the left button is pressed, work out how to detect that the circle crosses a wall from the right.
Do the same test for each wall using a loop.
Remember that if a ball is partly over a wall, you may want to push the ball slightly away (radius of circle) so that it appears to stop against the wall instead of through it.

2 Likes
void keyPressed(){
  if (keyCode==UP){
    y=y-5;
  }
  if (keyCode==DOWN){
    y=y+5;
  }
  if (keyCode==RIGHT){
    x=x+5;
  }
  if (keyCode==LEFT){
    x=x-5;
  }
}

I have the ball moving but I’m unsure what parameters to include to not make it go through all the walls.

Describe a circle “at x,y position” and has a “radius of r”.
Then the wall: “located at x,y” and has “width of w and height of h”
From those dimensions, you can work out where the right side and bottom of the wall are located.

A circle cannot be less than its radius away from another object, in this case from the left, top, right, or bottom of a given wall.
When the ball moves to the right, you would want to test against the left side of a wall.

By the way, I recommend using different names than “start” and “stop” for the size of the circle. Perhaps “diameter” (2x radius)?

2 Likes

You have a few options when you want to do collision detecting on walls.

  1. You mentioned trying to recognize colour. This is absolutely an option. What you want to do is to test a few pixels around the circle and if the color matches the color of a wall, then you know there is a wall there. Check the reference for pixel.

  2. You could divide the whole screen into a grid. I haven’t run your code, so i’m not sure what it looks like, but i am imagining something like pacman. So if you imagine pacman, you could easily divide the whole screen into a grid of squares. Where each tile has a label. It says “floor” or “wall” or “candy” og anything else. As long as you know which tile you’re in, you can check each tile around you to see if there is a wall or a treat or anything else near you. This is quite useful and enables you to easily add more stuff to your game.

  3. you can use boolean to check whether or not a wall is in front of you.

2 Likes

How would you go about detecting color when the circle is moved. I know you can use get() to read the pixel color. But I’m not sure how I would put this into my code. I was trying to do if, else and for statements and I couldn’t get anything to work.

First you need to collect the data, then you need to analyze it and then you need to react to it.

Imagine that you are walking around in a maze. Before you move you ask yourself “is there a walk in front of me?” In order to answer the question you pull out one of your senses and do a collection of data. You discover with your vusion that in front of you there is something red. And because you know that red is the color of the walls in the maze, you conclude that you are face to face with a mace. Now you react by not walking into wall. Perhaps you chose to turn left and start all over.

So these are the steps: collect, analyze and react. Try to translate into code and I will help you more

for (pixel color of background// don't know exactly what to put here)
(keyCode == LEFT || key == 'a') {
    x += -2;
}

else{ 
x+=0
}}

I am not sure what you are trying to do here, can you explain? You have a for loop. What is this for loop going through?

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



//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, 165, 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 (keyCode == RIGHT || key == 'd') {
  x += 2;
}
else if (keyCode == UP || key == 'w') {
  y += -2;
}
if (keyCode == DOWN || key == 's') {
  y += 2;
}
}
}

I was going to put that in with the keyCode if statements. I’m sorry i think im completely confused.

Okey, let’s forget about your code a bit. Not becuase it is bad or confusing or even wrong. Just because sometimes a fresh canvas can help a lot. Earlier you were talking about the get() function. Which, if we look at the reference, we can see that we can use it, for eksample, like this:

color c = get(25,25);

Now, because color is code for “store this number as a color”, c now contains the color of the pixel at the coordinates 25,25. That is how you collect your data.

So on our new blank canvas, we have nothing at all and we have stored the color of one pixel in a variable. How can we analyze it? How can we compare it to something else? How can we know that it is either what we want’ or what we don’t want?

1 Like

So from what I understand the variable c is now set to the RGB value of the pixel located on the (25,25) coordinate. Let’s say it’s red. Now that the variable is set to the color we can do stuff like background(c) and the background will now be that red. How to compare it to something else is where I get lost.

Yes!
Perhaps you can use an if statement?

if( c is equal to the color of the wall) {
then we can make a decision;
}

So let’s make a variable for the color of the wall, which we can name colorOfWall.
How can you write that with actual code? here is the reference on if statements: https://processing.org/reference/if.html

color ColorOfWall=get(25,25);
if (keyPressed == true) {
if (keyCode == LEFT || key == 'a') {
    x += -2;
}
   else if (ColorOfWall);{
  x+=0;
}
}}

Getting an error of int doesn’t match with boolean.

“=” means “assign this to”
For eksample, “int x = 5” means “assign 5 to int x” or “store the value 5 at the variable x, which is of the type int”.
when we want to check if something is the same we use “==”

for exapmle: if( c == colorOfWall);

Okey, I’ll help you tie it together.

First, we declare a variable to hold the color of the wall: color colorOfWall = color(255,0,0);
Then, we initiate the variable that will hold the color that we collect: color c; (we don’t have to give it a value yet.
Now we need to collect the color of an arbitrary coordinate and assign it to the placeholder: c = get(25,25);
Lastly, we have to check if the two colors match up: if(c == colorOfWall) [do something];

color colorOfWall = color(255,0,0);
color c;
if(c == colorOfWall) [do something];

If you understand this code, we can move on.

I’m still unsure how to combine this with key movement, and where would the line of code c=get(25,25) go.

If you are unsure and want to learn, the best way is to try to do it yourself. Post here if you don’t get it working and I will help you more

Sometimes, it is better to leave the code for a moment, whip out a pen and some paper, and try to figure stuff out doodling and writing the possible path down. Other than that, I’ll look
into your code, possibly run it and then try to help. If you could tell me a bit more clearly what you want, it’ll make my job a whole lot easier.