2013-03-09 79 views
1

我遇到了一个问题,将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; 
     } 
    } 
    } 
} 

回答

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

更新

解释在foreach版本在此代码中使用“为” 。

+0

我真的很感谢你的回答。你的代码比我的代码更干净,更高效。也就是说,我一直致力于扩展项目以添加功能(并最终将逻辑整合到文字游戏中),并且无法解释某些代码。我不熟悉你正在使用的一些语法,如带有四个参数的for循环(int),(Line l:lines)和其他各种东西。我很抱歉缺乏编程经验,并想知道是否有办法尽可能多地使用我的(坏)代码来解决我的问题? – Brannon 2013-03-12 22:14:14

+1

这是标准的java /处理语法,所以我可以肯定地解释你不理解的部分。从Java 1.5开始(很久以前=现在= QU),有两种方法可以循环。第一个是for(int i = 0; i 2013-03-13 12:28:26