Enemy Movement Match 3

Hey I’m trying to create a match 3 game with blocks that dont just drop downwards. I’ve tried several ways to get my blocks to do as i want but my booleans ain’t working correctly. The enemy should check below till it reaches the bottom or another block then if on top of another block it checks left or right, but one block below to see if it should drop down.
Here a picture of the game so far

this one shows the booleans as you can see left and right are false but should be true

that top block should have left and right being true

here the main code:

ArrayList<Block> block = new ArrayList<Block>();
Control con = new Control();
int s = 25;
int sx = 50;
void setup(){
  size(600,600);
  block.add(new Block(sx,height-(s*2),0));
}

void draw(){
  background(0);
  textSize(20);
  text("Size: " + block.size(), 5,20);
  for (Block b: block){
    b.show();
    b.check();
  }
  //con.show();
}

void keyPressed(){
  if (key == 'n'){
    con.update();
  }
  if (key == ' '){
    for (Block b: block){
      b.move();
      b.timer = 5;
    }
  }// n
}// keyPressed

here the block code:

class Block{
  int x,y,type;
  int timer = 0;
  int yspd = 0;
  int xspd = 0;
  boolean left, right, down,moved;
  Block(int x, int y, int type){
    this.x = x;
    this.y = y;
    this.type = type;
  }
  
  void show(){
    if (type == 0){fill(255,0,0);}
    if (type == 1){fill(0,255,0);}
    rect(x,y,s,s);
    textSize(20);
    /*text("L: " + left, x + 25, y);
    text("R: " + right, x + 125, y);
    text("D: " + down, x + 225, y);
    text("M: " + moved, x + 325, y);
    text("Xspd: " + xspd, 5, 60);
    text("Yspd: " + yspd, 5, 80);*/
  }// show
  
  void res(){
    if (timer > -1){timer -= 1;}
    down = true;
    left = true;
    right = true;
    xspd = 0;
    yspd = 0;
  }
  
  void check(){
    res();
    for (int i = 0; i < block.size(); i++){
      Block b = block.get(i);
      if (y + s == height || b.y - s == y && b.x == x){down = false;}
      if (x - s == 0 || b.x - s == x && b.y + s == y || b.y + s == height){left = false;}
      if (x + s == width || b.x + s == x && b.y + s == y || b.y + s == height){right = false;}
    }
    if (down == true){yspd = 1;}
    if (right == true && left == true && down == false){
      float r = random(1);
      r = round(r);
      if (r == 0){xspd = 1;}
      if (r == 1){xspd = -1;}
    }
    if (left == false && right == false && down == false){moved = true;}
  }// check
  
  void move(){
    if (timer > -2 && timer <= 0){
      y += yspd * s;
      x += xspd * s;
      timer = -3;
    }// timer
  }// move  
}

i made the timer reset when press space, so i can control it better & instead of using my controller i press n for next for more control.

1 Like

-a- your code can not run as there seems to be a
Control class missing

-b- i try follow your timer concept,
what actually is a counter ( counted down at every draw loop ( 60 times per sec ))
by printing the timer value ( in a code copy )

// program start
sub 1 
timer: -1
timer: -1
// ...
 timer: -1
key [ ]: set timer: 5
sub 1 
timer: 4
sub 1 
timer: 3
sub 1 
timer: 2
sub 1 
timer: 1
sub 1 
timer: 0
sub 1 
timer: -1
timer: -1
//...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

so my understanding is that you move UP by one pix
if you press key [space]
but the timer = -3 i never see ??

ok, i might got it wrong,
anyhow i not understand your concept,
but you can work on it by print variable “timer”
every time it is used.

if you wanted to build a real timer tell us.

1 Like

if it ran on its own then the timer = -3 wouldnt be there. It would just loop around letting the enemy move into the space i want them, but sadly my boolean aint working correct and you can delete the control class it has no use till i get everything working as it should.

the 3 false are set by your collision check,
if you check on yourself:

