2008年9月15日 星期一

封存網誌

這個網誌將不再更新,僅用於封存以前的文章,也不再提供留言功能。之前的文章我僅挑了些可能有用的出來,其他的都刪掉了。

以Erlang實作Port Mapping

最近又開始在閒暇時看Erlang的東西....
練習寫了一些簡單的東西,如這個映射TCP Port的程式 (將本地port映設到其他host的port)
例如 tcp_bridge:start("ptt.cc", 23, 1000) 後, telnet localhost:1000就會連到ptt bbs



其實上面的實作碼潛藏著一些問題,但是當作一個telnet的跳版已經夠用了。
這個邏輯以Erlang實作算是相當精簡的。

2008年8月20日 星期三

Boost 1.36.0 Released

Boost 1.36.0 Released

增加了四個Library

  • Unordered
    我覺得這是最簡單實用的一個Library
    長久以來,C++ STL都缺乏了Hash容器的支持
    std::tr1目前還很少compiler內建支援
    在VC可用stdext::unordered_set(map),但非標準,portability差

    boost這次納入了unordered_set, unordered_map
    遵循standard library命名的概念,類別名稱描述介面不描述實作
    其實骨子裡就是HashSet和HashMap,介面相容於tr1

  • Accumulators,簡單的統計用工具

  • Unit
    號稱Zero-overhead dimensional analysis and unit/quantity manipulation and conversion
    (其實就是在compile-time做掉檢查)
    大量使用MPI及template metaprogramming。

  • Exception
    這我沒仔細看....


另外已存在的Library也有很多的更新,改變最大的應該是ASIO。例如支持Windows下透過IOCP存取named pipe,剛好最近有要寫一些IPC的東西,之後應該會看一下ASIO這方面是否變利。

2008年8月3日 星期日

Linux+EeePC? It’s not easy….

這篇要講的是「EeePC Linux版不適合給不懂電腦的人使用」…

華碩一開始在出產7吋的EeePC時,對EeePC有這樣的定位:
「Easy to play, easy to work, easy to learn」1
「EeePC不是PC、不是筆記型電腦」
當時EeePC的規格低,運算能力較差
官方只有搭載Xandros Linux的作業系統,而沒有MS Windows的版本

EeePC具備有無線上網、文書、撥放DVD及特定格式的影片….等功能….
官方也僅止於保證這些功能可以正確運作而已,確實不到一般筆電的所有功能。
但是這樣C/P值不錯的硬體,落到電腦玩家的手上,
網路上開始流傳「解放EeePC的實力」的方法
例如安裝LazyEeePC、使用Debian的套件庫、在7″ EeePC上灌Windows XP等等…

後來隨著8.9″及10″的EeePC上市
EeePC也開始同時販售Linux和Windows版
無論從價位或者效能來看
似乎再也沒有人能說EeePC不是筆電、只是玩具

價位落在13K~19K間的新型EeePC,大家應該會期待他能夠做到筆電能做的大部份功能
如果使用Windows,應該是沒問題的
可是Linux版的功能卻沒有跟上硬體的演進,內建的功能依然相當簡陋
當然,網路上有很多非官方的教學,教人如何擴充EeePC Linux的功能
但是我必需指出,這些教學的內容相當不easy,也不一定在每個版本上的EeePC上能夠正常工作
甚至,對Linux有一定概念的人,也不一定能解決每一個遇到的問題。

以下是我使用EeePC 901 + Linux所遇到的問題…

多媒體撥放
DVD的方面
原本EeePC內建的SMPlayer+MPlayer組合可以正確的撥放

EeePC並沒有內建rmvb的解碼器
網路上有一個lazyeeepc的懶人包,可以幫我們安裝一些EeePC Linux版上好用的工具
包括了rmvb的解碼器,讓我們可以直接用MPlayer撥放rmvb檔案

安裝了LazyEeePC之後,試著撥放rmvb影片看看
結果聲音和影像都停格的慘不忍睹

在網路上找到一些文章,說這是因為LazyEeePC安裝的是RealPlayer 9的codec
如果安裝了RealPlayer 10或11的Linux版,就可以順暢的撥放影片
於是我試著裝了這兩個版本….不管那一個版本
一開始撥放影片時程式就會馬上當掉
後來發現是XVideo的問題,關掉XVideo就可以撥放,但仍然有非常嚴重的停格現像

後來又無意間找到一篇教學….
在SMPlayer中將影像輸出裝置設成X11
音訊輸出裝置設成ALSA
RMVB就可以很順暢的撥放了….

一切事情解決了嗎?還沒有
在這個環境下,我試著用MPlayer撥放DVD,結果卻會當機!
以有其他人和我遇到同樣的問題。
經過交叉測試之後,發現不管是Debian或者XEPC套件庫的MPlayer,都無法在我的電腦上正常撥放DVD

無線網路
Xandros管理無線網路的GUI相當簡陋
(我沒在有NB上跑過Linux, 不清楚他是不是直接拿debian的套件來用)
做連線/斷線動作時,有時會跳出視窗顯示ifconfig等指令的執行過程,有時不會顯示
有時連不上網路時,也不會顯示錯誤訊息
另外,我找不到如何在UI中直接調整認證方式為Shared key..
在使用Shared Key認證方式時,好像唯有打指令設定一途

