1. Armory -此指存放Bullet class的管理介面,為防止過度聯想,文中以原文armory表示,不另作翻譯。
2. Bullet - 「子彈」。敵機擊發出的投射物。在本文中具有三種與其相關之名詞,為避免混淆,特此注明:
i. 「子彈」:專指畫面中之物件。
ii. 「Bullet class」:專指「某一種類(a kind of)」的子彈。
iii. 「Bullet 結構體」:專指記錄一個子彈實體相關參數的結構體(structure)
3. Canvas -「畫面」。自機與子彈的活動範圍。本文中,畫面之座標以左上方為原點(0,0),右下為正;極座標以正右方為0度,順時針遞增,正上方為270度。
4. Enemy -「敵機」。在lbs系統中同一時間只存在一個,負責處理由命令列發出的擊發命令。
5. Frame - 「幀」。本文中時間的最小單位,預設每秒切成33個Frame。本文中以地區習慣不予翻譯。
6. Launch -「擊發」。本文中之「擊發」專指由敵機或子彈產生出新的子彈的動作,並避免其他同義詞所造成的混淆。
7. Player -「自機」。請注意對任何子彈來說,「自機」均指由使用者操控的avatar。
II. User Interface
1. 主畫面
2. 按鍵說明
i. w, a, s, d - 移動自機
ii. Enter - 暫停;切換Command mode / Test mode
iii. Arrow Key ↑/↓-於Command mode中往前或往後捲動已輸入的指令
iv. Backspace - 於Command mode中往回刪除一個字元
3. lbs指令說明
在主畫面中隨時可按下Enter鍵進入Command mode,於Command Prompt輸入並執行lbs指令。可用的指令如下,注意大小寫分別:
lbs指令 | 說明 | ||||
launch | 自armory中取具特定名稱的Bullet class由敵機目前所在位置擊發。 launch 名稱 [重複次數]
| ||||
load | 於檔案系統中讀取含有Bullet class宣告的.lua檔案並解析。 load 檔案名稱
| ||||
batch | 於檔案系統中讀取文字檔,並批次執行當中的lbs指令。 batch 檔案名稱
| ||||
stop 或 clear | 停止當前畫面中所有子彈的動作並清除之。 | ||||
exit 或 clear | 離開lbs。 |
使用範例,讀取並擊發Fireball:
>> load fireball.lua
OK.
>> launch Fireball
OK.
III. lbs API
一個可用的lua檔案必須含有兩個部分:Bullet class宣告及Bullet class之註冊(使用LBS_REGISTER巨集),以便lbs系統識別。Bullet class宣告中有可能含有其他形態之資料結構,以下將由小而大一一介紹:
1. Complex結構體
Complex結構體為lbs系統中對向量或畫面中特定點的描述方法,可兼容直角座標與極座標系統,並支援相對位置換算為畫面座標的運算。一個Complex結構體的描述需利用五元組(5-tuple)達成。例如:
out.target = {‘o’, 30, 40, 1, 2};
其中各項目為:
項次 | 名稱 | 說明 | ||||||||||||||||||
1 | ‘o’ / ’p’ | 必要項。若此項設為’o’,則表示此一Complex結構體使用直角座標;若為’p’,則表示此一Complex結構體使用極座標。若為其他不合法之值,則此結構體將被視為{‘o’, 0, 0, 0, 0}。 | ||||||||||||||||||
2 | a | 必要項。若此結構體使用直角坐標,則代表向量之x分量;若此結構體使用極座標,則代表向量之長度(length)。 | ||||||||||||||||||
3 | b | 必要項。若此結構體使用直角坐標,則代表向量之y分量;若此結構體使用極座標,則代表向量之角度(theta)。 | ||||||||||||||||||
4 | targetX | 選用項。表示目前結構體使用下列數值作為x分量的參考點:
| ||||||||||||||||||
5 | targetY | 選用項。表示目前結構體使用相應之數值作為y分量的參考點。值與參考點的組合請參考targetX之說明。 |
範例,請注意座標點與向量之不同:
i. {‘o’, 20, 30}:表示直角座標向量「往右20,往下30」。
ii. {‘p’, 2, 120}:表示極座標向量「長度2,角度120度」。
iii. {'o’, 0, -50, 1, 2}:表示位於「目前自機x座標,自機y座標」、「往左0,往上50」的點。
iv. {‘p’, 60, 270, 3, 7}:表示位於「目前敵機x座標,畫面最上端之y座標」、「270度方位,距離60」的點。
2. Env結構體
儲存環境常數之結構體,可於Bullet class中之actionCheck函式中提取,為一唯讀常數,並只有當次有效。使用前必須使用LBS_GETENV()巨集取得。Env結構體的內容各項如下表所示:
名稱 | 說明 |
env.selfX | 自機之X座標 |
env.selfY | 自機之Y座標 |
env.enemyX | 敵機之X座標 |
env.enemyY | 敵機之Y座標 |
env.left | 畫面之最左端座標 |
env.right | 畫面之最右端座標 |
env.top | 畫面之最上端座標 |
env.botton | 畫面之最下端座標 |
3. Bullet結構體
用以記錄單一個子彈實體目前參數的結構體。每次需要變更參數時會傳入Bullet class中之actionCheck函式中進行運算並傳回新的Bullet結構體。完整的運算架構將於III-4 Bullet class中敘述。Bullet結構體的內容各項如下表所示:
名稱 | 說明 | ||||||||
string type | 可讀寫。表此子彈之動作模式:
| ||||||||
int x | 唯讀。此一子彈之x座標值。 | ||||||||
int y | 唯讀。此一子彈之y座標值。 | ||||||||
Complex speed | 可讀寫。此子彈之速度向量。 | ||||||||
Complex accel | 可讀寫。此子彈之加速度向量。若此Complex結構體使用極座標,則其所指之角度將加上子彈之速度向量。 例如:speed = {‘p’, 30, 40}; accel = {‘p’, 40, 50},則accel所指向的角度為40+50 = 90度之方位(畫面正下方)。 | ||||||||
Complex target | 可讀寫。Homing模式下的目標點,隨著targetX、targetY參考點的設置不同,可以自動追蹤目標點而不需actionCheck介入。 | ||||||||
double maxAngle | 可讀寫。Homing模式下,子彈每次移動時,其轉向的量不會超過±maxAngle。 | ||||||||
int age | 唯讀。記錄此一子彈由被擊發到目前為止存活的Frame數。 | ||||||||
int dontCare | 可讀寫。一旦此值大於零,表示此一子彈在接下來的n個Frame中不會被傳遞進入actionCheck函式中作處理。 | ||||||||
bool visible | 可讀寫。控制子彈是否出現在畫面中。隱藏中的子彈對自機沒有擊中判定。 | ||||||||
int counter | 可讀寫。保留的數值,可供使用者自行記錄資訊。 |
4. Bullet class
Bullet class使用Lua語法中之table實現包含對某一種類之子彈的完整行為描述。相關屬性如下:
名稱 | 說明 |
string title | 設定該Bullet class提示之scenario name。 |
int size | 該Bullet class之子彈直徑。 |
int seq | 該Bullet class之子彈細分值。若seq = 8;則表示該子彈由8個線段圍成圓形。 |
table color | 該Bullet class之子彈顏色。以RGB順序排列,每項值由0.0~1.0,color = {1.0, 1.0, 1.0};為白色。 |
Bullet actionCheck( Bullet in ) | 該Bullet class之actionCheck函式。所有狀態變更之計算必須在此函式中完成。若某Bullet class未設定actionCheck,則屬於此Bullet class的所有子彈在進入actionCheck函式時將自動消滅。 |
actionCheck函式以一Bullet結構體為輸入,並以一更新後的Bullet結構體為輸出,為Bullet class最重要的一部分。以lbs方面的觀點看來,actionCheck函數在系統中扮演之角色可依下方流程圖表示:
5. LBS巨集
Lua處理過程中,有時候會需要與lbs系統做溝通,並達成較高階的任務。下表所列為檔案中可以使用的LBS巨集:
名稱 | 說明 |
table LBS_ENV() | 取得目前的Env結構體。 |
void LBS_REGISTER( string ClassName ) | 向lbs系統註冊ClassName所指之Bullet class宣告。 |
void LBS_LAUNCH( string ClassName, Bullet in ) | 自當前子彈之所在位置擊發一枚屬於ClassName Bullet class的子彈,並將其初始屬性設為in。 |
void LBS_BATCHLAUNCH( string ClassName, int StartTime, int EndTime, Bullet A, int n, Bullet B ) | 於目前Frame起算,StartTime至EndTime這幾個Frame之間,擊發n枚屬於ClassName Bullet class的子彈。 子彈的初始屬性由A往B內插,若A與B屬性有衝突時(例如A.type為Direct,而B.type為Homing時),以A之屬性為主。 當n為正值時,極座標向量的內插會經近邊,而n為負值時,極座標向量的內插會經遠邊。 (例如A.speed = {‘p’, 20, 0}; B.speed = {‘p’, 20, 30};n = 3會得出0, 15, 30,而n = -3會得出0, 195, 30) |
IV. Example: Spell “Fireball”
-- Fireball Bullet class宣告 --------------------------------------------------
Fireball = {
title = "Spell \"Fire Ball\""; --設定scenario name
size = 14; --設定子彈直徑=14px
seg = 12; --設定子彈細分值=12(子彈由12個線段圍成圓形)
color = {1.0, 0.0, 0.0}; --設定子彈顏色為紅色
actionCheck = function (bullet) --設定actionCheck函式
out = {}
if bullet.age == 0 then --若子彈之age為零(剛被擊發),將子彈設定以下屬性:
env = LBS_GETENV();
out.type = "Direct"; --定向彈。目標為自機當前所在位置,於50個Frame後抵達目標
out.speed = {'o', (env.selfX - bullet.x)/50, (env.selfY - bullet.y)/50};
out.accel = {'o', 0, 0}; --加速度為零
out.dontCare = 50; --50個Frame內此一子彈不會傳入actionCheck函式變更屬性
end
if bullet.age > 50 then --若子彈之age大於51,將子彈設定以下屬性:(引爆!)
for i = 1,60 do
bolt = {};
bolt.type = "Direct"; --定向彈。速度向量之方向為-180~180度之間,長度為0~5之間之隨機數
bolt.speed = {'p', math.random()*5.0, math.random()*360-180};
bolt.accel = {'o', 0, 0}; --加速度為零
bolt.dontCare = 10+math.random()*20; --10~20個Frame內此一子彈
LBS_LAUNCH("Bolt", bolt); --擊發屬於Bolt Bullet class的一枚子彈,使用剛剛產生的bolt Bullet結構體作為初始值
end --以迴圈連續擊發60個Bolt
out.type = "Removed"; --移除目前子彈
end
return out;
end
};
LBS_REGISTER("Fireball");
-- Bolt: Children of fireball -------------------------------------------------
Bolt = {
size = 10;
seg = 8;
color = {1.0, 0.3, 0.0};
-- 由於未設定actionCheck函式,此一Bullet class的子彈進行actionCheck運算時將自動被消滅
}
LBS_REGISTER("Bolt");
0 意見:
張貼留言