3d problem with a simple title game

I made a simple tile game in 2 in two dimensions and it works well (even if you have suggestions for the optimization are well accepted), but when I tried to render it in three dimensions the coordinates of the cubes are wrong, looking on the forum I don’t have found solutions, suggestions?
sorry for the english provided by gooogle!
*******************main program *******************

import processing.video.*;
Capture video;
PImage immagine ;
PImage immaginebk;
float velocita=.1;
int  righe=9;
int colonne=9;
int rigaVuota=int(random(0, righe));
int colonnaVuota=int(random(0, colonne));
int mattonellaVuota=(rigaVuota*colonnaVuota );
int mattonelladamuovere;
float passoW;
float passoH;
mattonella arraymatonelle[] =new mattonella[righe*colonne];
boolean finito=true;
boolean sceglinuova=true;
boolean trovatovuoto=true;
PVector cordinatevuoto;
PVector codinatemuovi;
PVector codinatetemp;
////////////////////////////////////////
void setup() {
  //  size(900, 600, P2D );

  fullScreen( P2D);
  passoW=width/righe;
  passoH=height/colonne;


  cordinatevuoto= new PVector();
  codinatemuovi= new PVector();
  immaginebk   = createImage(width, height, RGB);
  immagine  = createImage(640, 480, RGB);
  video = new Capture(this, 640, 480);
  video.start();
  int a=0;
  for (int c = 0; c <colonne; c++) {
    for (int r = 0; r <righe; r++) {
      arraymatonelle[a] =new mattonella();
      arraymatonelle[a].crea(r, c, (a==(mattonellaVuota)), a);
      a++;
    }
  }
}
void draw() {
  //background(0);
  video.read();
      video.loadPixels();

  immagine=video;
  video.loadPixels();
  immagine.updatePixels();
  immaginebk.copy(immagine, 0, 0, 640, 480, 0, 0, width, height);
  immaginebk.updatePixels();
  if (video.available()) {
    {   
      background(0);

      int a=-1;
      for (int c = 0; c <colonne; c++) {
        for (int r = 0; r <righe; r++)       
        {
          a++;
          arraymatonelle[a].disegna();
          if (( arraymatonelle[a].update()==true)&&(trovatovuoto==true ))
          {
            trovatovuoto=false;
            cordinatevuoto=arraymatonelle[a].returnCordinate();
            mattonellaVuota=a;
            codinatemuovi=sceglimuovi(cordinatevuoto);
          }
          if ((sceglinuova==true)&&(trovatovuoto==false )) {
            codinatetemp=arraymatonelle[a].returnCordinate();

            if ((codinatetemp.x==codinatemuovi.x)&&(codinatetemp.y==codinatemuovi.y))
            {
              sceglinuova=false;
              mattonelladamuovere=a;
            }
          }
          if ((sceglinuova==false)&&(trovatovuoto==false))
          {
            finito=false;
            finito= arraymatonelle[mattonelladamuovere].muovi(cordinatevuoto);
            if (finito) {
              arraymatonelle[mattonellaVuota].muoviVuoto(codinatemuovi);
              arraymatonelle[mattonellaVuota].disegna();
              arraymatonelle[mattonelladamuovere].disegna();
              arraymatonelle[mattonelladamuovere].updateCordinate();
              arraymatonelle[mattonellaVuota].updateCordinate();
              trovatovuoto=true;
              sceglinuova=true;
            } else {
              arraymatonelle[mattonelladamuovere].disegna();
            }
          }
        }
      }
    }
  }
}

the 2d titles:

class mattonella {
  //////////////////////// Dati
  int numero;
  boolean vuoto;
  PImage  img ;
  PVector cordinateFoto = new PVector();
  PVector Rigaecolonna = new PVector();
  PVector cordinate = new PVector();
  PVector cordinatecopia = new PVector();
 
  /////////////////////////////////costrutore
  mattonella() {
    img = createImage(width/ righe, height/ colonne, RGB);
    
  }
  ///////////////////////////////////////////////////////////////////////////////////////
  void crea(int r, int c, boolean sevuoto,int a) {
    numero=a;
    Rigaecolonna.set(r, c);
    img = createImage(width/ righe, height/ colonne, RGB);
    cordinateFoto.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    cordinate.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    cordinatecopia.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    vuoto=sevuoto;

  }
  /////////////////////////////////////////////////////
  void disegna() {
    image(img, cordinate.x, cordinate.y);
  }
  ///////////////////////////////////////////////////////////
  boolean update() {
    immaginebk.loadPixels();
    img.loadPixels();
    if (vuoto==false) {
      img.copy(immaginebk, int( cordinateFoto.x), int ( cordinateFoto.y), img.width, img.height, 0, 0, img.width, img.height);
      img.updatePixels();
    } else {
      for (int i=0; i<img.pixels.length; i++) {
        img .pixels[i] = color(255, 0, 0);
      }
    }
    img.updatePixels();
    return vuoto;
  }
  //////////////////////////////////////////////////////////////
  boolean muovi  (PVector destistanazione) {
    PVector dest= new PVector() ;
dest=destistanazione.copy();
if ((abs(dest.y-cordinate.y)<=velocita)&&
   (abs(cordinate.x-dest.x))<=velocita )
{
cordinate=dest.copy();
  return true;
  }else{
  
    if (dest.x>cordinate.x)
      {
        cordinate.add(+velocita,0);
      }
      else
      {
        cordinate.add(-velocita,0);
      }
    if (dest.y>cordinate.y)
      {
        cordinate.add(0,+velocita);
      }
      else
      {
        cordinate.add(0,-velocita);
      }
      return false;
  }
}
  
