2015年10月26日 星期一

GameMaker:Studio 學習筆記8

6、draw_set_blend_mode_ext(src,dest):設定繪製動作的延伸blend mode

重點1:

GMS在draw1個pixel時考慮兩個面相,一為source colour(我們打算繪製的顏色),二為destination colour(該pixel既存的顏色),混色計算方式是以pixel為單位,公式如下:

R.s*R.sf+R.d*R.df=R.outcome

G.s*G.sf+G.d*G.df=G.outcome

B.s*B.sf+B.d*B.df=B.outcome

A.s*A.sf+A.d*A.df=A.outcome

(R.outcome,G.outcome,B.outcome,A.outcome)即為該pixel顯示在畫面的色彩,而blend mode影響的是sf(source factor)與df(destination factor),各blend mode計算sf與df的方式可參照draw_set_blend_mode_ext function的說明文件

重點2:在混色計算時,位於不同surface的顏色是不會納入計算的

重點3:透明的點其RGB值不一定是0,在計算混色時要考慮其RGB值,例如RGBA為0.5,0.6,0.7,0和0,0,0,0看起來都是完全透明,但在計算混色時會有完全不同的結果,故以不透明的黑色(0,0,0,0)做為底色對後續的色彩控制會比較簡單,只要使用不透明的純白(1,1,1,1)以subtract模式就可以還原特定區域為底色,每次繪製的基礎都會相同

重點4:透明度對混色影響很大,其讓混色多了很多變化,但相對的也讓混色計算變得比較複雜,完全不透明的混色結果很容易掌握,有透明度的混色就相對複雜許多,例如想在已有色彩的區域繪製圖案,且希望結果和來源完全相同而不受目標點既有色彩影響,在來源無透明度或來源有透明度但目標與來源顏色完全相同時,使用bm_normal即可,若來源有透明度且目標顏色和來源不完全相同時,就需先將目標以純白subtract還原成(0,0,0,0)之後,再以ext(bm_one,bm_one)模式繪製以得到和來源完全相同的結果

關於blend mode的詳細說明可參照以下網址:

Explaining Blend Modes - Part 2 https://www.yoyogames.com/tech_blog/69

draw_set_blend_mode(bm_normal):

預設模式,效果為直接覆蓋,需注意若欲繪製的圖案本身有透明度且目標區域底色非透明無色,則繪製出來的圖案顏色會因與底色混合而與來源有差異,差異程度依來源與目標色彩及透明度而定

draw_set_blend_mode_ext(bm_one,bm_inv_src_alpha):

一般情況下當在同1個區域繪製2次且分別使用不同的alpha值,結果將會覆蓋而非累積,若希望以0.5的alpha值在相同位置繪製同1個image2次時能得到約alpha0.75的累積效果而不是直接覆蓋為0.5,則可用draw_set_blend_mode_ext(bm_one,bm_inv_src_alpha)這個blend mode,此mode適合用於繪製陰影(shadows)以及灰階的圖像

draw_set_blend_mode(bm_add):

適合用於明亮效果(bright effects)的混色,例如爆炸、雷射、光源等

draw_set_blend_mode(bm_subtract):

減除明暗度並依明暗度高低設定透明度,越暗的pixels畫出來的透明度愈高,適合用於從黑暗或陰影中挖出一個可視區

draw_set_blend_mode_ext(bm_normal,bm_zero):

直接取代該區域的色彩,畫同一個sprite在同一個位置會疊加而有愈來愈深的狀況,用此模式則不會疊加,可用以修復被破壞的形狀而不用先清除剩餘的部份

7、在上視角場景營造投擲物體飛越敵人的錯覺並適時發生反彈的方法:

設定速度快時不反彈,且depth小於其他物件(depth小的顯示在上層,會有飛越其上的錯覺),速度設定遞減,depth設定遞增,在速度下降到指定值之後讓反彈enable,此時depth也遞增到大於其他物件而在重疊時會被覆蓋(會有在地上被跨過的錯覺)

8、在上視角場景營造投擲物體在一定距離後落地的錯覺的方法:

類似營造投擲物體飛越敵人的錯覺之方式,以移動速度做為是否落地的判定依據,並在設定為落地的時機點設計適當的sprite移動方式,以模擬落地彈跳效果,同時播放落地音效增加擬真度

9、若指定父物件做為碰撞檢查的目標物件,例如collision_line,則會檢查所有子物件的instance是否有在此線上發生碰撞,若有則傳回其ID(有多個碰撞發生時,則傳回最接近起始點的instance ID),若無則傳回"noone"

10、路徑functions:

mp_potential_step(xgoal,ygoal,stepsize,checkall):朝目標點(xgoal,ygoal)移動instance,過程中迴避障礙物,stpesize為移動速度,checkall為false則只迴避實心(solid)物件,為true則全會迴避全部物件

mp_potential_step_object(xgoal,ygoal,stepsize,obj):往目標點移動,過程中迴避指定obj

mp_potential_path(path,xgoal,ygoal,stepsize,factor,checkall):計算instance本身與目標點之間的路徑,並產生1個路徑,類似於mp_potential_step,但並不移動,而是產生一個路徑,其中path是已存在的路徑index,將會被此function產生的路徑覆蓋,factor為運算時間,需大於1以避免無窮計算,時間內無法得出有效路徑則會傳回false,找到有效路徑則傳回true,即使false也會產生路徑,但只指向大概的方向而不會到達目標點

mp_potential_path_object(path,xgoal,ygoal,stepsize,factor,obj):同mp_potential_path,但只迴避指定obj

mp_potential_settings(maxrot,rotstep,ahead,onspot):設定mp_potential相同functions運作的方式

maxrot:設定每step允許instance從當下面對的方向轉向的角度上限,值愈大,愈容易找到有效路徑,但路徑愈不自然,值愈小,路徑愈平滑,但可能繞比較遠,甚至無法找到有效路徑,例如設為30,當下面對90度方向,每次轉5度檢查直線前方是否有碰撞,檢查到125度方向時找到可行路線,但因125-90=35超過上限30,因此此路徑不採用,換個角度講就是設定檢查有效路徑的範圍,例如設為90度就是檢查前方180度(左右各90度)的範圍內是否有有效路徑

rotstep:當前方有障礙物時,轉向進行下一個直線確認的單位轉向角度,角度愈小,找到路徑的可能性愈高,但需要的計算也愈多,速度相對較慢,例如設為10,當下面對90度方向且前方有障礙物,便會轉向10度確認100度方向直線前方是否有障礙物

ahead:設定檢查碰撞的範圍(可理解為視野,愈早看到障礙,愈早轉向),預設為3,代表3step內的碰撞都會被檢查到,並轉向,這個值愈小,愈晚轉向,值愈大,愈早轉向迴避

onspot:當可行範圍皆已檢查完畢且無有效路徑可行,則接下來的動作就依據此參數,設為true表示instance自當下面對方向旋轉"maxrot"設定角度後再開始檢查,設為false則不做任何動作,結束尋找路徑的動作,設為false很實用,像是車輛就適合用false,但設為false會降低找到路徑的機會

沒有留言:

張貼留言