跟貓借一隻手:召喚效率小幫手-變數(互動藝術創作分享教學)

前一篇文章中,我們透過逐一設定每顆氣球的大小、高度,成功繪製了天外奇蹟的電影海報,但如果今天要畫二十顆、甚至是上百顆氣球呢?如果一樣需要一顆一顆地設定給和值,那應該會做到天荒地老。日文中有一句俗語「猫の手も借りたい(ねこのてもかりたい)」,意思就是「非常忙錄,連貓的手都想借來幫忙」。今天我們就要借助貓的手──變數,來製作更加複雜的生成式藝術。

透過變數的幫忙減少重複繪製圓形、保留並延續上一個frame,進而動態畫面。
透過變數的幫忙減少重複繪製圓形、保留並延續上一個frame,進而動態畫面。
圖片來源: https://openprocessing.org/sketch/947819
Recomposition in colour A by Shun Hsun Liang

「變數」是程式語言中非常重要的概念。你可以想像它其實像一個抽屜,可將某些資料儲存起來。只要呼叫這個抽屜的名字就可以取用存在其中的資料。

在 JavaScript 中,變數宣告的語法為:

var r = 100     // 概念像是把 100 這個「數字」儲存在叫做 r 的這個抽屜中
var txt = '你好' // 也可以存「字串」在裡面 

取用變數的方法:呼叫它的名字!

print(r)       // 透過 print() 把 r 的內容印出來。結果會是 100 
print(txt)     // 會印出「'你好'」

透過「儲存櫃」這個概念,變數可以幫我們做到這些事:

  • 減少重複的動作 程式碼管理起來更方便,例如畫多個相同半徑的球時,可以快速同時改變他們的半徑。
var r = 50

ellipse(width/2, height/3, 50) 
ellipse(width/2, height/2, 50)     // 這兩個圓半徑重複了

ellipse(width/2, height/3, r, r)
ellipse(width/2, height/2, r, r)   // 這樣更好管理!
  • 暫存手邊需要的資料 利用變數的特性,先將經過運算的資料儲存起來,等到要用時再呼叫。
var brightnessR = r/2 + 40
var brightnessG = mouseX/2 + 40
var brightnessB = mouseY/2 + 40 + mouseX/5   // 這些算好後先準備起來

.....某些程式碼

fill(brightnessR, brightnessG, brightnessB)  // 要用到顏色囉,這樣好看多了!
  • 做較複雜運算時能夠解構、梳理並進一步清晰邏輯 我們可以直接拿變數再做進一步處理並存起,這能讓變數間的邏輯關係更清晰,而且你也不用在意原先的變數是怎麼來的。
var halfWidth = width/2    // 要一半視窗寬度,直接拿 width 來用!

var darkR = brightnessR/2
var darkG = brightnessG/2
var darkB = brightnessB/2  // 反正我要更暗的,直接拿原先的 brightness 除以 2 就好了

fill(darkR, darkG, darkB)
  • 保留先前的狀態,並藉此形成連續的狀態變化 這裡或許有些抽象,需要用到動畫影格(frame)的概念。應用變數的運算特性,我們可以把某些狀態,例如位置、大小、顏色等狀態先設定為變數,然後以先前的值運算並放回原先變數中來複寫舊內容,藉此來實現動態且連續地改變變數內容。
// 球會往畫面右下方移動
var x = 50, y = 50

function draw(){
    ellipse(x, y, 50) // 會取到更新的 x 及 y 位置資訊,並藉此畫出圓
    x = x+5           // 每次都拿原先的 x 來加 5,並塞回原先的 x
    y += 5            // 等同於 y = y+5,只是簡略寫法
}

介紹完變數的基礎概念,就讓我們進入範例練習吧!今天的靈感來源是川野 源(Hiroshi Kawano)的作品──Design 3-1. Data 4, 5, 6, 6, 6,哲學系出身的川野先生可以說是生成式藝術的先驅之一,早在1964年時便開始藉由電腦程式進行藝術創作,風格以色彩繽紛、交錯排列的方塊為主。