  ////////////////////////////////////////////////////////////
  PVector returnCordinate() {
    return cordinatecopia;
  }
    ////////////////////////////////////////////////////

    void updateCordinate() {
          cordinatecopia=cordinate.copy();
  }
  /////////////////////////////////////////////////////
  void muoviVuoto  (PVector dest) {
        PVector fine= new PVector() ;
    fine=dest.copy();
    cordinate= fine.copy();
  }
  
}

the 3d title:

class cubo { 
  //////////////////////// Dati
  int numero;
  PShape cubo;
  PShape lato1;
  PShape lato2;
  PShape lato3;
  PShape lato4;
  PShape lato5;
  PShape lato6;
  boolean vuoto;
  PImage  img ;
  PImage  img2 ;
  PVector cordinateFoto = new PVector();
  PVector Rigaecolonna = new PVector();
  PVector cordinate = new PVector();
  PVector cordinatecopia = new PVector();
  PVector lati = new PVector();

  /////////////////////////////////costrutore
  cubo() {
    img = createImage(width/ righe, height/ colonne, RGB);
    img2 = createImage(width/ righe, height/ colonne, RGB);
    for (int i = 0; i < img2.pixels.length; i++) {
      img2.pixels[i] = color(255*(int(random(0, 2))), 255*(int(random(0, 2))), 255*(int(random(0, 2))));
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////
  void crea(int r, int c, boolean sevuoto, int a) {
    cubo=createShape(GROUP);
    lato1=createShape();
    lato2=createShape();
    lato3=createShape();
    lato4=createShape();
    lato5=createShape();
    lato6=createShape();
    numero=a;
    Rigaecolonna.set(r, c);
    cordinateFoto.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height, 0);
    cordinate.set    (Rigaecolonna.x*img.width, Rigaecolonna.y*img.height, 0);
    println(cordinate.x,cordinate.y,cordinate.z);
    cordinatecopia.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height, 0);
    lati.set(cordinate.x+img.width,cordinate.y+img.height,-50);
    println(lati.x,lati.y,lati.z+"l");
    vuoto=sevuoto;
    lato1.beginShape();/////////////////////////////////davanti
    lato1.texture(img);
    lato1.textureMode(NORMAL);
    lato1.vertex(cordinate.x,cordinate.y,  cordinate.z, 0, 0);
    lato1.vertex(lati.x,     cordinate.y,  cordinate.z, 1, 0);
    lato1.vertex(lati.x,     lati.y,       cordinate.z, 1, 1);
    lato1.vertex(cordinate.x,lati.y,       cordinate.z, 0, 1);
    lato1.endShape();////////////////////////////////////////
    lato2.beginShape();/////////////////////////////////dietro
    lato2.texture(img2);
    lato2.textureMode(NORMAL);
    lato2.vertex(lati.x,     cordinate.y, lati.z, 0, 0);
    lato2.vertex(cordinate.x,cordinate.y, lati.z, 1, 0);
    lato2.vertex(cordinate.x,lati.y,      lati.z, 1, 1);
    lato2.vertex(lati.x,     lati.y,      lati.z, 0, 1);
    lato2.endShape();//////////////////////////////////////////////
    lato3.beginShape();//////////////////////////////////////sotto
    lato3.texture(img2);
    lato3.textureMode(NORMAL);
    lato3.vertex(cordinate.x,lati.y, lati.z, 0, 0);
    lato3.vertex(lati.x,     lati.y, lati.z, 1, 0);
    lato3.vertex(lati.x,     lati.y, cordinate.z, 1, 1);
    lato3.vertex(cordinate.x,lati.y, cordinate.z, 0, 1);
    lato3.endShape();///////////////////////////////////////////////
    lato4.beginShape();////////////////////////////////////sopra
    lato4.texture(img2);
    lato4.textureMode(NORMAL);
    lato4.vertex(cordinate.x,cordinate.y, cordinate.z, 0, 0);
    lato4.vertex(lati.x,     cordinate.y, cordinate.z, 1, 0);
    lato4.vertex(lati.x,     cordinate.y, lati.z, 1, 1);
    lato4.vertex(cordinate.x,cordinate.y, lati.z, 0, 1);
    lato4.endShape();//////////////////////////////////////////////////
    lato5.beginShape();///////////////////////////////////////////////dx
    lato5.texture(img2);
    lato5.textureMode(NORMAL);
    lato5.vertex(lati.x, cordinate.y,      lati.z, 0, 0);
    lato5.vertex(lati.x, cordinate.y,      cordinate.z, 1, 0);
    lato5.vertex(lati.x, lati.y,           cordinate.z, 1, 1);
    lato5.vertex(lati.x, lati.y,           lati.z, 0, 1);
    lato5.endShape();///////////////////////////////////////////////////
    lato6.beginShape();////////////////////////////////////////////sx
    lato6.texture(img2);
    lato6.textureMode(NORMAL);
    lato6.vertex(cordinate.x, cordinate.y,      cordinate.z, 0, 0);
    lato6.vertex(cordinate.x, cordinate.y,      lati.z, 1, 0);
    lato6.vertex(cordinate.x, lati.y,           lati.z, 1, 1);
    lato6.vertex(cordinate.x, lati.y,           cordinate.z, 0, 1);
    lato6.endShape();////////////////////////////////////////////////
    cubo.addChild(lato1);
    cubo.addChild(lato2);
    cubo.addChild(lato3);
    cubo.addChild(lato4);
    cubo.addChild(lato5);
    cubo.addChild(lato6);
    
  }
  /////////////////////////////////////////////////////
  void disegna() {
 //  shape(cubo,screenX(cordinate.x,cordinate.y),screenY(cordinate.x,cordinate.y) );
       shape(cubo,cordinate.x,cordinate.y);

  }
  ///////////////////////////////////////////////////////////
  boolean update() {
    immaginebk.loadPixels();
    img.loadPixels();
    if (vuoto==false) {
      img.copy(immaginebk, int( cordinateFoto.x), int ( cordinateFoto.y), img.width, img.height, 0, 0, img.width, img.height);
      img.updatePixels();
    } else {
       //img.copy(immaginebk, int( cordinateFoto.x), int ( cordinateFoto.y), img.width, img.height, 0, 0, img.width, img.height);
      //img.updatePixels();
//  scale(zoom);
 
}
    img.updatePixels();
    return vuoto;
  }
  //////////////////////////////////////////////////////////////
  boolean muovi  (PVector destistanazione) {
    PVector dest= new PVector() ;
    dest=destistanazione.copy();
    if ((abs(dest.y-cordinate.y)<=1)&&
      (abs(cordinate.x-dest.x))<=1 )
    {
      return true;
    }

    if (dest.x>cordinate.x)
    {
      cordinate.add(+velocita, 0);
    } else
    {
      cordinate.add(-velocita, 0);
    }
    if (dest.y>cordinate.y)
    {
      cordinate.add(0, +velocita);
    } else
    {
      cordinate.add(0, -velocita);
    }
    return false;
  }

