2013-03-09 2 views
1

У меня возникла проблема с потрясающим перетаскиванием Даниэля Шиффмана example в мой эскиз. Я использовал его раньше, и это здорово, однако я пытаюсь использовать его с некоторыми «причудливыми» циклами, чтобы применить его к нескольким объектам (в данном случае - к тексту), но безрезультатно. Все работает правильно, за исключением того, что объекты не перетаскиваются, когда они должны. Логично, что это происходит потому, что свойства offsetX и offsetY в классе Line продолжают обновляться, что заставляет объект оставаться неподвижным. Я уверен, что есть решение, но я не могу понять это. Возможно, я слишком долго смотрел на него. Я очень ценю помощь!Перетаскивание объектов в обработке

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

обновление

Разъяснения версию Еогеасп из «за», используемый в этом коде ,

+0

Я очень ценю ваш ответ. Ваш код намного чище и эффективнее моего. Тем не менее, я работал над расширением проекта, чтобы добавить функциональность (и, в конечном счете, включить логику в текстовую игру), и у меня возникли проблемы с интерпретацией некоторых из кода. Я не знаком с некоторыми синтаксисами, которые вы используете, как цикл for с четырьмя параметрами, (int), для (Line l: lines) и другими вещами. Я извиняюсь за недостаток опыта программирования и задавался вопросом, есть ли способ преодолеть мою проблему, используя как можно больше моего (плохого) кода? – Brannon

+1

это стандартный java/синтаксис обработки, поэтому я могу, конечно, объяснить биты, которые вы не понимаете. Начиная с java 1.5 (который сейчас QUITE давно = D) существует два способа цикла. Первый - для (int i = 0; i

Смежные вопросы