【问题标题】:Processing 3 - Calling draw() from a function doesn't update the screen处理 3 - 从函数调用 draw() 不会更新屏幕
【发布时间】:2017-07-08 07:27:51
【问题描述】:

我正在试验如何在一个函数中处理一些数据,同时在屏幕上显示一个加载栏。例如,我将一堆值添加到一个数组中——这个过程在我的计算机上大约需要 5 秒。我有以下代码:

ArrayList<String> strs = new ArrayList<String>();
String state;
float counter;

void setup() {
  size(640, 480);
  state = "load";
  noStroke();
}

void draw() {
  if (state.equals("load")) {
    load();
  } else if (state.equals("loading")) {
    background(255);
    fill(255, 0, 0);
    rect(0, height/2-25, map(counter, 0, 10000000, 0, width), 50);
  } else if (state.equals("play")) {
    background(0, 255, 0);
  }
}

void load() {
  state = "loading";
  for (int i = 0; i < 10000000; i++) {
    strs.add(str(pow(i, 2)));

    if (i % 1000 == 0) {
      counter = i;
      draw();
    }
  }
  state = "play";
}

但我只是得到一个灰屏(表明从未调用过 background(255))大约 5 秒钟,直到我得到一个绿屏。当然,我可以将代码替换为:

ArrayList<String> strs = new ArrayList<String>();
String state;
int counter;

void setup() {
  size(640, 480);
  state = "load";
  noStroke();
  counter = 0;
}

void draw() {
  if (state.equals("load")) {
    float theMillis = millis();
    while (millis()-theMillis < 1000.0/frameRate && counter < 10000000) {
      strs.add(str(pow(counter, 2)));
      counter++;
    }
    if (counter >= 10000000) {
      state = "play";
    }

    background(255);
    fill(255, 0, 0);
    rect(0, height/2-25, map(counter, 0, 10000000, 0, width), 50);
  } else if (state.equals("play")) {
    background(0, 255, 0);
  }
}

这适用于这个简单的示例,但我试图让 draw() 在从函数显式调用时工作,这取决于 load() 的复杂性(我实际上正在尝试工作的那个)在我的项目中,打开和解压缩文件、处理 JSONArrays 和 ArrayLists 等长达 250 多行。将加载函数拆分为 draw() 中的块可能是一场噩梦。那么有没有办法从函数内部更新屏幕?

提前感谢您的帮助:)

【问题讨论】:

    标签: screen processing draw updating


    【解决方案1】:

    正如您所发现的,在 draw() 函数完成之前,处理实际上不会更新屏幕。所以发生的事情是 draw() 函数被 Processing 调用,而在那个框架内,你碰巧自己调用了 draw() 函数。但是对draw() 的第一次调用还没有完成,所以屏幕没有更新。只有当您对draw() 的所有调用都完成并且第一个调用(处理进行的)完成时,它才会更新。

    像这样给自己打电话draw() 通常是个很糟糕的主意。您通常应该使用随时间更新的变量来更改每帧显示的内容。

    另一种选择是使用单独的线程来加载文件,这样绘图线程就可以继续。

    【讨论】:

    • 我尝试在load() 的开头添加noLoop() 和最后的loop(),它似乎没有改变任何东西 - 这样就没有办法draw()当我调用它时已经在运行......
    • @VladimirShevyakov 调用noLoop()loop() 不会改变第一次调用draw() 尚未完成的事实。
    • 啊。好吧,我实际上只是设法使用thread() 解决了问题
    • @VladimirShevyakov 是的,这就是我最后一句话的意思。但请注意,如果您在线程之间共享数据,则必须格外小心。
    猜你喜欢
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    相关资源
    最近更新 更多