  ////////////////////////////////////////////////////////////
  PVector returnCordinate() {
    return cordinatecopia;
  }
  ////////////////////////////////////////////////////

  void updateCordinate() {
    cordinatecopia=cordinate.copy();
  }
  /////////////////////////////////////////////////////
  void muoviVuoto  (PVector dest) {
    PVector fine= new PVector() ;
    fine=dest.copy();
    cordinate= fine.copy();
  }
}

the subrutines that chooses which tile to move:

Vector sceglimuovi(PVector cordinate )
{    
  int caso;
  PVector ctemp = new PVector();
  ctemp=cordinate.copy();
  caso=int(random(0, 4));
  switch(caso) {
  case 0: 
    if (cordinate.x==0) {
      ctemp.add(+passoW, 0);
    } else {
      ctemp.add(-passoW, 0);
    }
    break;
  case 1: 
    if (cordinate.x==(righe-1)*passoW)
    {
      ctemp.add(-passoW, 0);
    } else {
      ctemp.add(+passoW, 0);
    }
    break;
  case 2: 
    if (cordinate.y==0) {
      ctemp.add(0, +passoH);
    } else {
      ctemp.add(0, -passoH);
    }
    break;
  case 3: 
    if (cordinate.y==(colonne-1)*passoH) {
      ctemp.add(0, -passoH);
    } else {
      ctemp.add(0, +passoH);
    }
    break;
  }
  return ctemp;
}

obviously the various prints are for debugging and also the tile that turns red has that purpose,
in the 3d version the tiles are spaced and I can’t understand why, as already said by newbie I also accept suggestions, thanks!
obviously the 2d or 3d tiles are usable one at a time!

post a mcve

in practice I create the tile passing them row and column:

 int a=0;
  for (int c = 0; c <colonne; c++) {
    for (int r = 0; r <righe; r++) {
      arraymatonelle[a] =new mattonella();
      arraymatonelle[a].crea(r, c, (a==(mattonellaVuota)), a);
      a++;
    }
  }

