使用 pushmatrix() 函数显示消息的可点击 3d 形状?
Clickable 3d shape using pushmatrix() function to show a message?
你好,我想知道如何让我的 3D 条在每次点击时显示一条消息。
例如,我在 2D 图像上有一个 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 (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()
函数,它仍然可以工作吗?
首先,我建议缩进您的代码(Windows/Linux 上的 Ctrl + T
、OSX 上的 CMD+T
会为您完成这项工作)。这使您的代码更易于阅读/快速扫描。
在漫长的 运行 中,您会发现花在 reading/debugging 代码上的时间比实际打字还多,所以我强烈建议您做任何让您的生活更轻松的事情:)
根据我在您的代码中收集到的信息,您似乎对坐标和坐标系感到困惑。请查看 Coordinate Systems and 2D Transformation 教程
我这么说是因为您在坐标 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;
与使用 logical NOT) 的 drawText = !drawText;
相同
isOver()
函数类似于按钮示例 overCircle()
函数,但是它只是 return 一个布尔值(使用 <
作为条件运算符)
另请注意在用作按钮活动区域的方框附近绘制的圆圈,以及光标如何在方框角周围不发生变化。可以调整半径使其覆盖更多的框,但是由于椭圆的形状,活动区域将错过角落或越过侧面。另一个考虑是,如果您有许多框按钮,例如 dist()
可能会变慢(因为它在幕后使用 sqrt()
)。
我特别推荐 Button 示例中的 overRect()
函数:矩形将更好地适应该方向的 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、宽度和高度创建变量,以便轻松重复使用,而不是使用 copy/pasted 常量值。优点是它会使代码更灵活:更容易更改按钮位置、大小等。
如果您对函数和 return 值感到困惑,我推荐 Daniel Shiffman 的函数教程:
你好,我想知道如何让我的 3D 条在每次点击时显示一条消息。
例如,我在 2D 图像上有一个 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 (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()
函数,它仍然可以工作吗?
首先,我建议缩进您的代码(Windows/Linux 上的 Ctrl + T
、OSX 上的 CMD+T
会为您完成这项工作)。这使您的代码更易于阅读/快速扫描。
在漫长的 运行 中,您会发现花在 reading/debugging 代码上的时间比实际打字还多,所以我强烈建议您做任何让您的生活更轻松的事情:)
根据我在您的代码中收集到的信息,您似乎对坐标和坐标系感到困惑。请查看 Coordinate Systems and 2D Transformation 教程
我这么说是因为您在坐标 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;
与使用 logical NOT) 的 isOver()
函数类似于按钮示例overCircle()
函数,但是它只是 return 一个布尔值(使用<
作为条件运算符)
drawText = !drawText;
相同
另请注意在用作按钮活动区域的方框附近绘制的圆圈,以及光标如何在方框角周围不发生变化。可以调整半径使其覆盖更多的框,但是由于椭圆的形状,活动区域将错过角落或越过侧面。另一个考虑是,如果您有许多框按钮,例如 dist()
可能会变慢(因为它在幕后使用 sqrt()
)。
我特别推荐 Button 示例中的 overRect()
函数:矩形将更好地适应该方向的 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、宽度和高度创建变量,以便轻松重复使用,而不是使用 copy/pasted 常量值。优点是它会使代码更灵活:更容易更改按钮位置、大小等。
如果您对函数和 return 值感到困惑,我推荐 Daniel Shiffman 的函数教程: