如何让一个草图在另一个使用屏幕的草图中工作?

How to get a sketch to work within another sketch that is using screens?

我正在做一个涉及屏幕的项目。我希望能够将数字键用于哪些屏幕,这将把用户带入草图的交互部分。

我开始在一个单独的草图中处理程序的一个交互部分。这是草图:

 float x, y, r, g, b, radius;
int timer;

void setup() {
  size(500, 500);
  background(255);
  noStroke();
  smooth();
}

void draw() {
      Zon();
  }


void Zon(){
   // use frameCount to move x, use modulo to keep it within bounds
  x = frameCount % width;

  // use millis() and a timer to change the y every 2 seconds
  if (millis() - timer >= 8000) {
    y = random(height);
    timer = millis();
  }

  // use frameCount and noise to change the red color component
  r = noise(frameCount * 0.01) * 255;

  // use frameCount and modulo to change the green color component
  g = frameCount % 1;

  // use frameCount and noise to change the blue color component
  b = 255 - noise(1 + frameCount * 0.025) * 255;

  // use frameCount and noise to change the radius
  radius = noise(frameCount * 0.01) * mouseX;

  color c = color(r, g, b);
  fill(c);
  ellipse(x, y, radius, radius);
}

这是单独草图的代码。我希望能够将此草图放入我的实际项目中,但它不像在单独的草图中那样起作用。有人可以向我解释这是为什么吗?

我希望有一个白色背景,并且椭圆在屏幕上移动,留下一条轨迹。是不是因为背景一遍又一遍运行,把过程中的痕迹擦掉了?

当我移除背景时(255);它有点工作,除了它在菜单屏幕上的 运行,这是我不想要的。

此处为实际项目代码:

final int stateMenu = 0;
final int GreenBox = 3;
int state = stateMenu;
float x, y, r, g, b, radius;
int timer; 
PFont font;
PFont Amatic;


void setup()
{
  size(800, 700);
  smooth();
  font = createFont("ARCARTER-78.vlw", 14);
  textFont(font);
  //Amatic = createFont("Amatic-Bold.ttf",60);
  //textFont(Amatic);
  frameRate(15);
} 

void draw()
{
  // the main routine. It handels the states.
  // runs again and again
  switch (state) {
  case stateMenu:
    showMenu();
    break;
    case GreenBox:
    handleGreenBox();
    break;
    default:
    println ("Unknown state (in draw) "
      + state
      + " ++++++++++++++++++++++");
  }
}

  void keyPressed() {
  // keyboard. Also different depending on the state.
  switch (state) {
  case stateMenu:
    keyPressedForStateMenu();
    break;
    case GreenBox:
    keyPressedForGreenBox();
  }
  }

   void keyPressedForStateMenu() {
     switch(key){
       case '3':
       state = GreenBox;
       break;
       default:
    // do nothing
    break;
   }
   }
     void keyPressedForGreenBox(){
      switch(key) {
  default:
    state = stateMenu;
    break;
      }
     }
      void showMenu() {
  background(255);
  fill(0);
  textSize(45);
  //textFont(Amatic);
  text(" Music Box ", 330, 250, 3);
  textSize(14);
  text("Press 3 for Green", 350, 350);

} 

void handleGreenBox() {
      Zon();
} 


void Zon(){
  background(255);
  noStroke();
  smooth();
   // use frameCount to move x, use modulo to keep it within bounds
  x = frameCount % width;

  // use millis() and a timer to change the y every 2 seconds
  if (millis() - timer >= 8000) {
    y = random(height);
    timer = millis();
  }

  // use frameCount and noise to change the red color component
  r = noise(frameCount * 0.01) * 255;

  // use frameCount and modulo to change the green color component
  g = frameCount % 1;

  // use frameCount and noise to change the blue color component
  b = 255 - noise(1 + frameCount * 0.025) * 255;

  // use frameCount and noise to change the radius
  radius = noise(frameCount * 0.01) * mouseX;

  color c = color(r, g, b);
  fill(c);
  ellipse(x, y, radius, radius);
}

