首页 > 文档 > 翻译: 用其他开发环境写Processing 时如何处理多个类
2017
12-28

翻译: 用其他开发环境写Processing 时如何处理多个类

原文在此, 来自官方网站的教程页.


原文主题为如何用Eclipse 取代PDE 开发Processing 程序.
内容其实是把Processing 当成Java 三方库来使用的一般方法.

我自己在用非PDE 写Processing 的时候就怎样分割源码文件这个问题卡过一阵子.
虽然后来找了个野办法解决…但刚刚才看到官网其实是有教程的.
下面只截取原文中关于类处理的部分随便翻一下.

另外由于我不会用Eclipse , 而且这个内容也不是针对某个IDE 的,
下面提到Eclipse 的地方一律以”其他开发环境”替代.


The Short Version
>>> 概要:

The quick break down of what we did here:
>>> 关于如何用其他开发环境开发Processing 程序的步骤提纲:

1.Create a new Java Project
>>> 1.创建一个新的Java 项目.

2.Import the Processing core.jar from where your Processing is installed. Add it to the build path.
>>> 2.导入Processing 的core.jar 文件到库里并添加编译路径, 这个文件应该在你的Processing 安装位置.

3.Create a new class, and extend PApplet. Import the PApplet from processing.core.PApplet
>>> 3.从processing.core.PApplet 导入PApplet, 创建一个新类, 继承PApplet.

4.In main(), call PApplet.main(“YouClassName”);
>>> 4.在主函数里调用PApplet.main(), 参数为主类名的字符串.

5.Add a public void settings(), public void setup(), and public void draw().
>>> 5.往主类里直接添加settings(), setup(), draw(), 注意还需要添加public 权限修饰符.

6.Use the size() call inside of settings(), and other than that, use setup() and draw() like normal!
>>> 6.注意size() 函数必须在settings() 里面调用, 但setup() 和draw() 的用法与用PDE 时没有不同.

翻译: 用其他开发环境写Processing 时如何处理多个类 - 第1张  | Processing编程艺术


Processing in Eclipse with Multiple Classes
>>> 关于用其他开发环境写Processing 时如何处理多个类.

Take a look at this example Processing sketch.
>>> 下面来看一个范例程序.

The example is object-oriented and contains a class called “Stripe”.
>>> 这个范例使用了面向对象的编程手法, 它有一个类叫做”Stripe”.

In Processing, all classes are treated as “inner classes,” meaning they are not individual entities unto themselves, but rather are classes inside of the larger PApplet.
>>> 在Processing 里, 所有的类都是嵌套类, 意思是他们本身都不是一个独立的类, 只是一个内包在PApplet 这个大类里面的类.

This is why you can do anything you can do in a PApplet inside of the Stripe class.
>>> 否则你将不可能在Stripe 里面做任何普通PApplet 能够做到的事情.

You can draw onto the window calling rect() and access the PApplet variables such as width and height.
>>> 你能直接用rect() 函数往窗口上绘图, 或者直接调用PApplet 的参数, 比如width 和height.

To get this example working in Eclipse, it’s perfectly reasonable to just copy it in as is and include the Stripe class code below setup() and draw() inside the parent PApplet class.
>>> 要让这个范例在其他环境能跑, 首先你可以选择直接把这个类的代码复制到PApplet 主类里面, 比如setup() 和draw() 的下方.

However, the inner class methodology can quickly become unwieldy in the case of larger applications with lots and lots of classes.
>>> 但是如果以后项目越做越大, 类越来越多, 继续用嵌套类的手法会让代码很难处理.

And so we find ourselves in need of a means for creating separate Java classes in Eclipse that we can use in conjunction with a Processing-based application.
>>> 所以我们需要把类做成真正独立的Java 类, 还要让他们在Processing 程序中能互相作用.


First thing first, we can put all the code that is not the Stripe class in a Java class like with the first example.
>>> 首先, 我们可以把范例程序的主程序代码先照上述方法放到Java 主类当中.

import processing.core.*;

public class MyProcessingSketch extends PApplet {
  //	An array of stripes
  Stripe[] stripes = new Stripe[50];
  
  public static void main(String[] args){
    PApplet.main("MyProcessingSketch");
  }

  public void settings(){
    size(200,200);
  }


  public void setup() {
    // Initialize all "stripes"
    for (int i = 0; i < stripes.length; i++) {
      stripes[i] = new Stripe();
    }
  }

  public void draw() {
    background(100);
    // Move and display all "stripes"
    for (int i = 0; i < stripes.length; i++) {
      stripes[i].move();
      stripes[i].display();
    }
  }
}

 

Second, we create a new class called Stripe.
>>> 然后, 我们新建一个类, 命名为Stripe .