then the tile calculates the coordinates by itself:

  void crea(int r, int c, boolean sevuoto,int a) {
    numero=a;
    Rigaecolonna.set(r, c);
    img = createImage(width/ righe, height/ colonne, RGB);
    cordinateFoto.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    cordinate.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    cordinatecopia.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    vuoto=sevuoto;

  }

then, always the tile is drawn in the coordinates:

    lato1.vertex(cordinate.x,cordinate.y,  cordinate.z, 0, 0);

the photos show the result but I don’t understand why, sorry but a mcve it is difficult for me to do it!
thank you

2d the same main:


there is something I don’t know that distorts the cordinates in the 3d, yet the size of the tile is established with a screen calculation divided by row or column, in 2d it goes well in 3d no!
in the 3d version not even all the tiles are drawn and some of them are outside the window, whi ?

this is what I want to create with the computer that “plays”, all with the recovery of the camera that goes to compose the tiles:
SX466

mcve must be runnable

Post a code in one go

Read the tutorial on 3D

in practice I create the tile passing them row and column:

Then the depth is missing!

For 3D you need a PVector with 3 parameters

You fill them in 3-fold nested for loop

for x
  for y 
    for z 
      PVector....

the depth is at 0 or -50 constant

 Rigaecolonna.set(r, c);
    img = createImage(width/ righe, height/ colonne, RGB);
......etc
    cordinate.set    (Rigaecolonna.x*img.width, Rigaecolonna.y*img.height, 0);
    lati.set(cordinate.x+img.width, cordinate.y+img.height, -50);
etc 
    shape(cubo, cordinate.x, cordinate.y);

this is the printing of the coordinates of the upper right corner of the cube I am going to draw, the second row with the side l are the coordinates of the end of the side, all with 2 rows and two columns in a window 900 * 600, if a cube starts at 0 and ends at 450 and the other starts at 450 why do I get this? where does the space between the cubes come from?
I thank you for your patience, but I read the tutorial on 3d and I tried with the perspectives and with the screenX but I can’t get a wall of cubes like in 2d
0.0 0.0 0.0
450.0 300.0 -50.0l
450.0 0.0 0.0
900.0 300.0 -50.0l
0.0 300.0 0.0
450.0 600.0 -50.0l
450.0 300.0 0.0
900.0 600.0 -50.0l
the first probable cube was empty to make the game
Cattura

found the error! :
shape (cube, cordinate.x, cordinate.y);
it had to be just shape (cube), now I have to implement the movement!
thank you for your time

1 Like

here is a mcve of a 3D grid

The advantage of when you post an mcve:

  • I couldn’t run your code because there was camera stuff in it. With a mcve, there is no camera stuff.
  • A mcve is runnable with copying code from the forum in one go (and I don’t have to copy and paste 3 times from your post, when you posted the code in 3 or 4 sections as you did). No hassle for the helping person.
  • We don’t have to read hundreds of lines of code but see the core problem immediately
  • to get better help it’s easier if you name all functions in English and not in Spanish

Chrisir

float angle;   // for rotation 
float factor1=80.0; // dist between boxes

void setup() {
  size( 800, 800, P3D );

  stroke(111);  // gray 
  fill(255, 2, 2); // red
} // setup

void draw() {
  background(0);
  lights();

  translate(width/2, height/2, 0); 
  rotateY(angle);

  for (int x=0; x<3; x++) {
    for (int y=0; y<3; y++) {
      for (int z=0; z<3; z++) {

        pushMatrix(); 
        translate(x*factor1, 
          y*factor1, 
          z*factor1);
        box(40);  // size of 40 (width, height and depth) 
        popMatrix();
      }
    }
  }

  angle+=.01;
} // draw
1 Like

it is not Spanish but Italian:blush:
I don’t want to rotate the grid but I want to move a single cube (with constant z) instead of the empty space that is created at the beginning, all this with a video in real time, like the game of 16 posted above, for the code post I sorry but I have the object cubes (or tiles for the 2d) and a subroutine that chooses a cube (I have the tile) adjacent to the void to move it, the 3D I need to then zoom and move the camera, then maybe make us a simple game in which, after a certain number of computer moves, the player must recompose the image but as already said they are at the beginning and all this is done for study
this is the 2d code with the load of an image in the given directory (it is adapted so there is for example the copy of the image to scale it and adapt the webcam to the screen, I don’t know if it is the best method but it is the simplest that I found), now I am in difficulty for the movement to be adapted in 3d, the code is the following in a single screen, the “righe” and “colonna” variables at the beginning indicate the pieces of the puzzle while the translation speed is given by the velocita variable:

