How to make spheres stay green?

edited November 2017 in Library Questions

Hello, I'm developing a program in which I have red spheres that when clicked they change their color to green but when you click in another place, they turn back to the original color.

What I need to do is that when they are clicked they stay with the green color instead of turning back again to the original color ir order to make all the spheres look green. This logic hasn't got an order, I mean, any sphere could be pressed first or second, or last... Here is the code

import peasy.*;
import gifAnimation.*;

PeasyCam cam;

Gif myAnimation;

PShape ammonite;
PImage fondo, titulo, titulo2, ammoniteinicio, almeja, gestos, flecha;
String estado;
PFont helvetica, nexa;

// invisible PGraphics
PGraphics pg;

//define hot spots
PVector[] hotSpotsPosition=new PVector[5];
color[] hotSpotsColor =new color [hotSpotsPosition.length];
String[] hotSpotsText = new String [hotSpotsPosition.length];
PImage[] hotSpotsImg = new PImage [hotSpotsPosition.length];
boolean [] hotSpotsRightSide = new boolean [hotSpotsPosition.length];
Gif [] hotSpotsGif = new Gif [hotSpotsPosition.length];
boolean almejacerrada;
int undefined=-1;
int hotSpotFound=undefined; // when undefined no text is displayed

int mousePressedAtX;
int mousePressedAtY;

// button data
int buttonX, buttonY, 
  buttonWidth, buttonHeight;

void setup() {

  fullScreen(P3D);
  // size(900, 900, P3D);

  rectMode(CENTER);
  imageMode(CENTER);
  textAlign(CENTER);

  cam = new PeasyCam(this, 100);
  cam.setMinimumDistance(110);
  cam.setMaximumDistance(500);

  ammonite = loadShape("ammonite.obj");

  // define the hot spots in parallel arrays
  // the first hot spot is defined in hotSpotsPosition[0] and hotSpotsColor[0] and hotSpotsText[0] and so on
  // positions:
  hotSpotsPosition[0] = new PVector(-15, -20, 0);
  hotSpotsPosition[1] = new PVector(-5, -5, -25);
  hotSpotsPosition[2] = new PVector(-20, -10, 3);
  hotSpotsPosition[3] = new PVector(-25, -10, 15);
  hotSpotsPosition[4] = new PVector(-5, 19, -5);

  //colors: colors are not visible but must be unique
  hotSpotsColor[0] = color(255, 0, 0);
  hotSpotsColor[1] = color(100, 0, 0);
  hotSpotsColor[2] = color(110, 0, 0);
  hotSpotsColor[3] = color(120, 0, 0);
  hotSpotsColor[4] = color(160, 0, 0);

  // texts
  hotSpotsText[0] = "Embudo";
  hotSpotsText[1] = "Caparazon";
  hotSpotsText[2] = "Ojos";
  hotSpotsText[3] = "Tentaculos";
  hotSpotsText[4] = "Sifon";

  //images
  hotSpotsImg[0] = loadImage ("EMBUDO.png");
  hotSpotsImg[1] = loadImage ("CAPARAZON.png");
  hotSpotsImg[2] = loadImage ("OJOS.png"); 
  hotSpotsImg[3] = loadImage ("TENTACULOS.png");
  hotSpotsImg[4] = loadImage ("SIFON.png");

  //  for (PImage img : hotSpotsImg)
  //     img.resize(200, 0);

  // Gifs
  hotSpotsGif[0]  = new Gif(this, "embudoanim.gif");
  hotSpotsGif[1]  = new Gif(this, "caparazonanim.gif");
  hotSpotsGif[2]  = new Gif(this, "ojosanim.gif");
  hotSpotsGif[3]  = new Gif(this, "tentaculosanim.gif");
  hotSpotsGif[4]  = new Gif(this, "sifonanim.gif");



  // whether we display the spot left or right
  hotSpotsRightSide[0] = false;
  hotSpotsRightSide[1] = true;
  hotSpotsRightSide[2] = true;
  hotSpotsRightSide[3] = true;
  hotSpotsRightSide[4] = false;

  fondo = loadImage("fondo.jpg");
  titulo = loadImage("titulo.png");
  titulo2 = loadImage("conociendo.png");
  ammoniteinicio = loadImage("ammoniteparainicio.png");
  almeja = loadImage("almeja.png");
  gestos = loadImage("gestos2.png");
   flecha = loadImage("flecha.png");

  buttonX = 0;
  buttonY = 0;
  buttonWidth = 400;
  buttonHeight = 400;

  estado = "inicio";
  almejacerrada = false;
  helvetica = createFont("HelveticaWorld-Regular.ttf", 30);
  nexa = createFont("Nexa Bold.otf", 50);

  pg = createGraphics(width, height, P3D);

  fondo.resize(width, height);
  image(fondo, width/2, height/2);
} //func

void draw() {

  avoidClipping(); // so the graphic AMMONITE is not cut when rotating

  if (estado.equals("inicio")) {
    //-----------Stopping peasy ------
    cam.beginHUD();

    image(fondo, width/2, height/2);
    image(almeja, width-300, height-130, 250, 250);
    fill(0, 50);
    rect(width/2, height/2, width, height);
    fill(0, 30);
    noStroke();
    rect(width/2, 75, width, 150);
    fill(255);
    textFont(nexa);
    text("AMMONITE", width/2, height/6 - 50);
    text("EL ANCESTRO MARINO", width/2, height/6);
    textFont(helvetica);
    text("Toca para comenzar", width/2, height/2 + 300);
    image(gestos, width/2 + 400, height/2-100);

    cam.endHUD(); //--------------------------------
    pushMatrix();
    spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
    directionalLight(255, 255, 255, width/2, height/2, 20);
    scale(20);
    shape(ammonite);
    popMatrix();
  }//if
  // --------------------- next estado !!!! --------
  else if ( estado.equals("modelo")) {

    doEstadoModelo(); // most important
  }//else if
  // --------------------- EROR - NO estado - program error !!!! --------
  else {
    println ("--------------- EROR - NO estado in draw() !!!! --------");
    exit();
    return;
  }//else
}//func draw()

//------------------------------------------------------------------------

void mousePressed() {

  // mouse is pressed

  if (estado.equals("inicio")) {
    // start screen
    estado = "modelo";
  } 
  //
  // --------------------- next estado  --------
  //
  else if ( estado.equals("modelo")) {
    mousePressedAtX = width/2 - 400;
    mousePressedAtY = height/2;
    //
    color colorFromMouse = pg.get(mouseX, mouseY);
    int oldHotSpotFound=hotSpotFound; 
    // hotSpotFound=undefined; // reset 
    for (int i=0; i<hotSpotsPosition.length; i++) { 
      if (colorFromMouse==hotSpotsColor[i]) {
        if (i==oldHotSpotFound)
          hotSpotFound=undefined; // reset
        else 
        hotSpotFound=i; // set
        break;
      } 
      if (hotSpotFound!=undefined) {
        hotSpotFound = undefined;
      }
    }//for 
    //---
  }//else if 
  // --------------------- EROR - NO estado
  else {
    println ("--------------- EROR - NO estado in mousePressed()  --------");
    exit();
    return;
  }//else
}//func

