Прежде всего, я рекомендую сделать отступ в вашем коде (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.
Если вы не уверены в функциях и возвращаемых значениях, я рекомендую учебники по функциям Дэниела Шиффмана:
- 7.2: основы функций - учебное пособие по обработке
- 7.3: модульность с функциями - учебное пособие по обработке
- 7.4: возможность повторного использования с функциями - учебник по обработке