其他Linux Distribution
EeePC內建的Xandros功能明顯不足,或許有人會想要使用其他版本的Linux
但目前並沒有一個Linux Distribution對EeePC有完整的支援
eeebuntu, eeexubuntu這兩個專案,都還不能支援EeePC的所有硬體
PCMan等人開發的LXDE目前尚不支援EeePC 901

結語
本人並非微軟的愛好者。
我也相當遵敬、感謝lazyeeepc, LXDE, eeebuntu, eeeXubuntu的開發者。

我也可以想像,應該護有人跳出來說我資料找的不足。
在那裡有解決我遇到問題的方法。
但我必需指出,目前在EeePC上,Windows XP的支援性、易用性比Windows好的多。
對一個自認對Linux有一定程度了解的人,花兩個晚上還搞不定多媒體、無線網路。
這些東西使用Windows XP+MPlayer, KLite等免費軟體,幾分鐘就可以設定完閉。

對有一定Linux知識的玩家來說,Linux或許是你的好選擇。
但若你是要推薦給不太會用電腦的長輩、朋友、或是不想花太多時間調整系統。
我想「EeePC上Linux其實比Windows還簡單易用」這句話離限實還有一大段距離
如果你不想花一堆時間解決系統的問題,拿8G MLC硬碟去換XP的正版授權,我想是值得的。

最後,以上是我在2008/7月的使用心得。
這篇文章應具有時效性。
我也期待開源社群的活躍,或許有朝一日Linux會比Window還要Easy to use…


Footnotes:
  1. 參考此網頁的標題 [up]

4 Responses to “Linux+EeePC? It’s not easy….”

  1. songsongboyon 05 Aug 2008 at 2:07 am

    聽起來真是恐怖…連你都覺得難用的話 Orz

    不過是資工學生的就該買 Linux 版阿 XD (<= 偏見)

    反正現在也沒錢買這種東西,相信等我有錢時情況應該會好很多…吧?

  2. 大鳥on 09 Aug 2008 at 11:46 am

    你什麼時候留言的….
    我過了好幾天看到
    我WP的E-mail通知功能好像有點問題 Orz

  3. 玉子@香港on 29 Aug 2008 at 2:42 am

    咁 你一定要去呢度至得了,問 asus 係無用的, 佢地 d 技術人員一點都唔 pro, 夠胆同我講話 eeepc 目前係無任何 player 可以 support 到佢, 點知唔夠一個鐘我就搵到呢個網站, 我試過睇 rmvb, 不錯, 都幾流暢, 睇過呢個網站後, 包你愛上你的 eeepc.

    讓Eee PC內建的影音播放器支援rmvb
    http://blog.yam.com/tad0616/article/12306274

    Eee PC改造手冊
    http://blog.yam.com/BlogIndex.php?BLOG_ID=tad0616&CATEGORY_ID=1626347

2008年7月19日 星期六

一段愛與極座標系統的故事

被標題騙進來的人....這是數學文章不是愛情故事 XD

前陣子在同學Honda的BBS個版上看到一個關於笛卡兒的故事。其實這個故事源自於網路流傳,出處已經不詳了 (記得很久以前曾經看過不同的版本) ,在這裡引述一下....
十七世紀出生於法國的笛卡兒是第一個發現直角坐標的人,這對後人的貢獻相當大,可惜一生窮困潦倒。
一直到52歲,仍一直默默無名。當時法國正流行黑死病,笛卡兒不得不逃離,流浪到瑞典當乞丐。

某天,他在市場乞討時,有一群少女經過,
其中一名少女發現他的口音不像是瑞典人,她對笛卡兒非常好奇,於是上前問他:

「你從哪來的啊?」

「法國。」

「你是做什麼的啊?」

「我是數學家。」

這名少女叫克麗絲汀,18歲,是位公主,她和其它女孩不同,
克麗絲汀不喜歡文學,而是熱衷數學。
當她聽到笛卡兒說明身份後,感到相當大的興趣,於是把笛卡兒邀請回宮。

笛卡兒就成了她的數學老師,將一生的研究傾囊相授,
而克麗絲汀的數學也日益進步,直角坐標當時也只有笛卡兒這對師生才懂。

後來,他們之間產生了不一樣的情愫,發生喧騰一時的師生戀。
然而這件事傳到國王耳中,讓國王相當憤怒!下令將笛卡兒處死,克麗絲汀以自縊相逼,
國王害怕寶貝女兒真的會想不開,於是...將笛卡兒放逐回法國,也將克麗絲汀軟禁。

笛卡兒一回到法國沒多久就染上黑死病,躺在床上奄奄一息。
笛卡兒不斷地寫信到瑞典給克麗絲汀,都被國王攔截沒收。
克麗絲汀也就不曾收到過笛卡兒寫來的信...

就在笛卡兒快要死去的時候,他寄出了第13封信,當他寄出去沒多久後就氣絕身亡。
這封信的內容只有短短的一行...

r = a(1-sinθ)

