拖动处理中的对象 [英] dragging objects in processing

查看:150
本文介绍了拖动处理中的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个实施Daniel Shiffman令人敬畏的拖拉示例进入我的素描。我曾经使用它,这是伟大的,但是我试图用一些幻想循环应用到多个对象(在这种情况下,文本),但无济于事。一切正常工作除了对象不拖动时,他们应该。从逻辑上讲,这是因为 Line 类中的offsetX和offsetY属性继续更新,因此强制对象保持静止。我相信有一个解决方案,但我无法弄清楚。也许我一直在盯着它太久了。我非常感谢帮助!

  String [] doc; //每个文本文件行的字符串数组
int tSize; //文字大小
浮动宽松; //缓动
int boundaryOverlap; //单词重叠边的值
PFont字体; //字体
线条线;
布尔值clicked = false;

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

boundaryOverlap = 20; //单词重叠边的值
tSize = 32; //文本大小

//载入和格式化文本
doc = loadStrings(text.txt);
font = loadFont(Times-Roman-48.vlw);
textFont(font,tSize);

//线对象
lines = new Lines(doc);

//填充xAddition和yAddition数组
lines.populateArrays();
}

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

//循环遍历.txt中的每一行
for(int i = 0; i <= doc.length-1; i ++){
if(clicked)lines .clicked(ⅰ);
lines.move(我,点击); //更新doc [i]位置//删除
lines.display(i); //为text.txt中的每行文本绘制文本
}
}

void mousePressed(){
clicked = true;
}

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

$ / code $ / pre
$ b $ p

这是行类:

  class Lines {
//类属性
float [] x; //保存随机值的数组添加到x的位置
float [] y; //保存随机值的数组被添加到y以进行放置
float offsetX;
float offsetY;
String [] doc;

布尔dragging = false; //布尔值用于拖拽

//构造
Lines(String [] tempDoc){
doc = tempDoc;


//填充x和y数组
void populateArrays(){
x = new float [doc.length];
y = new float [doc.length];

//填充x和y数组
(int i = 0; i< = doc.length-1; i ++){
x [i] = int(random (0-boundaryOverlap,width-boundaryOverlap));
y [i] = int(random(0,height-boundaryOverlap));


$ b //绘制文本
void display(int i){
text(doc [i],x [i],y [一世]); //添加文本
if(addition [i]!= null)text(addition [i],x [i],y [i] +20);


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



//更新文本位置
void move(int i,boolean clicked){

// if mouseOver text悬停灰色
if(mouseX> x [i]&&
mouseX< x [i] + textWidth(doc [i])&&
mouseY< y [i]&&
mouseY> y [i] -tSize){

fill(100); //灰色文本填充

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

}

else {
fill(0); //如果文本不是mouseOver,填充是黑色的
dragging = false;


$ b //删除
void delete(int i){
//如果按下delete
if( (key == 8){
doc [i] =; // doc [空行的字符串]被替换为null
keyCode = 1;



$ b $ / code $ / pre

解决方案首先,不要使用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(我,点击); //更新doc [i]位置//删除
lines.display(i); //在text.txt中为每行文本绘制文本
}

点击,如果是的话,将该行标记为单击。然后你完全忽视这一点,并移动所有的行,而不看点击状态(它根本不用在移动函数中)。

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

pre $ LineCollection行;
float textSize;

void setup(){
size(400,400);
//修正文字大小,参考一个真实的字体
textSize = 32;
textFont(createFont(Times New Roman,textSize));
//解析字符串,构造行容器
String [] textValues = new String [] {lol,cat};
lines = new LineCollection(textValues);
//不要循环!只在事件保证时更新,
//基于redraw()调用
noLoop();

//通过绘图
绘制void draw(){background(255); lines.draw(); }
//通过事件处理来处理$ b $ void mouseMoved(){lines.mouseMoved(mouseX,mouseY);重绘(); }
void mousePressed(){lines.mousePressed(mouseX,mouseY);重绘(); }
void mouseDragged(){lines.mouseDragged(mouseX,mouseY);重绘(); }
void mouseReleased(){lines.mouseReleased(mouseX,mouseY);重绘(); }


/ **
*线的集合。这只是*一个收藏,
*它只是负责传递事件。
* /
class LineCollection {
Line [] lines;
int boundaryOverlap = 20;

//构造
LineCollection(String [] strings){
lines = new Line [strings.length];
int x,y;
for(int i = 0,last = strings.length; i x =(int)random(0,width);
y =(int)random(0,height);
lines [i] = new Line(strings [i],x,y);



//通过绘图
void draw(){

//因为我们不关心计数元素
//在我们的行容器中,我们使用for循环的foreach
//版本。这与
//相同。(int i = 0; i // Line l = lines [i];
// [ ...在这里使用...]
//}
//除了我们不需要手动解包我们的列表。

(Line l:lines){l.draw(); }
}

//通过事件处理来处理$ b $ void mouseMoved(int mx,int my){for(Line l:lines){l.mouseMoved(mx,my) ; }} $ b $ void mousePressed(int mx,int my){for(Line l:lines){l.mousePressed(mx,my); }} $ b $ 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); }}

$ b $ **
$个人行
* /
class行{
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);
}

返回(x <= mx& mx< = x + w& y < = my&& my< = y + h);
}

//鼠标移动:光标在这行吗?
//如果是这样,改变填充颜色
void mouseMoved(int mx,int my){
active = over(mx,my);
fillColor =(active?color(155,155,0):0);
}

//鼠标按下:我们是否活动?那么
//标记我们开始点击的位置,所以
//我们可以对
//鼠标拖动进行偏移计算。
void mousePressed(int mx,int my){
if(active){
cx = mx;
cy = my;
ox = 0;
oy = 0;



//鼠标点击拖动:如果我们处于活动状态,
//根据
/ /最初
//点击的位置和鼠标现在的位置之间的距离。
void mouseDragged(int mx,int my){
if(active){
ox = mx-cx;
oy = my-cy;



//鼠标释放:如果我们处于活动状态,
//提交此行
//位置的偏移量。另外,无论
//我们是否活跃,现在都不是。
void mouseReleased(int mx,int my){
if(active){
x + = mx-cx;
y + = my-cy;
ox = 0;
oy = 0;
}
active = false;


$ / code $ / pre
$ b

更新



解释了这个代码中使用的foreach版本。


I am having an issue implementing Daniel Shiffman's awesome dragging example into my sketch. I have used it before and it is great, however I am attempting to use it with some "fancy" for looping to apply it to multiple objects(in this case text) but to no avail. Everything works correctly except for the objects don't drag when they should. Logically, this makes since because the offsetX and offsetY properties in the Line class continue to update thus forcing the object to remain stationary. I am sure that there is a solution but I can't figure it out. Perhaps I have been staring at it for too long. I really appreciate the help!

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;
}

Here is the line class:

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;
      }
    }
  }
}

解决方案

First off, don't use vlw fonts. There is literally no reason to use a bitmap image file when everyone has Times New Roman installed. Just use createFont("Times New Roman",48). Now you can even change the textsize without it looking horrible because you just loaded the font, not a bitmap image.

That said, this code isn't really all that good... but working with it, the problem is here:

  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
  }

You check for clicked, and if so, mark the line as clicked. Then you completely disregard that and move all the lines, without looking at the "clicked" state (it is not used in the move function at all).

That said, what you're trying to do can be done much better, and much cleaner:

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;
  }
}

update

Explained the foreach version of "for" used in this code.

这篇关于拖动处理中的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