Processing程式語言回顧_基本語法練習回顧_程式簡化_物件導向_Part1
最近剛結束當兵第一階段難熬的新訓
由於生病不舒服在家養病
剛當完兵回來
說實在的於軍中12天
腦袋早已秀斗、生鏽差不多了
迅速重新運作成進去前的智商
再次來使用 以前大學所學過的
P語言(Processing) / based on JAVA
這門有趣易學的程式語言
溫故程式語法的手感吧!!!!
(在此使用之版本為3.3.5的Processing)
目標:
1.Processing 語法暖身
2.簡化程式練習
3.練習Ball設計藍圖(Class)與 物件實體建立、調用
===================================================================
一、基本語法練習回顧
先準備好 Processing 程式語言的主要架構
先準備好一個 寬640 高480大小 的畫布
準備完畫布之後 我們先來畫一個橢圓
我們沿著 畫布以最左上角座標(0,0)為起始位置
水平 x 200個單位(pixel)
垂直往下 100個單位(pixel)
繪製一個寬(width) 與 高(height) 皆為 80的橢圓(切記!! 非圓形)
接著我們希望這個橢圓能夠左右水平移動
我們宣告一個變數用來存取 x座標位置
一開始橢圓位在100
之後遞增1個單位
然後我們開始發現會出現畫圖的歷史移動軌跡
我們想消除這段彗星尾巴
因為我們於 draw() 區塊中只有針對 橢圓的x座標去做每次畫圖的更新
卻遺漏了背景每次也要跟著畫 跟著改變 再次上色
而且是在 橢圓移動繪製之前做
在 Processing 中我們使用 background 函數
做一些特定顏色的繪製
這裡設置0代表純黑色
那就會顯示像是 一顆白色雞蛋在夜空水瓶漂浮移動般
155則代表一半的濃度 也就是灰色
255則全白
當然我們也可指定 background(r ,g ,b);
依此類推
然後這個時候你又希望這個雞蛋能夠有彈性
會反彈回來
而不要只是一直向前移動
先過去
這裡也建議x所遞增的變量能夠在最上層宣告為全域變數
有個好處就是要改很好改
這裡我們將原本的 x+= 1 或 x++ 寫法
改寫在最外圍 上面部分 後續要改
若程式碼寫太長可以直接於開頭找尋並修改
(PS: 在此下方程式碼中 dx 其實講白話些 數值給愈大 雞蛋移動就愈快!!!
往後若要調整速度就只需要改一個地方即可)
只要x位置超出 整張畫布的寬就
再反方向彈回來
好 右邊雖然已經確實可以反彈但左邊又有超出不反彈的毛病了
我們再補上一道 if 判斷
這樣就模擬出一顆具有彈性的雞蛋了
使用 ScreenToGif
link : https://briian.com/15950/
但是依然有瑕疵
就是這顆雞蛋是以抵達 center的時候才反彈
而不是照著其 perimeter 去偵測
我們是希望觸碰到邊界立即反彈
這裡算是 Processing程式語言中的一個規範潛藏的小問題
它只能得知這顆橢圓的中心位置
所以起始的X座標位置其實位在 這顆雞蛋的中心處
至於雞蛋總寬為 120 , 一半則60
因此只要對X多加60即可獲得 靠右側的雞蛋邊界
靠左側 , 則反之
重新修正過後的Code
第一版.雞蛋左右反彈程式碼
二、程式簡化
Optimise the Code 階段
我們其實會發現這裡寫了兩個 if statement
其實沒捨麼必要 重複性太高(做的事情相似)
當撞到邊界就反向
後續其實只需要用一個 if statement 包覆即可
將兩個條件合併
然後做某些事
當然啦 在 第一版.雞蛋左右反彈程式碼中
我們針對反彈主要都是做純方向性的遞增 or 遞減 位移
其實也可利用前面說到的 特別宣告出來的 dx 全域變數
來做 * -1 的反向狀態更改喔!!!!!
第二版.簡化過後的雞蛋左右反彈程式碼
從18行 變 15行 程式碼 降低Code 重複性
但你後來又發現這樣的寫法
雖然很直觀
但假若我今天又要加另一顆球然後是上下反彈的話呢???
你說很簡單
那就直接再多畫一個球然後一樣設置兩個上下邊界超出 的判斷
簡化前版本
簡化後版本
所以這樣就簡化完了嗎????
仔細看你會發覺
有兩區塊程式碼其實有點相似
如果是如此
會發現
重複的程式碼一而再,再而三出現
每當我要再多畫一個會反彈的球或雞蛋的時候
就必須要重新在畫橢圓然後再給他一個 if 判斷
若我畫八個不同的圓
就會出現八組這樣的區塊 ---------------------->重複性極高!!!!
為此我們可以用 物件導向
來創建 球 的類別(物件之設計藍圖)
往後若有需要使用特定反彈球的動作
就直接建立一個物件模塊 後續再設定特定反彈參數即可
我們再對程式碼做重構優化它
(optimise the code)
三、物件導向
如何在 Processing中 創建一個 Class檔案並於主檔做調用
先 New Tab (Ctrl + Shift + N)
命名之
定義Ball類別 (檔案明即類別名 ------> 和Unity有點像)
相關private的屬性欄位
跟public 給別檔案用的動作執行方法
那這個時候我們就開始在想
一顆要能上下左右甚至斜邊移動的球 類別
要如何設計???
需要捨麼元素
目前我先想到的就是
至少要有
1.球自己的x , y 座標位置
2.然後就是對應的 dx ,dy 位移變化量
3.這顆球又是多大?? 球的寬高大小 用 size 定義(我們目前暫時先探討正圓型的球)
4.接著這顆球必須要能顯示出來 void display()
5.此外還必須能移動 void move()
所以感覺先寫這樣好了
主檔區塊
先實體化 該顆球物件
之後依序調用display() 及 move()兩個方法
成果如下
由於我是使用默認原本類別的x,y位置
所以每次執行都是從左上角初始化垂直掉下來,
因為dx變化量也固定住設為0 dy位移速度也固定為默認的+5(往下)
此外球還不會反彈
因此這裡對於 Ball 類別我們再做些更新
1.我們需要可自己設定球的dx,dy移動速度
如此我們就能將許多複雜的底層運作封裝於
類別方法之中
在主檔案區塊簡單一行調用即可
2.需獲取x,y,dx,dy的量
(藉由公開的方法間接獲得並設定之)
我們再次模擬一次垂直降落的球物件實體
並探討如何解決球不會反彈之問題
在此我們先用同樣的判斷條件寫法
與剛才相同
只不過這裡是調用物件中屬性
兩個上下邊界條件包覆於同一判斷區塊做反彈
目前程式
主檔區塊
Ball類別區塊
由於生病不舒服在家養病
剛當完兵回來
說實在的於軍中12天
腦袋早已秀斗、生鏽差不多了
迅速重新運作成進去前的智商
再次來使用 以前大學所學過的
P語言(Processing) / based on JAVA
這門有趣易學的程式語言
溫故程式語法的手感吧!!!!
(在此使用之版本為3.3.5的Processing)
目標:
1.Processing 語法暖身
2.簡化程式練習
3.練習Ball設計藍圖(Class)與 物件實體建立、調用
===================================================================
一、基本語法練習回顧
先準備好 Processing 程式語言的主要架構
先準備好一個 寬640 高480大小 的畫布
準備完畫布之後 我們先來畫一個橢圓
我們沿著 畫布以最左上角座標(0,0)為起始位置
水平 x 200個單位(pixel)
垂直往下 100個單位(pixel)
繪製一個寬(width) 與 高(height) 皆為 80的橢圓(切記!! 非圓形)
接著我們希望這個橢圓能夠左右水平移動
我們宣告一個變數用來存取 x座標位置
一開始橢圓位在100
之後遞增1個單位
然後我們開始發現會出現畫圖的歷史移動軌跡
我們想消除這段彗星尾巴
因為我們於 draw() 區塊中只有針對 橢圓的x座標去做每次畫圖的更新
卻遺漏了背景每次也要跟著畫 跟著改變 再次上色
而且是在 橢圓移動繪製之前做
在 Processing 中我們使用 background 函數
做一些特定顏色的繪製
這裡設置0代表純黑色
那就會顯示像是 一顆白色雞蛋在夜空水瓶漂浮移動般
155則代表一半的濃度 也就是灰色
255則全白
當然我們也可指定 background(r ,g ,b);
依此類推
然後這個時候你又希望這個雞蛋能夠有彈性
會反彈回來
而不要只是一直向前移動
先過去
這裡也建議x所遞增的變量能夠在最上層宣告為全域變數
有個好處就是要改很好改
這裡我們將原本的 x+= 1 或 x++ 寫法
改寫在最外圍 上面部分 後續要改
若程式碼寫太長可以直接於開頭找尋並修改
(PS: 在此下方程式碼中 dx 其實講白話些 數值給愈大 雞蛋移動就愈快!!!
往後若要調整速度就只需要改一個地方即可)
只要x位置超出 整張畫布的寬就
再反方向彈回來
好 右邊雖然已經確實可以反彈但左邊又有超出不反彈的毛病了
我們再補上一道 if 判斷
這樣就模擬出一顆具有彈性的雞蛋了
使用 ScreenToGif
link : https://briian.com/15950/
但是依然有瑕疵
就是這顆雞蛋是以抵達 center的時候才反彈
而不是照著其 perimeter 去偵測
我們是希望觸碰到邊界立即反彈
這裡算是 Processing程式語言中的一個規範潛藏的小問題
它只能得知這顆橢圓的中心位置
所以起始的X座標位置其實位在 這顆雞蛋的中心處
至於雞蛋總寬為 120 , 一半則60
因此只要對X多加60即可獲得 靠右側的雞蛋邊界
靠左側 , 則反之
重新修正過後的Code
第一版.雞蛋左右反彈程式碼
int x = 100; int dx = 5; void setup(){ size(640,480); } void draw(){ background(255,0,0); ellipse(x,100,120,80); //x++; x +=dx; if(x+60 > width){ dx = -5; } if(x-60 < 0){ dx = 5; } }
二、程式簡化
Optimise the Code 階段
我們其實會發現這裡寫了兩個 if statement
其實沒捨麼必要 重複性太高(做的事情相似)
當撞到邊界就反向
後續其實只需要用一個 if statement 包覆即可
將兩個條件合併
然後做某些事
當然啦 在 第一版.雞蛋左右反彈程式碼中
我們針對反彈主要都是做純方向性的遞增 or 遞減 位移
其實也可利用前面說到的 特別宣告出來的 dx 全域變數
來做 * -1 的反向狀態更改喔!!!!!
第二版.簡化過後的雞蛋左右反彈程式碼
從18行 變 15行 程式碼 降低Code 重複性
int x = 100; int dx = 10; void setup(){ size(640,480); } void draw(){ background(255,0,0); ellipse(x,100,120,80); //x++; x +=dx; if(x+60 > width || x-60 < 0){ dx = dx*-1; } }
但你後來又發現這樣的寫法
雖然很直觀
但假若我今天又要加另一顆球然後是上下反彈的話呢???
你說很簡單
那就直接再多畫一個球然後一樣設置兩個上下邊界超出 的判斷
簡化前版本
int x = 100; int dx = 5; int y = 50; int dy = 5; void setup() { size(640, 480); } void draw() { background(255, 0, 0); ellipse(x, 100, 120, 80); //x++; x +=dx; if (x+60 > width) { dx = -5; } if (x-60 < 0) { dx = 5; } ellipse(400, y, 50, 80); y += dy; if (y+40 > height) { dy = -5; } if (y-40 <0) { dy = 5; } }
簡化後版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | int x = 100; int y = 50; int dx = 5; int dy = 5; void setup() { size(640, 480); } void draw() { background(255, 0, 0); ellipse(x, 100, 120, 80); x +=dx; if(x+60 > width || x-60 < 0){ dx = dx*-1; } ellipse(400, y, 50, 80); y += dy; if (y+40 > height || y-40 <0) { dy = dy*-1; } } |
所以這樣就簡化完了嗎????
仔細看你會發覺
有兩區塊程式碼其實有點相似
如果是如此
會發現
重複的程式碼一而再,再而三出現
每當我要再多畫一個會反彈的球或雞蛋的時候
就必須要重新在畫橢圓然後再給他一個 if 判斷
若我畫八個不同的圓
就會出現八組這樣的區塊 ---------------------->重複性極高!!!!
為此我們可以用 物件導向
來創建 球 的類別(物件之設計藍圖)
往後若有需要使用特定反彈球的動作
就直接建立一個物件模塊 後續再設定特定反彈參數即可
我們再對程式碼做重構優化它
(optimise the code)
三、物件導向
如何在 Processing中 創建一個 Class檔案並於主檔做調用
先 New Tab (Ctrl + Shift + N)
命名之
定義Ball類別 (檔案明即類別名 ------> 和Unity有點像)
相關private的屬性欄位
跟public 給別檔案用的動作執行方法
一顆要能上下左右甚至斜邊移動的球 類別
要如何設計???
需要捨麼元素
目前我先想到的就是
至少要有
1.球自己的x , y 座標位置
2.然後就是對應的 dx ,dy 位移變化量
3.這顆球又是多大?? 球的寬高大小 用 size 定義(我們目前暫時先探討正圓型的球)
4.接著這顆球必須要能顯示出來 void display()
5.此外還必須能移動 void move()
所以感覺先寫這樣好了
主檔區塊
先實體化 該顆球物件
之後依序調用display() 及 move()兩個方法
成果如下
由於我是使用默認原本類別的x,y位置
所以每次執行都是從左上角初始化垂直掉下來,
因為dx變化量也固定住設為0 dy位移速度也固定為默認的+5(往下)
此外球還不會反彈
因此這裡對於 Ball 類別我們再做些更新
1.我們需要可自己設定球的dx,dy移動速度
如此我們就能將許多複雜的底層運作封裝於
類別方法之中
在主檔案區塊簡單一行調用即可
2.需獲取x,y,dx,dy的量
(藉由公開的方法間接獲得並設定之)
我們再次模擬一次垂直降落的球物件實體
並探討如何解決球不會反彈之問題
在此我們先用同樣的判斷條件寫法
與剛才相同
只不過這裡是調用物件中屬性
兩個上下邊界條件包覆於同一判斷區塊做反彈
目前程式
主檔區塊
Ball ball = new Ball(); void setup() { size(640, 480); } void draw() { background(255, 0, 0); ball.display(); ball.move(); //ball.setDx(5); //ball.setDy(5); if(ball.getY()+25 > height || ball.getY()-25<0){ ball.setDy(ball.getDy()*-1); } }
Ball類別區塊
public class Ball { private int y = 30; private int x = 30; private int dy = 5; private int dx = 0; private int size = 50; public void move() { y+=dy; x+=dx; } //have ability to change dx and dy public void setDx(int dx) { this.dx = dx; } public void setDy(int dy) { this.dy = dy; } //have ability to see where our ball located and the values of dx ,dy public int getX(){ return this.x; } public int getY(){ return this.y; } public int getDx() { return this.dx; } public int getDy() { return this.dy; } public void display() { ellipse(x, y, size, size); } }
留言
張貼留言