國王攔截到這封信後拆開看,發現並不是一如往常的情話。
於是找來城裡所有科學家來研究,但都沒有任何人能夠解開。
國王心想...反正笛卡兒就快要死了,而且公主被軟禁時都悶悶不樂,便把信交給克麗絲汀。

故事暫停一下。




前陣子在PTT程設版看到有人問這樣的問題:
請問版上大大 我現在有一張image(方形)
想把他 warping 成環型(甜甜圈)
網路上沒看到相似的方法
不知道版上的高手有沒有任何想法呢
可以提供給小弟

極座標系統(Polar coordinate system)是解決這個問題的一個快速途徑。下圖 ((圖片引用自維基共享資援)) 是極座標系統的一個範例。



極座標系統定義一個中心點O,並且以與中心點的距離r,以及夾角θ,定位平面上的任何一個點。

極座標系統 (r, θ) 和我們更熟知的直角座標系 (x,y) 間,可以下列公式轉換:

[tex]x = r cos \theta[/tex]
[tex]y = r sin \theta[/tex]
記得這是理組高中數學的內容....

這樣對我們先前提到的問題有什麼幫助呢?

讓我們想想,怎樣在極座標系上,表示半徑為10的圓?
[tex]r = 10[/tex]
怎樣在極座標系上,表示一個內圈半徑為10,外圈半徑為15的環?
[tex]10 < r < 15[/tex]

要怎麼把一個矩型的圖片Wrap(變型)到一個環上,答案就呼之欲出了。


(x,y)為原圖上的座標
(x',y')為目的圖上的座標 (使用直角座標系,x軸向右,y軸向上)
(r,θ)為目的圖上的極標
(w,h)為原圖上的寬及高
R1為環內圈半徑,R2為環的寬度

讓我們觀查一下這組等式:
[tex] r = \frac{y}{h} \times R_{2} + R_{1} [/tex]
[tex] \theta = \frac{x}{w} \times 2\pi [/tex]

第一式讓y值越高時,r越大,距離原點越遠
第二式讓原圖的x座標轉變為目的圖的θ角,達成繞原點一週

但電腦在運算時,最直觀的方法是用點陣圖來處理。
所以我們最好把找到給定(x', y'),找到(x,y)的公式。
因此,將上述等式移項

[tex]x = \theta \times \frac{w}{2\pi} [/tex]
[tex] y = (r-R_{1}) \times \frac{h}{R_{2}} [/tex]

配合

[tex]x' = r cos \theta[/tex]
[tex]y' = r sin \theta[/tex]

便可以(x',y')反查(x,y)

讓我們直接看看實作出來的效果
假設這是原圖(點擊放大) ((這是Gun and roses樂團Paradise City的第一句歌詞)) :



經過上述公式映射後會變成



看起來怪怪的應該是我沒有做Anti-aliasing。我用Matlab實作的程式碼置於文末,取樣時我是用nearest point,有興趣的人可以試著改成bilinear interpolation看看。




回到笛卡兒的故事吧....
當克麗絲汀收到這封信時,雀躍無比,她很高與她的愛人還是想念她。
她立刻動手研究這行字的秘密。沒多久就解出來了,用的就是「直角坐標圖」....

當 θ=0度時,r=a(1-0)=a
θ=90度時,r=a(1-1)=0
θ=180度時,r=a(1-0)=a
θ=270度時,r=a(1+1)=2a,

其中a為四截距的比值,再將所有的點連接起來...就是有名的心臟線

這是網路流傳文章的全文....可是看來他用的是極座標系統,與直角座標系並沒有直接的關係啊。

先不管這個,我們試著把這張圖畫出來吧,使用matlab是很簡單的..
close all; figure;
n = 10000;
a = 10;
X = zeros(n, 1);
Y = zeros(n, 1);
i = 0;
for theta = linspace(0, 2*pi, n+1)
i = i + 1;
r = a * ( 1 - sin(theta) );
X(i) = r * cos(theta);
Y(i) = r * sin(theta);
end
line(X,Y);




原來這張圖代表了笛卡兒對於公主的愛意啊....




至於這個故事的真實性,我想本來就是漏洞百出的,如果有興趣的話,這邊有人考據過了。我想,故事有趣就好,這時候真相可能不是那麼重要吧....XD如果有興趣,可以參考這篇文章

最後,我們可以用上面的方法,把一張矩型的圖片Wrap到一個心型的環上嗎?
原本的等式是
[tex]x = \theta \times \frac{w}{2\pi} [/tex]
[tex] y = (r-R_{1}) \times \frac{h}{R_{2}} [/tex]
我們簡單的以
[tex]R_{1} = a \times ( 1 - sin\theta ) [/tex]
代入即可得到


看起來怪怪的,圖片被太過扭曲了。至於為什麼會這樣,答案就留給有興趣的讀者自己找尋吧...

附上本文所用到的源碼及圖片,很久沒寫Matlab了,很多地方都沒寫好。[Link]

輕省筆電 無責任Survey

之前提到我想買輕省筆電 (我定位為:價位20K以下,重量1.5Kg以下的筆電) 。我針對目前的資訊做了一些調查。我主要是想拿來文書、上網,偶爾寫小程式,調查的方向偏向CPU運算、省電能力優秀的筆電。其實我對於這方面資訊也不甚了解,如果內容有所謬誤歡迎幫忙更正。