//import processing.video.*;
//Capture video;
int  righe=9;//number of lines
int colonne=9;//number of columns
float velocita=.1;//translation speed
///
PImage immagine ;
PImage immaginebk;
int rigaVuota=int(random(0, righe));/// line empty tile
int colonnaVuota=int(random(0, colonne));///column empty tile
int mattonellaVuota=(rigaVuota*colonnaVuota );// the empty tile
int mattonelladamuovere;//tile to move
float passoW;//the space that the tile must travel for x
float passoH;//the space that the tile must travel for y
mattonella arraymatonelle[] =new mattonella[righe*colonne];
boolean finito=true;///variable control,have you finished the movement?
boolean sceglinuova=true;///variable control,should I choose another tile?
boolean trovatovuoto=true;//variable control, did you find the void?
PVector cordinatevuoto;
PVector codinatemuovi;
PVector codinatetemp;
////////////////////////////////////////
void setup() {
    size(900, 600, P2D );

 //< fullScreen( P2D);
  passoW=width/righe;
  passoH=height/colonne;


  cordinatevuoto= new PVector();
  codinatemuovi= new PVector();
  immaginebk   = createImage(width, height, RGB);
  immagine  = createImage(640, 480, RGB);
//  video = new Capture(this, 640, 480);
//  video.start();
  int a=0;
  for (int c = 0; c <colonne; c++) {
    for (int r = 0; r <righe; r++) {
      arraymatonelle[a] =new mattonella();
      arraymatonelle[a].crea(r, c, (a==(mattonellaVuota)), a);
      a++;
    }
  }
}
void draw() {
  //background(0);
 // video.read();
 //     video.loadPixels();

 // immagine=video;
 // video.loadPixels();
 immagine = loadImage("img.jpg");
  immagine.updatePixels();
  immaginebk.copy(immagine, 0, 0, 640, 480, 0, 0, width, height);
  immaginebk.updatePixels();
//  if (video.available()) {
    {   
      background(0);

      int a=-1;
      for (int c = 0; c <colonne; c++) {
        for (int r = 0; r <righe; r++)       
        {
          a++;
          arraymatonelle[a].disegna();
          if (( arraymatonelle[a].update()==true)&&(trovatovuoto==true ))
          {
            trovatovuoto=false;
            cordinatevuoto=arraymatonelle[a].returnCordinate();
            mattonellaVuota=a;
            codinatemuovi=sceglimuovi(cordinatevuoto);
          }
          if ((sceglinuova==true)&&(trovatovuoto==false )) {
            codinatetemp=arraymatonelle[a].returnCordinate();

            if ((codinatetemp.x==codinatemuovi.x)&&(codinatetemp.y==codinatemuovi.y))
            {
              sceglinuova=false;
              mattonelladamuovere=a;
            }
          }
          if ((sceglinuova==false)&&(trovatovuoto==false))
          {
            finito=false;
            finito= arraymatonelle[mattonelladamuovere].muovi(cordinatevuoto);
            if (finito) {
              arraymatonelle[mattonellaVuota].muoviVuoto(codinatemuovi);
              arraymatonelle[mattonellaVuota].disegna();
              arraymatonelle[mattonelladamuovere].disegna();
              arraymatonelle[mattonelladamuovere].updateCordinate();
              arraymatonelle[mattonellaVuota].updateCordinate();
              trovatovuoto=true;
              sceglinuova=true;
            } else {
              arraymatonelle[mattonelladamuovere].disegna();
            }
          }
        }
      }
    }
  }
//}
class mattonella {
  //////////////////////// Dati
  int numero;
  boolean vuoto;//are you the empty tile?
  PImage  img ;//image to save a piece of the main image
  PVector cordinateFoto = new PVector();//vector with the coordinates of the piece in the main image
  PVector Rigaecolonna = new PVector();//row and column
  PVector cordinate = new PVector();//original coordinates
  PVector cordinatecopia = new PVector();//copy of the original coordinates to move the empty tile
 
  /////////////////////////////////costrutore
  mattonella() {
    img = createImage(width/ righe, height/ colonne, RGB);
    
  }
  ///////////////////////////////////////////////////////////////////////////////////////
  void crea(int r, int c, boolean sevuoto,int a) {
    numero=a; //tile number
    Rigaecolonna.set(r, c);
    img = createImage(width/ righe, height/ colonne, RGB);
    cordinateFoto.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    cordinate.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    cordinatecopia.set( Rigaecolonna.x*img.width, Rigaecolonna.y*img.height);
    vuoto=sevuoto;

  }
  /////////////////////////////////////////////////////
  void disegna() {
    image(img, cordinate.x, cordinate.y);
  }
  ///////////////////////////////////////////////////////////
  boolean update() {
    immaginebk.loadPixels();
    img.loadPixels();
    if (vuoto==false) {//if it is not empty take the coordinates from the main image and copy the photo
      img.copy(immaginebk, int( cordinateFoto.x), int ( cordinateFoto.y), img.width, img.height, 0, 0, img.width, img.height);
      img.updatePixels();
    } else {
      for (int i=0; i<img.pixels.length; i++) {
        img .pixels[i] = color(0, 0, 0);//if not color black
      }
    }
    img.updatePixels();
    return vuoto;//tell to main program if you are the empty tile
  }
  //////////////////////////////////////////////////////////////
  boolean muovi  (PVector destistanazione) {//this moves the tile to the destination, to be adapted for 3d?
    PVector dest= new PVector() ;
dest=destistanazione.copy();
if ((abs(dest.y-cordinate.y)<=velocita)&&
   (abs(cordinate.x-dest.x))<=velocita )
{
cordinate=dest.copy();
  return true;
  }else{
  
    if (dest.x>cordinate.x)
      {
        cordinate.add(+velocita,0);
      }
      else
      {
        cordinate.add(-velocita,0);
      }
    if (dest.y>cordinate.y)
      {
        cordinate.add(0,+velocita);
      }
      else
      {
        cordinate.add(0,-velocita);
      }
      return false;
  }
}
  
