不知道有沒有人對YouTube上的一首曖昧改編版有印像 (曾經被PO在ptt上面)
笑點可能要修過程式設計課的人才會懂..
我有在ptt2潛水看台大兩位資工系教授的個人版。其中一位教授稱他的程式作業叫『使徒』(於是學生們就得擊敗眾多的使徒 XDXD)
那位教授也開發了一個web-based的程式批改系統(像是ACM judge),叫做『批改娘』。
『批改娘』的系統好像常常被助教惡搞,於是今天在版上就看到了這樣的畫面
真是有趣的教授和助教啊....XD 有興趣的話前往ptt2應該不難找到那個版
2007年11月16日 星期五
2007年11月12日 星期一
Monte Carlo integration (蒙地卡羅積分)
2007年10月2日 星期二
下載檔案如何不造成lag?
Wordpress忘記密碼的解決方法
此處指自己架的wordpress,並非wordpress.com提供的service。
第一種方法:在login畫面點選forget password,會寄送一封信到你的信箱,附帶一個可以更改密碼的link,但要是這方法失效的話...
進phpmyadmin,修改wp_users table,將使用者的密碼欄位清空 (原本會看到一串16進位的數字),打上新的密碼,並點選MD5。phpmyadmin會幫你把密碼用MD5 hash後存入資料庫,收工。
事實上sql指令夠熟的話,直接去console下sql...
參考http://codex.wordpress.org/Resetting_Your_Password
第一種方法:在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日 星期一
遊戲中常見的幾種音樂格式
這篇是貼我自己以前寫的文章。
介紹這些格式的文章應該不少,但我想大多過於專業
我試著用自己的話,盡量簡單地描述四種遊戲最常見的音樂格式
失真壓縮就是指在壓縮的過程中,損失一些原有的資訊
舉大家比較熟悉的圖片來說,bmp就好像wav的角色
png,gif就是一種非失真壓縮(畫質不會變差),jpg就是失真壓縮
介紹這些格式的文章應該不少,但我想大多過於專業
我試著用自己的話,盡量簡單地描述四種遊戲最常見的音樂格式
- MIDI:通常副檔名為mid,MIDI是Music Instrument Digital Interface的簡寫
特色是檔案很小,非常小
簡單的這麼解釋好了:
mid檔就像是樂譜,記錄著「第5.02秒鋼琴要彈下sol、第6.31秒吉他要彈下ra」這樣的資訊
然而mid檔裡本身並沒有吉他、鋼琴的音色。這也就是為何mid檔案小的原因
那當我們的電腦撥放mid檔時,怎麼知道吉他、鋼琴的音色呢?
這是因為mid檔通常遵守一種叫「General MIDI」的格式
「樂器1」表示鋼琴、「樂器25」表示尼龍弦的古典吉他
然而我們的音效卡上有一個「MIDI音源器」,負責按照這些樂器編號,把聲音撥放出來
(當然有軟體音源這個例外,但不在此討論)
單純使用mid檔的話有一些限制- 音色是看使用者電腦上的音源,不同的電腦撥放出來的效果可能會不同
(大部份的人應該都是爛爛的AC97音效卡) - 音色有限,只有General MIDI提供的音色 (我記得是128種,不知道有沒有記錯)
- 效果有限,沒辦法自由的調整迴音、各種效果(equalizer, echo, reverb, flanger等....多不勝數)
- 音色是看使用者電腦上的音源,不同的電腦撥放出來的效果可能會不同
- Wave:通常副檔名為wav
特色是檔案很大,非常大
大家可以把他想像成忠實的把聲音記錄下來的檔案格式
音質最好,所以花費的空間多
(大家可以把他想像成圖檔中的bmp檔)
許多商業遊戲都是用CD音軌的方式來儲存音樂
CD音軌其實也是屬於Wave的無失真儲存方式
(CD音軌的資訊其實就等於Sample rate=44,100Hz 雙聲道的Wave檔)
很常見的編曲方式就是:使用MIDI編曲軟體+自己的軟/硬體音源 => 混音成wave檔
然後再看要不要做壓縮之類的
和單純使用General MIDI比起來,這樣可以使用很多種的效果,處理上也有很大的彈性
Wave和以下的mp3, ogg...等真正儲存聲音的,通稱為數位音訊檔
接下來只是把Wave壓縮過的格式,我就不詳細介紹了
主要的目的只是跟大家講數位音訊和mid檔之間的差別 - mp3:
相信大家都很熟悉吧 XD
mp3是將wave失真壓縮(註)後的一種格式 - 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看看...
疑...不知道怎麼回事的error,但我們見招拆招一下
方法一: 修改範例程式,再include之前加上
方法二: 修改glyt.h第45行,將
兩者任做一項,這樣就可以run囉...
其實我滿推薦寫程式的人不要「只」用微軟的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實作教學的。
先講一下類別的設計:
作用其實很簡單
延伸練習:這只是個小小範例,我的code有滿多問題的,如果你想練習的話...
先講一下類別的設計:
- MovingObject:所有戰場上會移動的物件,Player及Enemy的父類別
- Player:玩家自機,畫面上那個藍點
- Enemy:敵機,不停撞過來的那些小紅點
- GameMaster:管理整個遊戲的迴圈與邏輯
- GameWindow:遊戲視窗
作用其實很簡單
- 建立一個視窗,設定大小為400x400。
- 建立一個Layer,該視窗的主要圖層。
- 然後建立一個GameMaster物件,就這樣。接下來遊戲的進行都交給GameMaster控制。
- 建立fore(前景)圖層,所有遊戲的物件都畫在這個圖層上。
- 建立玩家物件及99個敵人物件,敵人物件用一個陣列(Array)存放。
- 建立一個Timer,每25ms呼叫一次 (理想狀態下40fps),負責玩家、敵機的移動、碰撞判定。
- 之前說過這個範例不要想用到圖檔,所以我們使用正方形來表示自機與子彈。size是邊長,color是顏色
- 繼承Layer物件,建構時將自己放在fore這個圖層上
- 建構時指定顏色(子彈是紅色)及邊長。
- init函式負責初始化敵機 (在畫面的邊緣出現,向畫面內非)
- check_bound函式負責檢查敵機是否出界了,如果是的話,呼叫init來重置敵機。
- update函式負責敵機的移動
- 建構時指定顏色(藍色)
- update函式負責移動,使用System.getKeyState()來判斷方向鍵是否已被按下。
延伸練習:這只是個小小範例,我的code有滿多問題的,如果你想練習的話...
- 我忘了寫Player出界的判定,請補上
- 碰撞判定的公式其實是不對的,你發現了嗎?請修正
- Frame穩速的機制是否有比使用Timer還要好的方式呢?
- 敵機移動的速度目都只是整數,請修改init函式讓敵機的移動速度不要那麼規律。
- 找找看還有沒有其他bug吧 :)
2007年2月20日 星期二
吉里吉里TJS特訓99
特訓99是數年前在巴哈姆特kuso版看到的一個遊戲,規則很簡單:「閃避畫面上的99顆子彈,看你可以撐幾秒」自從看到了這個遊戲之後,每到一個可以寫遊戲的環境,我都把他當hello, world來寫了,幫助熟悉整個程式環境。(印像中寫過C++/DirectDraw, J2SE, J2ME on 手機, VisualBasic, Ruby/RPG Maker XP還有什麼忘了)
剛剛把試著用吉里吉里的TJS寫了一下,心得...喵的文件有夠不完整,要到處翻來翻趣,有的地方乾脆去template裡直接看他怎麼寫的比較快。寫出來就這樣囉:
不停的閃子彈閃到死吧 XD
把以下程式複置貼到startup.tjs (原本的程式清掉) 即可
解說篇....下次再說吧 XD
剛剛把試著用吉里吉里的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的功能是這裡沒提到的,大家可以詳閱Wiki及RDoc。其實他們已經做了很多了....
說實話,我沒看過一個工具建構以3D介面為基楚的遊戲那麼容易的,這應該是他最大的優點吧。要是目前這個專案還有人持續在maintain,那我應該毫不考慮的繼續玩下去。
Shattered Ruby中的設計流程其實很高階,我們可以看到Tutorial幾乎都是用DSL的方式在寫作。但根據抽象滲漏法則,當專案被擴大的時候不知道會不會遇到麻煩...
好啦,Shattered Ruby就寫到這囉,我應該短期之內不會再碰他了。有什麼意見的話也歡迎提出來吧 :)
說實話,我沒看過一個工具建構以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全都反安裝。執行
然後再安裝0.3.3版的ShatteredRuby,可能又需要一些時間,因為另一個revision的DLL必需重新下載一次,安裝方式如下:
這樣就裝好了....但我們執行tetris時卻會發生錯誤....經過一連串的試誤,我發現在gemspec中這樣定義:shattered 0.3.3版需要shattered_pack及shattered_support0.3.3「以上」的版本。但事實上是不相容的。所以我們必需手動移除,再灌正確的版本。 (如果你熟希gems的話,你可以一開始就灌正確的版本,這樣比較快)
執行這四行吧:
事情還沒結束,還要上wiki的補丁。見A Confession這段。 (我試過了,上面手動灌0.3.3版和這個補丁兩者都是必需的,缺一不可,當初gemspec沒寫好的關係 Orz)
再跑一次tetris的script/runner
好啦....終於成功了....真累....
我們以俄羅斯方塊為例吧....先把他解壓到某個地方,然後我們開始裝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所產生的每個目錄的功用。不知道也沒關係,一開始我們需要注意的目錄其實很少:
與rails一樣,這個框架有內建一些generator幫助產生程式碼。他的概念大概是整個遊戲會在不同的state間轉換(state machine),每個state會有不同的input/output。現在我們產生了一個名為observation的state。但現在還不能執行,因為還沒有指定初始狀態。請照wiki上的步驟修改config/environment.rb (哇咧,連這個也要取和rails一樣的名字)
執行
接下來,跟著教學做吧...
我們可以看到程式又自動產生了一堆檔案。跟著Wiki上的教學修改ObservationState物件,我們可以看到這是一個Domain Specific Language應用的例證...code真是有夠簡單的 :) 注意因為最新版的generator有問題,可能會當機,請參閱wiki的說明從範例source code中得到正確的mesh檔。
接下來我就不詳細講,跟著wiki跑完這個簡單的tutorial並沒有問題。你應該可以得到一個旋轉的紅寶石,並且可以控制他左右移動。
注意一點:我覺得這裡的View並不是MVC架構中的View,反而比較像是Data Model(定義了物件的mesh和行為)。如果你本來懂MVC架構,這可能是比較容易混淆的地方。
- app:整個遊戲的主程式都在這裡面
- config:一些設定檔
- script:一些ruby的script,runner可以啟動遊戲、generate可以幫助產生程式碼等等...
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,實在是對他滿好奇的,所以今天就抓下來玩了一下。還滿有趣的,但不是每件事都那麼美好:
Shattered Ruby的安裝其實很簡單。首先你要先裝好Ruby及RubyGems (RubyGems是Ruby的套件管理系統)。在Windows系統下最方便的方法就是直接安裝Ruby One-click Installer就好了。
安裝好之後,進入命令提示字元,輸入
他就會自動幫你下載/安裝好。台灣最近連RubyForge的速度好像變慢了些,下載的過程中包括了OGRE, mingw, DirectX的DLL檔,所以可能需要比較久的時間,請耐心等候。
OK...Let's getting start
先建立一個空目錄,然後進到命令提示字元,切換到該目錄下...如:
最後一行是幫你建立一個遊戲專案目錄,讓我們看看裡面有什麼
有用過Ruby on rails的人應該都看的出來,這架構明顯是抄rails的吧 XD 只是一個用來寫網頁一個用來寫遊戲。
到這裡...簡介與安裝就結束囉。我們下篇繼續
- 先說優點,玩起來真的很像在用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的安裝其實很簡單。首先你要先裝好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
2007年2月14日 星期三
OGRE初學筆記--以Python為例 索引篇
原本只是想把筆記整理一下而已,根本沒有想過會寫到那麼詳細...在將近12小時之內打了十篇文章,連我自己都嚇了一跳。
其實我自己也是OGRE初學者,對Python的也是很不熟(我是Ruby的愛用者)。很可能會有錯誤,也請大家幫忙指教。這些筆記和原本的Wiki相比少了很多東西,建議大家還是詳閱Wiki比較好。希望大家有了這些中文筆記,能夠比較快上手一些。
就這樣囉,之前研究一陣子的東西,今天有空一次把他寫出來,超累的....祝大家去死去死節快樂 XD
其實我自己也是OGRE初學者,對Python的也是很不熟(我是Ruby的愛用者)。很可能會有錯誤,也請大家幫忙指教。這些筆記和原本的Wiki相比少了很多東西,建議大家還是詳閱Wiki比較好。希望大家有了這些中文筆記,能夠比較快上手一些。
- What's OGRE?:OGRE簡介
- OGRE + MinGW + Code::Blocks 安裝:C++的環境設定
- OGRE language binding:用Ruby, Python寫OGRE
- Python-Ogre安裝:超簡單的安裝說明 :)
- 寫在Python-OGRE Tutorial前面:寫Tutorial的環境設定步驟
- Python-Ogre Tutorial 1:SceneNode, Entity
- Python-Ogre Tutorial 1-2:續上篇,座標系統、旋轉
- Python-Ogre Tutorial 2:攝影機、光源、陰影
- Python-Ogre Tutorial 3:地型、天空、霧
- Python-Ogre Tutorial 4&5:有寫跟沒寫一樣,不用看了 XD
就這樣囉,之前研究一陣子的東西,今天有空一次把他寫出來,超累的....祝大家去死去死節快樂 XD
Python-Ogre Tutorial 4&5
請先閱讀「寫在OGRE Tutorial前面」,本文假設您的目錄配置都和我一樣。
本文參考PyOgre Beginner Tutorial 4, PyOgre Beginner Tutorial 5
為什麼要把這兩個tutorial合起來呢?這兩篇講的是OGRE Input,但是OGRE內建的Input是不被推薦使用的,所以我並不想詳談。
簡單的說,教學四講的是unbuffered input,在迴圈中不斷的去polling有沒有輸入事件發生。教學五講的是buffered input,比較像event-driven的感覺,Listener Pattern有寫過Java的人應該都不陌生。好....Input講完了。
輸入的部份,推薦另外用OIS或SDL處理。Python-OGRE已經內建了OIS了。
事實上我在Python-OGRE裡根本試不出內建Input怎麼用,SampleFramework裡也是直接使用OIS,所以找不到範例,在forum也找不到討論。但是看到這段程式碼:
似乎指出現在(1.4版Ogre)的Python-OGRE已經不能用內建輸入了。
另外請詳閱Wiki,了解什麼是FrameListener。
之後會再弄個OIS輸入處理篇吧,這一系列的文章就到此結束。
本文參考PyOgre Beginner Tutorial 4, PyOgre Beginner Tutorial 5
為什麼要把這兩個tutorial合起來呢?這兩篇講的是OGRE Input,但是OGRE內建的Input是不被推薦使用的,所以我並不想詳談。
簡單的說,教學四講的是unbuffered input,在迴圈中不斷的去polling有沒有輸入事件發生。教學五講的是buffered input,比較像event-driven的感覺,Listener Pattern有寫過Java的人應該都不陌生。好....Input講完了。
輸入的部份,推薦另外用OIS或SDL處理。Python-OGRE已經內建了OIS了。
事實上我在Python-OGRE裡根本試不出內建Input怎麼用,SampleFramework裡也是直接使用OIS,所以找不到範例,在forum也找不到討論。但是看到這段程式碼:
if (ogre.OgreVersion[0]+ ogre.OgreVersion[1]) == "12": # ogre 1.2.3 is latest SDK
from Ogre.sf import *
else: # assume it's ogre version 1.3, the CVS version that needs OIS
from Ogre.sf_OIS import *
似乎指出現在(1.4版Ogre)的Python-OGRE已經不能用內建輸入了。
另外請詳閱Wiki,了解什麼是FrameListener。
之後會再弄個OIS輸入處理篇吧,這一系列的文章就到此結束。
Python-Ogre Tutorial 3
請先閱讀「寫在OGRE Tutorial前面」,本文假設您的目錄配置都和我一樣。
本文參考PyOgre Beginner Tutorial 3
先建立C:\Python25\Python-Ogre-0.8\demos\tutorial\tut3.py,貼上這些程式碼:
wiki上使用getSceneManager,到Python-OGRE好像要用createSceneManger。這部份我不太確定,不過反正他work了:
有關SceneManager的細節我就不多談,有興趣的請自行查閱。我把焦點放在Terrian, Sky, Fog上。
地型
在一開始我們就copy了一些檔案到tutorial資料夾下,包括了terrian.cfg。其中指定了地型的材質、參數等等。最重要的是這一段:
terrian.png中,其實就是一個以顏色表示各點高度的heightmap。
天空
天空的貼圖法有三種:
霧
再修改一下_createScene...
被濃霧籠罩的山谷...
有關fog及plane的搭配請務必詳閱wiki,我在這就不多談了...
本文參考PyOgre Beginner Tutorial 3
先建立C:\Python25\Python-Ogre-0.8\demos\tutorial\tut3.py,貼上這些程式碼:
# coding=big5
import Ogre as ogre
import SampleFramework
class TutorialApplication(SampleFramework.Application):
def _createScene(self):
self.sceneManager.setWorldGeometry("terrain.cfg")
self.sceneManager.setSkyBox(True, "Examples/SpaceSkyBox")
def _chooseSceneManager(self):
self.sceneManager = self.root.createSceneManager(ogre.ST_EXTERIOR_CLOSE)
# 選擇場景管理器
if __name__ == '__main__':
ta = TutorialApplication()
ta.go()
wiki上使用getSceneManager,到Python-OGRE好像要用createSceneManger。這部份我不太確定,不過反正他work了:
有關SceneManager的細節我就不多談,有興趣的請自行查閱。我把焦點放在Terrian, Sky, Fog上。
地型
在一開始我們就copy了一些檔案到tutorial資料夾下,包括了terrian.cfg。其中指定了地型的材質、參數等等。最重要的是這一段:
# Heightmap source
PageSource=Heightmap
# Heightmap-source specific settings
Heightmap.image=terrain.png
terrian.png中,其實就是一個以顏色表示各點高度的heightmap。
天空
天空的貼圖法有三種:
- SkyBoxes,將天空貼在一個cube上
- SkyDomes,將天空貼在一個球體上 (但事實上他還是render在一個cube)
- SkyPlanes,將天空貼在平面上
- 如果你會看到y軸為負的方向(例如從天空之城向下看),使用SkyBoxes
- SkyDomes在接近y=0的地方會沒貼到圖,所以如果你的場景是被山或建築物圍繞著,推薦使用。
- SkyPlane的優點是GPU cost極小,另外,其他兩種貼圖方式和fog並用時可能產生問題 (請詳閱wiki種fog一節)
霧
再修改一下_createScene...
def _createScene(self):
self.sceneManager.setWorldGeometry("terrain.cfg")
fadeColour = (0.9, 0.9, 0.9)
self.sceneManager.setFog(ogre.FOG_LINEAR, fadeColour, 0, 50, 515)
self.renderWindow.getViewport(0).backgroundColour = fadeColour
self.sceneManager.setSkyDome(True, "Examples/CloudySky", 5, 500)
被濃霧籠罩的山谷...
有關fog及plane的搭配請務必詳閱wiki,我在這就不多談了...
Python-Ogre Tutorial 2
請先閱讀「寫在OGRE Tutorial前面」,本文假設您的目錄配置都和我一樣。
本文參考PyOgre Beginner Tutorial 2
先建立C:\Python25\Python-Ogre-0.8\demos\tutorial\tut2.py,貼上這些程式碼:
經過了這段修改,我們得到一個....全黑的畫面?是的。
由於TutorialApplication是繼承SampleFramework.Application類別,就算我們不設定Camera及Viewport,上層的物件也會自動幫我們建立。現在我們只是Override上層的method,手動建立一次而已。
Camera簡單講就是玩家視角,Viewport這裡不用詳細解釋,有興趣深入了解請詳讀wiki吧。
光線與陰影 (Light&Shadow)
重頭戲來了....廢話不多說,我們來試試吧....修改_createScene函式:
注意紅色的部份,是與PyOgre API不相容的地方。先看看結果吧:
漆黑的忍者拖著長長的倒影 (驚)
注意我們把ambient光源設定為0了,在這裡我要稍微解釋一下。
一般3D圖學中的打光效果分為:
現在我們將ambient設為零,而光源在忍者的背面,所以從正面看當然就是一片漆黑了。注意程式的最後兩行將光源設定圍紅色。
除了ambient外,Diffuse和Specular都是假定光線是從某種方向照過來的。OGRE裡光源有三種:
看到三個方向的影子了,雖然這張圖看不出什麼差,但這是三種不同光源(藍字)造成的。照慣例,紅字是與wiki不同的地方。
另外,陰影模式也有三種:
本文參考PyOgre Beginner Tutorial 2
先建立C:\Python25\Python-Ogre-0.8\demos\tutorial\tut2.py,貼上這些程式碼:
# coding=big5
import Ogre as ogre
import SampleFramework
class TutorialApplication(SampleFramework.Application):
def _createScene(self):
pass
def _createCamera(self):
self.camera = self.sceneManager.createCamera("PlayerCam")
# 建立PlayerCam (玩家攝影機物件)
self.camera.setPosition = (0, 10, 500)
# 設定位置
self.camera.lookAt((0, 0, 0))
# 設定方向
self.camera.nearClipDistance = 5
# 太近的東西看不到 (距離小於5)
def _createViewports(self):
vp = self.renderWindow.addViewport(self.camera)
vp.backgroundColour = (0, 0, 0)
self.camera.aspectRatio = vp.actualWidth / vp.actualHeight
if __name__ == '__main__':
ta = TutorialApplication()
ta.go()
- 這次我把註解直接打在程式碼裡面了,如果你的程式碼有中文的話,記得加上第一行coding的宣告,否則會沒辦法執行
- 注意紅字的地方,position property沒辦法用,要用setPosition
經過了這段修改,我們得到一個....全黑的畫面?是的。
由於TutorialApplication是繼承SampleFramework.Application類別,就算我們不設定Camera及Viewport,上層的物件也會自動幫我們建立。現在我們只是Override上層的method,手動建立一次而已。
Camera簡單講就是玩家視角,Viewport這裡不用詳細解釋,有興趣深入了解請詳讀wiki吧。
光線與陰影 (Light&Shadow)
重頭戲來了....廢話不多說,我們來試試吧....修改_createScene函式:
def _createScene(self):
sceneManager = self.sceneManager
sceneManager.ambientLight = (0, 0, 0)
# 不要ambient光源
sceneManager.shadowTechnique = ogre.SHADOWTYPE_STENCIL_ADDITIVE
# 設定陰影種類
ent = sceneManager.createEntity("Ninja", "ninja.mesh")
ent.castShadows = True # this is not actually needed
# 設定這個entity要有陰影效果
sceneManager.rootSceneNode.createChildSceneNode().attachObject(ent)
# 在scene中放置一個忍者
plane = ogre.Plane((0, 1, 0), 0)
# 建立地板平面
mm = ogre.MeshManager.getSingleton()
mm.createPlane('ground', ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME,
plane, 1500, 1500, 20, 20, True, 1, 5, 5, (0, 0, 1))
# 建立地板平面的Mesh
ent = sceneManager.createEntity("GroundEntity", "ground")
sceneManager.rootSceneNode.createChildSceneNode().attachObject(ent)
ent.setMaterialName("Examples/Rockwall")
# 將地板明面貼上岩石材質
ent.castShadows = False
light = self.sceneManager.createLight("Light1")
light.type = ogre.Light.LT_POINT
# 建立一個點光源
light.setPosition(0, 150, 250)
# 設定光源位置
light.setDiffuseColour(1.0, 0.0, 0.0)
light.setSpecularColour(1.0, 0.0, 0.0)
注意紅色的部份,是與PyOgre API不相容的地方。先看看結果吧:
漆黑的忍者拖著長長的倒影 (驚)
注意我們把ambient光源設定為0了,在這裡我要稍微解釋一下。
一般3D圖學中的打光效果分為:
- Ambient (我不太會翻譯...這個字是"周圍的"的意思)
舉個例子,在一個漆黑的房間中,有一個門縫、窗縫透了一點光進來。這時整個房間都會近乎均勻的被打到一點點的光線。這個其實是經過很多反射、散射所造成的效果,但是真的去計算這些物理現像實在太難了,所以我們就假設所有物體都會被定量的光線照到。(就算不是realtime rendering,在photorealistic rendering也是有用ambient的) - Diffuse (散射)
- Specular (鏡面反射)
現在我們將ambient設為零,而光源在忍者的背面,所以從正面看當然就是一片漆黑了。注意程式的最後兩行將光源設定圍紅色。
除了ambient外,Diffuse和Specular都是假定光線是從某種方向照過來的。OGRE裡光源有三種:
- Point:點光源
- Spotlight:聚光燈、手電筒,需要設定廣角範圍
- Directional:指向性光源,假設光源從無線遠處射來(如太陽)。需要設定範圍但不用設定位置。
light = sceneManager.createLight("Light3")
light.type = ogre.Light.LT_DIRECTIONAL
# 從無限遠處射來的光線
light.setDiffuseColour(.25, .25, 0)
light.setSpecularColour(.25, .25, 0)
# 設定顏色
light.setDirection(0, -1, 1)
# 要指定方向,不用指定位置
light = sceneManager.createLight("Light2")
light.type = ogre.Light.LT_SPOTLIGHT
# 聚光燈形式的光源
light.setDiffuseColour(0, 0, 1.0)
light.setSpecularColour(0, 0, 1.0)
# 顏色
light.setDirection(-1, -1, 0)
light.setPosition(300, 300, 0)
# 位置方向
light.setSpotlightRange(ogre.Degree(35), ogre.Degree(50))
# 廣角
看到三個方向的影子了,雖然這張圖看不出什麼差,但這是三種不同光源(藍字)造成的。照慣例,紅字是與wiki不同的地方。
另外,陰影模式也有三種:
- SHADOWTYPE_TEXTURE_MODULATIVE 最差,最少運算資源
- SHADOWTYPE_STENCIL_MODULATIVE
- SHADOWTYPE_STENCIL_ADDITIVE 最強,最多運算資源
Python-Ogre Tutorial 1-2
續上一篇..
座標系
OGRE的座標系系統是:x左右, y上下, z前後
有些其他系統會將y和z顛倒過來
再修改一下_createScene:
放了兩台機器人:)
注意倒數第二行紅字的部份,第二台機器人有(50, 0, 0)的位移量。
再注意倒數第二行,我們這次不把第二台機器人接上SceneManager的root SceneNode,而接上第一台機器人的SceneNode,並且給了(0, 100, 0)的位移量 (正上方一百單位)。
注意:ent2的位置現在完全跟隨著ent1,要是第一台機器人移動,第二台也會跟著動。Wiki中提到可以拿來做grouping (像星海的航空母艦子機 XD)
來看看旋轉類的效果吧:
注意紅色那三行就對了,不同的轉向函式。
最後,關於縮放(scaling)功能...
Wiki上的語法都不能用:
要用這個:
這裡有一些PyOgre及Python-Ogre的差異,可是沒寫到scale,害我自己找半天 :(
http://python-ogre.python-hosting.com/wiki/FAQindex:見Converting from PyOgre
Tutorial 1的部份寫了最多,接下來的幾個Tutorial會寫必較少。不是我偷懶喔,而是點到為止就好了。尤其是OGRE Input處理的部份,最後做遊戲時是不太會用到的。
座標系
OGRE的座標系系統是:x左右, y上下, z前後
有些其他系統會將y和z顛倒過來
再修改一下_createScene:
def _createScene(self):
sceneManager = self.sceneManager
sceneManager.ambientLight = (1, 1, 1)
ent1 = sceneManager.createEntity("Robot", "robot.mesh")
node1 = sceneManager.rootSceneNode.createChildSceneNode("RobotNode")
node1.attachObject(ent1)
ent2 = sceneManager.createEntity("Robot2", "robot.mesh")
node2 = sceneManager.rootSceneNode.createChildSceneNode("RobotNode2", (50, 0, 0))
node2.attachObject(ent2)
放了兩台機器人:)
注意倒數第二行紅字的部份,第二台機器人有(50, 0, 0)的位移量。
def _createScene(self):
sceneManager = self.sceneManager
sceneManager.ambientLight = (1, 1, 1)
ent1 = sceneManager.createEntity("Robot", "robot.mesh")
node1 = sceneManager.rootSceneNode.createChildSceneNode("RobotNode")
node1.attachObject(ent1)
ent2 = sceneManager.createEntity("Robot2", "robot.mesh")
node2 = node1.createChildSceneNode("RobotNode2", (0, 100, 0))
node2.attachObject(ent2)
再注意倒數第二行,我們這次不把第二台機器人接上SceneManager的root SceneNode,而接上第一台機器人的SceneNode,並且給了(0, 100, 0)的位移量 (正上方一百單位)。
注意:ent2的位置現在完全跟隨著ent1,要是第一台機器人移動,第二台也會跟著動。Wiki中提到可以拿來做grouping (像星海的航空母艦子機 XD)
來看看旋轉類的效果吧:
def _createScene(self):
sceneManager = self.sceneManager
sceneManager.ambientLight = (1, 1, 1)
ent1 = sceneManager.createEntity("Robot", "robot.mesh")
node1 = sceneManager.rootSceneNode.createChildSceneNode("RobotNode")
node1.attachObject(ent1)
node1.yaw(ogre.Degree(-90))
ent2 = sceneManager.createEntity("Robot2", "robot.mesh")
node2 = sceneManager.rootSceneNode.createChildSceneNode("RobotNode2", ogre.Vector3(50, 0, 0))
node2.attachObject(ent2)
node2.pitch(ogre.Degree(-90))
ent3 = sceneManager.createEntity("Robot3", "robot.mesh")
node3 = sceneManager.rootSceneNode.createChildSceneNode("RobotNode3", ogre.Vector3(100, 0, 0))
node3.attachObject(ent3)
node3.roll(ogre.Degree(-90))
注意紅色那三行就對了,不同的轉向函式。
最後,關於縮放(scaling)功能...
Wiki上的語法都不能用:
node.setScale(0.5, 0.2, 1)
node.scaleBy(2, 10, 1)
要用這個:
node.setScale(0.5, 0.2, 1)
這裡有一些PyOgre及Python-Ogre的差異,可是沒寫到scale,害我自己找半天 :(
http://python-ogre.python-hosting.com/wiki/FAQindex:見Converting from PyOgre
Tutorial 1的部份寫了最多,接下來的幾個Tutorial會寫必較少。不是我偷懶喔,而是點到為止就好了。尤其是OGRE Input處理的部份,最後做遊戲時是不太會用到的。
Python-Ogre Tutorial 1
請先閱讀「寫在OGRE Tutorial前面」,本文假設您的目錄配置都和我一樣。
本文參考PyOgre Beginner Tutorial 1
讓我們跟著上面那個tutorial的步驟一步一步做。首先我們看到這段程式,使用你熟悉的編輯器將他存到C:\Python25\Python-Ogre-0.8\demos\tutorial\tut1.py中
執行看看
結果當然有error囉,因為他引用了PyOgre的package名稱而非Python-Ogre
將程式的前兩行改成
It works!!右下角有OGRE的mark,左下角有FPS的效能數據。整個畫面黑黑的一片,因為我們還沒有放任何東西在場景中。其實PyOgre和Python-OGRE最大的差別應該就是在這個import package name吧,其他程式碼幾乎都可以直接work。
接下來我就簡化地follow tutorial,還是推薦大家詳閱原版的tutorial喔!!
我們稍微改寫一下_createScene函式:
然後再執行看看...
可以按上下左右、移動滑鼠試試喔!
第一行取得了sceneManager物件,在OGRE的架構中,所有你看的見的東西都是被這個物件管理的。
第二行設定了光源,要是拿掉了這行,畫面就會變成一片漆黑了。ambientLight是一種光源的類型,等到光源那節我再詳細介紹。
第三到五行在畫面上放置了一個機器人,這部份比較複雜一些,我們需要了解一些物件:
簡單來說,要在場景上放上一個物件至少要做三件事:
文章太長了,拆成兩篇...請看Python-Ogre Tutorial 1-2
本文參考PyOgre Beginner Tutorial 1
讓我們跟著上面那個tutorial的步驟一步一步做。首先我們看到這段程式,使用你熟悉的編輯器將他存到C:\Python25\Python-Ogre-0.8\demos\tutorial\tut1.py中
from pyogre import ogre
import SampleFramework
class TutorialApplication(SampleFramework.Application):
def _createScene(self):
pass
if __name__ == '__main__':
ta = TutorialApplication()
ta.go()
執行看看
cd \Python25\Python-Ogre-0.8\demos\tutorial
python tut1.py
結果當然有error囉,因為他引用了PyOgre的package名稱而非Python-Ogre
將程式的前兩行改成
import Ogre as ogre
import SampleFramework
It works!!右下角有OGRE的mark,左下角有FPS的效能數據。整個畫面黑黑的一片,因為我們還沒有放任何東西在場景中。其實PyOgre和Python-OGRE最大的差別應該就是在這個import package name吧,其他程式碼幾乎都可以直接work。
接下來我就簡化地follow tutorial,還是推薦大家詳閱原版的tutorial喔!!
我們稍微改寫一下_createScene函式:
def _createScene(self):
sceneManager = self.sceneManager
sceneManager.ambientLight = ogre.ColourValue(1, 1, 1)
ent1 = sceneManager.createEntity("Robot", "robot.mesh")
node1 = sceneManager.rootSceneNode.createChildSceneNode("RobotNode")
node1.attachObject(ent1)
然後再執行看看...
可以按上下左右、移動滑鼠試試喔!
第一行取得了sceneManager物件,在OGRE的架構中,所有你看的見的東西都是被這個物件管理的。
第二行設定了光源,要是拿掉了這行,畫面就會變成一片漆黑了。ambientLight是一種光源的類型,等到光源那節我再詳細介紹。
第三到五行在畫面上放置了一個機器人,這部份比較複雜一些,我們需要了解一些物件:
- MoveableObject:任何可以移動的物體。其實我們在這裡都不會直接取用他
- Entity:MoveableObject的子類別,你可以將任何可以用3D Mesh表示的物件看成一個Entity。(例如:人、魚、鳥、車)
然而燈光、攝影機...等等沒有3D模型的東西,他們是MoveableObject但不是Entity。 - SceneNode:這個概念比較抽象...我真的不太會解釋,請務必看wiki原文。
總而言之,每一個SceneNode都可以有他的parent及children,形成一個tree的結構。SceneNode記錄著相對於其parent的位置及方向。
SceneManager中有個root SceneNode,一般來說他應該是一切其他SceneNode的根源。我是把他想成類似世界原點座標..
簡單來說,要在場景上放上一個物件至少要做三件事:
- 建立Entity
程式碼第三行,載入robot的mesh並建立了這個entity - 建立SceneNode
程式碼第四行,注意他是從SceneManager建立這個SceneNode的。SceneNode必需以某種方式與SceneManager的root連結,我們才可以看的到他。 - 將Entity附在SceneNode上(程式碼第五行)
文章太長了,拆成兩篇...請看Python-Ogre Tutorial 1-2
寫在Python-OGRE Tutorial前面
接下來讓我們來看一些Tutorial吧。
從介紹OGRE的第一篇我就提到,學OGRE從Tutorial開始是最快的。在OGRE官方Wiki上有一系列的Tutorial教學。
另外在PyOgre頁面中也有五個Tutorial,這五個Tutorial其實和上面的Basic Tutorial 1~5內容是一樣的,只是程式語言從C++變成了Python。
但是,目前並沒有為最新的Python-Ogre寫的Tutorial。事實上PyOgre及Python-Ogre的API根本就差不多,只有一些細微的差異。但如果你用PyOgre的程式直接貼到Python-Ogre,還是會出一點錯的。
接下來我會把這五個Tutorial的筆記整理出來,並且在Python-OGRE上執行。希望可以讓大家很快的上手Python-OGRE。
如果你的遊戲運算量、動作性沒有那麼高,那用Python開發應該不錯。但這五個Tutorial只是教你OGRE的基本操作,無論如何,C++版本的那整套Tutorial還是推薦大家一定要去去看一下的。
開始囉,讓我們先準備一下環境。我很偷懶的直接在c:\Python25\Python-Ogre-0.8\demos建一個tutorial的目錄,並且將所需的檔案copy過去,在命令提示字元下執行這些指令就可完成:
SampleFramework.py是一個寫好的遊戲框架,定義了一些行為(例如說按上下左右攝影機就會移動,移動滑鼠就會轉向)。真正的implementation應該是在C:\Python25\Lib\site-packages\Ogre\sf.py,在前五個教學中我們先不用管他是什麼。
*.cfg是一些設定檔案,如果你完全照我的目錄配制的話,那就先不用管他是什麼東西了。
好,讓我們進入第一個Tutorial吧...
待續
從介紹OGRE的第一篇我就提到,學OGRE從Tutorial開始是最快的。在OGRE官方Wiki上有一系列的Tutorial教學。
另外在PyOgre頁面中也有五個Tutorial,這五個Tutorial其實和上面的Basic Tutorial 1~5內容是一樣的,只是程式語言從C++變成了Python。
但是,目前並沒有為最新的Python-Ogre寫的Tutorial。事實上PyOgre及Python-Ogre的API根本就差不多,只有一些細微的差異。但如果你用PyOgre的程式直接貼到Python-Ogre,還是會出一點錯的。
接下來我會把這五個Tutorial的筆記整理出來,並且在Python-OGRE上執行。希望可以讓大家很快的上手Python-OGRE。
如果你的遊戲運算量、動作性沒有那麼高,那用Python開發應該不錯。但這五個Tutorial只是教你OGRE的基本操作,無論如何,C++版本的那整套Tutorial還是推薦大家一定要去去看一下的。
開始囉,讓我們先準備一下環境。我很偷懶的直接在c:\Python25\Python-Ogre-0.8\demos建一個tutorial的目錄,並且將所需的檔案copy過去,在命令提示字元下執行這些指令就可完成:
cd \Python25\Python-Ogre-0.8\demos
md tutorial
cd tutorial
copy ..\ogre\SampleFramework.py .
copy ..\ogre\*.cfg .
SampleFramework.py是一個寫好的遊戲框架,定義了一些行為(例如說按上下左右攝影機就會移動,移動滑鼠就會轉向)。真正的implementation應該是在C:\Python25\Lib\site-packages\Ogre\sf.py,在前五個教學中我們先不用管他是什麼。
*.cfg是一些設定檔案,如果你完全照我的目錄配制的話,那就先不用管他是什麼東西了。
好,讓我們進入第一個Tutorial吧...
待續
Python-Ogre安裝
Python-Ogre的安裝反而比C++環境的安裝簡單的多。
來執行看看吧
成功!!
可以在我的電腦->內容->進階->環境變數->系統變數->path
在變數值後面加上;C:\Python25
記得重新開啟command console
就不用執行\Python25\python.exe 直接打python就好了,筆者的電腦因為有兩個版本的python,所以不做此設定。
- 安裝Python 2.5 Windows installer (假設裝到C:\Python25)
- 抓下Python-Ogre 0.80 Windows Release for Python 2.5,解壓至C:\Python25
- 進到命令提示字元,輸入
cd \python25\Python-Ogre-0.8
..\python setup.py install - 抓下Media for Python-Ogre,解壓後將C:\Python25\Python-Ogre-0.8\demos\media覆蓋
來執行看看吧
cd \Python25\Python-Ogre-0.8\demos\ogre
\Python25\python.exe Demo_Lighting.py
成功!!
可以在我的電腦->內容->進階->環境變數->系統變數->path
在變數值後面加上;C:\Python25
記得重新開啟command console
就不用執行\Python25\python.exe 直接打python就好了,筆者的電腦因為有兩個版本的python,所以不做此設定。
OGRE language binding
縱觀近年來程式語言的發展,我想大家應該都會同意動態、腳本語言可以縮短程式開發的時間。例如:
OGRE本身是使用C++寫的,但其龐大的社群使得我們可以找到一些其他語言binding的資源:
PyOgre
PyOgre的歷史應該滿悠久的,使用SWIG將OGRE與Python語言做結合,讓我們可以在Python中直接取用OGRE的物件。
PyOgre最新的版本應該是1.2版,但是官網的binary release竟然停留在2005年的1.0.6版,不知道在想什麼 =.= Wiki上面有熱心的網友自己編譯的win32 binary,但連結已失效了。目前取得最新版本的唯一方式就是自己去SVN checkout然後編譯。
PyOgre的優點應該是比較stable(應為已經開發很久了)、官網tutorial(在PyOgre的下半部)一定可以work。除此之外,官網論壇上的人似乎都比較推薦Python-Ogre。
Python-Ogre
Python-Ogre是另外一套Ogre的Python binding,相較於PyOgre使用SWIG,Python-Ogre使用Py++來自動化的做Warpper的動作。當然使用者可以不用理會這些,重點是Python-Ogre雖然發展不到半年的時間,但開發的動作相當迅速,應該可望完全取代掉PyOgre。
Shattered Ruby
Shattered Ruby是一套使用OGRE為底層的Game Framework,他不僅是做Warpper的動作而已,還開發了一些工具來加速遊戲設計的流程。
我想這個開發者一定對於Ruby on Rails的網頁框架十分熟悉,而把Rails這個網頁開發的很多概念拿到遊戲開發上,如:
當然,有其利必有其弊。這些動態語言的開發速度雖然勝過C++,但執行速度是一定比不過C++的,如何平衡當然就看你的應用囉。例如:
- 網頁開發:Agile web development with rails
- 遊戲開發:Game Programming with Python, Lua, and Ruby
- 知名MMORPG魔獸世界內建Lua Script
OGRE本身是使用C++寫的,但其龐大的社群使得我們可以找到一些其他語言binding的資源:
PyOgre
PyOgre的歷史應該滿悠久的,使用SWIG將OGRE與Python語言做結合,讓我們可以在Python中直接取用OGRE的物件。
PyOgre最新的版本應該是1.2版,但是官網的binary release竟然停留在2005年的1.0.6版,不知道在想什麼 =.= Wiki上面有熱心的網友自己編譯的win32 binary,但連結已失效了。目前取得最新版本的唯一方式就是自己去SVN checkout然後編譯。
PyOgre的優點應該是比較stable(應為已經開發很久了)、官網tutorial(在PyOgre的下半部)一定可以work。除此之外,官網論壇上的人似乎都比較推薦Python-Ogre。
Python-Ogre
Python-Ogre是另外一套Ogre的Python binding,相較於PyOgre使用SWIG,Python-Ogre使用Py++來自動化的做Warpper的動作。當然使用者可以不用理會這些,重點是Python-Ogre雖然發展不到半年的時間,但開發的動作相當迅速,應該可望完全取代掉PyOgre。
Shattered Ruby
Shattered Ruby是一套使用OGRE為底層的Game Framework,他不僅是做Warpper的動作而已,還開發了一些工具來加速遊戲設計的流程。
我想這個開發者一定對於Ruby on Rails的網頁框架十分熟悉,而把Rails這個網頁開發的很多概念拿到遊戲開發上,如:
- DRY: Don't repeat yourself
- CoC: Convention before configuration
- Generator
- Domain Specific Language
當然,有其利必有其弊。這些動態語言的開發速度雖然勝過C++,但執行速度是一定比不過C++的,如何平衡當然就看你的應用囉。例如:
- 格鬥遊戲、3D射擊遊戲:別鬧了,乖乖用C++寫吧。動態語言可以拿來輔助做流程控制用。
- 益智遊戲、冒險解迷:在運算量不大的前題下,整個遊戲都使用動態語言寫也是有可能的。
OGRE + MinGW + Code::Blocks 安裝
OGRE本身是用C++寫的,所以利用OGRE撰寫程式最直接的方法也就是使用C++。在OGRE官網 提供了幾種開發環境的SDK,當然你要自己在其他環境compile應該也是可以的,但新手的話最好照著他的instruction做吧。
MinGW
MinGW是什麼?有試著在windows下用gcc的人應該都知道,MinGW和cygwin是目前兩個將gcc port到windows下的方案。所以我們的編譯器就靠他了。
注意,不要下載官方的MinGW,因為OGRE對於libstdc++做了一些修正,請下載OGRE提供的MinGW ToolBox
Code::Blocks
這是一套聽說要追過Dev-C++的Open Source IDE (我最近很少在寫C,所以不太清楚)
注意:不要使用Code::Blocks 1.0 RC2及以前的版本,會當機。
Code::Blocks的官方論壇幾乎每天會放出新的nightly build。OGRE官網是建議抓最新的nightly build,不過抓之前可以看看該thread有沒有重大的bug :)
除了抓Wiki那兩個檔案外,記得抓mingwm10.7z,才有和mingw溝通的DLL
OGRE SDK
沒啥好說的,one-click installer
Direct9 SDK
最好裝一下,如果你跟我一樣不爽裝(XD)的話....
先 把sample build & run看看,如果跳出找不到D3DX9_??.dll (??可能是某兩個數字),去google 搜尋這個檔案的名稱就可以抓到了,把他丟進windows\system32之中。 (記得掃毒,但google明列前矛的網站應該還OK)
這樣做的話,在debug build中可能會需要D3DX9_??d.dll (多了一個d字,debug版本的dll)而當掉。如果你還是不想用DX的話...
在C:\OgreSDK\bin\debug (或你的安裝資料夾下) ,找到plugins.cfg中
將這行最前面加個井號註解掉,不要使用D3D,完全用OpenGL就好了。
來玩OGRE吧
Wiki最下面的那些setting可以先不要看,如果你抓的是2007.2.13之後的Code::Block nightly build,他裡面就有附OGRE的template project了。
正常的話可以直接build
萬歲!!成功 XD
(下一章應該寫OGRE + Python)
- VC.net 2005:雖然我滿不想用微軟的IDE,但為了方便我一開始試灌了這個方案。結果我發現還要另外抓四百多MB的windows platform SDK後,一怒之下就放棄了。
- VC.net 2003:聽說這版不用灌platform SDK,我不太確定,要試的人請自己survey。
- MinGW+CodeBlock:最後我還是選擇了gcc當我的底層compiler,於是就使用了這個方案。灌起來應該比VC麻煩一些吧。
MinGW
MinGW是什麼?有試著在windows下用gcc的人應該都知道,MinGW和cygwin是目前兩個將gcc port到windows下的方案。所以我們的編譯器就靠他了。
注意,不要下載官方的MinGW,因為OGRE對於libstdc++做了一些修正,請下載OGRE提供的MinGW ToolBox
Code::Blocks
這是一套聽說要追過Dev-C++的Open Source IDE (我最近很少在寫C,所以不太清楚)
注意:不要使用Code::Blocks 1.0 RC2及以前的版本,會當機。
Code::Blocks的官方論壇幾乎每天會放出新的nightly build。OGRE官網是建議抓最新的nightly build,不過抓之前可以看看該thread有沒有重大的bug :)
除了抓Wiki那兩個檔案外,記得抓mingwm10.7z,才有和mingw溝通的DLL
OGRE SDK
沒啥好說的,one-click installer
Direct9 SDK
最好裝一下,如果你跟我一樣不爽裝(XD)的話....
先 把sample build & run看看,如果跳出找不到D3DX9_??.dll (??可能是某兩個數字),去google 搜尋這個檔案的名稱就可以抓到了,把他丟進windows\system32之中。 (記得掃毒,但google明列前矛的網站應該還OK)
這樣做的話,在debug build中可能會需要D3DX9_??d.dll (多了一個d字,debug版本的dll)而當掉。如果你還是不想用DX的話...
在C:\OgreSDK\bin\debug (或你的安裝資料夾下) ,找到plugins.cfg中
Plugin=RenderSystem_Direct3D9
將這行最前面加個井號註解掉,不要使用D3D,完全用OpenGL就好了。
來玩OGRE吧
Wiki最下面的那些setting可以先不要看,如果你抓的是2007.2.13之後的Code::Block nightly build,他裡面就有附OGRE的template project了。
正常的話可以直接build
萬歲!!成功 XD
(下一章應該寫OGRE + Python)
2007年2月13日 星期二
What's OGRE?
OGRE是目前最大的open source 3d rendering engine之一,這四個字其實是Open soure GRaphic Engine的縮寫。
這套引擎的歷史已經很悠久了,相信很多人沒玩過也聽過。那我只在這裡做簡單的介紹:
學習OGRE最快的方法應該就是照著OGRE Tutorial跑一遍,千萬不要一開始就去看API Documentation,保證你看的頭昏腦脹。由於目前OGRE的繁中資源還滿少的,接下來我應該會把我的筆記簡單的整理出來,其實我自己也是最近在跑tutorial而已,對整個開發流程還只是一知半解,如有謬誤也請大家幫忙更正。
P.S. ogre這個字本身是食人魔的意思,開發人員明顯都是愛玩遊戲的人,固意把名稱縮成這四個字 XD
這套引擎的歷史已經很悠久了,相信很多人沒玩過也聽過。那我只在這裡做簡單的介紹:
- 他是一個繪圖引擎(rendering, 對岸好像稱為絢染)
- 他不是一個遊戲引擎,這個函式庫專注在3D繪圖上,少了音效、輸入、網路(optional)等部份。(事實上OGRE有很粗糙的輸入處理功能,但正式製作遊戲時不建議使用)
- DirectX及OpenGL都是較底層的繪圖函式庫,直接與硬體做溝通。
- DirectX是微軟的產品,只能在Windows系列上面跑。OpenGL是工業標準,能夠跨平台在Windows, Linux, Mac OSX上執行。
- OGRE提供了比較高階的C++物件導向封裝,學習起來比較簡單。他可以選擇呼叫底層的DirectX和OpenGL,達到跨平台的目的,在windows下也可使用表現可能較好的DX。
學習OGRE最快的方法應該就是照著OGRE Tutorial跑一遍,千萬不要一開始就去看API Documentation,保證你看的頭昏腦脹。由於目前OGRE的繁中資源還滿少的,接下來我應該會把我的筆記簡單的整理出來,其實我自己也是最近在跑tutorial而已,對整個開發流程還只是一知半解,如有謬誤也請大家幫忙更正。
P.S. ogre這個字本身是食人魔的意思,開發人員明顯都是愛玩遊戲的人,固意把名稱縮成這四個字 XD
訂閱:
文章 (Atom)