星期二, 2月 28, 2012

0.5lbs彈幕系統:UI與API

 ▲ 松浦 健一郎, "シューティングゲーム プログラミング", ソフトバンククリエイティブ, 2006

快速連結:0.5lbs彈幕系統:簡介與火力展示
檔案下載: lbs_win32_bin.zip
 

I. Terminology
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 「幀」。本文中時間的最小單位,預設每秒切成33Frame。本文中以地區習慣不予翻譯。
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 名稱 [重複次數]
名稱
欲擊發之Bullet class名稱
重複次數
若為大於零之值,待畫面中僅存自機與敵機時,此Bullet class將再次被擊發,直到達到指定的次數為只。預設值為無窮大。

load
於檔案系統中讀取含有Bullet class宣告的.lua檔案並解析。

load 檔案名稱
檔案名稱
含有Bullet class宣告的.lua檔案。若指定之檔案不存在,則有可能造成crash

batch
於檔案系統中讀取文字檔,並批次執行當中的lbs指令。

batch 檔案名稱
檔案名稱
含有lbs指令的文字檔。

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分量的參考點:
參考點
1
自機之X座標
2
自機之Y座標
3
敵機之X座標
4
敵機之Y座標
5
畫面之最左端座標
6
畫面之最右端座標
7
畫面之最上端座標
8
畫面之最下端座標
  
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
可讀寫。表此子彈之動作模式:
說明
Direct
直進彈。在此模式下targetmaxAngle之值將會被忽略,但可運用accel值達到曲線前進的效果。
Homing
追尾彈。子彈將會依speed之速度往target所指定之座標靠近,accel在此模式下將會取絕對值以對速度向量進行增減。
Deleted
刪除。此子彈將會在下一個Frame之前被移除處理序列。

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模式下的目標點,隨著targetXtargetY參考點的設置不同,可以自動追蹤目標點而不需actionCheck介入。
double maxAngle
可讀寫。Homing模式下,子彈每次移動時,其轉向的量不會超過±maxAngle
int age
唯讀。記錄此一子彈由被擊發到目前為止存活的Frame數。
int dontCare
可讀寫。一旦此值大於零,表示此一子彈在接下來的nFrame中不會被傳遞進入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.0color = {1.0, 1.0, 1.0};為白色。
Bullet actionCheck(
Bullet in
)
Bullet classactionCheck函式。所有狀態變更之計算必須在此函式中完成。若某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起算,StartTimeEndTime這幾個Frame之間,擊發n枚屬於ClassName
Bullet class
的子彈。
子彈的初始屬性由AB內插,若AB屬性有衝突時(例如A.typeDirect,而B.typeHoming),以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 意見:

張貼留言

Related Posts Plugin for WordPress, Blogger...