  ////////////////////////////////////////////////////////////
  PVector returnCordinate() {//says the original coordinates
    return cordinatecopia;
  }
    ////////////////////////////////////////////////////

    void updateCordinate() {
          cordinatecopia=cordinate.copy();//update the tile coordinates when the movement is finished
  }
  /////////////////////////////////////////////////////
  void muoviVuoto  (PVector dest) {//instant movement for the  empty tile
        PVector fine= new PVector() ;
    fine=dest.copy();
    cordinate= fine.copy();
  }
  
}
PVector sceglimuovi(PVector cordinate ) //he subroutine which, using the size of the tiles, chooses which to move
{    
  int caso;
  PVector ctemp = new PVector();
  ctemp=cordinate.copy();
  caso=int(random(0, 4));
  switch(caso) {
  case 0: 
    if (cordinate.x==0) {
      ctemp.add(+passoW, 0);
    } else {
      ctemp.add(-passoW, 0);
    }
    break;
  case 1: 
    if (cordinate.x==(righe-1)*passoW)
    {
      ctemp.add(-passoW, 0);
    } else {
      ctemp.add(+passoW, 0);
    }
    break;
  case 2: 
    if (cordinate.y==0) {
      ctemp.add(0, +passoH);
    } else {
      ctemp.add(0, -passoH);
    }
    break;
  case 3: 
    if (cordinate.y==(colonne-1)*passoH) {
      ctemp.add(0, -passoH);
    } else {
      ctemp.add(0, +passoH);
    }
    break;
  }
  return ctemp;
}

it is probably more complicated than it should be, but it is made to study objects and I changed my mind at work, then it will have to be optimized,thank you again and I hope it is clearer now!
the choice must also be optimized so that it does not come back

1 Like

you can remove the rotation from my code, I just wanted to demonstrate how to place cubes in 3D.

what is your question again?

I don’t have time, my apologies

my problem now is that I can’t move the program in 3D like the one in 2d but I’m looking for solutions, I posted the code to make you understand the purpose of the program, in a shape group (like my cube) where is the control point? with the tralate I get strange things, anyway if you don’t have time there is no problem

here one piece moves

float factor1=80.0; // dist between boxes
float offsety=0;

void setup() {
  size( 800, 800, P3D );

  stroke(111);  // gray 
  fill(255, 2, 2); // red
} // setup

void draw() {
  background(0);
  lights();

  translate(width/2-factor1, height/2, 0); 

  int i=0; 

  for (int x=0; x<3; x++) {
    for (int y=0; y<3; y++) {

      if (i==3) {

        pushMatrix(); 
        translate(x*factor1, 
          y*factor1+offsety, 
          1*factor1);
        box(70);  // size of 40 (width, height and depth) 
        popMatrix();
      } else
      {
        pushMatrix(); 
        translate(x*factor1, 
          y*factor1, 
          1*factor1);
        box(70);  // size of 40 (width, height and depth) 
        popMatrix();
      }
      i++;
    }
  }
  offsety-=0.2;
} // draw

finally I did it !, now I fail to prevent the computer from coming back after a move and playing with the mouse, but for that I still have to study, thanks again!
my mistake was in giving the coordinates to the pshape being created while now I create it of the right dimension and then with the function translate and with the popMatrix and pushMatrix the drawing where I want
ps with the image of the cam is more beautiful!

