【问题标题】:dragging objects in processing在处理中拖动对象
【发布时间】:2013-02-24 16:33:10
【问题描述】:

我在实现 Daniel Shiffman 将example 拖入我的草图时遇到了问题。我以前用过它,它很棒,但是我试图用一些“花哨的”循环将它应用到多个对象(在本例中为文本),但无济于事。除了对象不应该拖动之外,一切都正常工作。从逻辑上讲,这是因为 Line 类中的 offsetX 和 offsetY 属性继续更新,从而迫使对象保持静止。我确信有一个解决方案,但我无法弄清楚。也许我已经盯着它太久了。非常感谢您的帮助!

String[] doc; //array of Strings from each text documents line
int tSize; //text size
float easing; //easing
int boundaryOverlap; //value for words to overlap edges by
PFont font; //font
Lines lines;
boolean clicked = false;

void setup(){
  size(displayWidth/2,displayHeight); 
  background(255);
  fill(0);

  boundaryOverlap = 20; //value for words to overlap edges by
  tSize = 32; //text size

  //loads and formats text
  doc = loadStrings("text.txt"); 
  font = loadFont("Times-Roman-48.vlw");
  textFont(font, tSize);

  //lines object
  lines = new Lines(doc);

  //populate xAddition and yAddition arrays
  lines.populateArrays();
}

void draw(){
  background(255);
  fill(0);

  //loops through each line in .txt
  for(int i = 0; i <= doc.length-1; i++){
    if(clicked) lines.clicked(i);
    lines.move(i, clicked); //update doc[i] positions //deletes 
    lines.display(i); //draws text for each line of text in text.txt
   }
}

void mousePressed(){
   clicked = true;
}

void mouseReleased(){
   clicked = false; 
   lines.dragging = false;
}

这里是线类:

class Lines{
  //class properties
  float[] x; //array holding random values to be added to x for placement
  float[] y; //array holding random values to be added to y for placement
  float offsetX;
  float offsetY;
  String[] doc;

  boolean dragging = false; //boolean for dragging

  //construct
  Lines(String[] tempDoc){
    doc = tempDoc;
  }

  //fills x and y arrays
  void populateArrays(){
    x = new float[doc.length];
    y = new float[doc.length];

    //populates x and y arrays
    for(int i = 0; i <= doc.length-1; i++){   
      x[i] = int(random(0-boundaryOverlap, width-boundaryOverlap));
      y[i] = int(random(0, height-boundaryOverlap));
      }
  }

  //draws text
  void display(int i){
       text(doc[i], x[i], y[i]); //draw text
       //if(addition[i] != null) text(addition[i], x[i], y[i]+20);
  }


  void clicked(int i){
    if(mouseX > x[i] &&
       mouseX < x[i]+textWidth(doc[i]) &&
       mouseY < y[i] &&
       mouseY > y[i]-tSize){
       dragging = true;
       offsetX = x[i] - mouseX;
       offsetY = y[i] - mouseY;  
    }
  }

  //updates text positions
  void move(int i, boolean clicked){

       //if mouseOver text hover gray
       if( mouseX > x[i] &&
       mouseX < x[i]+textWidth(doc[i]) &&
       mouseY < y[i] &&
       mouseY > y[i]-tSize){

         fill(100); //gray text fill

         if(dragging){
           x[i] = mouseX + offsetX;
           y[i] = mouseY + offsetY;
         }

       }

       else{
         fill(0); //if not text not mouseOver fill is black
         dragging = false;
       }
  }

  //delete 
  void delete(int i){
    //if "delete" is pressed 
    if (keyPressed){
      if(key == 8){
        doc[i] = ""; // doc[line String that is being hovered over] is replaced with null
        keyCode = 1;
      }
    }
  }
}