FILE –> NEW –> CLASS. Name it “Stripe.” Click “finish.”
>>> 从 [菜单]–>[新建]–>[类], 输入”Stripe”后点击完成.

If we add the Processing code, Eclipse will give us a bunch of errors.
>>> 之后我们添加Processing 代码, 但开发环境会报一堆错给我们.

翻译: 用其他开发环境写Processing 时如何处理多个类 - 第2张  | Processing编程艺术

The errors are all on lines where we call a Processing function (such as rect()) or reference a Processing variable (such as width).
>>> 这些错都报在使用了Processing 函数(比如rect() )或变量(比如Width )的行上.

This is because a Stripe is not a PApplet and knows nothing about PApplets!
>>> 这是因为Stripe 不是一个PApplet , 它不知道什么是包含在PApplets 里面的.

We might be tempted to have Stripe extend PApplet, but this would be a fatal error.
>>> 然后你可能会想要让Stripe 继承PApplet , 但这就大错特错了.

A Stripe is not a PApplet. A Stripe is a rectangular object that we want to draw onto a PApplet.
>>> Stripe 是一根条子, 一根条子不应该是一整个窗口. 一根条子只是一个被你画到窗口上的方形对象.

What PApplet do we want to draw onto? The PApplet that is MyProcessingSketch.
>>> 那我们想把它画到哪个窗口上呢? 答案就是我们的主类MyProcessingSketch .

Instead of extending PApplet, we simply want to tell a Stripe object about a MyProcessingSketch.
>>> 我们想要干的只是告诉Stripe 对象MyProcessingSketch 的信息, 而不是让它去继承一整个窗口.

public class Stripe {
  PApplet parent; // The parent PApplet that we will render ourselves onto >>> 我们想要描绘的目标窗口

 

In the constructor, we initialize the parent:
>>> 我们在构造函数里初始化目标窗口.

Stripe(PApplet p) {
    parent = p;

 

And then anytime we want to call a Processing function, we access it via the parent variable.
>>> 当我们需要用到Processing 函数时就通过目标窗口访问它.

  // Draw stripe
  void display() {
    parent.fill(255,100);
    parent.noStroke();
    parent.rect(x,0,w,parent.height);
  }

 

Here’s the whole thing together:
>>> 修改后的类看起来是这样的:

import processing.core.PApplet;

public class Stripe {
  float x;       // horizontal location of stripe
  float speed;   // speed of stripe
  float w;       // width of stripe
  boolean mouse; // state of stripe (mouse is over or not?)
  PApplet parent; // The parent PApplet that we will render ourselves onto

  Stripe(PApplet p) {
    parent = p;
    x = 0;              // All stripes start at 0
    speed = parent.random(1);  // All stripes have a random positive speed
    w = parent.random(10,30);
    mouse = false;
  }

  // Draw stripe
  void display() {
    parent.fill(255,100);
    parent.noStroke();
    parent.rect(x,0,w,parent.height);
  }

  // Move stripe
  void move() {
    x += speed;
    if (x > parent.width+20) x = -20;
  }
}

 

Finally, the last change we have to make is how we call the constructor. Previously, we had:
>>> 最后我们需要改变的是调用构造函数的写法. 之前我们这样写:

stripes[i] = new Stripe();

 

But now when we construct a Stripe object, we must pass in a reference to a PApplet.
>>> 但现在我们构造Stripe 对象时是需要把主窗口的引用传递给它的.

And here, the PApplet is this, a reference to ourselves, the PApplet we are right now, MyProcessingSketch.
>>> 本例中, 这个主窗口就是我们自己的主类MyProcessingSketch , 我们用this 关键字把主类自身的应用传递给构造函数.

stripes[i] = new Stripe(this);

 

Here is the project source on GitHub.
>>> 你可以在Github 找到本例的代码.


Another important note. The Processing “color” primitive does not exist in Java.
>>> 另外还有一个重要问题, “color “在Processing 里是一个基本型, 但Java 里并没有这么一个东西.

In fact, in Processing a “color” is really just an integer (32 bits with red, green, blue, and alpha components).
>>> 其实Processing 里面的”color “就是一个普通的整形(32位, 红绿蓝透明通道各8位) 变量.

Processing translates “color” to “int”, but Eclipse won’t do that for you. So instead of saying:
>>> PDE会自动把”color ” 替换成”int “, 但其他环境不会这么做. 所以你不能写:

color pink = color(255,200,200);

 

you should say:
>>> 你要写成:

int pink = color(255,200,200);

 

and if you are in another class and have to refer to the “parent” PApplet:
>>> 最后如果你是在另一个外部类里写的话, 你需要引用目标窗口才可以调用color() 函数:

int pink = parent.color(255,200,200);

 



最后编辑:
作者:constrain
nullpointerexception

留下一个回复

你的email不会被公开。