【问题标题】:How to specifically color one rect when it's hovered over?悬停在一个矩形上时如何专门为它着色?
【发布时间】:2017-09-07 11:21:13
【问题描述】:

当鼠标悬停在单个矩形上时,如何为它着色?下面使用的具体方法真的没有给我任何关于如何解决这个问题的想法。它使用单个矩形在窗口中生成一个网格。如何在不中断代码的情况下监听mouseXmouseY 并为一个矩形着色?谢谢。

int cols,rows;
int scl = 20;
int gridsize = 0;

void setup(){
size(400,400);
int w = 400;
int h = 400;
cols = w / scl;
rows = h / scl;

}

void draw() {
//mouseX, mouseY
background(r,g,b);

for (int x = 0; x < cols; x++){
  for (int y = 0; y < rows; y++){
  stroke(55);
  //noFill();
  fill(50,50,50);
  rect(x*scl,y*scl,scl,scl);
    }
  }
}

作为参考,我正在使用 Processing 3 for Java。

【问题讨论】:

    标签: java processing onhover


    【解决方案1】:

    您可以随时检查鼠标是否在矩形范围内:

    • 你知道 mouseX,mouseY 的值
    • 您知道每个框的 x、y 和大小
    • 如果 mouseX 在 x 和 x+size 范围内,而 mouseY 在 y 和 y+size 范围内,则表示您在一个盒子上方。

    这是适用于您的代码的上述内容(如果条件格式化以便于查看,请随时重新格式化):

    int cols, rows;
    int scl = 20;
    int gridsize = 0;
    
    void setup() {
      size(400, 400);
      int w = 400;
      int h = 400;
      cols = w / scl;
      rows = h / scl;
    }
    
    void draw() {
      //mouseX, mouseY
      background(255);
    
      for (int x = 0; x < cols; x++) {
        for (int y = 0; y < rows; y++) {
          int xpos = x*scl;
          int ypos = y*scl;
          stroke(55);
          if(
            (mouseX >= xpos && mouseX <= xpos+scl) &&
            (mouseY >= ypos && mouseY <= ypos+scl)
            ){
            fill(90);
          }else{
            fill(50);
          }
    
          rect(xpos, ypos, scl, scl);
        }
      }
    }
    

    欲了解更多信息,请查看Processing Button example

    【讨论】:

    • 感谢您花时间为我解决这个问题,我真的很感激。完全按照我的意愿工作!
    【解决方案2】:

    George's answer 在这种情况下工作得很好,但是如果可能想在这里使用面向对象,还有另一种更复杂的方法。对于这个小例子,您可以有一个 Grid 类,它保存和管理一组 Cell 对象。或者你可以跳过Grid 类并在你的主草图中管理Cells。你可以给Cell 类一个函数来渲染它自己,你也可以给每个单元格一个颜色和一个大小,这完全取决于你。此外,它可能具有告诉您鼠标是否在其上方的功能以及更改其颜色的功能。骨架看起来像这样:

    class Cell {
    
    float x,y;
    float length, breadth;
    color col;
    
    Cell(float x, float y) {
        this.x = x;
        this.y = y;
    
        length = 10;
        breadth = 10;
        col = color(0);
    }
    
    void render() {
        fill(col);
        rect(x, y, length, breadth);
    }
    
    void setColor(color col) {
        this.col = col;
    }
    
    boolean mouseOver() {
        if(mouseX > x && mouseX < x+length) {
            if(mouseY > y && mouseY < y+breadth) {
                return true;
            }
        }
        return false;
    }
    

    现在您可以在主草图中使用该类及其方法来找到鼠标悬停在其上的单元格并在其上调用setColor 以更改其颜色。

    【讨论】:

    • 扩展的 OOP 选项很棒 (+1),但是一旦了解了基础知识,我认为问题就出在问题上。封装很棒,但逻辑是基础。从理论上讲,PShape's contains() 在封装方面可能也有帮助,但隐藏了检查背后的逻辑。
    【解决方案3】:

    乔治的回答是正确的。我赞成它,我相信您应该将其标记为正确答案。御史的回答基本上就是乔治的回答,搬进了班级。

    它们都使用点-矩形碰撞检测,检查点是否在矩形内。您只需根据点检查每个矩形(在您的情况下是鼠标位置),这样您就可以确定鼠标所在的矩形。即使您有一堆不同形状的矩形,这也可以工作,甚至可以使用重叠的矩形。

    另一种方法是使用基于网格的碰撞检测,它利用了你有一堆不重叠的均匀间隔的矩形这一事实。您只需使用除法来确定鼠标所在的单元格,然后将该单元格转换为坐标,然后使用这些坐标绘制矩形。这可能听起来令人困惑,但它看起来像这样:

    int cols;
    int rows;
    int scl = 20;
    
    void setup() {
      size(400, 400);
      cols = width / scl;
      rows = height / scl;
    }
    
    void draw() {
      background(100);
    
      for (int x = 0; x < cols; x++) {
        for (int y = 0; y < rows; y++) {
          stroke(55);
          fill(50, 50, 50);
          rect(x*scl, y*scl, scl, scl);
        }
      }
    
      int hoveredRectColX = int(mouseX / scl);
      int hoveredRectRowY = int(mouseY / scl);
      float rectX = hoveredRectColX * scl;
      float rectY = hoveredRectRowY * scl;
      fill(255, 0, 0);
      rect(rectX, rectY, scl, scl);
    }
    

    最后一段代码是肉和土豆。首先它计算出鼠标在哪一行和哪一列,然后计算出那个单元格的位置,并用它来绘制一个矩形。如果这没有意义,你能做的最好的事情就是拿出一张纸和一支铅笔,画一堆例子,看看发生了什么。

    无耻的自我推销:我在Processing中写了一个碰撞检测教程,包括点矩形和基于网格的碰撞检测,可here

    【讨论】:

    • 我在那里错过了一个节拍:降低“分辨率”在计算上比 5 次检查重复行*列次数要便宜得多。好一个! (+1)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 2012-03-01
    • 2011-11-09
    相关资源
    最近更新 更多