--- tags: 程式設計教材庫,範例版,互動藝術程式創作入門,Creative Coding --- # 第二個作業_學生版 --- ## 步驟1: 隨意畫一張圖 ![截圖 2023-12-24 下午11.53.25](https://hackmd.io/_uploads/r1Mr4ArwT.png) --- ### 程式碼 ```javascript= function setup() { createCanvas(windowWidth, windowHeight); //建立一個畫布,畫布為視窗大小的寬高 background("#fff1e6") } function draw() { fill("#ffd500") ellipse(360,242,200) //大圓 ellipse(280,155,80) //左耳 fill("#fdf0d5") ellipse(280,155,40) fill("#ffd500") ellipse(440,155,80) //右耳 fill("#fdf0d5") ellipse(440,155,40) fill("#000000") ellipse(330,200,30) //左眼 ellipse(380,200,30) //右眼 line(230,230,290,230) //左邊第一跟鬍子 line(230,260,290,260) //第二根 line(230,290,290,290) //第三根 line(420,230,480,230) //右邊第一跟鬍子 line(420,260,480,260) //第二根 line(420,290,480,290) //第三根 fill("#bc6c25") ellipse(360,248,20) //鼻子 line(358,258,350,264) line(362,258,370,264) fill("#e56b6f") ellipse(360,300,45,35) //嘴巴 } ``` ## 步驟2:眼睛隨著滑鼠移動 ![動畫3](https://hackmd.io/_uploads/Sku8FdUwp.gif) ```javascript function setup() { createCanvas(windowWidth, windowHeight); //建立一個畫布,畫布為視窗大小的寬高 background("#fff1e6") } function draw() { fill("#ffd500") ellipse(360,242,200) //大圓 ellipse(280,155,80) //左耳 fill("#fdf0d5") ellipse(280,155,40) fill("#ffd500") ellipse(440,155,80) //右耳 fill("#fdf0d5") ellipse(440,155,40) fill("#000000") ellipse(330+mouseX/30,200,30) //左眼 ellipse(380+mouseX/30,200,30) //右眼 line(230,230,290,230) //左邊第一跟鬍子 line(230,260,290,260) //第二根 line(230,290,290,290) //第三根 line(420,230,480,230) //右邊第一跟鬍子 line(420,260,480,260) //第二根 line(420,290,480,290) //第三根 fill("#bc6c25") ellipse(360,248,20) //鼻子 line(358,258,350,264) line(362,258,370,264) fill("#e56b6f") ellipse(360,300,45,35) //嘴巴 } ``` ## 步驟3:產生不同顏色的圖 ![截圖 2023-12-25 上午12.11.12](https://hackmd.io/_uploads/HkBcdABDa.png) --- ### 程式碼 ```javascript= var face_clr = "f9dc5c-fae588-fcefb4-fdf8e1-f9dc5c".split("-").map(a=>"#"+a) var eye_clr = "251605-c57b57-f1ab86-f7dba7-9cafb7f8f9fa-e9ecef-dee2e6-ced4da-adb5bd-6c757d-495057-343a40-212529".split("-").map(a=>"#"+a) function setup() { createCanvas(windowWidth, windowHeight); for(var i = 0;i<20;i=i+1){ drawface(face_clr[int(random(face_clr.length))],eye_clr[int(random(eye_clr.length))],random(0.3,1.2)) } } function drawface (face_clr=255,eye_clr=0,size=1) { //255與0為預設的值 push() //自行設定格式 translate(random(width),random(height)) //把原點(0,0)移動到(200,200) scale(size) fill(face_clr) fill(face_clr) ellipse(360,242,200) //臉 ellipse(280,155,80) //左耳 fill("#fdf0d5") ellipse(280,155,40) fill("#ffd500") ellipse(440,155,80) //右耳 fill("#fdf0d5") ellipse(440,155,40) fill(eye_clr) ellipse(330,200,30) //左眼 ellipse(380,200,30) //右眼 line(230,230,290,230) //左邊第一跟鬍子 line(230,260,290,260) //第二根 line(230,290,290,290) //第三根 line(420,230,480,230) //右邊第一跟鬍子 line(420,260,480,260) //第二根 line(420,290,480,290) //第三根 fill("#bc6c25") ellipse(360,248,20) //鼻子 line(358,258,350,264) line(362,258,370,264) fill("#e56b6f") ellipse(360,300,45,35) //嘴巴 pop() } ``` ## 步驟4:按下滑鼠產生圖案 ![動畫2](https://hackmd.io/_uploads/H1BqIdIv6.gif) ```javascript= var face_colors = "f9dc5c-fae588-fcefb4-fdf8e1-f9dc5c".split("-").map(a=>"#"+a) var eye_colors = "003049-d62828-f77f00-fcbf49-eae2b7".split("-").map(a=>"#"+a) // var pos_x=[200,500] // var pos_y=[400,600] // var sizes=[0.6,0.2] // var colors=["#ffb5a7","#fcd5ce"] var pos_x=[] var pos_y=[] var sizes=[] var colors=[] var v_y=[] var v_x=[] function setup() { createCanvas(windowWidth, windowHeight); // for(var i = 0;i<20;i=i+1){ // drawface(face_clr[int(random(face_clr.length))],eye_clr[int(random(eye_clr.length))],random(0.3,1.2)) // } } function draw() { background("#e0aaff"); for(var i=0;i<pos_x.length;i=i+1){ push() translate(pos_x[i],pos_y[i]) drawface(colors[i],0,sizes[i]) pop() pos_y[i] = pos_y[i] + v_y[i] if(pos_y[i]>height || pos_y[i]<0) { pos_x.splice(i,1) pos_y.splice(i,1) sizes.splice(i,1) colors.splice(i,1) v_y.splice(i,1) } } } function drawface (face_clr=255,eye_clr=0,size=1) { //255與0為預設的值 push() //自行設定格式 // translate(random(width),random(height)) //把原點(0,0)移動到(200,200) scale(size) fill(face_clr) ellipse(360,242,200) //大圓 ellipse(280,155,80) //左耳 fill("#fdf0d5") ellipse(280,155,40) fill("#ffd500") ellipse(440,155,80) //右耳 fill("#fdf0d5") ellipse(440,155,40) fill(eye_clr) ellipse(330,200,30) //左眼 ellipse(380,200,30) //右眼 line(230,230,290,230) //左邊第一跟鬍子 line(230,260,290,260) //第二根 line(230,290,290,290) //第三根 line(420,230,480,230) //右邊第一跟鬍子 line(420,260,480,260) //第二根 line(420,290,480,290) //第三根 fill("#bc6c25") ellipse(360,248,20) //鼻子 line(358,258,350,264) line(362,258,370,264) fill("#e56b6f") ellipse(360,300,45,35) //嘴巴 pop() } function mousePressed(){ pos_x.push(mouseX) pos_y.push(mouseY) sizes.push(random(0.3,1)) colors.push(face_colors[int(random(face_colors.length))]) v_y.push(random(-1,1)) } ``` --- ## 步驟5: 移動暫停鍵可以使用 ![動畫](https://hackmd.io/_uploads/BkONfuUwa.gif) --- ### 程式碼 ```javascript= var face_colors = "003049-d62828-f77f00-fcbf49-eae2b7".split("-").map(a=>"#"+a) var eye_colors = "251605-c57b57-f1ab86-f7dba7-9cafb7".split("-").map(a=>"#"+a) // var pos_x=[200,500] // var pos_y=[400,600] // var sizes=[0.6,0.2] // var colors=["#ffb5a7","#fcd5ce"] var pos_x=[] var pos_y=[] var sizes=[] var colors=[] var v_y=[] var v_x=[] var txts //宣告一個變數,變數存放著文字框內容 var face_move_var = false function setup() { createCanvas(windowWidth, windowHeight); intputElement = createInput("412730482陳儷靜") intputElement.position(10,10) //把文字方塊放到(10,10) intputElement.size(160,20) //文字的寬與高 //以下的style,可以搜尋 html input css找到相關資料 intputElement.style("font-size","20px") //文字框內的大小 intputElement.style("color","#0353a4") //文字顏色 intputElement.style("background","#e0aaff") //文字框的背景顏色 intputElement.style("border","none") // //按鈕的設定 btnMoveElement = createButton("移動") //產生一個按鈕,按鈕上有移動的字眼 btnMoveElement.position(170,10) //按鈕的位置 btnMoveElement.size(80,40) btnMoveElement.style("font-size","20px") btnMoveElement.style(color,"#0353a4") btnMoveElement.style("background-color","#2f3e46") btnMoveElement.mousePressed(face_move) btnStopElement = createButton("暫停") btnStopElement.position(270,10) //按鈕的位置 btnStopElement.size(80,40) btnStopElement.style("font-size","20px") btnStopElement.style(color,"#0353a4") btnStopElement.style("background-color","#2f3e46") btnStopElement.mousePressed(face_stop) //radio的設定,多個選項,只能選擇一個(單選題) radioElement = createRadio() radioElement.option("暫停") radioElement.option("旋轉") radioElement.option("移動") radioElement.position(370,10) //選鈕的位置 radioElement.size(200,40) radioElement.style("font-size","20px") radioElement.style(color,"#fff") radioElement.style("background-color","#fff3b0") // for(var i = 0;i<20;i=i+1){ // drawface(face_clr[int(random(face_clr.length))],eye_clr[int(random(eye_clr.length))],random(0.3,1.2)) // } } function draw() { background("#e0aaff"); for(var i=0;i<pos_x.length;i=i+1){ push() txts = intputElement.value(); //把文字框的文字內容,放到txts變數內 translate(pos_x[i],pos_y[i]) drawface(colors[i],0,sizes[i]) pop() if(face_move_var){ pos_y[i] = pos_y[i] + v_y[i] } if(pos_y[i]>height || pos_y[i]<0) { pos_x.splice(i,1) pos_y.splice(i,1) sizes.splice(i,1) colors.splice(i,1) v_y.splice(i,1) } } } function drawface (face_clr=255,eye_clr=0,size=1) { //255與0為預設的值 push() //自行設定格式 // translate(random(width),random(height)) //把原點(0,0)移動到(200,200) //文字框的顯示格式 scale(size) //先宣告放大縮小的比例尺 fill("#fff") fill(face_clr) ellipse(360,242,200) //大圓 ellipse(280,155,80) //左耳 fill("#fdf0d5") ellipse(280,155,40) fill("#ffd500") ellipse(440,155,80) //右耳 fill("#fdf0d5") ellipse(440,155,40) fill(eye_clr) ellipse(330,200,30) //左眼 ellipse(380,200,30) //右眼 line(230,230,290,230) //左邊第一跟鬍子 line(230,260,290,260) //第二根 line(230,290,290,290) //第三根 line(420,230,480,230) //右邊第一跟鬍子 line(420,260,480,260) //第二根 line(420,290,480,290) //第三根 fill("#bc6c25") ellipse(360,248,20) //鼻子 line(358,258,350,264) line(362,258,370,264) fill("#e56b6f") ellipse(360,300,45,35) //嘴巴 pop() } function mousePressed(){ if(mouseY>60){ //設定y軸為設定0~60間的座標值 //產生一個新的物件 pos_x.push(mouseX) pos_y.push(mouseY) sizes.push(random(0.3,1)) colors.push(face_colors[int(random(face_colors.length))]) v_y.push(random(-1,1)) } } function face_move(){ face_move_var = true } function face_stop(){ face_move_var = false } ``` --- ## 步驟6: 按下音樂鍵有音樂 ![螢幕擷取畫面 2023-12-25 131659](https://hackmd.io/_uploads/SkY_l9IPa.png) --- ### 程式碼 ```javascript= var sound1; var analyzer; function preload(){ sound1 = loadSound("mixkit-deep-urban-623.mp3") } var face_colors = "ffb5a7-fcd5ce-f8edeb-f9dcc4-fec89a".split("-").map(a=>"#"+a) var eye_colors = "251605-c57b57-f1ab86-f7dba7-9cafb7".split("-").map(a=>"#"+a) // var pos_x=[200,500] // var pos_y=[400,600] // var sizes=[0.6,0.2] // var colors=["#ffb5a7","#fcd5ce"] var pos_x=[] var pos_y=[] var sizes=[] var colors=[] var v_y=[] var v_x=[] var txts //宣告一個變數,變數存放著文字框內容 var face_move_var = false var lang = navigator.language //取的瀏覽器的語系 var myRec = new p5.SpeechRec(lang) var face_Rot_var = false function setup() { createCanvas(windowWidth, windowHeight); analyzer = new p5.Amplitude(); analyzer.setInput(sound1); intputElement = createInput("412730482陳儷靜") intputElement.position(10,10) //把文字方塊放到(10,10) intputElement.size(160,20) //文字的寬與高 //以下的style,可以搜尋 html input css找到相關資料 intputElement.style("font-size","20px") //文字框內的大小 intputElement.style("color","#0353a4") //文字顏色 intputElement.style("background","#e0aaff") //文字框的背景顏色 intputElement.style("border","none") // //按鈕的設定 btnMoveElement = createButton("移動") //產生一個按鈕,按鈕上有移動的字眼 btnMoveElement.position(170,10) //按鈕的位置 btnMoveElement.size(80,40) btnMoveElement.style("font-size","20px") btnMoveElement.style(color,"#0353a4") btnMoveElement.style("background-color","#2f3e46") btnMoveElement.mousePressed(face_move) btnStopElement = createButton("暫停") btnStopElement.position(270,10) //按鈕的位置 btnStopElement.size(80,40) btnStopElement.style("font-size","20px") btnStopElement.style(color,"#0353a4") btnStopElement.style("background-color","#2f3e46") btnStopElement.mousePressed(face_stop) btnVoiceElement = createButton("音樂") //產生一個按鈕,按鈕上有移動的字眼 btnVoiceElement.position(600,10) //按鈕的位置 btnVoiceElement.size(80,40) btnVoiceElement.style("font-size","20px") btnVoiceElement.style(color,"#0353a4") btnVoiceElement.style("background-color","#2f3e46") btnVoiceElement.mousePressed(voice_go) //radio的設定,多個選項,只能選擇一個(單選題) radioElement = createRadio() radioElement.option("暫停") radioElement.option("旋轉") radioElement.option("移動") radioElement.position(370,10) //選鈕的位置 radioElement.size(200,40) radioElement.style("font-size","20px") radioElement.style(color,"#fff") radioElement.style("background-color","#fff3b0") radioElement.mousePressed(face_move) // for(var i = 0;i<20;i=i+1){ // drawface(face_clr[int(random(face_clr.length))],eye_clr[int(random(eye_clr.length))],random(0.3,1.2)) // } } function draw() { background("#e0aaff"); var mode = radioElement.value(); for(var i=0;i<pos_x.length;i=i+1){ push() txts = intputElement.value(); //把文字框的文字內容,放到txts變數內 translate(pos_x[i],pos_y[i]) if(mode=="旋轉" || face_Rot_var){ rotate(sin(frameCount/10*v_y[i])) } drawface(colors[i],0,sizes[i]) pop() if(face_move_var || mode=="移動"){ pos_y[i] = pos_y[i] + v_y[i] } if(pos_y[i]>height || pos_y[i]<0) { pos_x.splice(i,1) pos_y.splice(i,1) sizes.splice(i,1) colors.splice(i,1) v_y.splice(i,1) } } } function drawface (face_clr=255,eye_clr=0,size=1) { //255與0為預設的值 push() //自行設定格式 // translate(random(width),random(height)) //把原點(0,0)移動到(200,200) //文字框的顯示格式 scale(size) //先宣告放大縮小的比例尺 fill(face_clr) ellipse(360,242,200) //臉 ellipse(280,155,80) //左耳 fill("#fdf0d5") ellipse(280,155,40) fill("#ffd500") ellipse(440,155,80) //右耳 fill("#fdf0d5") ellipse(440,155,40) fill(eye_clr) ellipse(330,200,30) //左眼 ellipse(380,200,30) //右眼 line(230,230,290,230) //左邊第一跟鬍子 line(230,260,290,260) //第二根 line(230,290,290,290) //第三根 line(420,230,480,230) //右邊第一跟鬍子 line(420,260,480,260) //第二根 line(420,290,480,290) //第三根 fill("#bc6c25") ellipse(360,248,20) //鼻子 line(358,258,350,264) line(362,258,370,264) fill("#e56b6f") ellipse(360,300,45,35) //嘴巴 pop() //把原本設定的格式全部取消 } function mousePressed(){ if(mouseY>60){ //設定y軸為設定0~60間的座標值 //產生一個新的物件 push() pos_x.push(mouseX) pos_y.push(mouseY) sizes.push(random(0.3,1)) colors.push(face_colors[int(random(face_colors.length))]) v_y.push(random(-1,1)) pop() } } function face_move(){ face_move_var = true } function face_stop(){ face_move_var = false } function voice_go(){ myRec.onResult = showResult //取的語音辨識後去執行function showResult myRec.start() //開始辨識 } function showResult(){ if(myRec.resultValue == true){ print(myRec.resultString) let lowStr = myRec.resultString.toLowerCase(); let mostrecentword = lowStr.split('').pop(); if(myRec.resultString.indexOf("走") !== -1){ face_move_var = true } if(myRec.resultString.indexOf("停") !== -1){ face_move_var = false face_Rot_var = false if(myRec.resultString.indexOf("轉") !== -1){ face_Rot_var = true } } } } function voice_go(){ //按下音樂鍵有音樂 if(sound1.isPlaying){ sound1.play(); } else{ sound1.stop(); } } ``` --- ## 步驟7: 按下開始會有音樂並跟著動 ## 按下暫停停止擺動,音樂也暫停 -![動畫4](https://hackmd.io/_uploads/S1tjVc8v6.gif) -- ### 程式碼 ```javascript= function preload(){ sound1 = loadSound("mixkit-deep-urban-623.mp3") } var face_colors = "ffb5a7-fcd5ce-f8edeb-f9dcc4-fec89af".split("-").map(a=>"#"+a) var eye_colors = "251605-c57b57-f1ab86-f7dba7-9cafb7".split("-").map(a=>"#"+a) //var pos_x=[200,500] //var pos_y=[400,600] //var sizes=[0.6,0.2] //var colors=["#00b4d8","#edede9"] var pos_x=[] //產生物件的x軸位置 var pos_y=[] var sizes=[] var colors=[] var v_y=[] //移動速度 var v_x=[] var txts var face_move_var = false //語音辨識的初始設定 var lang = navigator.language ||en-US //瀏覽器的語系 var myRec = new p5.SpeechRec(lang) var face_Rot_var = false function setup() { createCanvas(windowWidth, windowHeight); analyzer=new p5.Amplitude(); analyzer.setInput(sound1); inputElement = createInput("412730482") //產生一個文字方塊 inputElement.position(10,10) //把把文字方塊放到(10,10) inputElement.size(140,20) //以下style,可以google搜尋html input css找到相關資料 inputElement.style("font-size","20px") inputElement.style("color","#fff") //文字框的背景顏色 inputElement.style("background","#bde0fe") //文字框的背景顏色 inputElement.style("border","none") //"移動"按鈕設定 btnMoveElement = createButton("移動") //產生一個按鈕,按鈕上有"移動"字 btnMoveElement.position(170,10) //按鈕的位置 btnMoveElement.size(80,40) //按鈕的高與寬 btnMoveElement.style("font-size","20px") //按鈕內的文字大小 btnMoveElement.style("color","#fff") //按鈕內的文字顏色 btnMoveElement.style("background","#2f3e46") btnMoveElement.mousePressed(face_move) //"暫停"按鈕設定 btnStopElement = createButton("暫停") btnStopElement.position(270,10) //按鈕的位置 btnStopElement.size(80,40) btnStopElement.style("font-size","20px") btnStopElement.style("color","#fff") btnStopElement.style("background","#2f3e46") btnStopElement.mousePressed(face_stop) //radio的設定,多個選項,只能選一個(單選) radioElement = createRadio() radioElement.option("暫停") radioElement.option("旋轉") radioElement.option("移動") radioElement.position(370,10) //選鈕的位置 radioElement.size,(200,40) //選鈕的高與寬 radioElement.style("font-size","20px") //選鈕內的文字大小 radioElement.style("color","#fff") //選鈕內的文字顏色 radioElement.style("background-color","#2f3e46") radioElement.mousePressed(face_move) //"語音"按鈕設定 btnVoiceElement = createButton("音樂") btnVoiceElement.position(600,10) //按鈕的位置 btnVoiceElement.size(80,40) btnVoiceElement.style("font-size","20px") btnVoiceElement.style("color","#fff") btnVoiceElement.style("background","#2f3e46") btnVoiceElement.mousePressed(voice_go) //checkBox的設定,多個選項,可以選多個(複選題) //for(var i=0;i<20;i=i+1){ //drawface(face_colors[int(random(face_colors.length))],eye_colors[int(random(eye_colors.length))],random(0.3,1.2)) //} } function draw() { background("#bde0fe"); mode= radioElement.value(); for(var i=0;i<pos_x.length;i=i+1) { push() txts = inputElement.value(); translate(pos_x[i],pos_y[i]) if(sound1.isPlaying()){ AudioContext=getAudioContext(); amplitude=map(analyzer.getLevel(),0,1,0,100) angle=sin(amplitude*v_y[i]) rotate(angle) drawface(colors[i],0,sizes[i]) } else{ drawface(colors[i],0,sizes[i]) } if(mode =="旋轉" || face_Rot_var ){ rotate(sin(frameCount/20*v_y[i])) } drawface(colors[i],0,sizes[i]) pop() if(face_move_var ||mode =="移動" ){ //在face_move_var為ture的時候,臉物件會移動 pos_y[i] = pos_y[i] + v_y[i] //移動 } if(pos_y[i]>height || pos_y[i]<0 ) //判斷有沒有碰到上邊 { pos_x.splice(i,1) pos_y.splice(i,1) sizes.splice(i,1) colors.splice(i,1) v_y.splice(i,1) } } } function drawface(face_clr=255,eye_clr=0,size=1){ //255與0為預設的值 push() //自行設定格式 //translate(random(width),random(height)) //原點(0,0)移動到(200,200) scale(size) //先宣告放大縮小的比例尺 //文字框的顯示格式 fill("#023047") //設定文字顏色 textSize(50) //文字大小 text(txts,-50,250) //顯示文字,文字內容為txts,放在位置座標為(50,200) fill(face_clr) ellipse(360,242,200) //臉 ellipse(280,155,80) //左耳 fill("#fdf0d5") ellipse(280,155,40) fill("#ffd500") ellipse(440,155,80) //右耳 fill("#fdf0d5") ellipse(440,155,40) fill(eye_clr) ellipse(330,200,30) //左眼 ellipse(380,200,30) //右眼 line(230,230,290,230) //左邊第一跟鬍子 line(230,260,290,260) //第二根 line(230,290,290,290) //第三根 line(420,230,480,230) //右邊第一跟鬍子 line(420,260,480,260) //第二根 line(420,290,480,290) //第三根 fill("#bc6c25") ellipse(360,248,20) //鼻子 line(358,258,350,264) line(362,258,370,264) fill("#e56b6f") ellipse(360,300,45,35) //嘴巴 pop() //把原本設定全部取消 } function mousePressed(){ if(mouseY>60){ //設定Y軸為0~60間的座標值都不會產生物件 pos_x.push(mouseX) pos_y.push(mouseY) sizes.push(random(0.5,0.3)) colors.push(face_colors[int(random(face_colors.length))]) v_y.push(random(-1,1)) print(pos_x) } } function face_move(){ face_move_var = true sound1.play(); } function face_stop(){ face_move_var = false sound1.stop(); } function voice_go(){ myRec.onResult = showResult //取的語音辨識後去執行function myRec.start() //開始辨識 } function showResult(){ if(myRec.resultValue == true) { print(myRec.resultString) let lowStr = myRec.resultString.toLowerCase(); let mostrecentword = lowStr.split(' ').pop(); // if(myRec.resultString.indexOF("走") !== -1){ face_move_var = true } if(myRec.resultString.indexOF("停") !== -1){ face_move_var = false face_Rot_var = false } if(myRec.resultString.indexOF("轉") !== -1){ face_Rot_var = true } } } ``` --- ## 步驟5: 按下滑鼠,開口 ![](https://hackmd.io/_uploads/r1RoKr-mo.gif) --- ### 程式碼 ```javascript= ``` --- ## 搭配聲音 ![](https://hackmd.io/_uploads/rkNWynb7o.gif) ```javascript= ``` 第二個作業_學生版.md 目前顯示的是「第二個作業_學生版.md」。