Кликабельная трехмерная фигура с использованием функции pushmatrix () для отображения сообщения? - PullRequest
0 голосов
/ 10 апреля 2020

Здравствуйте, я хотел бы знать, как я могу сделать так, чтобы мои 3D-бары отображали сообщение каждый раз, когда на него нажимали.

Например, у меня есть 3D-баров на 2D-изображении, и когда я наводил курсор на и нажмите его один раз, когда оно должно отобразить сообщение на том же экране, и если я щелкну на нем еще раз, сообщение исчезнет.

Мой код:

boolean drawText = false;

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

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

pushMatrix();
fill(204, 0, 0, 151);
translate(42, 75, 0);
box (5, 5, 10);
if(dist(mouseX,mouseY,27,-22)<0){
cursor(HAND);
} else {
cursor(ARROW);
}
if (drawText) {
fill(#FFFF00);
text("Hi!", 27, -22);
}
popMatrix(); 

pushMatrix();
fill(204, 0, 0, 151);
translate(42, 75, 0);
box (5, 5, 10);
popMatrix(); 

}
void mousePressed() {
if (mouseButton == LEFT && dist(mouseX,mouseY,27,-22)<0) {
drawText = drawText ? false : true;
}
}

Я хотел бы знать, если у меня есть более чем одна 3D-фигура, как бы я создал кнопку, используя mousePressed(), чтобы позволить мне использовать левую кнопку при нажатии на форму. Кроме того, так как я использую функцию pushMatrix(), все еще возможно ли это для работы?

1 Ответ

0 голосов
/ 10 апреля 2020

Прежде всего, я рекомендую сделать отступ в вашем коде (Ctrl + T в Windows / Linux, CMD+T в OSX работает за вас). Это делает ваш код намного проще для чтения / сканирования.

В долгосрочной перспективе вы поймете, что тратите больше времени на чтение / отладку кода, чем на фактический набор текста, поэтому я настоятельно рекомендую делать все, что облегчит вашу жизнь:)

Из того, что я понял в вашем коде, похоже, что вы запутались в координатах и ​​системах координат. Пожалуйста, ознакомьтесь с учебниками Системы координат и 2D трансформация

Я говорю это потому, что вы рисуете оба блока друг над другом в координатах 42, 75. Кроме того, вы проверяете расстояние между координатами мыши и 27,-22 (где вы также рисуете текст. Кстати, расстояние никогда не будет < 0.

Для отладки вашей программы неплохо ее сломать вплоть до разделов и тестируем по одному за раз. Лично я пишу минимальный набросок, чтобы проверить предположения, прежде чем воплощать их в большую программу.

Например, опровергнуть dist() < 0 легко с минимальным наброском теста. Новый эскиз, вставьте следующее и запустите:

void draw(){
  background(255);
  line(50,50,mouseX,mouseY);
  fill(0);
  text("x:"+mouseX+",y:"+mouseY + "\nd:" + dist(mouseX,mouseY,50,50),mouseX,mouseY);
}

Еще одна вещь, о которой следует помнить, это то, что вы будете использовать глобальные координаты при проверке границ 2D-экрана вокруг блоков, а не относительные координаты (смещение с помощью translate() ).

Вот измененная версия вашего эскиза с использованием dist():

boolean drawText = false;

float radius = 22.5;
float diameter = radius * 2;

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

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

  pushMatrix();
  // visualise radius
  fill(255,30);

  ellipse(44, 80, diameter, diameter);
  ellipse(108, 80, diameter, diameter);

  fill(204, 0, 0, 151);
  translate(42, 75, 0);
  box (50, 50, 10);

  if(isOver(mouseX, mouseY, 44, 80, radius) ||
     isOver(mouseX, mouseY, 108, 80, radius)) {
    cursor(HAND);
  } else {
    cursor(ARROW);
  }
  if (drawText) {
    fill(#FFFF00);
    text("Hi!", 27, -22);
  }
  popMatrix(); 

  pushMatrix();
  fill(35, 198, 13, 151);
  translate(110, 75, 0);
  box (50, 50, 10);
  popMatrix();
}

void mousePressed() {
  if (mouseButton == LEFT) {

    if(isOver(mouseX, mouseY, 44, 80, radius) ||
       isOver(mouseX, mouseY, 108, 80, radius)) {

      drawText = !drawText;

     }
  }
}

boolean isOver(int mx, int my, float x, float y, float radius){
  return dist(mx,my,x,y) < radius;
}

Не берите в голову, я использую несколько ярлыков:

  • drawText = drawText ? false : true; аналогично drawText = !drawText; с использованием логическое НЕ )
  • функция isOver() аналогична функции примера overCircle() кнопки, однако она просто возвращает s логическое значение (с использованием < в качестве условного оператора)

Также обратите внимание на круги, нарисованные рядом с полями, которые действуют как активные области кнопки, и то, как курсор не изменяется по углам рамки. Радиус можно настроить так, чтобы он охватывал больше ящиков, однако из-за формы эллипса активная область пропустит углы или go по сторонам. Другое предположение, что если у вас будет много кнопок с прямоугольниками, например, dist(), может стать медленным (поскольку он использует sqrt() за кулисами).

В частности, я рекомендую что-то вроде функции overRect() из примера Button: прямоугольник будет лучше соответствовать форме 3D-прямоугольника в этой ориентации и будет быстрее вычислять:

boolean drawText = false;

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

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

  pushMatrix();
  fill(204, 0, 0, 151);
  translate(42, 75, 0);
  box (50, 50, 10);

  if(isOver(mouseX, mouseY, 13, 47, 57, 57) ||
     isOver(mouseX, mouseY, 82, 47, 57, 57)) {
    cursor(HAND);
  } else {
    cursor(ARROW);
  }
  if (drawText) {
    fill(#FFFF00);
    text("Hi!", 24, -38);
  }
  popMatrix(); 

  pushMatrix();
  fill(35, 198, 13, 151);
  translate(110, 75, 0);
  box (50, 50, 10);
  popMatrix();
}

void mousePressed() {
  if (mouseButton == LEFT) {
    if(isOver(mouseX, mouseY, 13, 47, 57, 57) ||
       isOver(mouseX, mouseY, 82, 47, 57, 57)) {

      drawText = !drawText;

     }
  }
}

boolean isOver(int mx, int my, int x, int y, int w, int h){
  return ((mx >= x && mx <= x + w) &&
          (my >= y && my <= y + h));
}

В качестве улучшения вы можете создать переменные в верхней части эскиза для глобальной 2D-рамки каждой кнопки x, y, ширины и высоты, чтобы их можно было легко использовать повторно вместо использования значений константы, скопированных или вставленных. Преимущество состоит в том, что это сделает код более гибким: проще изменить положение кнопки, размер и т. Д. c.

Если вы не уверены в функциях и возвращаемых значениях, я рекомендую учебники по функциям Дэниела Шиффмана:

  1. 7.2: основы функций - учебное пособие по обработке
  2. 7.3: модульность с функциями - учебное пособие по обработке
  3. 7.4: возможность повторного использования с функциями - учебник по обработке
...