//import processing.video.*;
//Capture video;
int  righe=10;//number of lines
int colonne=10;//number of columns
float velocita=.1;//translation speed
///
PImage immagine ;
PImage immaginebk;
int rigaVuota=int(random(0, righe));/// line empty tile
int colonnaVuota=int(random(0, colonne));///column empty tile
int mattonellaVuota=(rigaVuota*colonnaVuota );// the empty tile
int mattonelladamuovere;//tile to move
float passoW;//the space that the tile must travel for x
float passoH;//the space that the tile must travel for y
cubo arraymatonelle[] =new cubo[righe*colonne];
boolean finito=true;///variable control,have you finished the movement?
boolean sceglinuova=true;///variable control,should I choose another tile?
boolean trovatovuoto=true;//variable control, did you find the void?
PVector cordinatevuoto;
PVector codinatemuovi;
PVector codinatetemp;
////////////////////////////////////////
void setup() {
    size(900, 600, P3D );

 //< fullScreen( P2D);
  passoW=width/righe;
  passoH=height/colonne;


  cordinatevuoto= new PVector();
  codinatemuovi= new PVector();
  immaginebk   = createImage(width, height, RGB);
  immagine  = createImage(640, 480, RGB);
//  video = new Capture(this, 640, 480);
//  video.start();
  int a=0;
  for (int c = 0; c <colonne; c++) {
    for (int r = 0; r <righe; r++) {
      arraymatonelle[a] =new cubo();
      arraymatonelle[a].crea(r, c, (a==(mattonellaVuota)), a);
      a++;
    }
  }
}
void draw() {
  //background(0);
 // video.read();
 //     video.loadPixels();

 // immagine=video;
 // video.loadPixels();
 immagine = loadImage("img.jpg");
  immagine.updatePixels();
  immaginebk.copy(immagine, 0, 0, 640, 480, 0, 0, width, height);
  immaginebk.updatePixels();
//  if (video.available()) {
    {   
      background(0);

      int a=-1;
      for (int c = 0; c <colonne; c++) {
        for (int r = 0; r <righe; r++)       
        {
          a++;
          arraymatonelle[a].disegna();
          if (( arraymatonelle[a].update()==true)&&(trovatovuoto==true ))
          {
            trovatovuoto=false;
            cordinatevuoto=arraymatonelle[a].returnCordinate();
            mattonellaVuota=a;
            codinatemuovi=sceglimuovi(cordinatevuoto);
          }
          if ((sceglinuova==true)&&(trovatovuoto==false )) {
            codinatetemp=arraymatonelle[a].returnCordinate();

            if ((codinatetemp.x==codinatemuovi.x)&&(codinatetemp.y==codinatemuovi.y))
            {
              sceglinuova=false;
              mattonelladamuovere=a;
            }
          }
          if ((sceglinuova==false)&&(trovatovuoto==false))
          {
            finito=false;
            finito= arraymatonelle[mattonelladamuovere].muovi(cordinatevuoto);
            if (finito) {
              arraymatonelle[mattonellaVuota].muoviVuoto(codinatemuovi);
              arraymatonelle[mattonellaVuota].disegna();
              arraymatonelle[mattonelladamuovere].disegna();
              arraymatonelle[mattonelladamuovere].updateCordinate();
              arraymatonelle[mattonellaVuota].updateCordinate();
              trovatovuoto=true;
              sceglinuova=true;
            } else {
              arraymatonelle[mattonelladamuovere].disegna();
            }
          }
        }
      }
    }
  }
//}
//************************************************************************************************
class cubo { 
  //////////////////////// Dati
  int numero;
  PShape cubo;
  PShape lato1;
  PShape lato2;
  PShape lato3;
  PShape lato4;
  PShape lato5;
  PShape lato6;
  boolean vuoto;
  PImage  img ;
  PImage  img2 ;
  PVector cordinateFoto = new PVector();
  PVector cordinate = new PVector();
  PVector cordinatecopia = new PVector();