void doEstadoModelo() {

  makeInternalPGraphics();

  // background
  cam.beginHUD(); // ----
  image(fondo, width/2, height/2, width, height);
  textFont(nexa);
  fill(0, 40);
  rect(width/2, 75, width, 150);
  fill(255);
  text("CONOCIENDO AL AMMONITE", width/2, height/6 - 50);
  if (almejacerrada == true) {
    image(almeja, width-300, height-130, 250, 250);
  }
  almejacerrada = true;
  image(flecha, 125, height/6 - 60 , 125, 125);

  if (mousePressed && mouseX < 300 && mouseX > 0 && mouseY > 0 && mouseY < 300) {
    estado = "inicio";
  }
  cam.endHUD(); // ----

  // show Ammonite
  pushMatrix();
  spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
  directionalLight(255, 255, 255, width/2, height/2, 20);
  scale(20);
  shape(ammonite);
  popMatrix();

  cam.beginHUD(); // ----
  // ----


  // text field

  if (hotSpotFound!=undefined) {

    if (hotSpotsRightSide[hotSpotFound]) {
      // show rect with text
      // on right side
      pushMatrix();
      //  translate(mousePressedAtX, mousePressedAtY, hotSpotsPosition[hotSpotFound].z);
      translate(mousePressedAtX, mousePressedAtY );
      buttonX=mousePressedAtX;
      buttonY=mousePressedAtY;
      scale(0.5);
      fill(250, 250, 35);
      // rect(mousePressedAtX, mousePressedAtY, 100, 100);
      fill(255);
      textFont(nexa);
      textSize(90);
      textMode(SHAPE);
      translate(0, 0, 0.2);

      if (hotSpotsImg[hotSpotFound]!=null) {
        // translate(100+hotSpotsImg[hotSpotFound].width/2, 0, 0);
        image(hotSpotsImg[hotSpotFound], 0, 0);
        text(hotSpotsText[hotSpotFound], width/2, -500);
        //fill(0, 0, 0, 50);
      }
      popMatrix();
    } else
    {
      // show rect with text
      // on left side
      pushMatrix();
      // translate(mousePressedAtX, mousePressedAtY, hotSpotsPosition[hotSpotFound].z);
      translate(mousePressedAtX, mousePressedAtY );
      buttonX=mousePressedAtX;
      buttonY=mousePressedAtY;
      //  translate(-50, 0, 0);
      fill(250, 250, 35, 0);
      scale(0.5);
      fill(255);
      // rect(mousePressedAtX, mousePressedAtY, 100, 100);
      textFont(nexa);
      textSize(90);
      textMode(SHAPE);
      translate(0, 0, 0.2);

      if (hotSpotsImg[hotSpotFound]!=null) {
        // translate(-25-hotSpotsImg[hotSpotFound].width/4, hotSpotsImg[hotSpotFound].height/2, 0);
        image(hotSpotsImg[hotSpotFound], 0, 0);
        text(hotSpotsText[hotSpotFound], width/2, -500);
        //fill(0, 0, 0, 50);
        //rect(buttonX, buttonY, buttonWidth, buttonHeight);
      }
      popMatrix();
    }// else
  }//if
  cam.endHUD(); // ----

  // spheres
  for (int i=0; i<hotSpotsPosition.length; i++) {
    PVector pv = hotSpotsPosition[i];
    pushMatrix();
    translate(pv.x, pv.y, pv.z);
    noStroke();
    // use any color your want here
    fill(0, 255, 255, 70); // normal
    if (i==hotSpotFound) {
      fill(2, 255, 100, 70); // highlight
    } 
    sphere(7);

    popMatrix();
  }
}//func

void makeInternalPGraphics() {
  pg.beginDraw();
  pg. perspective(PI/3.0, (float) width/height, 1, 1000000);
  pg.setMatrix(getMatrix()); // replace the PGraphics-matrix
  pg.background(0);
  pg.noLights();
  for (int i=0; i<hotSpotsPosition.length; i++) {
    PVector pv=hotSpotsPosition[i];
    pg.pushMatrix();
    pg.translate(pv.x, pv.y, pv.z);
    pg.noStroke();
    pg.fill(hotSpotsColor[i]);
    pg.sphere(7);
    pg.popMatrix();
  }//for
  pg.endDraw();
}//func

void avoidClipping() {
  // avoid clipping :
  // https : // // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
  perspective(PI/3.0, (float) width/height, 1, 1000000);
}//func
//

The part color change is made in line 302.

Any help?? Thanks

«1