//    for (int i = 0; i < block.size(); i++){
    for (int i = 1; i < block.size(); i++){

by the way, this checks should not use “==”
as it only works in integer and with step = 1 pix.
better use a
>= <=

Why would I use 2 for loops to check collision? I just the block to loop through every other block not have them all loop through every block. & I know where they are set just wondering why they not getting a positive reading.

it is your code, or not?

I wrote the code. I know where the checks are. IDK why the checks aint working

possibly they work but movement code not like what you expected:
use diag printing:

colcheck        end: down: true left true right true
L: true R: true D: true M: false Xspd: 0 Yspd: 1 x 50 y 550
res timer -1
colcheck        end: down: true left true right true
L: true R: true D: true M: false Xspd: 0 Yspd: 1 x 50 y 550
res timer -1
colcheck        end: down: true left true right true
key [ ] call move
move start: x50 y 550 timer -1
move end: x 50 y 575 timer -3
key [ ] set timer 5
L: true R: true D: true M: false Xspd: 0 Yspd: 1 x 50 y 575
res timer 4
colcheck        end: down: false left false right false
L: false R: false D: false M: true Xspd: 0 Yspd: 0 x 50 y 575
res timer 3
colcheck        end: down: false left false right false
L: false R: false D: false M: true Xspd: 0 Yspd: 0 x 50 y 575
res timer 2
colcheck        end: down: false left false right false
L: false R: false D: false M: true Xspd: 0 Yspd: 0 x 50 y 575
res timer 1
colcheck        end: down: false left false right false
L: false R: false D: false M: true Xspd: 0 Yspd: 0 x 50 y 575
res timer 0
colcheck        end: down: false left false right false
L: false R: false D: false M: true Xspd: 0 Yspd: 0 x 50 y 575
res timer -1
colcheck        end: down: false left false right false
L: false R: false D: false M: true Xspd: 0 Yspd: 0 x 50 y 575
res timer -1
colcheck        end: down: false left false right false
L: false R: false D: false M: true Xspd: 0 Yspd: 0 x 50 y 575

//https://discourse.processing.org/t/enemy-movement-match-3/9558
// check KLL
boolean diagp = true;

ArrayList<Block> block = new ArrayList<Block>();
//Control con = new Control();
int s = 25;
int sx = 50;
void setup(){
  size(600,600);
  block.add(new Block(sx,height-(s*2),0));
}

void draw(){
  background(0);
  textSize(20);
  text("Size: " + block.size(), 5,20);
  for (Block b: block){
    b.show();
    b.check();
  }
  //con.show();
}

void keyPressed(){
  if (key == 'n'){
//    con.update();
  }
  if (key == ' '){
    for (Block b: block){
      if (diagp) println("key [ ] call move");
      b.move();
      b.timer = 5;
      if (diagp) println("key [ ] set timer "+b.timer);
    }
  }// n
}// keyPressed


class Block{
  int x,y,type;
  int timer = 0;
  int yspd = 0;
  int xspd = 0;
  boolean left, right, down,moved;
  Block(int x, int y, int type){
    this.x = x;
    this.y = y;
    this.type = type;
  }
  
  void show(){
    if (type == 0){fill(255,0,0);}
    if (type == 1){fill(0,255,0);}
    rect(x,y,s,s);
    if (diagp) println("L: "+left+" R: "+right+" D: "+down+" M: "+moved+" Xspd: "+xspd+" Yspd: "+yspd+" x "+x+" y "+y);
  }// show
  
  void res(){
    if (timer > -1){timer -= 1;}
    down = true;
    left = true;
    right = true;
    xspd = 0;
    yspd = 0;
    if (diagp) println("res timer "+timer);
  }
  
  void check(){
    res();
    for (int i = 0; i < block.size(); i++){
      Block b = block.get(i);
      if (y + s == height || b.y - s == y && b.x == x){down = false;}
      if (x - s == 0 || b.x - s == x && b.y + s == y || b.y + s == height){left = false;}
      if (x + s == width || b.x + s == x && b.y + s == y || b.y + s == height){right = false;}
      if (diagp) println("colcheck        end: down: "+down+" left "+left+" right "+right);
    }
    if (down == true){yspd = 1;}
    if (right == true && left == true && down == false){
      float r = random(1);
      r = round(r);
      if (r == 0){xspd = 1;}
      if (r == 1){xspd = -1;}
    }
    if (left == false && right == false && down == false){moved = true;}
  }// check
  
  void move(){
    if (diagp) println("move start: x"+x+" y "+y+" timer "+timer);
    if (timer > -2 && timer <= 0){
      y += yspd * s;
      x += xspd * s;
      timer = -3;
      if (diagp) println("move end: x "+x+" y "+y+" timer "+timer);
    }// timer
  }// move  
}

the timer counter in res() counts,
but does not do anything?
and the move ( after key [space] ) does one jump down to the limit
was this the idea?

i know that println(""); thing might be a oldstyle,
i like it because i can follow what happens in every loop
( possibly combine with frameRate(1); )
but the Processing IDE 3(.5.3)
also allow to use DEBUG, play with it.

1 Like

They don’t work. I placed up a picture showing the boolean doesn’t work. & I use n & space as i explained to see if it works. It like you didnt even read the 2 times i already said this.

i only wanted to show you about tools to check on your logic…

right, but i could not check it until i added a second BLOCK to above code
and see what happens when you do a collision check over all block from inside the class.

and i found out that i could see and understand nothing using

  • your text()
  • or my println()

until i changed again and use a ID parameter for the block.
now i can identify what happens in your logic.

  • with 2 blocks you make each
    • reset
    • 2 limit/collision checks

and that looks also 2 times for
b.y + s == height
and sets left and right to false.

in words: ! your logic is:
if one block is down at the screen end
both can not move left right.

here a print snap AFTER i pressed [space]
and both blocks jumped down s ???

log
D: false L: false R: false M: true Xspd: 0 Yspd: 0 x 50 y 575
res timer -1
block 0 ID 1 at x 50 y 575
check down: IF y + s == height true ||  b.y - s == y false && b.x == x true THEN down to false: false
check left: IF x - s == 0 false || b.x - s == x false && b.y + s == y false || b.y + s == height true THEN left to false: false
check right: IF x + s == width false || b.x + s == x false && b.y + s == y false || b.y + s == height true THEN right to false: false
colcheck        end: down: false left: false right: false
block 1 ID 1 at x 50 y 575
check down: IF y + s == height true ||  b.y - s == y false && b.x == x true THEN down to false: false
check left: IF x - s == 0 false || b.x - s == x false && b.y + s == y false || b.y + s == height false THEN left to false: false
check right: IF x + s == width false || b.x + s == x false && b.y + s == y false || b.y + s == height false THEN right to false: false
colcheck        end: down: false left: false right: false
D: true L: false R: false M: false Xspd: 0 Yspd: 1 x 50 y 125
res timer -1
block 0 ID 2 at x 50 y 125
check down: IF y + s == height false ||  b.y - s == y false && b.x == x true THEN down to false: true
check left: IF x - s == 0 false || b.x - s == x false && b.y + s == y false || b.y + s == height true THEN left to false: false
check right: IF x + s == width false || b.x + s == x false && b.y + s == y false || b.y + s == height true THEN right to false: false
colcheck        end: down: true left: false right: false
block 1 ID 2 at x 50 y 125
check down: IF y + s == height false ||  b.y - s == y false && b.x == x true THEN down to false: true
check left: IF x - s == 0 false || b.x - s == x false && b.y + s == y false || b.y + s == height false THEN left to false: false
check right: IF x + s == width false || b.x + s == x false && b.y + s == y false || b.y + s == height false THEN right to false: false
colcheck        end: down: true left: false right: false

2 Likes

ok, so that’s the problem? Thanks for telling me. I thought since i just looped through on the block and didnt use the b.left it would only effect the block that is looping not the block that it checking against. & they are both meant to fall when hit space. When i place the auto move in there could be 3 or 4 blocks moving at once.