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

Processing數位互動介面開發軟體應用 – 快速了解Processing IDE

0133_3951a0ce16425be1758203872045dbd7ff3766db.png

 

作者

曾吉弘

难度

普通

材料表

1.    Arduino UNO

 

Processing

       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),不同平台在語法上當然會有差異,但介面與開發精神都是一樣的,歡迎都試試看,觸類旁通喔!

0131_3951a0ce16425be1758203872045dbd7ff3766db.png

 

 

下載

    請開啟 Processing 官方網站的下載頁面,根據您所使用的硬體平台下載對應的版本。    本文將使用 Windows 10作業系統使用 Processing 3.5.4 版本,別擔心,其他平台的作法也是一樣簡單,下載-->解壓縮-->開啟 IDE。Processing 3.5 版 32位元更提供 ARM 平台,因此 Rasbperry Pi 這類的單板電腦也可以執行,很適合做為獨立的藝術展示裝置。阿吉老師有蠻多學生都選擇這個方案,比使用筆記型電腦來得更方便,在可攜性也更高(不小心壞掉也比較不心痛...)

0226_38dc11882797647cddbbab16beb4eeb746cb5ae0.png

 

下載之後解壓縮,資料夾內容如下。點選 processing.exe 就可以開啟主畫面

0329_434cf65587be7f5ca56956a58156a852cdb38455.png

 

如何執行?

 

請在 Processing 介面右上角按下 File / New 開啟一個新的 Processing 專案,並在白色區域輸入以下這一行:

println("hello Processing!");

 

按下畫面左上角的 Run 按鈕,會在下方 console 處看到 hello Processing!,這就是之前填在括號中的文字內容,效果類似 Arduino IDE 的 Serial.println(),可以顯示變數值或一段文字,讓使用者知道發生了什麼事情,屬於最基礎的輸出範例。

0427_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 來取得滑鼠座標,這是非常貼心的做法。後續文章就會介紹如何使用類似的指令來取得鍵盤的按鍵狀態。

0525_a2612195b455b06b876b37367a88e2655dfea103.png

 

想想看,如果在執行 line() 指令之前加入以下指令,會產生怎樣的效果呢?

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

 

ASWD方塊移動遊戲

    來看一個整合性的範例吧,告訴您如何使用鍵盤按鍵來控制畫面上小方塊的移動方向。在早期用鍵盤來玩射擊遊戲的年代(啊,暴露年齡),就是用這四個鍵控制飛機,以及其他發射飛彈或特殊功能按鍵。執行畫面如下:

0623_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度移動
  3.  

範例哪邊找

 

   如果對上面三個範例意猶未盡的話,那麼從官方範例來學習吧!點選 Processing IDE 的 File / Example 會跳出以下視窗,這裡是 Processing 所提供的各種範例。幾乎所有範例都可以直接執行,寫得相當簡潔漂亮,也提供了類似上述 mouseX mouseY 之類方便又好用的內建變數或函數。從現在的角度來看可能不太稀奇,您也許會覺得很多程式環境都有,但別忘了 Processing 可是從2001年就提出了,一些觀念在當年可說是相當領先的。

0727_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,這樣秒針、分針與時針就會一樣粗。

0822_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 的選單,其中以書名或範例名稱來分類,這樣就全部匯入了,直接點選喜歡的範例來玩玩看吧,幾乎都可以直接執行(或安裝必要的函式庫即可)。 

0920_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