2008年7月15日 星期二

Blogger新提供XML匯入匯出功能

Blogger於六月已經開始提供了XML匯入匯出的功能
網路上也有些中文的試用報告,如:Josh's Note: 來試試新玩意之六,Blogger in Draft:Import/Export
這部份我就不多說了。

本站之前提供了一個問題百出的Blog搬家工具 - BlogTrans。
這個工具搬家到Blogger,最大的限制就是每天只能匯入五十篇,以及匯入留言時會有些問題。

Blogger提供的這個新功能,匯出的XML檔基本上是Atom格式,但有的地方必需符合Blogger自己的規格。
一個重要的地方是:這個功能可以匯入留言,也沒有一天五十篇的限制。
所以要是我們摸透了他的XML格式,就有希望利用這個功能,做為將其他Blog資料 (例如無名) 匯入Blogger的方便跳版。

稍微看了一下他的格式,基本上每篇文章的結構是這樣

<entry>
<id>tag:blogger.com,1999:blog-1.post-1</id>
<published>2008-07-14T08:49:00.004-07:00</published>
<updated>2008-07-14T08:56:06.128-07:00</updated>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/blogger/2008/kind#post'/>
<category scheme='http://www.blogger.com/atom/ns#' term='Label2'/><category scheme='http://www.blogger.com/atom/ns#' term='Label1'/>
<title type='text'>Test1</title>
<content type='html'>Test12</content>
<link rel='alternate' type='text/html' href='http://test0012463.blogspot.com/2008/07/test1_9163.html' title='Test1'/>
<link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3196312873051422574/posts/default/3405625350671241273'/>
<author>
<name>大宅鳥</name>
<uri>http://abcde.com</uri>
<email>12345@msn.com</email>
</author>
</entry>

如果要用程式生成這樣的格式,有幾點要注意的:

  • 最重要的一點,id tag似乎只能是tag:blogger.com,1999:blog-12345.post-23456這樣的格式,但裡面的數字不管填什麼,匯入時都沒有問題

  • 已經存在的欄位不要空著。Author裡的name, uri, email其實都沒有作用,但不打的話就會發生錯誤。

  • Comment的部份好像複雜一些,我還沒有摸清他的規則。


目前只研究到這樣。

2007年11月16日 星期五

台大教授的程式作業批改系統

不知道有沒有人對YouTube上的一首曖昧改編版有印像 (曾經被PO在ptt上面)



笑點可能要修過程式設計課的人才會懂..

我有在ptt2潛水看台大兩位資工系教授的個人版。其中一位教授稱他的程式作業叫『使徒』(於是學生們就得擊敗眾多的使徒 XDXD)

那位教授也開發了一個web-based的程式批改系統(像是ACM judge),叫做『批改娘』。
『批改娘』的系統好像常常被助教惡搞,於是今天在版上就看到了這樣的畫面

使�

真是有趣的教授和助教啊....XD 有興趣的話前往ptt2應該不難找到那個版

2007年11月12日 星期一

Monte Carlo integration (蒙地卡羅積分)

蒙地卡羅積分是一個能夠求積分近似值的方法。這個方法應該有很多應用吧,我印像最深刻的是影像合成中的ray tracing演算法(可用於計算一個點受到的照度)。因為學弟的論文可能會用到這個方法,我曾經學過但是有點忘了,而且竟然找不太到中文的資源,所以復習一下順便做一下筆記。

假設有一個對x的定積分式


如下圖,如果f為折線的函式,則黃色區塊的面積即為自0到1積分的結果。

monte1

當然,我們很容易可以利用三角形面積公式,或者對f求定積分,而算出黃色區域的面積。然而,假設我們沒有這樣的先備知識,或者黃色區域的面積是難以求得的,那要怎麼辦呢?

2007年10月2日 星期二

下載檔案如何不造成lag?

前言:這篇想要寫的盡量簡單易懂,所以用了一些技術上不太正確的譬喻,高手看到請鞭小力一點。


劇情:小明在外租屋,房東家裡裝了一條ADSL網路,免費分給各位房客用。小明的朋友阿喵架了一個FTP站,在上面放了一些電影。有一天,小明在阿喵的FTP上抓電影時,房東的兒子打網路遊戲突然變的很不順,下達一個攻擊指令後過三秒才會有反應。房東的兒子和房東說了這樣的情況,於是房東就把房客們的網路線拔掉了...如果有在網路上下載檔案(FTP, BT, eMule)的人,應該常常會有這種經驗...打BBS或網路遊戲突然變的很lag(指網路回應時間很慢)。要怎麼避免這種狀況呢?

Wordpress忘記密碼的解決方法

此處指自己架的wordpress,並非wordpress.com提供的service。

第一種方法:在login畫面點選forget password,會寄送一封信到你的信箱,附帶一個可以更改密碼的link,但要是這方法失效的話...

進phpmyadmin,修改wp_users table,將使用者的密碼欄位清空 (原本會看到一串16進位的數字),打上新的密碼,並點選MD5。phpmyadmin會幫你把密碼用MD5 hash後存入資料庫,收工。

事實上sql指令夠熟的話,直接去console下sql...

