互動教學模組
48 個可以直接在瀏覽器裡玩的教學模組:座標、迴圈、向量、noise、粒子、遞迴、L-System、Boids,每一個都附 p5.js 程式碼。
基礎
- 座標探索:(0, 0) 在左上角:畫布左上角是 (0, 0),往右 x 變大、往下 y 變大;circle 的 x、y 是圓心,rect 是左上角。
- setup 跑一次,draw 一直跑:setup() 按下 Play 時跑一次,draw() 每秒重複很多次;沒有 background() 就會留下軌跡。
- 取座標小工具:點一下,變成 vertex:beginShape() 開始、一個一個 vertex(x, y) 放點、endShape(CLOSE) 收尾,就能畫任意形狀;點一下畫布取座標,程式碼跟著多一行。
程式結構
- 變數是抽屜:x = x + 速度:變數像一個抽屜,存起來、叫名字拿回來;x = x + 速度 放在 draw() 裡,保留上一格的狀態,球就會動。
- for 迴圈:一圈一圈看它畫:for 迴圈把一件事重複很多次:i 從 1 開始,每圈加 1,小於 n 就繼續。
- 兩層 for 迴圈:排出一面格子:for 裡面再包一層 for 就是格子;用 % 餘數決定哪一格換色,就能排出花磚那種規律。
- 函數:把一朵花打包成 drawFlower():函數把重複的步驟打包、取名字,參數讓每次畫得不一樣;有名字的模組,也最好跟 AI 協作。
畫布操作
- translate/rotate/scale:動的是那張紙:translate、rotate、scale 動的是畫布(那張紙),不是圖形本身。
- push/pop:畫完就把紙轉回來:push() 保存畫布狀態、pop() 還原,每一圈都從同一張紙開始;先移再轉和先轉再移,結果不一樣。
- 表情筆刷:把一張臉變成筆刷:translate 到滑鼠之後,五官只要算相對位置;共用同一個變數,兩隻眼睛才不會鬥雞眼。
數學
- 弧線遊樂場:一段弧線怎麼長成鸚鵡螺:arc() 畫一段沒畫完的橢圓;配上 rotate(frameCount) 讓它每一格多轉一點、順便長大。
- sin → map → 顏色:sin 在 −1 到 1 之間來回擺,map 把它換算成 0 到 255,就能當成會呼吸的顏色。
- sin 與 cos:一個點繞圓,影子在上下與左右擺:點在圓上轉,左右是 cos、上下是 sin;把 sin 隨時間畫下來就是波浪,(r·cos, r·sin) 能排成一圈。
- random():每一次都抽一支新的籤:random(a, b) 每次在 a 到 b 之間抽一個數;randomSeed() 把籤筒順序固定,同一個種子永遠同一組結果。
- noise() vs random():會跳的亂數和會流動的亂數:random() 每次都是全新的籤、會跳;noise() 相鄰的輸入得到相近的值、會流動,像山脈和水流。「裡面除・外面除」模式:noise(x / 10) 的 10 管取樣多平順,外面再除管力量多大。
- 向量:一支有方向、有長度的箭頭:向量=往哪個方向、走多遠;可以相加(頭接尾)、旋轉、放大縮小,一直累加就是在畫一條路徑。
- 一顆粒子:位置、速度、加速度:每一格:速度加到位置上、加速度加到速度上;拖曳把球丟出去,撞到邊就反彈。
- 力場:用 noise 給每一格一個方向:把 noise 的值換成角度,畫面上每一格都有一支箭頭;粒子走到哪一格,就被那一格的箭頭推著走。
- 粒子系統:很多顆粒子,留下軌跡:幾百顆粒子跟著力場走,不清畫面、只蓋一層很淡的底色,軌跡就留下來變成畫。
- 很多力加在一起:重力、風、阻力:每一個力都是一支向量,applyForce 把它們加進加速度;質量越大越難推動,每一格最後要把加速度歸零。
- 吸引與排斥:往滑鼠走的粒子:目標減掉自己的位置,就是「往那裡去」的向量;調成固定長度當成力,粒子就會被滑鼠吸過去或推開。
- 粒子的生與死:發射器與壽命:發射器每一格生出新粒子,粒子帶著壽命慢慢變淡,死掉就從陣列移除;陣列長度會穩定在一個數字。
- 宇宙模擬器:萬有引力:每一顆星都拉著其他所有的星:力跟質量成正比、跟距離平方成反比。拖曳丟出一顆星,看它繞行、被吞掉或被甩出去。
- noise 怎麼取值:步長與切片:noise(x, y, z) 是在一片連續的地形上取值:除得越大、步子越小,相鄰兩點越接近,所以越連續;z 換一個數字就是換一張切片,v.x 和 v.y 用不同切片才不會都往同一個方向。
自然的演算法
- 海龜繪圖:往前走、轉彎:海龜只懂 F(前進畫線)和 + − (轉彎);translate 走到線尾、rotate 轉向,就是 p5 的海龜,也是 L-System 與遞迴樹的地基。
- 遞迴分裂:一個變兩個:遞迴就是函式呼叫自己:branch 畫一段、走到尾端、左右各分一枝,每多一層數量翻倍(2 的 n 次方);也可以看成粒子壽命到了就分裂成兩顆,走過的路就是樹枝。
- L-System:用一條字串長出植物:L-System 分兩步:先把字串一代一代替換、越換越長,再交給海龜畫(F 畫線、+ − 轉向、[ 記住位置、] 回到記住的位置)。
- 碎形:自己裡面還有自己:碎形是放大看細節還是跟整體一樣;每層把形狀拆成幾個縮小的自己,數量隨深度成倍成長(Koch 雪花、Sierpinski 三角形、圓中圓、H 樹)。
- Boids 群聚:三條規則,沒有領頭:Craig Reynolds 的 Boids:每隻鳥只看感知半徑內的鄰居,守分離、對齊、聚合三條規則,沒有領頭的鳥,鳥群自己長出來。
- 鏈條:兩條限制,長出會游的身體:一串點,頭追滑鼠,每一點用「距離固定」和「夾角限制」兩條規則跟著前一點;再沿脊椎的法線依寬度畫出蛇或魚的身體。
- 地形:noise 就是一張高度圖:noise(x / scl, y / scl) 給每個點一個 0–1 的高度:按高度分段上色是地圖,畫高度相同的線是等高線,一排排往下畫是山脈剪影。
- 年輪:用 noise 繞一個圈:半徑加上 noise 就是不規則的圈;noise 要用 (cos(a)*k, sin(a)*k) 取值,走回起點值一樣,圈才接得起來,用 noise(a) 取值接縫會斷;每圈換第三個座標就長成年輪。
- 圓填滿:一個一個長大,互不重疊:每格在隨機位置試著放新圓,被別的圓蓋住就放棄;圓一直長大,dist() 小於兩半徑相加加間隙就停,慢慢塞滿,縫隙被小圓填掉(Circle Packing)。
- Boids 向量解剖:一隻鳥怎麼算出下一步:把 Boids 一隻鳥的一步拆成七個向量操作:找鄰居、分離、對齊、聚合、轉向(力=想要的速度-現在的速度)、合力、更新;畫面一步一步畫箭頭,程式碼放在旁邊,亮起來的行就是現在這一步。
聲音 × 視覺
- 喊、敲、彈:同一個畫面,三種聲音進來:麥克風、鼓機、鍵盤都會叫同一組回呼(kickDetected、notePressed…),畫面的程式不用改;開場先看整堂的地圖。
- 聲音是一條波:多大聲、多高:聲音是空氣的振動:波有多高是多大聲(振幅),一秒振動幾次是多高(頻率,赫茲);可以聽、可以用麥克風看自己的聲音。
- 音量 micLevel:從波形到 0..1:一小段波形算 RMS、換成分貝,再把一段分貝夾成 0..1,就是 oav-p5 的 micLevel;為什麼要用分貝:耳朵聽的是比例;底線會跟著房間的底噪走。
- 頻譜:bass、mid、treble:一個聲音裡同時有很多頻率,FFT 把它拆開;oav-p5 把它分成低、中、高三段(20–250、250–2000、2000–8000 Hz)。
- 節拍偵測:什麼時候算「一下」:比最近的平均大一截、而且離上一下超過 100 毫秒,就算一下;拍手容易算、講話不容易。
- 對應:把聲音的數字變成畫面:map() 把 0..1 換成大小、顏色、速度、數量;constrain 夾住範圍;換一條曲線,小聲也看得到。
- lag:數字用追的,不要用跳的:照秒數追上去:上升、下降各一個秒數(跟 TouchDesigner 的 Lag CHOP 同一件事);lerp 會因為電腦快慢手感不同。
- env:打一下就是一個包絡:一下事件跳到 1 再慢慢回到 0(TouchDesigner 的 Trigger CHOP);attack、decay 兩個秒數;連打會重新觸發。
- 16 步音序器:時間一格一格走:一小節切成 16 格,播放頭每格往前一步;BPM 決定一格多長;這就是 Demo 2 那張鼓機卡。
- 一行字寫節奏:空白等分、* 加快、~ 休息、[ ] 擠進一拍、逗號疊層、(3,8)、< >:每個字都對得到時間軸上的一下,正在響的字會亮;打錯會標出第幾個字;下面同時看放進 16 格的樣子。
- 歐幾里得節奏:k 下平均分在 n 格:把 k 下盡量平均地放進 n 格;很多傳統節奏就是它((3,8)、(5,8));第三個數字是晚幾格開始;大鼓、小鼓、鈸三圈疊起來就是 bd(3,8), sd(2,8,2), hh(5,8)。
- 小節、拍、步:BPM 換成秒:60 ÷ BPM 是一拍幾秒;一小節 4 拍 16 步;drumPhase、beatPhase 連續地走;cue() 在第幾小節觸發。
- MIDI:一個音是一個號碼加一個力度:note 0–127(60 是中央 C)、velocity 是按多用力、旋鈕 0–127 變成 0..1;底下傳的是三個位元組。
- 音高變顏色、變位置:MIDI 號碼換成頻率;一個八度繞一圈就是色相環;音高也可以變成 x 位置;和弦是一個幾何形狀。
到 Hahow 報名。價格與優惠以 Hahow 頁面為準。