嘿!您似乎在 United States,您想使用我们的 English 网站吗?
Switch to English site
Skip to main content

Processing数位互动介面开发软件应用 – 快速了解Processing IDE

作者

曾吉弘

难度

普通

材料表

1.    Arduino UNO

 

Processing0625_e15dbfa60e559bf1a5cfa05054e9bc9ab3304bb5.png

       Processing 是由 MIT 媒体实验室的 Casey Reas 和 Benjamin Fry 推出的开放原始码程序语言(最早发想是在2001年,之后于2012年与 Daniel Shiffman 成立 Processing 基金会),专门为电子艺术和视觉互动设计所设计。根据官方网站,Processing 有以下特色:

  • 免费下载且开放原始码
  • 交互式程序设计,能处理各种 2D、3D、PDF 或 SVG 输出
  • 整合 OpenGL 进行 2D/3D 加速
  • 跨平台:GNU/Linux、Mac OS X、Windows、Android 与 ARM
  • 超过 100 个以上的函式库,立即可用
  • 文件丰富,坊间相关书籍也很多

    CAVEDU 从 2011 年接触 Processing 之后,很喜欢它对于声光效果的处理效果,与计算机周边硬件也有很好的结合(各种USB接口装置几乎即插即用)。或者透过 Arduino (一样是用 USB)来搭配各种电子组件也没有问题。阿吉老师之前也尝试把 Processing 专题应用在 Android 装置上(参考 Processing for Android ),但后来智能型手机的方案都改成用 App Inventor 来做。这篇文章是 Processing 系列文章的第一篇,将介绍 Processing 环境的基本设定,后续会陆续介绍许多有趣的应用,希望大家喜欢喔!

    先来看看 Processing 官方网站,由上方横幅可以看到目前重要的分支有 Processingp5.jsPrcessing.pyProcessing for Android 以及 Processing for Pi (Raspberry Pi),不同平台在语法上当然会有差异,但接口与开发精神都是一样的,欢迎都试试看,触类旁通喔!

0134_3951a0ce16425be1758203872045dbd7ff3766db.png

 

 

下载

    请开启 Processing 官方网站的下载页面,根据您所使用的硬件平台下载对应的版本。    本文将使用 Windows 10操作系统使用 Processing 3.5.4 版本,别担心,其他平台的作法也是一样简单,下载-->解压缩-->开启 IDE。Processing 3.5 版 32位更提供 ARM 平台,因此 Rasbperry Pi 这类的单板计算机也可以执行,很适合做为独立的艺术展示装置。阿吉老师有蛮多学生都选择这个方案,比使用笔记本电脑来得更方便,在可移植性也更高(不小心坏掉也比较不心痛...)

0228_38dc11882797647cddbbab16beb4eeb746cb5ae0.png

 

下载之后解压缩,文件夹内容如下。点选 processing.exe 就可以开启主画面

0331_434cf65587be7f5ca56956a58156a852cdb38455.png

 

如何执行?

请在 Processing 界面右上角按下 File / New 开启一个新的 Processing 项目,并在白色区域输入以下这一行:

println("hello Processing!");

 

按下画面左上角的 Run 按钮,会在下方 console 处看到 hello Processing!,这就是之前填在括号中的文字内容,效果类似 Arduino IDE 的 Serial.println(),可以显示变量值或一段文字,让用户知道发生了什么事情,属于最基础的输出范例。

0429_92f502df12fa5ef16bb6ff87d93e7ef3a693c167.png

 

上述范例属于单次执行,如果需要持续执行的话,就需要用 draw() 函式把一段程序包起来看看第二个范例:

void setup() {
  size(400, 400);
  stroke(255);
  background(192, 64, 0);
}

void draw() {
  line(150, 25, mouseX, mouseY);
}

 

   setup() 函式是用来初始化程序的许多东西,分别设定窗口大小、边线颜色为白色以及背景颜色等等(Processing 很贴心地在 Tools 选单中提供了 Color Selector,让您快速找到喜欢的颜色)。setup() 只会执行一次而已,接着就会自动进入 draw() 函式,要重复执行的程序都要放在这里面。在此只有一行:

  line(150, 25, mouseX, mouseY);

 

  line() 指令会在 (150, 25) 这个点与鼠标XY坐标之间绘制一条直线,但因为 draw() 函式会不断执行。因此当程序执行之后,在窗口中移动鼠标就可以看到如下图的效果。Processing 可直接透过 mouseX mouseY 来取得鼠标坐标,这是非常贴心的做法。后续文章就会介绍如何使用类似的指令来取得键盘的按键状态。

0527_a2612195b455b06b876b37367a88e2655dfea103.png

 

想想看,如果在执行 line() 指令之前加入以下指令,会产生怎样的效果呢?

void draw() {
  background(192, 64, 0);
  line(150, 25, mouseX, mouseY);
}

 

ASWD方块移动游戏

    来看一个整合性的范例吧,告诉您如何使用键盘按键来控制画面上小方块的移动方向。在早期用键盘来玩射击游戏的年代(啊,暴露年龄),就是用这四个键控制飞机,以及其他发射飞弹或特殊功能按键。执行画面如下:

0626_e15dbfa60e559bf1a5cfa05054e9bc9ab3304bb5.png

 

    程序中可以看到 keyPressed 这个变量,只要用户按下任何一个键盘按键,这个变量值就会为 True,反之则为 False。接着再用 key == 'w' 来判断按下了哪一个按键。请低头看看您的键盘,aswd 是不是刚好是左、下、上与右四个方向呢?

    这个游戏中可以调整的效果为每一次按下 aswd 按钮时,方块移动的距离,也就是 xPos 与 yPos 的增量(现在为5),增量愈大,每次方块移动的距离就愈大。另一个就是 delay() 的时间,现在为 100毫秒,代表一秒钟会重复执行 loop() 的内容10次 (1秒 = 1000毫秒,1000/100 = 10次)。这个数字愈小,更新就愈快。

   比较一下:增量 = 50,delay(100),以及增量 = 5,delay(10),这两种搭配之下,每秒钟方块移动的距离是否相同?移动的效果又有什么不一样呢?