UPDATE `xxx_blog`.`wp_users` SET `user_pass` = MD5( 'password' ) WHERE `wp_users`.`ID` =2 ;

參考http://codex.wordpress.org/Resetting_Your_Password

2007年3月19日 星期一

遊戲中常見的幾種音樂格式

這篇是貼我自己以前寫的文章。



介紹這些格式的文章應該不少,但我想大多過於專業
我試著用自己的話,盡量簡單地描述四種遊戲最常見的音樂格式

  1. MIDI:通常副檔名為mid,MIDI是Music Instrument Digital Interface的簡寫
    特色是檔案很小,非常小

    簡單的這麼解釋好了:

    mid檔就像是樂譜,記錄著「第5.02秒鋼琴要彈下sol、第6.31秒吉他要彈下ra」這樣的資訊
    然而mid檔裡本身並沒有吉他、鋼琴的音色。這也就是為何mid檔案小的原因

    那當我們的電腦撥放mid檔時,怎麼知道吉他、鋼琴的音色呢?
    這是因為mid檔通常遵守一種叫「General MIDI」的格式
    「樂器1」表示鋼琴、「樂器25」表示尼龍弦的古典吉他
    然而我們的音效卡上有一個「MIDI音源器」,負責按照這些樂器編號,把聲音撥放出來
    (當然有軟體音源這個例外,但不在此討論)

    單純使用mid檔的話有一些限制

    1. 音色是看使用者電腦上的音源,不同的電腦撥放出來的效果可能會不同
      (大部份的人應該都是爛爛的AC97音效卡)
    2. 音色有限,只有General MIDI提供的音色 (我記得是128種,不知道有沒有記錯)
    3. 效果有限,沒辦法自由的調整迴音、各種效果(equalizer, echo, reverb, flanger等....多不勝數)


  2. Wave:通常副檔名為wav
    特色是檔案很大,非常大

    大家可以把他想像成忠實的把聲音記錄下來的檔案格式

    音質最好,所以花費的空間多
    (大家可以把他想像成圖檔中的bmp檔)

    許多商業遊戲都是用CD音軌的方式來儲存音樂
    CD音軌其實也是屬於Wave的無失真儲存方式
    (CD音軌的資訊其實就等於Sample rate=44,100Hz 雙聲道的Wave檔)


    很常見的編曲方式就是:使用MIDI編曲軟體+自己的軟/硬體音源 => 混音成wave檔

    然後再看要不要做壓縮之類的
    和單純使用General MIDI比起來,這樣可以使用很多種的效果,處理上也有很大的彈性


    Wave和以下的mp3, ogg...等真正儲存聲音的,通稱為數位音訊檔
    接下來只是把Wave壓縮過的格式,我就不詳細介紹了
    主要的目的只是跟大家講數位音訊和mid檔之間的差別

  3. mp3
    相信大家都很熟悉吧 XD


    mp3是將wave失真壓縮(註)後的一種格式

  4. ogg
    可以參考維基百科: Ogg Vorbis

    一樣是失真壓縮
    據說同樣壓縮比下的音質比mp3還好,我自己倒是沒試過
    在一般使用者間這個格式還是沒有比mp3被廣為使用


註:失真壓縮
失真壓縮就是指在壓縮的過程中,損失一些原有的資訊

舉大家比較熟悉的圖片來說,bmp就好像wav的角色
png,gif就是一種非失真壓縮(畫質不會變差),jpg就是失真壓縮

2007年3月8日 星期四

GLUT+Code::Blocks+Mingw環境設定

GLUT....不介紹了,反正就是OpenGL的一些Toolkit,讓programmer避免處理low level的視窗控制。

其實我滿推薦寫程式的人不要「只」用微軟的IDE。之前看到某位網友抱怨,他們學校沒有正版的VC教育版,老師還要求要用VC寫作業。多推廣一下免費開源的IDE不是很好嗎?



Code::Blocks+Mingw的安裝可以參考這篇,如果不是要跑OGRE的話,直接去官網下載區抓安裝包應該比較簡單 (with Mingw compiler的)。

原本的GLUT Windows Binary和Mingw似乎不太相容,請抓GLUT for Mingw32,隨便解壓到一個目錄(我放在Mingw下),就可以了。

預備動作就這麼簡單 (不過我灌時試GLUT library試了一陣子,才發現要抓Mingw版的) ,進到Code::Block,New project -> GLUT project -> 到GLUT's location時輸入你安裝GLUT的位置。