  /////////////////////////////////costrutore
  cubo() {
    img = createImage(width/ righe, height/ colonne, RGB);
    img2 = createImage(width/ righe, height/ colonne, RGB);
    for (int i = 0; i < img2.pixels.length; i++) {
      img2.pixels[i] = color(255*(int(random(0, 2))), 255*(int(random(0, 2))), 255*(int(random(0, 2))));
    }
  }
  ///////////////////////////////////////////////////////////////////////////////////////
  void crea(int r, int c, boolean sevuoto, int a) {
    cubo=createShape(GROUP);
    lato1=createShape();
    lato2=createShape();
    lato3=createShape();
    lato4=createShape();
    lato5=createShape();
    lato6=createShape();
    numero=a;
    cordinateFoto.set( r*img.width, c*img.height, 0);
    cordinate.set    (r*img.width, c*img.height, 0);
    cordinatecopia.set( r*img.width, c*img.height, 0);
    vuoto=sevuoto;
    lato1.beginShape();/////////////////////////////////davanti
    lato1.texture(img);
    lato1.textureMode(NORMAL);
    lato1.vertex(0, 0, 0, 0, 0);
    lato1.vertex(img.width, 0,0, 1, 0);
    lato1.vertex(img.width, img.height, 0, 1, 1);
    lato1.vertex(0, img.height, 0, 0, 1);
    lato1.endShape();////////////////////////////////////////
    lato2.beginShape();/////////////////////////////////dietro
    lato2.texture(img2);
    lato2.textureMode(NORMAL);
    lato2.vertex(img.width, 0,- 50, 0, 0);
    lato2.vertex(0, 0,- 50, 1, 0);
    lato2.vertex(0, img.height,- 50, 1, 1);
    lato2.vertex(img.width, img.height,- 50, 0, 1);
    lato2.endShape();//////////////////////////////////////////////
    lato3.beginShape();//////////////////////////////////////sotto
    lato3.texture(img2);
    lato3.textureMode(NORMAL);
    lato3.vertex(0, img.height, -50, 0, 0);
    lato3.vertex(img.width, img.height, -50, 1, 0);
    lato3.vertex(img.width, img.height, 0, 1, 1);
    lato3.vertex(0, img.height, 0, 0, 1);
    lato3.endShape();///////////////////////////////////////////////
    lato4.beginShape();////////////////////////////////////sopra
    lato4.texture(img2);
    lato4.textureMode(NORMAL);
    lato4.vertex(0, 0, 0, 0, 0);
    lato4.vertex(img.width,0, 0, 1, 0);
    lato4.vertex(img.width, 0, -50, 1, 1);
    lato4.vertex(0, 0,-50, 0, 1);
    lato4.endShape();//////////////////////////////////////////////////
    lato5.beginShape();///////////////////////////////////////////////dx
    lato5.texture(img2);
    lato5.textureMode(NORMAL);
    lato5.vertex(img.width, 0, -50, 0, 0);
    lato5.vertex(img.width, 0, 0, 1, 0);
    lato5.vertex(img.width, img.height, 0, 1, 1);
    lato5.vertex(img.width, img.height,-50, 0, 1);
    lato5.endShape();///////////////////////////////////////////////////
    lato6.beginShape();////////////////////////////////////////////sx
    lato6.texture(img2);
    lato6.textureMode(NORMAL);
    lato6.vertex(0, 0, 0, 0, 0);
    lato6.vertex(0,0, -50, 1, 0);
    lato6.vertex(0, img.height, -50, 1, 1);
    lato6.vertex(0,img.height,0, 0, 1);
    lato6.endShape();////////////////////////////////////////////////
    cubo.addChild(lato1);
    cubo.addChild(lato2);
    cubo.addChild(lato3);
    cubo.addChild(lato4);
    cubo.addChild(lato5);
    cubo.addChild(lato6);
 
  }
  /////////////////////////////////////////////////////
  void disegna() {
                   pushMatrix ();
    translate (cordinate.x, cordinate.y);
    shape(cubo);
    popMatrix ();
  }
  ///////////////////////////////////////////////////////////
  boolean update() {

    if (vuoto==false) {
      img.updatePixels();
      immaginebk.loadPixels();
      img.loadPixels();
      img.copy(immaginebk, int( cordinateFoto.x), int ( cordinateFoto.y), img.width, img.height, 0, 0, img.width, img.height);
      img.updatePixels();
    }
else   {
cubo.setVisible(false);
  }
    return vuoto;
  }
  //////////////////////////////////////////////////////////////
  boolean muovi  (PVector destistanazione) {
    PVector dest= new PVector() ;
dest=destistanazione.copy();
if ((abs(dest.y-cordinate.y)<=velocita)&&
   (abs(cordinate.x-dest.x))<=velocita )
{
cordinate=dest.copy();
  return true;
  }else{
  
    if (dest.x>cordinate.x)
      {
        cordinate.add(+velocita,0);
      }
      else
      {
        cordinate.add(-velocita,0);
      }
    if (dest.y>cordinate.y)
      {
        cordinate.add(0,+velocita);
      }
      else
      {
        cordinate.add(0,-velocita);
      }
      return false;
  }
}
  
 
  ////////////////////////////////////////////////////////////
  PVector returnCordinate() {
    return cordinatecopia;
  }
  ////////////////////////////////////////////////////

  void updateCordinate() {
    cordinatecopia=cordinate.copy();
  }
  /////////////////////////////////////////////////////
  void muoviVuoto  (PVector dest) {
    PVector fine= new PVector() ;
    fine=dest.copy();
    cordinate= fine.copy();
  }
}


//***************************************************************************************************
PVector sceglimuovi(PVector cordinate ) //he subroutine which, using the size of the tiles, chooses which to move
{    
  int caso;
  PVector ctemp = new PVector();
  ctemp=cordinate.copy();
  caso=int(random(0, 4));
  switch(caso) {
  case 0: 
    if (cordinate.x==0) {
      ctemp.add(+passoW, 0);
    } else {
      ctemp.add(-passoW, 0);
    }
    break;
  case 1: 
    if (cordinate.x==(righe-1)*passoW)
    {
      ctemp.add(-passoW, 0);
    } else {
      ctemp.add(+passoW, 0);
    }
    break;
  case 2: 
    if (cordinate.y==0) {
      ctemp.add(0, +passoH);
    } else {
      ctemp.add(0, -passoH);
    }
    break;
  case 3: 
    if (cordinate.y==(colonne-1)*passoH) {
      ctemp.add(0, -passoH);
    } else {
      ctemp.add(0, +passoH);
    }
    break;
  }
  return ctemp;
}
2 Likes

Congratulations!

Please try if background and lights (); at start of draw() improves the scene