【问题讨论】:

    标签: for-loop draggable drag processing offset


    【解决方案1】:

    首先,不要使用 vlw 字体。当每个人都安装了 Times New Roman 时,实际上没有理由使用位图图像文件。只需使用 createFont("Times New Roman",48)。现在您甚至可以更改文本大小而不会看起来很糟糕,因为您只是加载了字体,而不是位图图像。

    也就是说,这段代码并不是真的那么好......但是使用它,问题就在这里:

      for(int i = 0; i <= doc.length-1; i++){
        if(clicked) lines.clicked(i);
        lines.move(i, clicked); //update doc[i] positions //deletes 
        lines.display(i); //draws text for each line of text in text.txt
      }
    

    您检查是否已单击,如果是,则将该行标记为已单击。然后你完全无视这一点并移动所有行,而不查看“点击”状态(它根本不用于移动功能)。

    也就是说,你想要做的事情可以做得更好,更干净:

    LineCollection lines;
    float textSize;
    
    void setup(){
      size(400,400);
      // fix the text size, reference a real font
      textSize = 32; 
      textFont(createFont("Times New Roman", textSize));
      // parse strings, construct Lines container
      String[] textValues = new String[]{"lol","cat"};
      lines = new LineCollection(textValues);
      // Do not loop! only update when events warrant,
      // based on redraw() calls  
      noLoop();
    }
    // fall through drawing
    void draw() { background(255); lines.draw(); }
    // fall through event handling
    void mouseMoved() { lines.mouseMoved(mouseX,mouseY); redraw(); }
    void mousePressed() { lines.mousePressed(mouseX,mouseY); redraw(); }
    void mouseDragged() { lines.mouseDragged(mouseX,mouseY); redraw(); }
    void mouseReleased() { lines.mouseReleased(mouseX,mouseY); redraw(); }
    
    
    /**
     * A collection of lines. This is *only* a collecton,
     * it is simply responsible for passing along events.
     */
    class LineCollection {
      Line[] lines;
      int boundaryOverlap = 20;
    
      // construct
      LineCollection(String[] strings){
        lines = new Line[strings.length];
        int x, y;
        for(int i=0, last=strings.length; i<last; i++) {
          x = (int) random(0, width);
          y = (int) random(0, height);
          lines[i] = new Line(strings[i], x, y);   
        }
      }
    
      // fall through drawing   
      void draw() {
    
        // since we don't care about counting elements
        // in our "lines" container, we use the "foreach"
        // version of the for loop. This is identical to
        // "for(int i=0; i<lines.size(); i++) {
        //    Line l = lines[i];
        //    [... use l here ...]
        //  }"
        // except we don't have to unpack our list manually.
    
        for(Line l: lines) { l.draw(); }
      }
    
      // fall through event handling
      void mouseMoved(int mx, int my) { for(Line l: lines) { l.mouseMoved(mx,my); }} 
      void mousePressed(int mx, int my) { for(Line l: lines) { l.mousePressed(mx,my); }} 
      void mouseDragged(int mx, int my) { for(Line l: lines) { l.mouseDragged(mx,my); }}
      void mouseReleased(int mx, int my) { for(Line l: lines) { l.mouseReleased(mx,my); }}
    }
    
    /**
     * Individual lines
     */
    class Line {
      String s;
      float x, y, w, h;
      boolean active;
      color fillColor = 0;
      int cx, cy, ox=0, oy=0;
    
      public Line(String _s, int _x, int _y) {
        s = _s;
        x = _x;
        y = _y;
        w = textWidth(s);
        h = textSize;
      }
    
      void draw() {
        fill(fillColor);
        text(s,ox+x,oy+y+h);
      }
    
      boolean over(int mx, int my) {
        return (x <= mx && mx <= x+w && y <= my && my <= y+h);
      }
    
      // Mouse moved: is the cursor over this line?
      // if so, change the fill color
      void mouseMoved(int mx, int my) {
        active = over(mx,my);
        fillColor = (active ? color(155,155,0) : 0);
      }
    
      // Mouse pressed: are we active? then
      // mark where we started clicking, so 
      // we can do offset computation on
      // mouse dragging.
      void mousePressed(int mx, int my) {
        if(active) {
          cx = mx;
          cy = my;
          ox = 0;
          oy = 0; 
        }
      }
    
      // Mouse click-dragged: if we're active,
      // change the draw offset, based on the
      // distance between where we initially
      // clicked, and where the mouse is now.
      void mouseDragged(int mx, int my) {
        if(active) {
          ox = mx-cx;
          oy = my-cy;
        }
      }
    
      // Mouse released: if we're active,
      // commit the offset to this line's
      // position. Also, regardless of
      // whether we're active, now we're not.  
      void mouseReleased(int mx, int my) {
        if(active) {
          x += mx-cx;
          y += my-cy;
          ox = 0;
          oy = 0;
        }
        active = false;
      }
    }
    

    更新

    解释了此代码中使用的“for”的 foreach 版本。

    【讨论】:

    • 非常感谢您的回答。你的代码比我的更干净、更高效。也就是说,我一直在努力扩展项目以添加功能(并最终将逻辑合并到文字游戏中)并且在解释某些代码时遇到了麻烦。我不熟悉您使用的一些语法,例如带有四个参数的 for 循环、(int)、for(Line l:lines) 和其他各种东西。我为我缺乏编程经验而道歉,并想知道是否有办法使用尽可能多的(坏)代码来解决我的问题?
    • 这是标准的 java/Processing 语法,所以我当然可以解释您不理解的部分。从 java 1.5 开始(很久以前现在 =D),有两种循环方式。第一个是 for(int i=0; i
    猜你喜欢
    • 2014-01-10
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多