這樣開好專案後會出現template的範例程式,compile&run看看...
C:\codeblock\GLUTMingw32\include\GL\glut.h:45: error: redeclaration of C++ built-in type `short'
疑...不知道怎麼回事的error,但我們見招拆招一下
方法一: 修改範例程式,再include之前加上# define _WCHAR_T_DEFINED
方法二: 修改glyt.h第45行,將typedef unsigned short wchar_t;這行給註解掉

兩者任做一項,這樣就可以run囉...

2007年2月21日 星期三

TJS特訓99解說篇

上一篇忘了說,我的架構主要是參考這篇TJS實作教學的

先講一下類別的設計:
  • MovingObject:所有戰場上會移動的物件,Player及Enemy的父類別
  • Player:玩家自機,畫面上那個藍點
  • Enemy:敵機,不停撞過來的那些小紅點
  • GameMaster:管理整個遊戲的迴圈與邏輯
  • GameWindow:遊戲視窗
GameWindow類別
作用其實很簡單
  • 建立一個視窗,設定大小為400x400。
  • 建立一個Layer,該視窗的主要圖層。
  • 然後建立一個GameMaster物件,就這樣。接下來遊戲的進行都交給GameMaster控制。
GameMaster類別
  • 建立fore(前景)圖層,所有遊戲的物件都畫在這個圖層上。
  • 建立玩家物件及99個敵人物件,敵人物件用一個陣列(Array)存放。
  • 建立一個Timer,每25ms呼叫一次 (理想狀態下40fps),負責玩家、敵機的移動、碰撞判定。
MovingObject類別
  • 之前說過這個範例不要想用到圖檔,所以我們使用正方形來表示自機與子彈。size是邊長,color是顏色
  • 繼承Layer物件,建構時將自己放在fore這個圖層上
Enemy類別
  • 建構時指定顏色(子彈是紅色)及邊長。
  • init函式負責初始化敵機 (在畫面的邊緣出現,向畫面內非)
  • check_bound函式負責檢查敵機是否出界了,如果是的話,呼叫init來重置敵機。
  • update函式負責敵機的移動
Player類別
  • 建構時指定顏色(藍色)
  • update函式負責移動,使用System.getKeyState()來判斷方向鍵是否已被按下。
我就不一行一行的講解程式碼了,有興趣的話可以留言討論。



延伸練習:這只是個小小範例,我的code有滿多問題的,如果你想練習的話...
  1. 我忘了寫Player出界的判定,請補上
  2. 碰撞判定的公式其實是不對的,你發現了嗎?請修正
  3. Frame穩速的機制是否有比使用Timer還要好的方式呢?
  4. 敵機移動的速度目都只是整數,請修改init函式讓敵機的移動速度不要那麼規律。
  5. 找找看還有沒有其他bug吧 :)

2007年2月20日 星期二

吉里吉里TJS特訓99

特訓99是數年前在巴哈姆特kuso版看到的一個遊戲,規則很簡單:「閃避畫面上的99顆子彈,看你可以撐幾秒」自從看到了這個遊戲之後,每到一個可以寫遊戲的環境,我都把他當hello, world來寫了,幫助熟悉整個程式環境。(印像中寫過C++/DirectDraw, J2SE, J2ME on 手機, VisualBasic, Ruby/RPG Maker XP還有什麼忘了)

剛剛把試著用吉里吉里的TJS寫了一下,心得...喵的文件有夠不完整,要到處翻來翻趣,有的地方乾脆去template裡直接看他怎麼寫的比較快。寫出來就這樣囉:


不停的閃子彈閃到死吧 XD
  • 其實code寫的很差,我只是一直翻文件然後找出一個能寫出來的方法而已。很多地方應該可以再修正的。碰撞判定的公式其實也是錯的,可是我懶得改了,可以跑就好了啦,只是做個小範例而已 @@
  • 為了簡化範例,被擊中game over時就直接跳出遊戲了 (好我懶得做game over畫面了 XD)
  • 為了簡化範例所以沒有貼圖,都是用方塊表示。這樣只需要把程式複置貼上就可以跑囉


把以下程式複置貼到startup.tjs (原本的程式清掉) 即可

class MovingObject extends Layer{
var master;
var size;
var color;

function MovingObject(gm, window, parent) {
super.Layer(window, parent);
master = gm;
visible = true;
setSize(size, size);
fillRect(0, 0, size, size, color);
}
}

class Enemy extends MovingObject {
var vx, vy;
function Enemy(gm, window, parent) {
size = 6;
color = 0xffff0000;
super.MovingObject(gm, window, parent);
init();
}
function init() {
var side = Math.floor(Math.random()*4);
switch (side) {
case 0:
top = 0;
left = Math.floor(Math.random()*400);
vx = Math.floor(Math.random()*5)-2;
vy = Math.floor(Math.random()*2)+1;
break;
case 1:
top = 400;
left = Math.floor(Math.random()*400);
vx = Math.floor(Math.random()*5)-2;
vy = -Math.floor(Math.random()*2)-1;
break;
case 2:
left = 0;
top = Math.floor(Math.random()*400);
vy = Math.floor(Math.random()*5)-2;
vx = Math.floor(Math.random()*2)+1;
break;
default:
left = 400;
top = Math.floor(Math.random()*400);
vy = Math.floor(Math.random()*5)-2;
vx = -Math.floor(Math.random()*2)-1;
break;
}
}
function check_bound() {
if (top>-5&&top<405&&top>-5&&top<405)
return;
init();
}
function update() {
top += vy;
left += vx;
check_bound();
}
}

class Player extends MovingObject {
function Player(gm, window, parent) {
size = 10;
color = 0xff0000ff;
super.MovingObject(gm, window, parent);
top = left = 200;
}
function update() {
var speed = 2;
if (System.getKeyState(VK_DOWN))
top += speed;
if (System.getKeyState(VK_UP))
top -= speed;
if (System.getKeyState(VK_LEFT))
left -= speed;
if (System.getKeyState(VK_RIGHT))
left += speed;
}
}

class GameMaster {
var window;
var parent;
var fore;

var player;
var enemies;

var timer1;

function GameMaster(win, par) {
window = win;
parent = par;

fore = new Layer(win, par);

with (fore) {
.visible = true;
.setSize(400, 400);
}

timer1 = new Timer(onTimer1, "");
timer1.interval = 25;
timer1.enabled = true;

player = new Player(this, window, fore);

enemies = [];
for (var i=0; i<99; ++i) {
enemies.add(new Enemy(this, window, fore));
}

}
function onTimer1() {
player.update();
for (var i=0; i<enemies.count; ++i) {
var e = enemies[i];
e.update();
if (Math.abs(e.top-player.top)<10&&Math.abs(e.left-player.left)<10)
window.close();
}
}

}

class GameWindow extends Window {
var master;

function GameWindow() {

super.Window();

add(new Layer(this, null));
primaryLayer.setSize(400, 400);
setInnerSize(400, 400);

caption = "特訓99";
visible = true;

master = new GameMaster(this, primaryLayer);
}
function finalize() {
super.finalize();
}
function action(ev) { }
}
var win = new GameWindow();


解說篇....下次再說吧 XD

2007年2月16日 星期五

初探Shattered Ruby(4) - 結論

前四篇對於Shattered Ruby似乎是貶多於褒,但其實我覺得這東西還是滿有趣的。有很多implement的功能是這裡沒提到的,大家可以詳閱WikiRDoc。其實他們已經做了很多了....

說實話,我沒看過一個工具建構以3D介面為基楚的遊戲那麼容易的,這應該是他最大的優點吧。要是目前這個專案還有人持續在maintain,那我應該毫不考慮的繼續玩下去。

Shattered Ruby中的設計流程其實很高階,我們可以看到Tutorial幾乎都是用DSL的方式在寫作。但根據抽象滲漏法則,當專案被擴大的時候不知道會不會遇到麻煩...

好啦,Shattered Ruby就寫到這囉,我應該短期之內不會再碰他了。有什麼意見的話也歡迎提出來吧 :)

初探Shattered Ruby(3) - 回到舊版本玩Example

我們可以看到Shattered Ruby Wiki首頁上有好幾個Tutorial&Example,但除了第一個之外,其他都不能在最新的版本上跑。如果我們要快速的玩玩看Example的話(不想去改code),可能回到舊版本是比較快的選擇。

我們以俄羅斯方塊為例吧....先把他解壓到某個地方,然後我們開始裝0.3.3版的Shattered Ruby

首先為了避免混淆,我們先將舊版本的ShatteredRuby全都反安裝。執行

C:\temp\mygame>gem uninstall shattered*

Select RubyGem to uninstall:
1. shattered-0.4.0.1
2. shattered_ogre-0.4-windows
3. shattered_pack-0.4.0.1
4. shattered_support-0.4.0.1
5. All versions
> 5
Successfully uninstalled shattered version 0.4.0.1
Successfully uninstalled shattered_ogre version 0.4
Successfully uninstalled shattered_pack version 0.4.0.1
Successfully uninstalled shattered_support version 0.4.0.1


然後再安裝0.3.3版的ShatteredRuby,可能又需要一些時間,因為另一個revision的DLL必需重新下載一次,安裝方式如下:

C:\temp\mygame>gem install -y shattered -v 0.3.3
Bulk updating Gem source index for: http://gems.rubyforge.org
Bulk updating Gem source index for: http://gems.rubyforge.org
Select which gem to install for your platform (i386-mswin32)
1. shattered_ogre 0.4 (windows)
2. shattered_ogre 0.3.3 (windows)
3. Cancel installation
> 2
Bulk updating Gem source index for: http://gems.rubyforge.org
Bulk updating Gem source index for: http://gems.rubyforge.org
Successfully installed shattered-0.3.3
Successfully installed shattered_ogre-0.3.3-windows
Successfully installed shattered_pack-0.4.0.1
Successfully installed shattered_support-0.4.0.1
下略

這樣就裝好了....但我們執行tetris時卻會發生錯誤....經過一連串的試誤,我發現在gemspec中這樣定義:shattered 0.3.3版需要shattered_pack及shattered_support0.3.3「以上」的版本。但事實上是不相容的。所以我們必需手動移除,再灌正確的版本。 (如果你熟希gems的話,你可以一開始就灌正確的版本,這樣比較快)

執行這四行吧:

gem uni shattered_support -i
gem uni shattered_pack -i
gem i shattered_support -v 0.3.3
gem i shattered_pack -v 0.3.3


事情還沒結束,還要上wiki的補丁。見A Confession這段。 (我試過了,上面手動灌0.3.3版和這個補丁兩者都是必需的,缺一不可,當初gemspec沒寫好的關係 Orz)

再跑一次tetris的script/runner



好啦....終於成功了....真累....

初探Shattered Ruby(2) - Follow the first tutorial

如果你玩過rails,你大概一秒鐘就可以知道shatter所產生的每個目錄的功用。不知道也沒關係,一開始我們需要注意的目錄其實很少:
  • app:整個遊戲的主程式都在這裡面
  • config:一些設定檔
  • script:一些ruby的script,runner可以啟動遊戲、generate可以幫助產生程式碼等等...
接下來就請跟著官網wiki的Your first move這篇教學做吧。
ruby script/generate state observation
與rails一樣,這個框架有內建一些generator幫助產生程式碼。他的概念大概是整個遊戲會在不同的state間轉換(state machine),每個state會有不同的input/output。現在我們產生了一個名為observation的state。但現在還不能執行,因為還沒有指定初始狀態。請照wiki上的步驟修改config/environment.rb (哇咧,連這個也要取和rails一樣的名字)

執行ruby script/runner吧,程式順利啟動了,雖然因為我們沒在場景上放上任何物件,所以畫面是一片全黑的,但至少應該可以順利執行了。

接下來,跟著教學做吧... ruby script/generate actor dirty_ruby
我們可以看到程式又自動產生了一堆檔案。跟著Wiki上的教學修改ObservationState物件,我們可以看到這是一個Domain Specific Language應用的例證...code真是有夠簡單的 :) 注意因為最新版的generator有問題,可能會當機,請參閱wiki的說明從範例source code中得到正確的mesh檔。

接下來我就不詳細講,跟著wiki跑完這個簡單的tutorial並沒有問題。你應該可以得到一個旋轉的紅寶石,並且可以控制他左右移動。



注意一點:我覺得這裡的View並不是MVC架構中的View,反而比較像是Data Model(定義了物件的mesh和行為)。如果你本來懂MVC架構,這可能是比較容易混淆的地方。

初探Shattered Ruby(1) - 簡介&安裝&Getting Start

之前在OGRE language binding中曾經稍微提到過Shattered Ruby,實在是對他滿好奇的,所以今天就抓下來玩了一下。還滿有趣的,但不是每件事都那麼美好:
  • 先說優點,玩起來真的很像在用Ruby on Rails寫網頁,操作有夠簡單,很少的程式碼就可以寫出一個小遊戲。
  • Shattered Ruby已經快要半年沒有更新了,根據官方blog的說法,開發人員有其他事情在忙著。
  • 有些功能在最新版本(0.4)反而無法使用,作者在wiki上說很快就會修正,但很久沒動靜了。另外,Wiki上很多tutorial及example並不能在最新版本上跑,document is out of date.
  • Lack of support,開發人員不知道什麼時候才會回來,搞不好一輩子都不會開發了,除非你有自己去延續開發的心理準備,否則...XD
  • Python-OGRE裡至少有提供了ODE, OgreNewt這些物理引擎的介面。如果在Shattered Ruby做碰撞判定,你不是要自己寫native binding,不然就是要拿慢到要死的Ruby去計算? (我是Ruby的擁護者,但Ruby的長處絕不在物理運算 XD)
目前看起來,做做小遊戲可以,拿來開發中大型遊戲還差的遠。所以我大概分成三篇稍微介紹一下Shattered Ruby就會結束了。

Shattered Ruby的安裝其實很簡單。首先你要先裝好Ruby及RubyGems (RubyGems是Ruby的套件管理系統)。在Windows系統下最方便的方法就是直接安裝Ruby One-click Installer就好了。

安裝好之後,進入命令提示字元,輸入
gem i -y shattered
他就會自動幫你下載/安裝好。台灣最近連RubyForge的速度好像變慢了些,下載的過程中包括了OGRE, mingw, DirectX的DLL檔,所以可能需要比較久的時間,請耐心等候。

OK...Let's getting start

先建立一個空目錄,然後進到命令提示字元,切換到該目錄下...如:

cd \
mkdir temp
cd temp
shattered mygame

最後一行是幫你建立一個遊戲專案目錄,讓我們看看裡面有什麼

C:\temp>dir mygame
磁碟區 C 中的磁碟沒有標籤。
磁碟區序號: 1CD9-4BA7

C:\temp\mygame 的目錄

2007/02/16 下午 04:57 <DIR> .
2007/02/16 下午 04:57 <DIR> ..
2007/02/16 下午 05:01 <DIR> app
2007/02/16 下午 04:59 <DIR> config
2007/02/16 下午 04:57 <DIR> doc
2007/02/16 下午 04:57 <DIR> log
2007/02/16 下午 04:57 454 Rakefile
2007/02/16 下午 04:57 905 README
2007/02/16 下午 04:57 <DIR> script
2007/02/16 下午 04:57 <DIR> test
2007/02/16 下午 04:57 <DIR> vendor
2 個檔案 1,359 位元組
9 個目錄 7,678,304,256 位元組可用


有用過Ruby on rails的人應該都看的出來,這架構明顯是抄rails的吧 XD 只是一個用來寫網頁一個用來寫遊戲。

到這裡...簡介與安裝就結束囉。我們下篇繼續

2007年2月15日 星期四

(閒聊)在blogspot貼程式

不知道什麼狀況會造成縮排的空格全部不見 (好像要到撰寫模式才會,但大部份狀況下又都不會)。對於python尤其可怕,這是我唯一一個用過的語言用縮排做blocking的....Orz