有人可以帮我解决这个问题吗?

如果您希望能够绘制背景并在该背景之上绘制 "trail",那么您有两种选择:

选项 1: 创建一个数据结构,其中包含您需要绘制的所有内容,然后每帧绘制该数据结构中的所有内容。这可以像 ArrayList<PVector> 一样简单,或者您最好创建自己的 类 来封装您需要了解的所有内容,以便在框架中绘制所有内容。

选项 2: 创建一个 PGraphics 以供您绘制轨迹。然后将背景绘制到屏幕上,然后将 PGraphics 绘制到屏幕上。有关此方法的信息可以在 the reference.

中找到

采用哪种方法完全取决于您自己。我建议将一个小示例放在一起,对每个示例进行测试,看看哪个对您更有意义。然后,如果您遇到困难,可以 post 那个小例子的 MCVE。祝你好运。

在您的原始代码中您没有清除背景,但在合并后的代码版本中您是:

void Zon(){
  background(255);
 ...

正如您指出的那样,您不希望这样。 唯一的另一个问题是您仍然需要调用 background(255),但只需调用一次,当您从菜单状态切换到 GreenBox 状态时:

void keyPressedForStateMenu() {
  switch(key) {
  case '3':
    state = greenBox;
    //clear the menu once when moving into greenBox
    background(255);
    break;
  default:
    // do nothing
    break;
  }
}

您已经很好地识别了问题以及如何部分解决问题,只是需要在更改模式时清除背景。

您的代码将如下所示:

final int stateMenu = 0;
final int greenBox = 3;
int state = stateMenu;

float x, y, r, g, b, radius;
int timer; 
PFont font;
PFont Amatic;


void setup()
{
  size(800, 700);
  smooth();
  //maybe loadFont ?
  font = createFont("ARCARTER-78.vlw", 14);
  textFont(font);
  //Amatic = createFont("Amatic-Bold.ttf",60);
  //textFont(Amatic);
  frameRate(15);
} 

void draw()
{
  // the main routine. It handels the states.
  // runs again and again
  switch (state) {
  case stateMenu:
    showMenu();
    break;
  case greenBox:
    handlegreenBox();
    break;
  default:
    println ("Unknown state (in draw) "
      + state
      + " ++++++++++++++++++++++");
  }
}

void keyPressed() {
  // keyboard. Also different depending on the state.
  switch (state) {
    case stateMenu:
      keyPressedForStateMenu();
      break;
    case greenBox:
      keyPressedForgreenBox();
  }
}

void keyPressedForStateMenu() {
  switch(key) {
  case '3':
    state = greenBox;
    //clear the menu once when moving into greenBox
    background(255);
    break;
  default:
    // do nothing
    break;
  }
}
void keyPressedForgreenBox() {
  switch(key) {
  default:
    state = stateMenu;
    break;
  }
}
void showMenu() {
  background(255);
  fill(0);
  textSize(45);
  //textFont(Amatic);
  text(" Music Box ", 330, 250);
  textSize(14);
  text("Press 3 for Green", 350, 350);
} 

void handlegreenBox() {
  Zon();
} 


void Zon() {
  //don't clear the buffer continuously if you want to leave trails
//  background(255);
  noStroke();
  smooth();
  // use frameCount to move x, use modulo to keep it within bounds
  x = frameCount % width;

  // use millis() and a timer to change the y every 2 seconds
  if (millis() - timer >= 8000) {
    y = random(height);
    timer = millis();
  }

  // use frameCount and noise to change the red color component
  r = noise(frameCount * 0.01) * 255;

  // use frameCount and modulo to change the green color component
  g = frameCount % 1;

  // use frameCount and noise to change the blue color component
  b = 255 - noise(1 + frameCount * 0.025) * 255;

  // use frameCount and noise to change the radius
  radius = noise(frameCount * 0.01) * mouseX;

  color c = color(r, g, b);
  fill(c);
  ellipse(x, y, radius, radius);
}