寫在前面的話
很久沒有寫博文了。最近在整理Processing有關文件,看到之前做的一些例子,想著分享在網際網路上,當然和以前一樣,目前也僅為了給初學者有個學習參考,筆者能力有限。廢話不多說,幹就完事了。
來做個紋理怎麼樣?基本紋理很多樣式,我們慢慢嘗試去實現,今天搞一個網格紋理,準確的說是棋盤格,就像下圖所示:
開始
首先寫好Processing該有的樣子,定義settings()
,setup()
,draw()
等函式:
void settings(){
size(800,800);
}
void setup() {
}
void draw() {
}
這個settings()
我會單獨去做講解,這裡簡單說一下:它是早於setup()
初始化的處理函式,有點像Unity指令碼系統中Start()
和Awake()
的關係,但是邏輯層面是不一樣的。很多PApplet類中的函式在這裡是不能被呼叫的,除了size()
和smooth()
兩個函式。而且,一旦寫了settings()
,就必須得把上述兩個函式寫在settings()
裡頭!大家以後都可以養成習慣這麼去填寫,因為Processing系統這麼設定,有它的道理,不過如果是純碎學習,那不碼這個settings()
也無妨。還有個值得說的,因為只是要做個圖,其實draw()
沒必要寫上。
小試牛刀
我們先試一試畫一個矩形框,如下:
noStroke();
fill(255);
rect(150,150,100,100);
這樣會在畫布上出現一個白色矩形框,ok,接下來要做的是把這個事情給過程化(程式導向),寫個函式封裝其過程:
void drawRect(int c, int x, int y, int w, int h) {
noStroke();
fill(c);
rect(x, y, w, h);
}
drawRect()
可以被傳入五個引數,分別代表其顏色、座標資訊x,y、矩形長寬大小。為什麼能這麼去封裝它,這要求思考問題本身。細細觀察棋盤格的特點,黑白方塊相隔,如果抽象出它的屬性,那麼就不難想得到有諸如上述的引數,我們把它稱之為屬性(當然這個說法其實是不嚴謹的,因為現在我們的程式設計思路僅僅是程式導向,在OOP物件導向中這個特點會更加明顯)[哦對,有讀者感興趣的話也能找找有關函數語言程式設計的資料,絕對會讓你開拓眼界,在思考問題的方式上會有不一樣的感受哦,參考https://www.zhihu.com/question/28292740?sort=created]。
再接再厲
有了這個函式就可以在外頭傳進引數來繪製想要的結果,那問題來了,如何傳進去?首先是顏色,顏色好辦,
int c = color(200,20,20); //這裡可以將color型別看成是int 型別,其實在計算機裡顏色這概念也就是一個數值而已
這樣就結束了。然後是位置,如果你之前學過或者感受過迴圈結構(程式設計是要多多感受的,你說程式設計有沒有套路,其實很多時候是可以憑經驗辦事的),那麼就不難想到兩個for迴圈遍歷來繪製佈滿整個畫布的圖形的例子,那在這裡,同樣是做這樣的處理(這就是所謂的演算法):
for (int x = 0; x < width; x += increW)
{
for (int y = 0; y < height; y += increH)
{
int c = color(255);
drawRect(c, x, y, increW, increH);
}
}
而對於矩形大小,我們做一假設,設想要在畫布上繪製10*10個方塊陣列,那麼每個方塊的大小,即位置偏移增量increW
和increH
(increment表示增量,一般我們會使用常用的英文縮寫定義變數名)就可以這麼計算得出:
increW = width / WCOUNT; // WCOUNT、HCOUNT代表數量10、10 你可以寫成 increW=width/WCOUNT;這樣,沒問題!
increH = height / HCOUNT; // 但是養成良好的程式設計習慣和修養,加上些空格,你自己也覺得便於閱讀,還haokanmeiguan
在for語句的第三個表示式中寫明x自加increW,y自加increH,得到的結果便是每次傳入drawRect()
函式中的位置有了相應偏移,大小也有了定義,即每次位移的數值。如果你按照這一步驟敲碼執行,你會得到全白的畫布,為什麼呢?很簡單,事實上Processing已經幫你繪製了這麼多方塊,只是顏色統一,位置統一,完美無瑕得散步在畫布上了,沒有任何縫隙。而要想實現間隔黑白效果,是不是還得加上黑色方塊呢。是的,就得是要繪製這樣的rect:
noStroke();
fill(0);
rect(150,150,100,100);
但是,如何把它整合在for迴圈體裡呢?這就又要談到簡單的演算法技巧,我們可以引入一個開關變數來處理間隔繪製不同顏色的流程,對於"開關變數"這一說法,讀者請參考https://blog.csdn.net/fddxsyf123/article/details/62848357這一篇之前寫的。在這裡你腦力應是如下的邏輯:
if(k == 0)
{
fill(255);
rect(150,150,100,100);
}
if(k == 1)
{
fill(0);
rect(150,150,100,100);
}
結成正果
我們進一步把它簡化,看成是奇數和偶數差別,這樣只要定義一個int值,每次繪畫完畢,相當於狀態要改變了,就得切換,這個值自加一個值或者自減就可以達成了。有機整合進迴圈體,可以這樣表示:
int k = 0; // k代表狀態,具體數值代表什麼意思得看上下文
int c = 0;
for (int x = 0; x < width; x += increW)
{
for (int y = 0; y < height; y += increH)
{
if(k % 2 == 0) //注意這個判斷條件是關鍵的,判斷是否被2整除,如果真,則是偶數,反之奇數,這就達成了兩種狀態互切效果
c = color(255);
else
c = color(0);
drawRect(c, x, y, increW, increH);
k++; //一個狀態完畢,切換
}
k++; //現在是一列一列遍歷繪製,因此沒換一列也得切換狀態,形成棋盤網格效果
}
好了基本圖形已經展現出來了~~~ 完整程式碼如下:
int increW;
int increH;
int WCOUNT = 10;
int HCOUNT = 10;
void drawRect(int c, int x, int y, int w, int h) {
noStroke();
fill(c);
rect(x, y, w, h);
}
void settings() {
size(800, 800);
}
void setup() {
increW = width/WCOUNT;
increH = height/HCOUNT;
int k = 0;
int c = 0;
for (int x = 0; x < width; x += increW)
{
for (int y = 0; y < height; y += increH)
{
if (k % 2 == 0)
c = color(255);
else
c = color(0);
drawRect(c, x, y, increW, increH);
k++;
}
k++;
}
}
void draw() {
}
呈現的效果
寫在最後的話
好久沒寫了,是該多分享多交流,我會同步更新於CSDN上,請多多支援鼓勵,有問題留言,感謝。