int xPos=200, yPos=200;
void setup() {
  size(400, 400);
  smooth();
}

void draw() {
  background(204); 
  if (keyPressed) {
    if (key == 'w') {
      yPos -= 5;
    }
    if (key == 's') {
      yPos += 5;
    }
    if (key == 'a') {
      xPos -= 5;
    }
    if (key == 'd') {
      xPos += 5;
    }
  }
  rect(xPos-25, yPos-25, 50, 50); 
  delay(100);
}

 

想想看:

  1. 如何做到按下 space 键来发射飞弹?
  2. 如何做到组合键的功能?例如按下d与w键让方块往右上角45度移动

范例哪边找

   如果对上面三个范例意犹未尽的话,那么从官方范例来学习吧!点选 Processing IDE 的 File / Example 会跳出以下窗口,这里是 Processing 所提供的各种范例。几乎所有范例都可以直接执行,写得相当简洁漂亮,也提供了类似上述 mouseX mouseY 之类方便又好用的内建变量或函数。从现在的角度来看可能不太稀奇,您也许会觉得很多程序环境都有,但别忘了 Processing 可是从2001年就提出了,一些观念在当年可说是相当领先的。

0729_a25580e0a5d15a50aa900bf7ad9f15998996fc2b.png

 

    阿吉老师就很喜欢 Example/Input 下的 Clock 范例,只有54行程序代码就很优雅地做到指针式时钟,Processing 提供了很直觉的 second()、minute()与 hour()函式来直接取得系统时间。再根据现在的时间来决定秒针、分针与时针的位置。这三根针就是三条直线,起点都是Processing 窗口的中点( cx = width/2; cy = height/2;),但终点就要各自根据秒、分、时的数值,透过三角函数就可以算出来每个指针的终点了。以秒针来说就是这个指令:

line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius);

 

其中关键就是 s:s 是秒数(second())的范围从原本的 0 - 60 转换到 0 - 2π 再减去 π/2。之所以要这样做是因为:时间的 0 秒是从 12点钟方向开始,但角度的 0 度却是从3点钟方向(X轴正向)开始。

  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;

 

而 secondsRadius 是用来决定秒针的长度,由以下程序可以看出 radius (灰色的时钟钟面)为画面宽度或高度(取两者最小值)的一半。而 secondsRadius 为 radius 的 0.72 倍。

  int radius = min(width, height) / 2;
  secondsRadius = radius * 0.72;

 

最后可以看到 Processing 用 strokeWeight() 语法来调整每根指针的粗细,您可以把每个数字都设为1,这样秒针、分针与时针就会一样粗。

0824_3537da3876e42001adda88c68f8b95cdec34b759.png

 

/**
 * Clock. 
 * 
 * The current time can be read with the second(), minute(), 
 * and hour() functions. In this example, sin() and cos() values
 * are used to set the position of the hands.
 */

int cx, cy;
float secondsRadius;
float minutesRadius;
float hoursRadius;
float clockDiameter;

void setup() {
  size(640, 360);
  stroke(255);
  
  int radius = min(width, height) / 2;
  secondsRadius = radius * 0.72;
  minutesRadius = radius * 0.60;
  hoursRadius = radius * 0.50;
  clockDiameter = radius * 1.8;
  
  cx = width / 2;
  cy = height / 2;
}

void draw() {
  background(0);
  
  // Draw the clock background
  fill(80);
  noStroke();
  ellipse(cx, cy, clockDiameter, clockDiameter);
  
  // Angles for sin() and cos() start at 3 o'clock;
  // subtract HALF_PI to make them start at the top
  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
  float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; 
  float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;
  
  // Draw the hands of the clock
  stroke(255);
  strokeWeight(1);
  line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius);
  strokeWeight(2);
  line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius);
  strokeWeight(4);
  line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius);
  
  // Draw the minute ticks
  strokeWeight(2);
  beginShape(POINTS);
  for (int a = 0; a < 360; a+=6) {
    float angle = radians(a);
    float x = cx + cos(angle) * secondsRadius;
    float y = cy + sin(angle) * secondsRadius;
    vertex(x, y);
  }
  endShape();
}

 

    还想要更多范例吗?请由 Processing IDE 的 Sketch / Import Library / Add Library,会跳出 Contribution Manager 窗口,有四个卷标:

  • Library: 函式库
  • Mode: 切换不同模式,例如 android
  • Tools: 工具软件
  • Example: 其他教学范例

   这边示范如何汇入 Daniel Shiffman 的 “Learning Processing 2nd Edition” 的书籍程序代码范例,请在 Contribution Manager 窗口点选 Example,找到这本书的名字,接着点选右下角的 Install,稍等一下就可以了。

   接着回到 Example 窗口,最下面会多一个 Contributed Examples 的选单,其中以书名或范例名称来分类,这样就全部汇入了,直接点选喜欢的范例来玩玩看吧,几乎都可以直接执行(或安装必要的函式库即可)。 

0922_fdf9349542856c05920ad9f309d9dfca28788e68.png

 

CAVEDU Education is devoted into robotics education and maker movement since 2008, and is intensively active in teaching fundamental knowledge and skills. We had published many books for readers in all ages, topics including Deep Learning, edge computing, App Inventor, IoT and robotics. Please check CAVEDU's website for more information: http://www.cavedu.com, http://www.appinventor.tw
DesignSpark Electrical Logolinkedin