2011/07/14

Structure 2 : Continuous (processing教學)

最近深居簡出下,自己都會好好的穩定心情好好精進,  才怪.

不是一會兒昏死在床上,要麻就是去游泳(暢游無邊的網海)
.............  但還好我良知未泯,快活過後總會看個一兩頁課本
.............  總知我知道只要持之以恆好漢也能磨成繡花針

anyway,  希望對processing有興趣的人可以自己多看一點,
因為我的進度實在是忽高忽低,正確來說是忽低忽無,
所以如果你真的很有興趣的話,多看點然後換你來教我. :)

------------------------------------------------------------------------------------------------------------------


在其一段落嘗試畫一張圖之後,我們即將進入如何做動畫,
但processing基本上只會生產圖面,也就是無論今天是2D或3D,
它所顯示的動畫都是靠一張一張圖接續而成的,
也就是我們常可以在網站上看到那些會動的圖片, GIF.

一切會從p173的Structure 2 : Continuous講起,
我們跳過了p144-172總共28頁(好爽噢),
因為這些內容主要是在介紹一些數位藝術家,
可能是靠寫flash或processing之類的來作畫,
我個人比較喜歡的是p153跟p157的內容,
詳情可以參考以下兩個網站

p153 Mandelbrot Set
http://processing.org/learning/topics/mandelbrot.html

p157 Complexification
http://www.complexification.net/
這網站我好喜歡啊,可是它絕大多數的作品都是用flash做的,
真的是永遠學不完啊,人真的要會取捨.

以下我想把東西講得直接一點(也就是不要問為什麼),可能還比較好理解.
當要做動畫時, void這個詞是很重要的,它代表一個空集合.
舉例來說當我們要吃牛排時,
void就是一些罐子,裡面裝的是胡椒跟海鹽,
當我們要喝濃湯時,我們拿胡椒罐,當我們要吃牛排時,我們拿海鹽罐.

也就是這些罐子(void)是預先準備好的,當有需要時再拿來用,
這可以避免當我們processing要寫很長時,往往會因為一個小地方寫錯而整個程式動不了,
雖然以我這猶如128mb隨身碟的腦袋要寫什麼可歌可泣落落長的程式是不可能地.

一個動畫的基本是絕對要有void setup()跟void draw()的,
setup指的是背景設定,也就是我們長長在設的size(),background(),smooth()等等.
而draw則是指畫void裡面的東西,通常我們會有void apple, void ball等等很多void,
但只會有一個void draw, 因為畢竟我們只有一個畫面,你同時draw一堆也看不到,
所以才會有很多void,然後叫進void draw內一起畫.
讓我以一個簡單的畫圓來解釋.會有兩組寫法,但結果一樣.


void setup(){
  size(200,200);
  background(255);

  noFill();
  smooth();
  //noLoop(); 
}

//我們可以看到setup裡面有我們常用的定義尺寸跟背景顏色和smooth,
//而noLoop這東西指的是不要loop,也就是不要畫動畫的意思
//所以通常我們是無需打它的,在這只是打給你試試看.


int n = 0;
int r = 0;

//這是一定要記得的一件事,所有在void draw內有用到的float或int
//請一定要打在void draw之外,p174有解釋


void draw(){
 
  frameRate(50); 

//frameRate代表的是播放速度,也就是每隔多久換下一張圖
//數字越高越快,但過高或過低則不會有效果了


  r += 1;
  n += 1;
 
  if(n > 0){
    background(255);
    n = 0;
  }

//因為我是要畫一個圓不斷放大,但如果我沒有把之前的圖蓋掉的話
//那前面的圖就會一直墊在下面遮不掉
//因為我在setup裡設noFill(),如果沒設其實效果一樣,但在這我想講的比較細些
//為了確保我每換一張圖的時候前面的圖都被蓋掉
//所以我設了一個int n, n += 1,並if它只要 > 0時馬上背景刷白,然後n再度為0

  if(r > 200){
    r = 0;
  }

//r是我圓的半徑,如果我今天不限制它一到200(也就是圓碰到圖框邊時)歸0
//那你就會看到圓一直畫然後就跑出圖框,一片白了


  ellipseMode(CENTER); 
  ellipse(100,100,r,r);

//簡單的畫圓

  //if(frameCount < 201){
  //  saveFrame("p178-1-###.jpg");
  //}

//我們前面在畫單張圖時,可以簡單的以saveFrame輸出
//但當動畫時,我們要每一步驟的圖片才能後續用軟體制成GIF
//所以就用if告訴電腦在算到201張圖之前,每一張圖都幫我存起來
//也就是frameCount,最後總共我們會算輸出200張
 
}




另一種的寫法就像我剛剛提到的,
我先寫好一個要畫圓的void,然後在我需要的時候再把它叫進void draw內,如下

void setup(){
  size(200,200);
  background(255);
  noFill();
  smooth();
}


int n = 0;
int r = 0;


void draw(){  

  frameRate(50);
 
  n += 1;

  r += 1;


  if(n > 0){
    background(255);
    n = 0;
  }

//到這都跟上面一樣,唯一不同的是下面

  cr(100,r);
//這代表我要把一個叫cr的void叫進來(就跟設int或float一樣)
//而它裡面的(100,r)對應的正是下面void cr內的(int x, int y)
//所以得到的結果我知道x永遠為100,而y會+=1
}


void cr(int x,int y){
  ellipseMode(CENTER);
  ellipse(x,x,y,y);

//這邊一定要記得的是,除了void draw外
//你任何void內所設的float或int都要寫在( )內
//這樣把它丟入void draw時,它才會抓得到你所設的參數


在經過簡單的介紹後,你應該知道void基本是在幹麻了,
再來就是如何絞盡腦汁去想怎麼畫囉.
另外請不要在void draw內寫for loop,
不是不能寫,只是不要寫卡好啦,自己試就知道為什麼了.

另外關於動畫怎麼後製,
一個是直接錄螢幕(我用的是Cam Studio)
一個是把圖片們做成GIF(我用的是Photoscape) 
應該都滿好在網路上找到 ? ? 版的 
再來就是今天的無題作品囉!


void setup(){
  size(200,200);
  background(255);
  smooth();
}

int n = 0;
int a = 0;
int r = 0;

void draw(){
 
  frameRate(50);
 
  r += 1;
  n += 1;
  a += 5;
 
  if(n > 300){
    background(255);
    n = 0;
  }
 
  if(r > 300){
    r = 0;
  }

  pushMatrix();
  rectA(a,r);
  popMatrix();
 
  translate(100,100);
  rotate(radians(a));
  strokeWeight(random(1,4));
  stroke(255,222);
  line(0,0,150,150);

  //if(frameCount < 301){
  //  saveFrame("p180-###.jpg");
  //}
}

void rectA(int q,int k){
  translate(100,100);
  rotate(radians(q));
  stroke(0,20);
  strokeWeight(0.5);
  fill(random(255),random(255),random(255),20);
  rectMode(CENTER); 
  rect(0,0,k,k);
}

Try it. :) 

沒有留言:

張貼留言