如果不知道從何下手,可以利用Google Arts等藝術相關的搜尋引擎,從藝術家們的作品之中找尋靈感唷。

參考圖片Title: Design 3-1. Data 4, 5, 6, 6, 6 Year: 1964
Title: Design 3-1. Data 4, 5, 6, 6, 6 Year: 1964
圖片來源: http://dada.compart-bremen.de/item/artwork/1372

首先準備幾個會用到的變數,相當於桌子裡面空的抽屜,待會我們會把工具逐一放到抽屜裡面。這邊要注意的是變數的命名有一定的準則:

  1. 可讀性 :好的命名必須名符其實,讓人一看就懂。在大型的專案中,常常有機會需要維護別人的code或vice versa,如果打開code看到一連串aaa、bbb、ccc的變數命名,也許你從茶水間回來椅子上面就多了幾個圖釘(喂)。
  2. 駝峰式:每種語言的方式不一,有些採用首字母小寫駝峰式、有些則是首字母大寫駝峰式。沒有硬性的規定,但坊間通常會有不成文的默契。(p5.js使用的是首字母小寫駝峰式)
  3. 避開保留字:指程式語言保留下來的英文單字,作為語法的關鍵字(Keyword)不能當變數名稱,如先前所使用的square()、background()等已被p5.js作為函式庫內語法使用的英文單字。

根據川野先生的作品,我們可以大致推測需要的變數會有顏色、尺寸、還有在不同方塊之中當前使用的顏色與變換的顏色。

//Inspired by the work of Hiroshi Kawano
var colors;
var size;
var probChangeColor;
var currentColor;

接下來準備800*800px的畫布,使用語法noLoop()避免一直重複執行,設定方塊中的尺寸和改變顏色的基準值,由於方塊都是純色塊,所以使用noStorke()取消外框線。

第一步設定創作環境

接下來針對會使用到的顏色給予RGB值,不知道RGB是什麼的請看前篇的色票介紹。把色票放到名叫colors的陣列(array)裡面,陣列是一種資料的集合,也是一種比較複雜的物件 (object),我們剛剛針對不同的顏色名稱給予了相對的RGB值,所以只要在陣列裡面填入顏色名稱,程式就會自動理解名稱背後所代表的意義,這就是變數儲存櫃的特性。

因為我們希望作畫時隨機選取顏色,所以命名一個新的function叫randomColor(),他有點像大樂透抽號碼時的球池,在這個球池中我們會有號碼,所以運用語法array.length()回傳該陣列實體中包含的元素個數,再透過random()隨機產生0~6區間的數字,用floor()將數字轉成最接近該值的整數。因為陣列有順序的概念,所以抽出來的整數字代表陣列中的第幾個,再將值return。

設定顏色與隨機程式
註:因為考慮到畫作色彩的平衡性,所以陣列colors中ㄉㄉㄜ的white使用兩次

準備開始繪製主要的元素──彩色方塊

function createComposition() {
  for (var y = 0; y < height; y += size) {
    for (var x = 0; x < width; x += size) {
      if (random(1) < probChangeColor) {
        currentColor = randomColor();
      }
      fill(currentColor);
      square(x, y, size);
    }
  }
}
繪製彩色方塊

加個邊框感覺更像畫作,命名一個function為addBorder()調整框線的粗度、顏色和畫線方向。

調整框線

接下來加入一些跟使用者的互動,只要每次按下空白鍵space,就會自動產生新的pattern。

自動產生新畫作的互動

這樣就完成啦~成品請往這邊走 👉🏻 https://openprocessing.org/sketch/1108202

語法統整大補帖

圖形相關語法:ellipse()、circle()、rect()
填色相關語法: fill()、background()
線條相關語法: line()、stroke()、noStroke()、strokeWeight()
文字相關語法: text()、textAlign()

想學習更多程式創作嗎?那你必不可以錯過哲宇老師的【互動藝術程式創作入門】課程,快跟著其他一千多名同學開始發揮你無限的創意吧!

作者:Ju編 Jeudi Kuo


訂閱 Creative Coding Taiwan 電子報:


PHP Code Snippets Powered By : XYZScripts.com