最近買了好幾個board game給小朋友玩,第一個買的是魔法迷宮 Master Labyrinth,這也是來自德國的遊戲,在 【桌上遊戲】奇幻迷宮 Amazing Labyrinth 這篇文章中,詳細地介紹了玩法。
但我們買到後,因為計算分數跟取任務卡我覺得太麻煩了,小朋友也不是很瞭解任務是什麼,所以並沒有照著說明書的方法玩,我們就單純地把迷宮放上去,1~20與25號共21個圓形材料放上去,然後就開始玩了,迷宮的推法跟走法都一樣,但大家得按照材料卡的數字順序,一個一個拿,最後就比誰拿到的材料卡多。
其實這樣就可以有些變化了,一開始我們玩推完迷宮卡後,就只能夠取得一個材料卡,然後就得停下來,後來就玩推完迷宮卡後,可以連續取得材料卡,只要能走得到的地方都能拿。
小朋友一開始玩的時候,還不知道怎麼在自己沒辦法取得材料卡的時候,就故意把別人的棋子推到沒辦法走的地方,但多玩幾次之後,他也慢慢知道怎麼陷害別人了。
魔法迷宮的遊戲在網路上有好幾個版本,我們買得有幾隻魔法棒,還有好多張三個材料的任務卡,雖然要一千多元,但這算是一個很值得買的桌上遊戲。
魔法迷宮 Master Labyrinth
2009/6/3
2009/5/1
Flex DisplayObject mask, blend mode, filters
Masks Blend Modes Graphics Filters 這三篇文章討論圖形的基本處理,配合Using filters in Flex 這篇文章,我們可以用程式對 DisplayObject 套上一些特效。
對一個UI元件,可以用繼承自 DisplayObject 的 filters Array 填上多個 filter classes,包含 DropShadowFilter(加上陰影), GlowFilter(顏色像墨水暈開的樣子,呈現在元件的外框上), and BlurFilter(模糊), BevelFilter(將元件以九宮格的方式切割後,分別給以不同的顏色或陰影,讓元件更有立體感),這些filter 都能用在所有 DisplayObejct 的子類別上,包含MovieClip, SimpleButton, TextField, Video objects, BitmapData。
另外有個ShaderFilter,可以即時下載 pbj 濾鏡檔案,並將該檔案的ByteArray資料轉換成ShaderFilter,就能讓照片有水波紋的效果,以這篇文章為例 Pixel Bender,可以使用Pixel Bender 的功能,自己寫濾鏡。
Blend mode 只會影響non-transparent與semi-transparent的區域,有以下這幾種: NORMAL, ADD, ALPHA, DARKEN, DIFFERENCE, ERASE, HARDLIGHT, INVERT, LAYER, LIGHTEN, MULTIPLY, OVERLAY, SCREEN, SUBTRACT,舉例來說,如果是BlendMode.LIGHTEN,因為每一個pixel都是由 RGB 三原色所組成的,Blend mode 會比較三個部份,並採用比較亮(大)的數字作為結果,例如 display object 的 pixel color 為 0xFFCC33,背景 pixel color 為 0xDDF800,結果就是 0xFFF833,因為 0xFF>0xDD 0xCC<0xf8,>0x00。DisplayObject blendMode 這裡有把所有的 BlendMode 舉例說明結果。
-----------------
在測試的時候,會用 actionscript 撰寫 Sprite 元件,但是在Canvas上 addChild 的時候,卻遇到這樣的問題:
TypeError: Error #1034: 強制轉型失敗: 無法將 flash.display::Sprite@83de181 轉換成 mx.core.IUIComponent
是因為 Canvas 繼承 Container 繼承 UIComponent 繼承 FlexSprite 繼承 Sprite 繼承 DisplayObjectContainer 繼承 InteractiveObject 繼承 DisplayObject,而在 Canvas上要增加元件的 addChild(child:DisplayObject):DisplayObject,雖然參數是 DisplayObject,但是addChild的原始程式裡面,卻有轉型的動作 child is UIComponent,所以必須要先 var tempUI:UIComponent=new UIComponent(); 把 tempSprite 放到 UICompoenent 裡面 tempUI.addChild(tempSprite); ,這樣才能 在 Canvas 上 addChild(tempUI);
-----------------
cacheAsBitmap
這個屬性並不是提昇效能的萬靈丹,反而要小心使用。在livedocs的說明中:將影片片段的 cacheAsBitmap 屬性設為 true 之後,並不會變更顯示結果,但是影片片段會自動執行像素貼齊。在不同複雜程度的向量內容上,動畫速度都可以獲得明顯的提升。cacheAsBitmap 屬性最適合與主要為靜態內容,且不會經常縮放和旋轉的影片片段搭配使用。
所以如果只是在x、y軸移動DisplayObject,那麼cacheAsBitmap可以提昇效能,但如果要旋轉、縮放、更改透明度,cacheAsBitmap則會拖慢顯示速度。
不應該濫用cacheAsBitmap
Why cacheAsBitmap is bad
cacheAsBitmap (MovieClip.cacheAsBitmap 屬性)
對一個UI元件,可以用繼承自 DisplayObject 的 filters Array 填上多個 filter classes,包含 DropShadowFilter(加上陰影), GlowFilter(顏色像墨水暈開的樣子,呈現在元件的外框上), and BlurFilter(模糊), BevelFilter(將元件以九宮格的方式切割後,分別給以不同的顏色或陰影,讓元件更有立體感),這些filter 都能用在所有 DisplayObejct 的子類別上,包含MovieClip, SimpleButton, TextField, Video objects, BitmapData。
另外有個ShaderFilter,可以即時下載 pbj 濾鏡檔案,並將該檔案的ByteArray資料轉換成ShaderFilter,就能讓照片有水波紋的效果,以這篇文章為例 Pixel Bender,可以使用Pixel Bender 的功能,自己寫濾鏡。
Blend mode 只會影響non-transparent與semi-transparent的區域,有以下這幾種: NORMAL, ADD, ALPHA, DARKEN, DIFFERENCE, ERASE, HARDLIGHT, INVERT, LAYER, LIGHTEN, MULTIPLY, OVERLAY, SCREEN, SUBTRACT,舉例來說,如果是BlendMode.LIGHTEN,因為每一個pixel都是由 RGB 三原色所組成的,Blend mode 會比較三個部份,並採用比較亮(大)的數字作為結果,例如 display object 的 pixel color 為 0xFFCC33,背景 pixel color 為 0xDDF800,結果就是 0xFFF833,因為 0xFF>0xDD 0xCC<0xf8,>0x00。DisplayObject blendMode 這裡有把所有的 BlendMode 舉例說明結果。
-----------------
在測試的時候,會用 actionscript 撰寫 Sprite 元件,但是在Canvas上 addChild 的時候,卻遇到這樣的問題:
TypeError: Error #1034: 強制轉型失敗: 無法將 flash.display::Sprite@83de181 轉換成 mx.core.IUIComponent
是因為 Canvas 繼承 Container 繼承 UIComponent 繼承 FlexSprite 繼承 Sprite 繼承 DisplayObjectContainer 繼承 InteractiveObject 繼承 DisplayObject,而在 Canvas上要增加元件的 addChild(child:DisplayObject):DisplayObject,雖然參數是 DisplayObject,但是addChild的原始程式裡面,卻有轉型的動作 child is UIComponent,所以必須要先 var tempUI:UIComponent=new UIComponent(); 把 tempSprite 放到 UICompoenent 裡面 tempUI.addChild(tempSprite); ,這樣才能 在 Canvas 上 addChild(tempUI);
-----------------
cacheAsBitmap
這個屬性並不是提昇效能的萬靈丹,反而要小心使用。在livedocs的說明中:將影片片段的 cacheAsBitmap 屬性設為 true 之後,並不會變更顯示結果,但是影片片段會自動執行像素貼齊。在不同複雜程度的向量內容上,動畫速度都可以獲得明顯的提升。cacheAsBitmap 屬性最適合與主要為靜態內容,且不會經常縮放和旋轉的影片片段搭配使用。
所以如果只是在x、y軸移動DisplayObject,那麼cacheAsBitmap可以提昇效能,但如果要旋轉、縮放、更改透明度,cacheAsBitmap則會拖慢顯示速度。
不應該濫用cacheAsBitmap
Why cacheAsBitmap is bad
cacheAsBitmap (MovieClip.cacheAsBitmap 屬性)
2009/3/30
神秘島 by 凡爾納
神秘島出版於一八七四年,比艾西莫夫早了一百年,在還那個工業革命的時代裡,凡爾納將煉鋼、化學反應與熱氣球這些先進的技術寫到小說裡面,透過工程師賽勒斯,把所有技術實現出來。
這本書唯一看到的反派角色,只有一艘曇花一現的海盜船,這裡面還有六個逃往森林裡的海盜,其他的部份,就是五個人+一隻狗+一隻猩猩,互相幫助解決問題,後來還拯救了被放逐在塔波島的海盜愛爾迪,還有海底兩萬里的尼莫船長。
說真的情節有點悶,不夠緊湊,還有這幾個「移民」,一直撿到一些特別的,沒辦法製造出來的東西,例如槍枝,在我個人看起來,其實是有些突兀,雖然這本書最令人津津樂道的,就是「移民」能徒手以自己的知識,就地取材製造出自己所需要的東西,而且這幾個人之間,完全沒有猜忌也少有爭執,不同職業的他們,都能以工程師為核心而各司其職。如果真讓賽勒斯還能直接土法做出槍枝來,可能就太誇張了。
科幻是要預知未來,奇幻則是天馬行空,我們會對艾西莫夫如此推崇,是因為他的科幻領先了目前的所有科技,雖然凡爾納沒能作到,但因為他比艾西莫夫早了一百年,而十八世紀末到十九世紀,恰好是科學突飛猛進的時代,如果凡爾納能在二十世紀,或許能寫出另一個不同的神秘「星球」而不是神秘「島」。
這本書唯一看到的反派角色,只有一艘曇花一現的海盜船,這裡面還有六個逃往森林裡的海盜,其他的部份,就是五個人+一隻狗+一隻猩猩,互相幫助解決問題,後來還拯救了被放逐在塔波島的海盜愛爾迪,還有海底兩萬里的尼莫船長。
說真的情節有點悶,不夠緊湊,還有這幾個「移民」,一直撿到一些特別的,沒辦法製造出來的東西,例如槍枝,在我個人看起來,其實是有些突兀,雖然這本書最令人津津樂道的,就是「移民」能徒手以自己的知識,就地取材製造出自己所需要的東西,而且這幾個人之間,完全沒有猜忌也少有爭執,不同職業的他們,都能以工程師為核心而各司其職。如果真讓賽勒斯還能直接土法做出槍枝來,可能就太誇張了。
科幻是要預知未來,奇幻則是天馬行空,我們會對艾西莫夫如此推崇,是因為他的科幻領先了目前的所有科技,雖然凡爾納沒能作到,但因為他比艾西莫夫早了一百年,而十八世紀末到十九世紀,恰好是科學突飛猛進的時代,如果凡爾納能在二十世紀,或許能寫出另一個不同的神秘「星球」而不是神秘「島」。
2009/3/22
神奇的 Runtime.exec 遇到保留字元的處理方法
要產生Process執行command line程式,在java裡面是使用Runtime.exec,在JDK 1.5之後出現了另一個 ProcessBuilder,ProcessBuilder多了管理環境變數的方法,也能切換工作目錄。一般使用Runtime Process會先遇到IO Blocking的問題,這個可以參考這些文章:When Runtime.exec() won't、java中呼叫.bat 卻沒有反應.... 、StreamGobbler的詳細解釋,使用 StreamGobbler 解決。但另外遇到 shell command 裡面的保留字元時,就會產生了一些奇怪的問題。
最常見的就是空白字元,例如在命令的執行路徑上,出現了空白字元,以 windows 來說,如果直接在"命令提示字元"中,打上 c:\Program Files\xxx\xxx.exe,就會出現路徑的錯誤,因為shell沒辦法處理有空白字元的路徑,所以要執行的時候,就得加上 雙引號 變成 "c:\Program Files\xxx\xxx.exe",這樣就可以執行了。
在Linux環境也是一樣的,遇到空白字元,就會發生問題,除了用 雙引號的方法之外,單引號也可以,或是加上escape char \,例如 /home/root/bin/xx x.sh ,可以改成 "/home/root/bin/xx x.sh" 或是 '/home/root/bin/xx x.sh' 或是在空白前面加上escape char /home/root/bin/xx\ x.sh 就可以執行了。
事實上除了空白字元之外,還有可能會遇到 ( ) " ' 這些字元,都是shell上的保留字元。為了求得一個能同時在 linux 與 windows 都能運作的執行方法,用雙引號似乎就能同時解決這樣的問題,但是事實上,放到 Runtim.exec 裡面執行時,又不是這麼一回事。為了執行一個程式,現在有幾種寫法可以用,(1) 將命令含參數,弄成一個字串,然後放到 runtime.exec 執行 (2) 將命令含參數,弄成一個字串,然後前面加上 shell ,例如windows 平台就寫 cmd /c、而linux 平台就寫 /bin/sh -c,然後放到 runtime.exec 執行 (3) 將命令與參數作成 List shellcmd,然後用 new ProcessBuilder(shellcmd).start() 執行 (4) 將命令與參數作成 List shellcmd ,前面加上 shell,cmd /c 或是 /bin/sh -c,然後用 new ProcessBuilder(shellcmd).start() 執行。
測試許久,最後還是沒有辦法找到一種方式,同時適用於 windows 與 linux,結果以 ffmpeg bin\ffmpeg.exe 與 ffmpeg bin\ffmpeg 兩個執行檔為例,假設我要執行 ffmpeg -i test.wmv -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 test.flv,在 windows平台,我得寫
List cmdlist=new ArrayList();
cmdlist.add("\"ffmpeg bin\ffmpeg\"");
cmdlist.add("-i");
cmdlist.add("\"test.wmv\""); // 因為檔案路徑有可能會含有空白字元,就幫他加上雙引號
cmdlist.add("-ab");
cmdlist.add("56");
cmdlist.add("-ar");
cmdlist.add("22050");
cmdlist.add("-b");
cmdlist.add("500");
cmdlist.add("-r");
cmdlist.add("15");
cmdlist.add("-s");
cmdlist.add("320x240");
cmdlist.add("\"test.flv\""); // 因為檔案路徑有可能會含有空白字元,就幫他加上雙引號
new ProcessBuilder(cmdlist).start();
而在 linux平台,我得寫
List cmdlist=new ArrayList();
cmdlist.add("/bin/sh");
cmdlist.add("-c");
cmdlist.add("\"ffmpeg bin\ffmpeg\" -i \"test.wmv\" -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 \"test.flv\"
"); // 因為檔案路徑有可能會含有空白字元,就幫他加上雙引號
new ProcessBuilder(cmdlist).start();
最常見的就是空白字元,例如在命令的執行路徑上,出現了空白字元,以 windows 來說,如果直接在"命令提示字元"中,打上 c:\Program Files\xxx\xxx.exe,就會出現路徑的錯誤,因為shell沒辦法處理有空白字元的路徑,所以要執行的時候,就得加上 雙引號 變成 "c:\Program Files\xxx\xxx.exe",這樣就可以執行了。
在Linux環境也是一樣的,遇到空白字元,就會發生問題,除了用 雙引號的方法之外,單引號也可以,或是加上escape char \,例如 /home/root/bin/xx x.sh ,可以改成 "/home/root/bin/xx x.sh" 或是 '/home/root/bin/xx x.sh' 或是在空白前面加上escape char /home/root/bin/xx\ x.sh 就可以執行了。
事實上除了空白字元之外,還有可能會遇到 ( ) " ' 這些字元,都是shell上的保留字元。為了求得一個能同時在 linux 與 windows 都能運作的執行方法,用雙引號似乎就能同時解決這樣的問題,但是事實上,放到 Runtim.exec 裡面執行時,又不是這麼一回事。為了執行一個程式,現在有幾種寫法可以用,(1) 將命令含參數,弄成一個字串,然後放到 runtime.exec 執行 (2) 將命令含參數,弄成一個字串,然後前面加上 shell ,例如windows 平台就寫 cmd /c、而linux 平台就寫 /bin/sh -c,然後放到 runtime.exec 執行 (3) 將命令與參數作成 List
測試許久,最後還是沒有辦法找到一種方式,同時適用於 windows 與 linux,結果以 ffmpeg bin\ffmpeg.exe 與 ffmpeg bin\ffmpeg 兩個執行檔為例,假設我要執行 ffmpeg -i test.wmv -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 test.flv,在 windows平台,我得寫
List
cmdlist.add("\"ffmpeg bin\ffmpeg\"");
cmdlist.add("-i");
cmdlist.add("\"test.wmv\""); // 因為檔案路徑有可能會含有空白字元,就幫他加上雙引號
cmdlist.add("-ab");
cmdlist.add("56");
cmdlist.add("-ar");
cmdlist.add("22050");
cmdlist.add("-b");
cmdlist.add("500");
cmdlist.add("-r");
cmdlist.add("15");
cmdlist.add("-s");
cmdlist.add("320x240");
cmdlist.add("\"test.flv\""); // 因為檔案路徑有可能會含有空白字元,就幫他加上雙引號
new ProcessBuilder(cmdlist).start();
而在 linux平台,我得寫
List
cmdlist.add("/bin/sh");
cmdlist.add("-c");
cmdlist.add("\"ffmpeg bin\ffmpeg\" -i \"test.wmv\" -ab 56 -ar 22050 -b 500 -r 15 -s 320x240 \"test.flv\"
"); // 因為檔案路徑有可能會含有空白字元,就幫他加上雙引號
new ProcessBuilder(cmdlist).start();
2009/3/15
理由 by 宮部美幸
這本書是因為看了模仿犯之後,才去買來看的,這是模仿犯2001年得獎作品的前作,是在1999年得到直木獎。但老實說,看這本書的時候,並沒有看模仿犯急著想要看完的感覺,反而是硬逼著自己把他看完的。
原因在於白描的方式,又完全沒有推理的成份,我並沒有期待想看到結局的感覺,這樣的描述方式,跟我常常閱讀的科幻小說,是完全不一樣的。也跟模仿犯不同,因為在模仿犯裡,我會急著想知道和平是怎麼被抓的,在理由裡面,我卻不在意,石田直澄會怎麼落網。這兩種完全不一樣的感覺,
這本書越到後面的寫法,是以記者採訪當事者,然後當事者現身說法,描述當時發生的事情,由當事者自己描述自己的心境。許多評論都說,這是宮部美幸作品的特色,因為他能精準地描寫事件的發生,對每一個人的影響,還有每一個人的看法,看過作品之後,確實如此。
但讀完理由之後,我也沒有特別記得哪一個情節,哪一句話,只記得該案件發生的過程,另外也對石田直澄要一直逃的決定,覺得不大合理,也許是我比較自私,但如果我沒有殺人,卻又要我一直逃,為了掩護一位帶著孩子的媽,這絕對是行不通的,因為被通緝之後,等於完全沒有人生了,況且如果犯法,要逃走也是要偷渡逃到另一個國家,而不是一直留在國內,那絕對不是長久之計。
理由,不夠驚悚,也沒有緊湊的情節,還是模仿犯比較精彩一些。
原因在於白描的方式,又完全沒有推理的成份,我並沒有期待想看到結局的感覺,這樣的描述方式,跟我常常閱讀的科幻小說,是完全不一樣的。也跟模仿犯不同,因為在模仿犯裡,我會急著想知道和平是怎麼被抓的,在理由裡面,我卻不在意,石田直澄會怎麼落網。這兩種完全不一樣的感覺,
這本書越到後面的寫法,是以記者採訪當事者,然後當事者現身說法,描述當時發生的事情,由當事者自己描述自己的心境。許多評論都說,這是宮部美幸作品的特色,因為他能精準地描寫事件的發生,對每一個人的影響,還有每一個人的看法,看過作品之後,確實如此。
但讀完理由之後,我也沒有特別記得哪一個情節,哪一句話,只記得該案件發生的過程,另外也對石田直澄要一直逃的決定,覺得不大合理,也許是我比較自私,但如果我沒有殺人,卻又要我一直逃,為了掩護一位帶著孩子的媽,這絕對是行不通的,因為被通緝之後,等於完全沒有人生了,況且如果犯法,要逃走也是要偷渡逃到另一個國家,而不是一直留在國內,那絕對不是長久之計。
理由,不夠驚悚,也沒有緊湊的情節,還是模仿犯比較精彩一些。
訂閱:
文章 (Atom)