haxball 球場的檔案的副檔名是 .hbs (haxball stadium)
可以用
notepad.exe(記事本)
其他文字編輯軟件 打開編輯
下面是classic.hbs(預設球場)的內容 裡面其實是一串JSON
{
"name" : "Classic",
"width" : 420,
"height" : 200,
"spawnDistance" : 170,
"bg" : { "type" : "grass", "width" :370, "height" : 170, "kickOffRadius" : 75,"cornerRadius" : 0 },
"vertexes": [
{ "x" : -370, "y" :170, "trait" : "ballArea" },
{ "x" : -370, "y" :64, "trait" : "ballArea" },
{ "x" : -370, "y" :-64, "trait" : "ballArea" },
{ "x" : -370, "y" : -170, "trait" :"ballArea" },
{ "x" : 370, "y" : 170, "trait": "ballArea" },
{ "x" : 370, "y" :64, "trait" : "ballArea" },
{ "x" : 370, "y" :-64, "trait" : "ballArea" },
{ "x" : 370, "y" : -170, "trait" :"ballArea" },
{ "x" : 0, "y" : 200,"trait" : "kickOffBarrier" },
{ "x" : 0, "y" : 75, "trait": "kickOffBarrier" },
{ "x" : 0, "y" : -75,"trait" : "kickOffBarrier" },
{ "x" : 0, "y" : -200, "trait" :"kickOffBarrier" },
{ "x" : -380, "y" : -64, "trait" :"goalNet" },
{ "x" : -400, "y" : -44, "trait" :"goalNet" },
{ "x" : -400, "y" : 44,"trait" : "goalNet" },
{ "x" : -380, "y" : 64,"trait" : "goalNet" },
{ "x" : 380, "y" : -64, "trait" :"goalNet" },
{ "x" : 400, "y" : -44, "trait" :"goalNet" },
{ "x" : 400, "y" : 44,"trait" : "goalNet" },
{ "x" : 380, "y" : 64,"trait" : "goalNet" }
],
"segments" : [
{ "v0" : 0, "v1" : 1, "trait" :"ballArea" },
{ "v0" : 2, "v1" : 3, "trait" :"ballArea" },
{ "v0" : 4, "v1" : 5, "trait" :"ballArea" },
{ "v0" : 6, "v1" : 7, "trait" :"ballArea" },
{ "v0" : 12, "v1" : 13, "trait" :"goalNet", "curve" : -90 },
{ "v0" : 13, "v1" : 14, "trait" :"goalNet" },
{ "v0" : 14, "v1" : 15, "trait" :"goalNet", "curve" : -90 },
{ "v0" : 16, "v1" : 17, "trait" :"goalNet", "curve" : 90 },
{ "v0" : 17, "v1" : 18, "trait" :"goalNet" },
{ "v0" : 18, "v1" : 19, "trait" :"goalNet", "curve" : 90 },
{ "v0" : 8, "v1" : 9, "trait" :"kickOffBarrier" },
{ "v0" : 9, "v1" : 10, "trait" :"kickOffBarrier", "curve" : 180, "cGroup" :["blueKO"] },
{ "v0" : 9, "v1" : 10, "trait" :"kickOffBarrier", "curve" : -180, "cGroup" :["redKO"] },
{ "v0" : 10, "v1" : 11, "trait" :"kickOffBarrier" }
],
"goals" : [
{ "p0" : [-370, 64], "p1" : [-370,-64],"team" : "red" },
{ "p0" : [370, 64], "p1" : [370,-64],"team" : "blue" }
],
"discs" : [
{ "pos" : [-370, 64], "trait" :"goalPost", "color" : "FFCCCC" },
{ "pos" : [-370, -64], "trait" :"goalPost", "color" : "FFCCCC" },
{ "pos" : [ 370, 64], "trait" :"goalPost", "color" : "CCCCFF" },
{ "pos" : [ 370, -64], "trait" :"goalPost", "color" : "CCCCFF" }
],
"planes" : [
{ "normal" : [0, 1], "dist" : -170,"trait" : "ballArea" },
{ "normal" : [0,-1], "dist" : -170,"trait" : "ballArea" },
{ "normal" : [ 0, 1], "dist" : -200,"bCoef" : 0.1 },
{ "normal" : [ 0,-1], "dist" : -200,"bCoef" : 0.1 },
{ "normal" : [ 1, 0], "dist" : -420,"bCoef" : 0.1 },
{ "normal" : [-1, 0], "dist" : -420,"bCoef" : 0.1 }
],
"traits" : {
"ballArea" : { "vis" : false, "bCoef": 1, "cMask" : ["ball"] },
"goalPost" : { "radius" : 8,"invMass" : 0, "bCoef" : 0.5 },
"goalNet" : { "vis" : true, "bCoef" :0.1, "cMask" : ["ball"] },
"kickOffBarrier" : { "vis" : false,"bCoef" : 0.1, "cGroup" : ["redKO","blueKO"], "cMask" : ["red", "blue"] }
}
}
我們從頭看起
"name" : "Classic",
即是將球場的 名字 設置成 Classic
"width": 420,
"height" : 200,
這兩個是設定 球場可視範圍 的闊和高(由球場中心)
總闊 是 840, 總高 是 400
剛好是畫面的上限 可視範圍 超出畫面上限 畫面會移動
"spawnDistance" : 170,
設置 球員重生距離 為 170
這個距離是 球員重生位置 與 球場中心 的距離
"bg": { "type" : "grass", "width" : 370,"height" : 170, "kickOffRadius" : 75,"cornerRadius" : 0 },
設置 背景(background)
"type":"grass" ←種類(type) 可以是 grass / hockey
"width" : 370, "height" : 170 ←背景 的 闊和高
"kickOffRadius": 75 ←開球半徑 球場中心圓的大小
"cornerRadius":0 ←將背景 的 直角改成圓角
"vertexes": [...]
設置 點 的位置 (一直線 是由 兩點 構成)
{"x" : -370, "y" : 170, "trait" :"ballArea" },
點 的坐標x, y
"trait"下面會講 暫時理解為 特質/一組屬性
"segments": [...]
把 兩點 連成 一線
{"v0" : 0, "v1" : 1, "trait" :"ballArea" }, || {"v0" : 2, "v1" : 3, "trait" :"ballArea" },
將 第0點 與 第1點 連成 線 || 將 第2點 與 第3點 連成 線
線 的特質可以與 點 不同 所以要標明
點 的次序是 按照"vertexes" 中排序 即是
"vertexes": [
{ "x" : -370, "y" :170, "trait" : "ballArea" }, //←第0點
{ "x" : -370, "y" :64, "trait" : "ballArea" }, //←第1點
{ "x" : -370, "y" :-64, "trait" : "ballArea" }, //←第2點
{ "x" : -370, "y" : -170, "trait" :"ballArea" }, //←第3點
...
],
"goals": [...]
設置 球門線 的位置
{"p0" : [-370, 64], "p1" : [-370,-64], "team" :"red" },
p0 的坐標 p1 的坐標 連成 球門線
"team"記住這是哪一隊 球門線
"discs": [...]
設置 圓盤 這個/些圓盤 並不是 ball 不能踢 亦不能入球得分
{"pos" : [-370, 64], "trait" :"goalPost", "color" : "FFCCCC" },
"pos"會記住 圓盤 的位置
"color"是眾多屬性中的一種 屬性可以放在 "trait" 裡 亦可以抽出來
"planes": [...]
設置 邊界 這是一條無限長的直線 能與邊界碰撞的物件 不能走出邊界外
{"normal" : [0, 1], "dist" : -170, "trait" :"ballArea" },
"normal"會記住 邊界 面向的範圍 數值範圍是 1 至 -1
"dist"會記住 邊界 與 球場中心 的距離
{"normal" : [ 0, 1], "dist" : -200, "bCoef" : 0.1},中
"bCoef"亦是眾多屬性中的一種 可以放在 "trait" 裡
"traits": {...}
設置 特質
"ballArea": { "vis" : false, "bCoef" : 1, "cMask" :["ball"] },
"ballArea"中 ballArea 這個字可以是任何字
{...}中的就是 對應特質中的屬性
通常會用在"traits"的屬性有
"vis"(visual) ←看得見 就是 "vis": true 反之 false
"bCoef" (bounce coefficient) ←物件的反彈係數 兩件會碰撞的物件 係數會相乘
"cGroup"(collision group) ←碰撞組別 值可以多於一個
"ball" "red" "blue" "wall" "redKO" "blueKO" "all" 或是 空的 ""
"cMask" (collision mask) ←碰撞面具(?) 值同上
例如:
物件1 的 cGroup 是 ball , cMask 是 ball 物件2 的 cGroup 是 ball , cMask 是 ball 物件3 的 cGroup 是 red , cMask 是 blue 物件4 的 cGroup 是 blue , cMask 是 red |
物件1 與 物件2 會碰撞 物件3 與 物件4 會碰撞 物件1 與 物件3 不會碰撞 物件1 與 物件4 不會碰撞 物件2 與 物件3 不會碰撞 物件2 與 物件4 不會碰撞 |
意思是若要 兩者碰撞
物件A cGroup 中的值 物件B cMask 中的亦要有相同值 同樣
物件B cGroup 中的值 物件A cMask 中的亦要有相同值 才會碰撞
因為 物件A碰撞物件B = 物件B碰撞物件A
"color" ←值會是16進位值色碼
"radius" ←適用於 "discs" "ballPhysics"(沒有出現在classic.hbs中) 的屬性
"invMass"(inverse mass) ←可以理解為質量 值越低 就越難被推動
"damping" ←可以理解為摩擦力
值為1時 不會減速 亦 不會加速
少於1時會減速 值越低 減速度越高
加於1時會加速 值越高 加速度越高
**所有數值皆有 正 負
等神人再研究...