Answers

  • Please don't post new questions about the same code unnecessarily. This is the third or fourth or fifth thread about this code, it's very hard to keep up.

  • Koogs, but this are different problems that I am having. So sorry.

  • But it's the same code over and over again. Keep it all together.

  • There was a time when I spent my time answering questions. Now I spend it all tidying up after people like you.

  • Ok, so sorry, don't know that it was so much problem, I wont do it anymore. Thanks.

  • You say that but...

    https://forum.processing.org/two/discussion/comment/109843/#Comment_109843

    You've posted the same code twice more since then.

  • So what should I do If i have a new problem with a code that i have already posted? Should I stay with my problem cause I can't post the same code?

  • I answered in a private message already.

    You could post the message here.

    Didn’t you like my message?

  • edited November 2017 Answer ✓

    Hey!

    Please let us write here, no private messages anymore.

    Ok, look at lines 91 to 96 above

    There we store data

    You want the same lines for saying sphereIsPermanentlyGreen

    So make an array sphereIsPermanentlyGreen like in those lines and all slots in it are initially false

    There’s a tutorial on arrays

    Now once one sphere is clicked, set the array at this slot to true — in mousePressed

    Use hotSpotFound as the index for your new array sphereIsPermanentlyGreen:

    Now when displaying the spheres check if (i ==hotSpotFound || sphereIsPermanentlyGreen[hotSpotFound]==true){

    Use green

    }

    else {use color }

    Ok?

    ==true is obsolete but just for clarification

  • // I declare the array
    boolean [] sphereIsPermantentlyGreen = new boolean [hotSpotsPosition.length];
    
    // I define the value of the solts
       sphereIsPermantentlyGreen[0] = false;
       sphereIsPermantentlyGreen[1] = false;
       sphereIsPermantentlyGreen[2] = false;
        sphereIsPermantentlyGreen[3] = false;
       sphereIsPermantentlyGreen[4] = false;
    

    This would be the first part, right?

    Now, I should put this

    sphereIsPermantentlyGreen[hotSpotFound] = true

    in which line? I was thinking about line 267 and 294, is that right?

  • edited November 2017
    import peasy.*;
    import gifAnimation.*;
    
    PeasyCam cam;
    Gif myAnimation;
    boolean showingAnim=false;
    PShape ammonite;
    PImage fondo, titulo, titulo2, ammoniteinicio, almeja, gestos, flecha;
    String estado;
    PFont helvetica, nexa;
    
    // invisible PGraphics
    PGraphics pg;
    
    //define hot spots
    PVector[] hotSpotsPosition=new PVector[5];
    color[] hotSpotsColor =new color [hotSpotsPosition.length];
    String[] hotSpotsText = new String [hotSpotsPosition.length];
    PImage[] hotSpotsImg = new PImage [hotSpotsPosition.length];
    boolean [] hotSpotsRightSide = new boolean [hotSpotsPosition.length];
    Gif [] hotSpotsGif = new Gif [hotSpotsPosition.length];
    boolean [] sphereIsPermantentlyGreen = new boolean [hotSpotsPosition.length];
    boolean almejacerrada;
    int undefined=-1;
    int hotSpotFound=undefined; // when undefined no text is displayed
    
    int mousePressedAtX;
    int mousePressedAtY;
    
    // button data
    int buttonX, buttonY, 
      buttonWidth, buttonHeight;
    
    void setup() {
    
      fullScreen(P3D);
      // size(900, 900, P3D);
    
      rectMode(CENTER);
      imageMode(CENTER);
      textAlign(CENTER);
      textMode(CENTER);
    
      cam = new PeasyCam(this, 100);
      cam.setMinimumDistance(110);
      cam.setMaximumDistance(500);
    
      ammonite = loadShape("ammonite.obj");
    
      // define the hot spots in parallel arrays
      // the first hot spot is defined in hotSpotsPosition[0] and hotSpotsColor[0] and hotSpotsText[0] and so on
      // positions:
      hotSpotsPosition[0] = new PVector(-15, -20, 5);
      hotSpotsPosition[1] = new PVector(-5, -5, -25);
      hotSpotsPosition[2] = new PVector(-20, -10, 3);
      hotSpotsPosition[3] = new PVector(-30, -10, 20);
      hotSpotsPosition[4] = new PVector(-5, 19, -5);
    
      //colors: colors are not visible but must be unique
      hotSpotsColor[0] = color(255, 0, 0);
      hotSpotsColor[1] = color(100, 0, 0);
      hotSpotsColor[2] = color(110, 0, 0);
      hotSpotsColor[3] = color(120, 0, 0);
      hotSpotsColor[4] = color(160, 0, 0);
    
      // texts
      hotSpotsText[0] = "Embudo";
      hotSpotsText[1] = "Caparazón";
      hotSpotsText[2] = "Ojos";
      hotSpotsText[3] = "Tentáculos";
      hotSpotsText[4] = "Sifón";
    
      //images
      hotSpotsImg[0] = loadImage ("calamares.png");
      hotSpotsImg[1] = loadImage ("tamaños.png");
      hotSpotsImg[2] = loadImage ("estatica.png"); 
      hotSpotsImg[3] = loadImage ("tentaculos.png");
      hotSpotsImg[4] = loadImage ("limitados.png");
    
      //  for (PImage img : hotSpotsImg)
      //     img.resize(200, 0);
    
      // Gifs
      hotSpotsGif[0]  = new Gif(this, "embudoanim.gif");
      hotSpotsGif[1]  = new Gif(this, "caparazonanim.gif");
      hotSpotsGif[2]  = new Gif(this, "ojosanim.gif");
      hotSpotsGif[3]  = new Gif(this, "tentaculosanim.gif");
      hotSpotsGif[4]  = new Gif(this, "sifonanim.gif");
    
      for (Gif g1 : hotSpotsGif) {
        g1.play();
      }
    
    
      // whether we display the spot left or right
      hotSpotsRightSide[0] = false;
      hotSpotsRightSide[1] = true;
      hotSpotsRightSide[2] = true;
      hotSpotsRightSide[3] = true;
      hotSpotsRightSide[4] = false;
    
      // whether we display the that it's not green
      sphereIsPermantentlyGreen[0] = false;
      sphereIsPermantentlyGreen[1] = false;
      sphereIsPermantentlyGreen[2] = false;
      sphereIsPermantentlyGreen[3] = false;
      sphereIsPermantentlyGreen[4] = false;
    
      fondo = loadImage("fondo.jpg");
      titulo = loadImage("titulo.png");
      titulo2 = loadImage("conociendo.png");
      ammoniteinicio = loadImage("ammoniteparainicio.png");
      almeja = loadImage("almeja.png");
      gestos = loadImage("gestos2.png");
      flecha = loadImage("flecha.png");
    
      buttonX = 0;
      buttonY = 0;
      buttonWidth = 400;
      buttonHeight = 400;
    
      estado = "inicio";
      almejacerrada = false;
      helvetica = createFont("HelveticaWorld-Regular.ttf", 30);
      nexa = createFont("Nexa Bold.otf", 50);
    
      pg = createGraphics(width, height, P3D);
    
      fondo.resize(width, height);
      image(fondo, width/2, height/2);
    } //func
    
    void draw() {
    
      avoidClipping(); // so the graphic AMMONITE is not cut when rotating
    
      if (estado.equals("inicio")) {
        //-----------Stopping peasy ------
        cam.beginHUD();
    
        image(fondo, width/2, height/2);
        image(almeja, width-300, height-130, 250, 250);
        fill(0, 50);
        rect(width/2, height/2, width, height);
        fill(0, 30);
        noStroke();
        rect(width/2, 75, width, 150);
        fill(255);
        textFont(nexa);
        text("AMMONITE", width/2, height/6 - 50);
        text("EL ANCESTRO MARINO", width/2, height/6);
        textFont(helvetica);
        text("Toca para comenzar", width/2, height/2 + 300);
        image(gestos, width/2 + 400, height/2-100);
    
        cam.endHUD(); //--------------------------------
        pushMatrix();
        spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
        directionalLight(255, 255, 255, width/2, height/2, 20);
        scale(20);
        shape(ammonite);
        popMatrix();
      }//if
      // --------------------- next estado !!!! --------
      else if ( estado.equals("modelo")) {
    
        doEstadoModelo(); // most important
      }//else if
      // --------------------- EROR - NO estado - program error !!!! --------
      else {
        println ("--------------- EROR - NO estado in draw() !!!! --------");
        exit();
        return;
      }//else
    }//func draw()
    
    //------------------------------------------------------------------------
    
    void mousePressed() {
    
      // mouse is pressed
    
      if (estado.equals("inicio")) {
        // start screen
        estado = "modelo";
      } 
      //
      // --------------------- next estado  --------
      //
      else if ( estado.equals("modelo")) {
        mousePressedAtX = width/2 - 450;
        mousePressedAtY = height/2;
        //
        color colorFromMouse = pg.get(mouseX, mouseY);
        int oldHotSpotFound=hotSpotFound; 
        // hotSpotFound=undefined; // reset 
        for (int i=0; i<hotSpotsPosition.length; i++) { 
          if (colorFromMouse==hotSpotsColor[i]) {
            if (i==oldHotSpotFound)
              hotSpotFound=undefined; // reset
            else 
            hotSpotFound=i; // set
            break;
          } 
          if (hotSpotFound!=undefined) {
            hotSpotFound = undefined;
          }
        }//for 
        //---
      }//else if 
      // --------------------- EROR - NO estado
      else {
        println ("--------------- EROR - NO estado in mousePressed()  --------");
        exit();
        return;
      }//else
    }//func
    
    void doEstadoModelo() {
    
      makeInternalPGraphics();
    
      // background
      cam.beginHUD(); // ----
      image(fondo, width/2, height/2, width, height);
      textFont(nexa);
      fill(0, 40);
      rect(width/2, 75, width, 150);
      fill(255);
      text("CONOCIENDO AL AMMONITE", width/2, height/6 - 50);
      if (almejacerrada == true) {
        image(almeja, width-300, height-130, 250, 250);
      }
      almejacerrada = true;
      image(flecha, 125, height/6 - 60, 125, 125);
    
      if (mousePressed && mouseX < 200 && mouseX > 0 && mouseY > 0 && mouseY < 200 && estado.equals("modelo")) {
        estado = "inicio";
      }
      cam.endHUD(); // ----
    
      // show Ammonite
      pushMatrix();
      spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
      directionalLight(255, 255, 255, width/2, height/2, 20);
      scale(20);
      shape(ammonite);
      popMatrix();
    
      cam.beginHUD(); // ----
      // ----
    
    
      // text field
    
      if (hotSpotFound!=undefined) {
    
        if (hotSpotsRightSide[hotSpotFound]) {
          // show rect with text
          // on right side
          pushMatrix();
          //  translate(mousePressedAtX, mousePressedAtY, hotSpotsPosition[hotSpotFound].z);
          translate(mousePressedAtX, mousePressedAtY );
          buttonX=mousePressedAtX;
          buttonY=mousePressedAtY;
          scale(0.5);
          fill(250, 250, 35);
          // rect(mousePressedAtX, mousePressedAtY, 100, 100);
          fill(255);
          textFont(nexa);
          textSize(90);
          //  textMode(SHAPE);
          translate(0, 0, 0);
    
          if (hotSpotsImg[hotSpotFound]!=null) {
            // translate(100+hotSpotsImg[hotSpotFound].width/2, 0, 0);
    
            image(hotSpotsImg[hotSpotFound], 0, 0);
            text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
            sphereIsPermantentlyGreen[hotSpotFound] = true;
    
            //fill(0, 0, 0, 50);
          }
          popMatrix();
        } else
        {
          // show rect with text
          // on left side
          pushMatrix();
    
          translate(mousePressedAtX, mousePressedAtY );
          buttonX=mousePressedAtX;
          buttonY=mousePressedAtY;
    
          fill(250, 250, 35, 0);
          scale(0.5);
          fill(255);
    
          textFont(nexa);
          textSize(90);
          // textMode(SHAPE);
          translate(0, 0, 0);
    
          if (hotSpotsImg[hotSpotFound]!=null) {
    
            image(hotSpotsImg[hotSpotFound], 0, 0);
            text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
            sphereIsPermantentlyGreen[hotSpotFound] = true;
          }
          popMatrix();
        }// else
      }//if
      cam.endHUD(); // ----
    
      // spheres
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv = hotSpotsPosition[i];
    
        pushMatrix();
        translate(pv.x, pv.y, pv.z);
        // use any color your want here
    
        if (i==hotSpotFound || sphereIsPermantentlyGreen[hotSpotFound] == true) {
          fill(2, 255, 100, 70); // highlight
        } else {
          fill(255, 70); // normal
        }
        sphere(4);
    
        popMatrix();
      }
    }//func
    
    void makeInternalPGraphics() {
      pg.beginDraw();
      pg. perspective(PI/3.0, (float) width/height, 1, 1000000);
      pg.setMatrix(getMatrix()); // replace the PGraphics-matrix
      pg.background(0);
      pg.noLights();
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv=hotSpotsPosition[i];
        pg.pushMatrix();
        pg.translate(pv.x, pv.y, pv.z);
        pg.noStroke();
        pg.fill(hotSpotsColor[i]);
        pg.sphere(4);
        pg.popMatrix();
      }//for
      pg.endDraw();
    }//func
    
    void avoidClipping() {
      // avoid clipping :
      // https : // // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
      perspective(PI/3.0, (float) width/height, 1, 1000000);
    }//func
    //
    

    The code is now like this but the program crashes.

    I think it's because of this lines

     if (hotSpotsImg[hotSpotFound]!=null) {
    
                    image(hotSpotsImg[hotSpotFound], 0, 0);
                    text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
                    sphereIsPermantentlyGreen[hotSpotFound] = true;
                  }
    

    But I don't know where I should set the sphere to true if itsn't there.

  • edited November 2017

    Set to true in 202; but you must make { } around 202 and your new line

  • When set to true later you must evaluate the array — see above....

  • Okey, thanks! I didn't understand this

    must make { around 202 and your new line

    I'm so sorry cause i'm always asking questions that may sound stupid but sometimes it's difficult for me to understand not only things related to the code but also about the language! :(

    I'm sure you will be rewarded for being such a good person and help me and lots of persons here in the forum.

  • Try it

    Finish it

    Then post your entire code again

  • Try it

    Finish it

    Then post your entire code again

  • import peasy.*;
    import gifAnimation.*;
    
    PeasyCam cam;
    Gif myAnimation;
    boolean showingAnim=false;
    PShape ammonite;
    PImage fondo, titulo, titulo2, ammoniteinicio, almeja, gestos, flecha;
    String estado;
    PFont helvetica, nexa;
    
    // invisible PGraphics
    PGraphics pg;
    
    //define hot spots
    PVector[] hotSpotsPosition=new PVector[5];
    color[] hotSpotsColor =new color [hotSpotsPosition.length];
    String[] hotSpotsText = new String [hotSpotsPosition.length];
    PImage[] hotSpotsImg = new PImage [hotSpotsPosition.length];
    boolean [] hotSpotsRightSide = new boolean [hotSpotsPosition.length];
    Gif [] hotSpotsGif = new Gif [hotSpotsPosition.length];
    boolean [] sphereIsPermanentlyGreen = new boolean [hotSpotsPosition.length];
    boolean almejacerrada;
    int undefined=-1;
    int hotSpotFound=undefined; // when undefined no text is displayed
    
    int mousePressedAtX;
    int mousePressedAtY;
    
    // button data
    int buttonX, buttonY, 
      buttonWidth, buttonHeight;
    
    void setup() {
    
      fullScreen(P3D);
      // size(900, 900, P3D);
    
      rectMode(CENTER);
      imageMode(CENTER);
      textAlign(CENTER);
      textMode(CENTER);
    
      cam = new PeasyCam(this, 100);
      cam.setMinimumDistance(110);
      cam.setMaximumDistance(500);
    
      ammonite = loadShape("ammonite.obj");
    
      // define the hot spots in parallel arrays
      // the first hot spot is defined in hotSpotsPosition[0] and hotSpotsColor[0] and hotSpotsText[0] and so on
      // positions:
      hotSpotsPosition[0] = new PVector(-15, -20, 5);
      hotSpotsPosition[1] = new PVector(-5, -5, -25);
      hotSpotsPosition[2] = new PVector(-20, -10, 3);
      hotSpotsPosition[3] = new PVector(-30, -10, 20);
      hotSpotsPosition[4] = new PVector(-5, 19, -5);
    
      //colors: colors are not visible but must be unique
      hotSpotsColor[0] = color(255, 0, 0);
      hotSpotsColor[1] = color(100, 0, 0);
      hotSpotsColor[2] = color(110, 0, 0);
      hotSpotsColor[3] = color(120, 0, 0);
      hotSpotsColor[4] = color(160, 0, 0);
    
      // texts
      hotSpotsText[0] = "Embudo";
      hotSpotsText[1] = "Caparazón";
      hotSpotsText[2] = "Ojos";
      hotSpotsText[3] = "Tentáculos";
      hotSpotsText[4] = "Sifón";
    
      //images
      hotSpotsImg[0] = loadImage ("calamares.png");
      hotSpotsImg[1] = loadImage ("tamaños.png");
      hotSpotsImg[2] = loadImage ("estatica.png"); 
      hotSpotsImg[3] = loadImage ("tentaculos.png");
      hotSpotsImg[4] = loadImage ("limitados.png");
    
      //  for (PImage img : hotSpotsImg)
      //     img.resize(200, 0);
    
      // Gifs
      hotSpotsGif[0]  = new Gif(this, "embudoanim.gif");
      hotSpotsGif[1]  = new Gif(this, "caparazonanim.gif");
      hotSpotsGif[2]  = new Gif(this, "ojosanim.gif");
      hotSpotsGif[3]  = new Gif(this, "tentaculosanim.gif");
      hotSpotsGif[4]  = new Gif(this, "sifonanim.gif");
    
      for (Gif g1 : hotSpotsGif) {
        g1.play();
      }
    
    
      // whether we display the spot left or right
      hotSpotsRightSide[0] = false;
      hotSpotsRightSide[1] = true;
      hotSpotsRightSide[2] = true;
      hotSpotsRightSide[3] = true;
      hotSpotsRightSide[4] = false;
    
      // whether we display the that it's not green
      sphereIsPermanentlyGreen[0] = false;
      sphereIsPermanentlyGreen[1] = false;
      sphereIsPermanentlyGreen[2] = false;
      sphereIsPermanentlyGreen[3] = false;
      sphereIsPermanentlyGreen[4] = false;
    
      fondo = loadImage("fondo.jpg");
      titulo = loadImage("titulo.png");
      titulo2 = loadImage("conociendo.png");
      ammoniteinicio = loadImage("ammoniteparainicio.png");
      almeja = loadImage("almeja.png");
      gestos = loadImage("gestos2.png");
      flecha = loadImage("flecha.png");
    
      buttonX = 0;
      buttonY = 0;
      buttonWidth = 400;
      buttonHeight = 400;
    
      estado = "inicio";
      almejacerrada = false;
      helvetica = createFont("HelveticaWorld-Regular.ttf", 30);
      nexa = createFont("Nexa Bold.otf", 50);
    
      pg = createGraphics(width, height, P3D);
    
      fondo.resize(width, height);
      image(fondo, width/2, height/2);
    } //func
    
    void draw() {
    
      avoidClipping(); // so the graphic AMMONITE is not cut when rotating
    
      if (estado.equals("inicio")) {
        //-----------Stopping peasy ------
        cam.beginHUD();
    
        image(fondo, width/2, height/2);
        image(almeja, width-300, height-130, 250, 250);
        fill(0, 50);
        rect(width/2, height/2, width, height);
        fill(0, 30);
        noStroke();
        rect(width/2, 75, width, 150);
        fill(255);
        textFont(nexa);
        text("AMMONITE", width/2, height/6 - 50);
        text("EL ANCESTRO MARINO", width/2, height/6);
        textFont(helvetica);
        text("Toca para comenzar", width/2, height/2 + 300);
        image(gestos, width/2 + 400, height/2-100);
    
        cam.endHUD(); //--------------------------------
        pushMatrix();
        spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
        directionalLight(255, 255, 255, width/2, height/2, 20);
        scale(20);
        shape(ammonite);
        popMatrix();
      }//if
      // --------------------- next estado !!!! --------
      else if ( estado.equals("modelo")) {
    
        doEstadoModelo(); // most important
      }//else if
      // --------------------- EROR - NO estado - program error !!!! --------
      else {
        println ("--------------- EROR - NO estado in draw() !!!! --------");
        exit();
        return;
      }//else
    }//func draw()
    
    //------------------------------------------------------------------------
    
    void mousePressed() {
    
      // mouse is pressed
    
      if (estado.equals("inicio")) {
        // start screen
        estado = "modelo";
      } 
      //
      // --------------------- next estado  --------
      //
      else if ( estado.equals("modelo")) {
        mousePressedAtX = width/2 - 450;
        mousePressedAtY = height/2;
        //
        color colorFromMouse = pg.get(mouseX, mouseY);
        int oldHotSpotFound=hotSpotFound; 
        // hotSpotFound=undefined; // reset 
        for (int i=0; i<hotSpotsPosition.length; i++) { 
          if (colorFromMouse==hotSpotsColor[i]) {
            if (i==oldHotSpotFound)
              hotSpotFound=undefined; // reset
           else {
            sphereIsPermanentlyGreen[hotSpotFound] = true; 
          }
            hotSpotFound=i; // set
            break;
          } 
          if (hotSpotFound!=undefined) {
            hotSpotFound = undefined;
          }
        }//for 
        //---
      }//else if 
      // --------------------- EROR - NO estado
      else {
        println ("--------------- EROR - NO estado in mousePressed()  --------");
        exit();
        return;
      }//else
    }//func
    
    void doEstadoModelo() {
    
      makeInternalPGraphics();
    
      // background
      cam.beginHUD(); // ----
      image(fondo, width/2, height/2, width, height);
      textFont(nexa);
      fill(0, 40);
      rect(width/2, 75, width, 150);
      fill(255);
      text("CONOCIENDO AL AMMONITE", width/2, height/6 - 50);
      if (almejacerrada == true) {
        image(almeja, width-300, height-130, 250, 250);
      }
      almejacerrada = true;
      image(flecha, 125, height/6 - 60, 125, 125);
    
      if (mousePressed && mouseX < 200 && mouseX > 0 && mouseY > 0 && mouseY < 200 && estado.equals("modelo")) {
        estado = "inicio";
      }
      cam.endHUD(); // ----
    
      // show Ammonite
      pushMatrix();
      spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
      directionalLight(255, 255, 255, width/2, height/2, 20);
      scale(20);
      shape(ammonite);
      popMatrix();
    
      cam.beginHUD(); // ----
      // ----
    
    
      // text field
    
      if (hotSpotFound!=undefined) {
    
        if (hotSpotsRightSide[hotSpotFound]) {
          // show rect with text
          // on right side
          pushMatrix();
          //  translate(mousePressedAtX, mousePressedAtY, hotSpotsPosition[hotSpotFound].z);
          translate(mousePressedAtX, mousePressedAtY );
          buttonX=mousePressedAtX;
          buttonY=mousePressedAtY;
          scale(0.5);
          fill(250, 250, 35);
          // rect(mousePressedAtX, mousePressedAtY, 100, 100);
          fill(255);
          textFont(nexa);
          textSize(90);
          //  textMode(SHAPE);
          translate(0, 0, 0);
    
          if (hotSpotsImg[hotSpotFound]!=null) {
            // translate(100+hotSpotsImg[hotSpotFound].width/2, 0, 0);
    
            image(hotSpotsImg[hotSpotFound], 0, 0);
            text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
    
    
            //fill(0, 0, 0, 50);
          }
          popMatrix();
        } else
        {
          // show rect with text
          // on left side
          pushMatrix();
    
          translate(mousePressedAtX, mousePressedAtY );
          buttonX=mousePressedAtX;
          buttonY=mousePressedAtY;
    
          fill(250, 250, 35, 0);
          scale(0.5);
          fill(255);
    
          textFont(nexa);
          textSize(90);
          // textMode(SHAPE);
          translate(0, 0, 0);
    
          if (hotSpotsImg[hotSpotFound]!=null) {
    
            image(hotSpotsImg[hotSpotFound], 0, 0);
            text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
          }
          popMatrix();
        }// else
      }//if
      cam.endHUD(); // ----
    
      // spheres
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv = hotSpotsPosition[i];
    
        pushMatrix();
        translate(pv.x, pv.y, pv.z);
        // use any color your want here
        fill(255, 70); // normal
        if (i==hotSpotFound || sphereIsPermanentlyGreen[hotSpotFound] == true) {
          fill(2, 255, 100, 70); // highlight
        } else {
          fill(255, 70); // normal
        }
        sphere(4);
    
        popMatrix();
      }
    }//func
    
    void makeInternalPGraphics() {
      pg.beginDraw();
      pg. perspective(PI/3.0, (float) width/height, 1, 1000000);
      pg.setMatrix(getMatrix()); // replace the PGraphics-matrix
      pg.background(0);
      pg.noLights();
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv=hotSpotsPosition[i];
        pg.pushMatrix();
        pg.translate(pv.x, pv.y, pv.z);
        pg.noStroke();
        pg.fill(hotSpotsColor[i]);
        pg.sphere(4);
        pg.popMatrix();
      }//for
      pg.endDraw();
    }//func
    
    void avoidClipping() {
      // avoid clipping :
      // https : // // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
      perspective(PI/3.0, (float) width/height, 1, 1000000);
    }//func
    //
    

    Look, I'm doing in the proper way everything as you told me, I don't get any error but the program still crashing.

  • edited November 2017

    You must include line 204 in the brackets {} together with 202....

    I am still not sure you fully understand the code

    It crashed in which way ? Error message??

  • I am not at home and write on my phone

    That’s why I can’t fix it here

    Did you use ctrl-t and check indents / columns of pairs of {}

  • What’s this: almejacerrada

  • It's okey, I understood the code but it's the first time i'm working with so many if clauses inside other if clauses, also it's a year since the last time I programmed something.

    It crashed in the way that I press play and it locks on the first screen and I have no response, I have to close it because java dosn't respond.

  • What’s this: almejacerrada

    That's an image of a clam that i'm using

  • Restart computer maybe?

    Do you run it on iPad now...?

  • If you knew objects and classes we could unify your bunch of parallel arrays into one.

    But I don’t want to impose this approach on to you

    https://forum.processing.org/two/discussion/8081/from-several-arrays-to-classes

  • edited November 2017

    No, I'm running it on my pc

    It shows me this line when I close the program, as if there was an error on that line...

  • Yes, last year I made a simple game with object and classes but it was too simple, but I want to have this ready for today because I have to show it in a museum.

    Maybe is too late to start reorganazing the sketch

  • almejacerrada

    Is not an image but a Boolean!!!!!

  • I see where you error is

    In the yellow line use i as index of the array obviously

  • WHY did you write it crashes without error when the yellow line is so visibly marked....?

    I‘ll be home soon and can finish it for you

  • Okey, I done it, also in line 202 I used i as index.

    The code is now like this!

    import peasy.*;
    import gifAnimation.*;
    
    PeasyCam cam;
    Gif myAnimation;
    boolean showingAnim=false;
    PShape ammonite;
    PImage fondo, titulo, titulo2, ammoniteinicio, almeja, gestos, flecha;
    String estado;
    PFont helvetica, nexa;
    
    // invisible PGraphics
    PGraphics pg;
    
    //define hot spots
    PVector[] hotSpotsPosition=new PVector[5];
    color[] hotSpotsColor =new color [hotSpotsPosition.length];
    String[] hotSpotsText = new String [hotSpotsPosition.length];
    PImage[] hotSpotsImg = new PImage [hotSpotsPosition.length];
    boolean [] hotSpotsRightSide = new boolean [hotSpotsPosition.length];
    Gif [] hotSpotsGif = new Gif [hotSpotsPosition.length];
    boolean [] sphereIsPermanentlyGreen = new boolean [hotSpotsPosition.length];
    boolean almejacerrada;
    int undefined=-1;
    int hotSpotFound=undefined; // when undefined no text is displayed
    
    int mousePressedAtX;
    int mousePressedAtY;
    
    // button data
    int buttonX, buttonY, 
      buttonWidth, buttonHeight;
    
    void setup() {
    
      fullScreen(P3D);
      // size(900, 900, P3D);
    
      rectMode(CENTER);
      imageMode(CENTER);
      textAlign(CENTER);
      textMode(CENTER);
    
      cam = new PeasyCam(this, 100);
      cam.setMinimumDistance(110);
      cam.setMaximumDistance(500);
    
      ammonite = loadShape("ammonite.obj");
    
      // define the hot spots in parallel arrays
      // the first hot spot is defined in hotSpotsPosition[0] and hotSpotsColor[0] and hotSpotsText[0] and so on
      // positions:
      hotSpotsPosition[0] = new PVector(-15, -20, 5);
      hotSpotsPosition[1] = new PVector(-5, -5, -25);
      hotSpotsPosition[2] = new PVector(-20, -10, 3);
      hotSpotsPosition[3] = new PVector(-30, -10, 20);
      hotSpotsPosition[4] = new PVector(-5, 19, -5);
    
      //colors: colors are not visible but must be unique
      hotSpotsColor[0] = color(255, 0, 0);
      hotSpotsColor[1] = color(100, 0, 0);
      hotSpotsColor[2] = color(110, 0, 0);
      hotSpotsColor[3] = color(120, 0, 0);
      hotSpotsColor[4] = color(160, 0, 0);
    
      // texts
      hotSpotsText[0] = "Embudo";
      hotSpotsText[1] = "Caparazón";
      hotSpotsText[2] = "Ojos";
      hotSpotsText[3] = "Tentáculos";
      hotSpotsText[4] = "Sifón";
    
      //images
      hotSpotsImg[0] = loadImage ("calamares.png");
      hotSpotsImg[1] = loadImage ("tamaños.png");
      hotSpotsImg[2] = loadImage ("estatica.png"); 
      hotSpotsImg[3] = loadImage ("tentaculos.png");
      hotSpotsImg[4] = loadImage ("limitados.png");
    
      //  for (PImage img : hotSpotsImg)
      //     img.resize(200, 0);
    
      // Gifs
      hotSpotsGif[0]  = new Gif(this, "embudoanim.gif");
      hotSpotsGif[1]  = new Gif(this, "caparazonanim.gif");
      hotSpotsGif[2]  = new Gif(this, "ojosanim.gif");
      hotSpotsGif[3]  = new Gif(this, "tentaculosanim.gif");
      hotSpotsGif[4]  = new Gif(this, "sifonanim.gif");
    
      for (Gif g1 : hotSpotsGif) {
        g1.play();
      }
    
    
      // whether we display the spot left or right
      hotSpotsRightSide[0] = false;
      hotSpotsRightSide[1] = true;
      hotSpotsRightSide[2] = true;
      hotSpotsRightSide[3] = true;
      hotSpotsRightSide[4] = false;
    
      // whether we display the that it's not green
      sphereIsPermanentlyGreen[0] = false;
      sphereIsPermanentlyGreen[1] = false;
      sphereIsPermanentlyGreen[2] = false;
      sphereIsPermanentlyGreen[3] = false;
      sphereIsPermanentlyGreen[4] = false;
    
      fondo = loadImage("fondo.jpg");
      titulo = loadImage("titulo.png");
      titulo2 = loadImage("conociendo.png");
      ammoniteinicio = loadImage("ammoniteparainicio.png");
      almeja = loadImage("almeja.png");
      gestos = loadImage("gestos2.png");
      flecha = loadImage("flecha.png");
    
      buttonX = 0;
      buttonY = 0;
      buttonWidth = 400;
      buttonHeight = 400;
    
      estado = "inicio";
      almejacerrada = false;
      helvetica = createFont("HelveticaWorld-Regular.ttf", 30);
      nexa = createFont("Nexa Bold.otf", 50);
    
      pg = createGraphics(width, height, P3D);
    
      fondo.resize(width, height);
      image(fondo, width/2, height/2);
    } //func
    
    void draw() {
    
      avoidClipping(); // so the graphic AMMONITE is not cut when rotating
    
      if (estado.equals("inicio")) {
        //-----------Stopping peasy ------
        cam.beginHUD();
    
        image(fondo, width/2, height/2);
        image(almeja, width-300, height-130, 250, 250);
        fill(0, 50);
        rect(width/2, height/2, width, height);
        fill(0, 30);
        noStroke();
        rect(width/2, 75, width, 150);
        fill(255);
        textFont(nexa);
        text("AMMONITE", width/2, height/6 - 50);
        text("EL ANCESTRO MARINO", width/2, height/6);
        textFont(helvetica);
        text("Toca para comenzar", width/2, height/2 + 300);
        image(gestos, width/2 + 400, height/2-100);
    
        cam.endHUD(); //--------------------------------
        pushMatrix();
        spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
        directionalLight(255, 255, 255, width/2, height/2, 20);
        scale(20);
        shape(ammonite);
        popMatrix();
      }//if
      // --------------------- next estado !!!! --------
      else if ( estado.equals("modelo")) {
    
        doEstadoModelo(); // most important
      }//else if
      // --------------------- EROR - NO estado - program error !!!! --------
      else {
        println ("--------------- EROR - NO estado in draw() !!!! --------");
        exit();
        return;
      }//else
    }//func draw()
    
    //------------------------------------------------------------------------
    
    void mousePressed() {
    
      // mouse is pressed
    
      if (estado.equals("inicio")) {
        // start screen
        estado = "modelo";
      } 
      //
      // --------------------- next estado  --------
      //
      else if ( estado.equals("modelo")) {
        mousePressedAtX = width/2 - 450;
        mousePressedAtY = height/2;
        //
        color colorFromMouse = pg.get(mouseX, mouseY);
        int oldHotSpotFound=hotSpotFound; 
        // hotSpotFound=undefined; // reset 
        for (int i=0; i<hotSpotsPosition.length; i++) { 
          if (colorFromMouse==hotSpotsColor[i]) {
            if (i==oldHotSpotFound)
              hotSpotFound=undefined; // reset
           else {
            sphereIsPermanentlyGreen[i] = true; 
    
            hotSpotFound=i; // set
            }
            break;
          } 
          if (hotSpotFound!=undefined) {
            hotSpotFound = undefined;
          }
        }//for 
        //---
      }//else if 
      // --------------------- EROR - NO estado
      else {
        println ("--------------- EROR - NO estado in mousePressed()  --------");
        exit();
        return;
      }//else
    }//func
    
    void doEstadoModelo() {
    
      makeInternalPGraphics();
    
      // background
      cam.beginHUD(); // ----
      image(fondo, width/2, height/2, width, height);
      textFont(nexa);
      fill(0, 40);
      rect(width/2, 75, width, 150);
      fill(255);
      text("CONOCIENDO AL AMMONITE", width/2, height/6 - 50);
      if (almejacerrada == true) {
        image(almeja, width-300, height-130, 250, 250);
      }
      almejacerrada = true;
      image(flecha, 125, height/6 - 60, 125, 125);
    
      if (mousePressed && mouseX < 200 && mouseX > 0 && mouseY > 0 && mouseY < 200 && estado.equals("modelo")) {
        estado = "inicio";
      }
      cam.endHUD(); // ----
    
      // show Ammonite
      pushMatrix();
      spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
      directionalLight(255, 255, 255, width/2, height/2, 20);
      scale(20);
      shape(ammonite);
      popMatrix();
    
      cam.beginHUD(); // ----
      // ----
    
    
      // text field
    
      if (hotSpotFound!=undefined) {
    
        if (hotSpotsRightSide[hotSpotFound]) {
          // show rect with text
          // on right side
          pushMatrix();
          //  translate(mousePressedAtX, mousePressedAtY, hotSpotsPosition[hotSpotFound].z);
          translate(mousePressedAtX, mousePressedAtY );
          buttonX=mousePressedAtX;
          buttonY=mousePressedAtY;
          scale(0.5);
          fill(250, 250, 35);
          // rect(mousePressedAtX, mousePressedAtY, 100, 100);
          fill(255);
          textFont(nexa);
          textSize(90);
          //  textMode(SHAPE);
          translate(0, 0, 0);
    
          if (hotSpotsImg[hotSpotFound]!=null) {
            // translate(100+hotSpotsImg[hotSpotFound].width/2, 0, 0);
    
            image(hotSpotsImg[hotSpotFound], 0, 0);
            text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
    
    
            //fill(0, 0, 0, 50);
          }
          popMatrix();
        } else
        {
          // show rect with text
          // on left side
          pushMatrix();
    
          translate(mousePressedAtX, mousePressedAtY );
          buttonX=mousePressedAtX;
          buttonY=mousePressedAtY;
    
          fill(250, 250, 35, 0);
          scale(0.5);
          fill(255);
    
          textFont(nexa);
          textSize(90);
          // textMode(SHAPE);
          translate(0, 0, 0);
    
          if (hotSpotsImg[hotSpotFound]!=null) {
    
            image(hotSpotsImg[hotSpotFound], 0, 0);
            text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
          }
          popMatrix();
        }// else
      }//if
      cam.endHUD(); // ----
    
      // spheres
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv = hotSpotsPosition[i];
    
        pushMatrix();
        translate(pv.x, pv.y, pv.z);
        // use any color your want here
        fill(255, 70); // normal
        if (i==hotSpotFound || sphereIsPermanentlyGreen[i] == true) {
          fill(2, 255, 100, 70); // highlight
        } else {
          fill(255, 70); // normal
        }
        sphere(4);
    
        popMatrix();
      }
    }//func
    
    void makeInternalPGraphics() {
      pg.beginDraw();
      pg. perspective(PI/3.0, (float) width/height, 1, 1000000);
      pg.setMatrix(getMatrix()); // replace the PGraphics-matrix
      pg.background(0);
      pg.noLights();
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv=hotSpotsPosition[i];
        pg.pushMatrix();
        pg.translate(pv.x, pv.y, pv.z);
        pg.noStroke();
        pg.fill(hotSpotsColor[i]);
        pg.sphere(4);
        pg.popMatrix();
      }//for
      pg.endDraw();
    }//func
    
    void avoidClipping() {
      // avoid clipping :
      // https : // // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
      perspective(PI/3.0, (float) width/height, 1, 1000000);
    }//func
    //
    
  • Is the ammonite upside down now?

  • Is the ammonite upside down now?

    Yes, it has been in that position from the first time i believe, do you know how to change the default position of peasycam?

  • edited November 2017 Answer ✓

    With putting i in: does your code fully run now?

  • Yes, now it's running perfectly, now i'm gonna make something that when you have pressed every sphere, it shows u a screen that the experience have ended!

  • all right. Congratulations!

    I am offline then.

    Send me a personal message when you need help but write also here. Don't open a new discussion.

    Chrisir

    ;-)

  • does the animation play?

    For the upside down problem:

    see in setup() where you define in camera?

    Add this line:

          cam.rotateZ(radians(180));  // rotate around the x-axis passing through the subject
    
  • Thanks for your help!!

    I'm gonna write you if I have any problem, thanks thanks thanks!!!

  • using this you can zoom much closer:

       cam.setMinimumDistance(1);
    
  • does the animation play?

    Nope :(

    It appears as if it was an image

    Thanks a lot those lines of code, they were really useful!

  • did you download the jar

    and dragged it unto your sketch?????

  • did you write a small test sketch as I told you to ?

  • I have to go

    bye

  • Yes, I drag the jar but didn't practice with a small test sketch, thanks for your help Chrisir!

  • You dragged the downloaded jar on the sketch code??????

    What subfolders do you have ??? Data ?

  • edited November 2017

    hello,

    Here comes a new version where we count how many spheres have been clicked (like 3/5 have been clicked).

    (Note that I made new functions to make the main functions shorter; you don't have to do that)

    To see how the counting of the clicks is done follow the variable countHotSpotsClicked. Just use the search of processing with ctrl-f to look at the places where I used it.

    Basically we add 1 to it (using the short form ++) in mousePressed() when the sphere hasn't been clicked before (using if here). Then we display it in the function showBackground() (which is called from draw()).

    Chrisir

    import peasy.*;
    import gifAnimation.*;
    
    // camera 
    PeasyCam cam;
    
    // invisible PGraphics
    PGraphics pg;
    
    //define hot spots
    PVector[] hotSpotsPosition=new PVector[5];
    color[] hotSpotsColor =new color [hotSpotsPosition.length];
    String[] hotSpotsText = new String [hotSpotsPosition.length];
    PImage[] hotSpotsImg = new PImage [hotSpotsPosition.length];
    boolean [] hotSpotsRightSide = new boolean [hotSpotsPosition.length];
    Gif [] hotSpotsGif = new Gif [hotSpotsPosition.length];
    boolean [] sphereIsPermanentlyGreen = new boolean [hotSpotsPosition.length];
    
    int countHotSpotsClicked = 0; 
    
    boolean almejacerrada;
    
    boolean showingAnim=false;
    PShape ammonite;
    PImage fondo, titulo, titulo2, ammoniteinicio, almeja, gestos, flecha;
    String estado;
    PFont helvetica, nexa;
    
    final int undefined=-1;     // a constant 
    int hotSpotFound=undefined; // when undefined no image shown / no text is displayed
    
    int mousePressedAtX;
    int mousePressedAtY;
    
    // button data
    int buttonX, buttonY, 
      buttonWidth, buttonHeight;
    
    // -----------------------------------------------------------------------------
    
    void setup() {
    
      fullScreen(P3D);
      // size(900, 900, P3D);
    
      rectMode(CENTER);
      imageMode(CENTER);
      textAlign(CENTER);
      // textMode(CENTER);
    
      cam = new PeasyCam(this, 100);
      cam.setMinimumDistance(1);
      cam.setMaximumDistance(500);
      cam.rotateZ(radians(180));  // rotate around the x-axis passing through the subject
    
      ammonite = loadShape("ammonite.obj");
    
      // important sub function 
      defineHotSpots(); 
    
      fondo = loadImage("fondo.jpg");
      titulo = loadImage("titulo.png");
      titulo2 = loadImage("conociendo.png");
      ammoniteinicio = loadImage("ammoniteparainicio.png");
      almeja = loadImage("almeja.png");
      gestos = loadImage("gestos2.png");
      flecha = loadImage("flecha.png");
    
      buttonX = 0;
      buttonY = 0;
      buttonWidth = 400;
      buttonHeight = 400;
    
      estado = "inicio";
      //almejacerrada = false;
      helvetica = createFont("HelveticaWorld-Regular.ttf", 30);
      nexa = createFont("Nexa Bold.otf", 50);
    
      pg = createGraphics(width, height, P3D);
    
      fondo.resize(width, height);
      image(fondo, width/2, height/2);
    } //func
    
    void draw() {
      if (estado.equals("inicio")) {
        doEstadoInicio();
      }//if
      //  next estado --------
      else if ( estado.equals("modelo")) {
        doEstadoModelo(); // most important
      }//else if
      //  EROR - NO estado - program error  --------
      else {
        println ("--- EROR - NO estado in draw() --- ");
        exit();
        return;
      }//else
    }//func draw()
    
    //------------------------------------------------------------------------
    
    void mousePressed() {
    
      // mouse is pressed
    
      if (estado.equals("inicio")) {
        // start screen
        estado = "modelo";
      } 
      //  next estado  --------
      else if ( estado.equals("modelo")) {
        // estado modelo
        mousePressedParaEstadoModelo();
        //---
      }//else if 
      //  EROR - NO estado
      else {
        println ("---- EROR - NO estado in mousePressed()  --------");
        exit();
        return;
      }//else
    } //func
    
    // ----------------------------------------------------------
    // ----------------------------------------------------------
    // called from setup() 
    
    void defineHotSpots() {
    
      // define the hot spots in parallel arrays
      // the first hot spot is defined in hotSpotsPosition[0] and hotSpotsColor[0] and hotSpotsText[0] and so on
      // positions:
      hotSpotsPosition[0] = new PVector(-15, -20, 5);
      hotSpotsPosition[1] = new PVector(-5, -5, -25);
      hotSpotsPosition[2] = new PVector(-20, -10, 3);
      hotSpotsPosition[3] = new PVector(-30, -10, 20);
      hotSpotsPosition[4] = new PVector(-5, 19, -5);
    
      //colors: colors are not visible but must be unique
      hotSpotsColor[0] = color(255, 0, 0);
      hotSpotsColor[1] = color(100, 0, 0);
      hotSpotsColor[2] = color(110, 0, 0);
      hotSpotsColor[3] = color(120, 0, 0);
      hotSpotsColor[4] = color(160, 0, 0);
    
      // texts
      hotSpotsText[0] = "Embudo";
      hotSpotsText[1] = "Caparazón";
      hotSpotsText[2] = "Ojos";
      hotSpotsText[3] = "Tentáculos";
      hotSpotsText[4] = "Sifón";
    
      //images
      hotSpotsImg[0] = loadImage ("calamares.png");
      hotSpotsImg[1] = loadImage ("tamaños.png");
      hotSpotsImg[2] = loadImage ("estatica.png"); 
      hotSpotsImg[3] = loadImage ("tentaculos.png");
      hotSpotsImg[4] = loadImage ("limitados.png");
    
      //  for (PImage img : hotSpotsImg)
      //     img.resize(200, 0);
    
      // Gifs
      hotSpotsGif[0]  = new Gif(this, "embudoanim.gif");
      hotSpotsGif[1]  = new Gif(this, "caparazonanim.gif");
      hotSpotsGif[2]  = new Gif(this, "ojosanim.gif");
      hotSpotsGif[3]  = new Gif(this, "tentaculosanim.gif");
      hotSpotsGif[4]  = new Gif(this, "sifonanim.gif");
    
      for (Gif g1 : hotSpotsGif) {
        g1.play();
      }
    
      // whether we display the spot left or right
      hotSpotsRightSide[0] = false;
      hotSpotsRightSide[1] = true;
      hotSpotsRightSide[2] = true;
      hotSpotsRightSide[3] = true;
      hotSpotsRightSide[4] = false;
    
      // whether we display the that it's not green
      sphereIsPermanentlyGreen[0] = false;
      sphereIsPermanentlyGreen[1] = false;
      sphereIsPermanentlyGreen[2] = false;
      sphereIsPermanentlyGreen[3] = false;
      sphereIsPermanentlyGreen[4] = false;
    }
    
    // ----------------------------------------------------------
    // called from draw() 
    
    void doEstadoInicio() {
    
      // so the graphic AMMONITE is not cut when rotating
      avoidClipping(); 
    
      //-----------Stopping peasy ------
      cam.beginHUD();
    
      image(fondo, width/2, height/2);
      image(almeja, width-300, height-130, 250, 250);
      fill(0, 50);
      rect(width/2, height/2, width, height);
      fill(0, 30);
      noStroke();
      rect(width/2, 75, width, 150);
      fill(255);
      textFont(nexa);
      text("AMMONITE", width/2, height/6 - 50);
      text("EL ANCESTRO MARINO", width/2, height/6);
      textFont(helvetica);
      text("Toca para comenzar", width/2, height/2 + 300);
      if (gestos!=null)
        image(gestos, width/2 + 400, height/2-100);
    
      cam.endHUD(); //--------------------------------
    
      //----------- AMMONITE ------
      pushMatrix();
      spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
      directionalLight(255, 255, 255, width/2, height/2, 20);
      scale(20);
      shape(ammonite);
      popMatrix();
    }
    
    void doEstadoModelo() {
    
      // so the graphic AMMONITE is not cut when rotating
      avoidClipping();
    
      makeInternalPGraphics();
    
      showBackground(); 
    
      showAmmonite(); 
    
      showTextField(); 
    
      showSpheres();
    }//func
    
    void showBackground() {
    
      // background
    
      cam.beginHUD(); // ----
      image(fondo, width/2, height/2, width, height);
      textFont(nexa);
      fill(0, 40);
      rect(width/2, 75, width, 150);
      fill(255);
      text("CONOCIENDO AL AMMONITE", width/2, height/6 - 50);
      text(countHotSpotsClicked+"/"+ hotSpotsPosition.length, 
        68, 68); 
      if (almejacerrada == true) {
        image(almeja, width-300, height-130, 250, 250);
      }
      almejacerrada = true;
      if (flecha!=null)
        image(flecha, 125, height/6 - 60, 125, 125);
      if (mousePressed && 
        mouseX < 200 && mouseX > 0 && mouseY > 0 && mouseY < 200 && 
        estado.equals("modelo")) {
        estado = "inicio";
      }
      cam.endHUD(); // ----
    }
    
    void showAmmonite() {
      // show Ammonite
      pushMatrix();
      spotLight(255, 255, 255, 80, 20, 40, -1, 0, 0, PI/2, 2);
      directionalLight(255, 255, 255, width/2, height/2, 20);
      scale(20);
      shape(ammonite);
      popMatrix();
    }
    
    void showTextField() {
    
      // text field
    
      if (hotSpotFound==undefined) {
        return;   // quit here
      }
    
      cam.beginHUD(); // ----
    
      if (hotSpotsRightSide[hotSpotFound]) {
        // show rect with text
        // on right side
        pushMatrix();
        //  translate(mousePressedAtX, mousePressedAtY, hotSpotsPosition[hotSpotFound].z);
        translate(mousePressedAtX, mousePressedAtY );
        buttonX=mousePressedAtX;
        buttonY=mousePressedAtY;
        scale(0.5);
        fill(250, 250, 35);
        // rect(mousePressedAtX, mousePressedAtY, 100, 100);
        fill(255);
        textFont(nexa);
        textSize(90);
        //  textMode(SHAPE);
        translate(0, 0, 0);
    
        if (hotSpotsImg[hotSpotFound]!=null) {
          // translate(100+hotSpotsImg[hotSpotFound].width/2, 0, 0);
    
          image(hotSpotsImg[hotSpotFound], 0, 0);
          text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
    
    
          //fill(0, 0, 0, 50);
        }
        popMatrix();
      } else
      {
        // show rect with text
        // on left side
        pushMatrix();
    
        translate(mousePressedAtX, mousePressedAtY );
        buttonX=mousePressedAtX;
        buttonY=mousePressedAtY;
    
        fill(250, 250, 35, 0);
        scale(0.5);
        fill(255);
    
        textFont(nexa);
        textSize(90);
        // textMode(SHAPE);
        translate(0, 0, 0);
    
        if (hotSpotsImg[hotSpotFound]!=null) {
    
          image(hotSpotsImg[hotSpotFound], 0, 0);
          text(hotSpotsText[hotSpotFound], width/2 + 150, -500);
        }
        popMatrix();
      } // else
    
      cam.endHUD(); // ----
    }
    
    void showSpheres() {
    
      // spheres
    
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv = hotSpotsPosition[i];
    
        pushMatrix();
        translate(pv.x, pv.y, pv.z);
    
        if (i==hotSpotFound || sphereIsPermanentlyGreen[i]) {
          fill(2, 255, 100, 70); // highlight
        } else {
          fill(255, 70); // normal
        }
        sphere(4);
    
        popMatrix();
      }//for
    }//func
    
    // ----------------------------------------------------------
    // called from mousePressed() 
    
    void mousePressedParaEstadoModelo() {
      //
      mousePressedAtX = width/2 - 450;
      mousePressedAtY = height/2;
      //
      color colorFromMouse = pg.get(mouseX, mouseY);
      int oldHotSpotFound=hotSpotFound; 
    
      // hotSpotFound=undefined; // reset // ??????
    
      for (int i=0; i<hotSpotsPosition.length; i++) {
    
        // found a sphere? 
        if (colorFromMouse==hotSpotsColor[i]) {
          // Yes, we found a sphere that has been clicked on
          // Is the sphere the current one? 
          if (i==oldHotSpotFound) {
            hotSpotFound=undefined; // reset (off)
          } else {
            // set sphere ON
            // Do we need to count it?  
            if (!sphereIsPermanentlyGreen[i]) { 
              countHotSpotsClicked++; // yes
            }
            // mark as permanently green 
            sphereIsPermanentlyGreen[i] = true;
            // set current index hotSpotFound to i 
            hotSpotFound=i; // set current
          }
          break;
        } 
    
        if (hotSpotFound!=undefined) { // ??????
          hotSpotFound = undefined;
        }
      }//for
    }//func 
    
    // ---------------------------------------------------------------
    // Minor functions 
    
    void makeInternalPGraphics() {
      pg.beginDraw();
      pg. perspective(PI/3.0, (float) width/height, 1, 1000000);
      pg.setMatrix(getMatrix()); // replace the PGraphics-matrix
      pg.background(0);
      pg.noLights();
      for (int i=0; i<hotSpotsPosition.length; i++) {
        PVector pv=hotSpotsPosition[i];
        pg.pushMatrix();
        pg.translate(pv.x, pv.y, pv.z);
        pg.noStroke();
        pg.fill(hotSpotsColor[i]);
        pg.sphere(4);
        pg.popMatrix();
      }//for
      pg.endDraw();
    }//func
    
    void avoidClipping() {
      // avoid clipping :
      // https : // // forum.processing.org/two/discussion/4128/quick-q-how-close-is-too-close-why-when-do-3d-objects-disappear
      perspective(PI/3.0, (float) width/height, 1, 1000000);
    }//func
    //
    
  • edited November 2017

    Three remarks:

    One sphere is hidden?

    you know, you have 5 hot spots but honestly I can see only 4.

    Number 2 is almost hidden behind the eyes.

    to test this, instead of using the sphere output, use this:

        if (i==2)
          fill(255, 2, 2); 
        sphere(6);
    
        popMatrix();
    

    move its position further out maybe.

    Reset sphere counter

    Use this by the way to reset countHotSpotsClicked and remove green from all spheres:

    //-----------------------------------------------------------
    
    void keyPressed() {
      switch(key) {
    
      case ' ':
        // reset 
        countHotSpotsClicked = 0;
        for (int i=0; i<hotSpotIsPermanentlyGreen.length; i++) { 
          hotSpotIsPermanentlyGreen[i] = false;
        }
        break; 
    
      default:
        break;
      }//switch
    }//dfunc 
    
    // ----------------------------------------------------------
    

    Your text and images

    I have to say when an image is open, it's hard to see.

    It has another light or shadow depending of the rotation position of the sphere also.

    I suggest you say noLights(); before drawing text and image here.

    You might even make a filled rect behind the image and text to make it better readable.

    Chrisir

  • One sphere is hidden?

    I mean the red sphere, it's normally much smaller and hard to see:

    Unbenannt

  • Wow Chris, that code is awesome!! It's just what I was looking for, you're amazing!!!

    Thanks a lot!!! I really really appreciate your effort!

    Thanks, I'm gonna read it to understand perfectly what you have done, thanks!!!

  • edited November 2017

    Now, let's see.

    do you mind uploading your entire project again?

    if (countHotSpotsClicked == 5)

    you could bring in an extra text or button

Sign In or Register to comment.