Moving object with noLoop()

Hey!
I made this code:
Grid 40x60 with 10 red blocks and 1 yellow block. And I can move the yellow block with the w-a-s-d keys. But the red blocks keep getting a new position. That problem is fixed when I add the noLoop(). But then I can’t move the yellow block anymore…
Does someone know how to keep the red blocks on the same position but be able to move the yellow block?

int widthGrid = 60;
int heightGrid = 40;
int block[][] = new int[widthGrid][heightGrid];
int blockX[] = new int [widthGrid];
int blockY[] = new int [heightGrid];
int widthBlock = 10;
int heightBlock = 10;
int positionYellowX = 10;
int positionYellowY = 10;


void setup() {
  size(600, 400);
  
  for (int i = 0; i < widthGrid; i++) {
    blockX[i] = i;
  }
  for (int i = 0; i < heightGrid; i++){
    blockY[i] = i;
  }
}

void draw() { 
  for (int i = 0; i < widthGrid; i++) {
    for (int j = 0; j < heightGrid; j++) {
      int xPositionBlock = i * widthBlock;
      int yPositionBlock = j * heightBlock;
      fill(#0ff09d);
      rect(xPositionBlock, yPositionBlock, widthBlock, heightBlock);
    }
  }
  for (int i = 0; i < 10; i++) {
    int positionRedX = blockX[(int)random(60)] * 10;
    int positionRedY = blockY[(int)random(40)] * 10;
    fill(#ff0000);
    rect(positionRedX, positionRedY, widthBlock, heightBlock);
  } 
  fill(#ffff00);
  rect(positionYellowX, positionYellowY, 10, 10);
  
}

void keyPressed() {
  if (key == 'd' || key == 'D') {
    positionYellowX += 10;
  } else  if (key == 'a' || key == 'A') {
    positionYellowX -= 10;
  } else if (key == 'w' || key == 'W') {
    positionYellowY -= 10;
  } else if (key == 's' || key == 'S') {
    positionYellowY += 10;
  }
}
2 Likes

I think you should move all of the red block code into void setup(), because you only want it to run once. In void draw, it gets loaded and reloaded over and over again and gives them new positions. When you put noLoop(), the yellow block appeared to stop moving because it is also in void draw(). The yellow block is actually changing places, but it is only drawn once if you use noLoop().

Here;

int widthGrid = 60;
int heightGrid = 40;
int block[][] = new int[widthGrid][heightGrid];
int blockX[] = new int [widthGrid];
int blockY[] = new int [heightGrid];
int widthBlock = 10;
int heightBlock = 10;
int positionYellowX = 10;
int positionYellowY = 10;


void setup() {
  size(600, 400);
  
  for (int i = 0; i < widthGrid; i++) {
    blockX[i] = i;
  }
  for (int i = 0; i < heightGrid; i++){
    blockY[i] = i;
  }
    for (int i = 0; i < widthGrid; i++) {
    for (int j = 0; j < heightGrid; j++) {
      int xPositionBlock = i * widthBlock;
      int yPositionBlock = j * heightBlock;
      fill(#0ff09d);
      rect(xPositionBlock, yPositionBlock, widthBlock, heightBlock);
    }
  }
  for (int i = 0; i < 10; i++) {
    int positionRedX = blockX[(int)random(60)] * 10;
    int positionRedY = blockY[(int)random(40)] * 10;
    fill(#ff0000);
    rect(positionRedX, positionRedY, widthBlock, heightBlock);
  } 
}

void draw() { 
  fill(#ffff00);
  rect(positionYellowX, positionYellowY, 10, 10);
  
}

void keyPressed() {
  if (key == 'd' || key == 'D') {
    positionYellowX += 10;
  } else  if (key == 'a' || key == 'A') {
    positionYellowX -= 10;
  } else if (key == 'w' || key == 'W') {
    positionYellowY -= 10;
  } else if (key == 's' || key == 'S') {
    positionYellowY += 10;
  }
}
3 Likes

Also, is this going to be a snake game? Just curious. :relaxed:

1 Like

That part will cause another problem. Remove the bottom rect() function from there and place it in another for loop in draw again.

Else the red blocks will be overridden when background() is called.

And add background() back in draw (first line), Else the yellow block is going to make a path…

Don’t mind my post if you want to draw a path with the yellow block :sweat_smile:

3 Likes

There’s no background. The ‘background’ is the grid, which is made up of separate squares. The background() function will erase them.

That‘s true for now, but he has a Block[][] which isn‘t used yet, so i assume he‘s going to use it later on to draw the grid (although there are better ways).

But that could also just be residual code that wasn‘t deleted yet. If that‘s the case, you could use that [][] instead of having two arrays, which would be more convinient.

Doesn’t it not make a difference, except for the extra line of code?

Well, it‘s 2 lines, but it will become more and more, the more you access the blockX and blockY. But there‘s no real need to do that. Just noticed that he had it and told him that it‘d be a better option to use, since it‘s already there. :wink:

I’d say unless he’s coding the next hit nintendo switch game, it won’t make a difference of more than 5-10 lines.:wink:

Probably not, but it‘s better to know than not know :sweat_smile:

Thanks!
It is going to be a diving for treasure kind of game and the grid is the ocean :ocean: . The red blocks are the bombs :bomb:.
If I run the code there is the yellow path Lexyth talks about.
Is there any way to remove that path? Because I have no idea how.
(+ I might add a background later :grimacing:)

int widthGrid = 60;
int heightGrid = 40;
int block[][] = new int[widthGrid][heightGrid];
int blockX[] = new int [widthGrid];
int blockY[] = new int [heightGrid];
int widthBlock = 10;
int heightBlock = 10;
int positionYellowX = 10;
int positionYellowY = 10;

int sea = 100;


void setup() {
  size(600, 500);
  
  for (int i = 0; i < widthGrid; i++) {
    blockX[i] = i;
  }
  for (int i = 0; i < heightGrid; i++){
    blockY[i] = i;
  }
    for (int i = 0; i < widthGrid; i++) {
    for (int j = 0; j < heightGrid; j++) {
      int xPositionBlock = i * widthBlock;
      int yPositionBlock = j * heightBlock;
      fill(#0ff09d);
      rect(xPositionBlock, yPositionBlock + sea, widthBlock, heightBlock);
    }
  }
  for (int i = 0; i < 10; i++) {
    int positionRedX = blockX[(int)random(60)] * 10;
    int positionRedY = blockY[(int)random(40)] * 10;
    fill(#ff0000);
    rect(positionRedX, positionRedY + sea, widthBlock, heightBlock);
  } 
}

void draw() { 
  fill(#ffff00);
  rect(positionYellowX, positionYellowY, 10, 10);
}

void keyPressed() {
  if (key == 'd' || key == 'D') {
    positionYellowX += 10;
  } else  if (key == 'a' || key == 'A') {
    positionYellowX -= 10;
  } else if (key == 'w' || key == 'W') {
    positionYellowY -= 10;
  } else if (key == 's' || key == 'S') {
    positionYellowY += 10;
  }
}
1 Like

Mmh… You are right, the yellow path is a problem and I want to add a background later. But I think I don’t understand you because if I remove the rect() and add a loop in the draw it doesn’t work… :thinking:

•Add a background() method in draw (first line!).
• Copy the for loops, which have a rect() method in them into draw.
• From the for loops in draw, delete the other methods, except the rect() method

That way you will redraw each frame the grid, the red box and the yellow box

1 Like

don’t necessarily need a background() function

int widthGrid = 60;
int heightGrid = 40;
int block[][] = new int[widthGrid][heightGrid];
int blockX[] = new int [widthGrid];
int blockY[] = new int [heightGrid];
int widthBlock = 10;
int heightBlock = 10;
int positionYellowX = 10;
int positionYellowY = 10;

int sea = 100;


void setup() {
  size(600, 500);
  for (int i = 0; i < 10; i++) {
    int positionRedX = blockX[(int)random(60)] * 10;
    int positionRedY = blockY[(int)random(40)] * 10;
    fill(#ff0000);
    rect(positionRedX, positionRedY + sea, widthBlock, heightBlock);
  } 
}

void draw() { 
  for (int i = 0; i < widthGrid; i++) {
    blockX[i] = i;
  }
  for (int i = 0; i < heightGrid; i++){
    blockY[i] = i;
  }
    for (int i = 0; i < widthGrid; i++) {
    for (int j = 0; j < heightGrid; j++) {
      int xPositionBlock = i * widthBlock;
      int yPositionBlock = j * heightBlock;
      fill(#0ff09d);
      rect(xPositionBlock, yPositionBlock + sea, widthBlock, heightBlock);
    }
  }
  fill(#ffff00);
  rect(positionYellowX, positionYellowY, 10, 10);
}

void keyPressed() {
  if (key == 'd' || key == 'D') {
    positionYellowX += 10;
  } else  if (key == 'a' || key == 'A') {
    positionYellowX -= 10;
  } else if (key == 'w' || key == 'W') {
    positionYellowY -= 10;
  } else if (key == 's' || key == 'S') {
    positionYellowY += 10;
  }
}
1 Like

Sorry, but i have to disagree. Your code would not draw the red boxes anymore, and it sets the blockX and blockY again for no reason. Using my method only takes 3 changes and works.

(I don‘t know if it Sounds like „my Code is best“ or anything, but that’s not what i mean :sweat_smile: Just saying that it‘s working and yours won’t do what he asked… it still sound pretty offensive, but it‘s not meant that way…)

2 Likes

I think you have to consider your project in a different sense.

You have a gird where some will be red and one will be white.

The red ones will not move. This means they must be set (randomly) outside of the loop that allows you to animate them. This ‘assignment’ code for an array that contains their locations must be in the setup. You can do this in a few ways, using arrays (https://processing.org/tutorials/arrays/) is probably easier than classes https://processing.org/reference/class.html).

You can use the block[ ][ ] setup you have set up but are not using, or you can use PVectors to store the locations ( https://processing.org/reference/PVector.html ).

In the draw function you will draw the background grid, and then draw the red squares based upon the pre-recorded locations stored in the array. Since you want to avoid having the yellow trail I would do this instead of the alternative, where you ‘erase’ the previous yellow location in the same way you draw the background color.

Learn to break your idea down into steps to be able to make it easier. I could rewrite your code, but that doesn’t help you learning.

record red locations in setup()
set first yellow location in setup()

draw background in draw()
draw red blocks at red locations in draw()
move/check/draw yellow location in draw()

2 Likes