lf2改ai教學
lf2吧
全部回复
仅看楼主
level 12
mrsmallbee 楼主
3樓:條件
4樓:運算符
5樓:變量
6樓:範圍
7樓:命令
8樓:函數
9樓:調試
10樓:錯誤
11樓:目標加載
2017年02月26日 17点02分 1
level 12
mrsmallbee 楼主
下載:[无效] https://pan.baidu.com/s/1qYttnKK
它不會編輯lf2.exe,只會在啟動時讀取您的AI腳本(如果您使用調試版本,會自動重新加載它們,所以沒有必要重新啟動以應用更改)。只是想玩別人製作的AI的話,下載發佈版本。將dll放入您的lf2目錄,並創建一個名為AI的文件夾,將腳本放入。如果想開始創建自己的AI,下載調試版本。將該dll貼到您的lf2目錄。啟動lf2.exe將打開一個控制台,給你關於運行AI腳本的信息。現在你可以在你的lf2目錄中創建一個名為AI的文件夾用來放置你的AI腳本。腳本用Angel Script編寫,它使用基本的C語法。我們需要的所有部件都很容易。Angel Script基本上是文本文件,除了它們的文件結尾是“.as”,所以你可以使用任何文本編輯器來創建和編輯它們。以你想使用的id編號來命名文件。
每個AI腳本需要包含以下兩個函數中至少一個:
id()函數 - 這將替換角色的AI,並讓你控制它做的一切。
ego()函數 - 如果你不使用id()函數,這個函數將被原來的基礎AI調用。
顯然,如果你只是想做一個近戰角色,在某些情況作出某些動作的話,你只需使用ego()函數。 這裡有一個非常簡單的AI腳本例子:
int ego(){
if (self.hp < 400){
DdJ();
}
return 0;
}
這個代碼可能對John有用,因為他會在他的HP低於400時嘗試使出治療自己。但是對於作戰的AI將需要一些更複雜的條件確保在正確的時機執行動作。 請注意,ego()函數不是你的角色的主要AI函數,因此需要'返回'到它被調用的函數。 通過return 0; 0將控制返回給基礎AI(id()函數)。 如果你寫return 1; 您可以在ego()函數中保留控制權。 如果稍後創建自己的函數,它們可能會返回其他值,具體取決於它們的用途。
2017年02月26日 17点02分 2
level 12
mrsmallbee 楼主
條件是你最好的朋友。 除了在角色數據裡面註明mp限制,這些將幫助AI決定在什麼時候使出什麼動作。 它的基本語法如下所示:
if (條件){//如果條件滿足,執行
命令(); //執行命令
}
但是你也可以用else ifs或在沒有條件滿足時只用else將它分支到許多不同的條件:
if (條件1){
命令1();
}
else if (條件2){
命令2();
}
else {
命令3();
}
現在仔細看看條件本身,你將需要運算符來為他們工作。
2017年02月26日 17点02分 3
level 12
mrsmallbee 楼主
運算符允許您比較事物並將多個條件鏈接在一起。 這些是您可能使用的比較運算符:
變量 == 1 //變量等於1
變量 != 1 //變量不等於1
變量 >= 1 //變量大於或等於1
變量 <= 1 //變量小於或等於1
變量 > 1 //變量大於1
變量 < 1 //變量小於1
這些是鏈接操作符,你需要有多個條件:
條件1 && 條件2 //條件1和條件2都符合
條件1 || 條件2 //條件1,條件2或兩者都滿足
您還可以使用括號以更複雜的方式將它們鏈接:
條件1 && (條件2 || 條件3) //條件1,並且至少滿足條件2或條件3
並且為了比較各項條件以執行動作,你需要角色和它的目標的各種信息:變量。
2017年02月26日 17点02分 4
level 12
mrsmallbee 楼主
Silva已经讓我们访问角色(自己)和目标的很多數據,并希望增加更多。您的腳本裏所有以下的變量都需要用self.或target.作為前綴:
id //即該實體的ID,同 data.txt 所描述
num //實體的流水編號,表示 loadTarget(num) 可以將當前的 target 切換成該物件
type //該物件的 type,同 data.txt 所描述
weapon_type//手持物件的 type (有刀和飛旋鏢的特殊數字)
weapon_held//手持物件實體的編號
frame //實體目前的 frame ,在寫連技的時候很有用
state //實體目前的 state ,用以判斷其狀態
team //實體的隊伍
clone //-1表示非分身,3或者其他數字表示是分身 (AI可以直接看破分身術!)
fall //實體目前的 fall 值,一般為 0,被攻擊後會上升。 >0: DoP, >70: 被踢出
bdefend //實體目前的 bdefend 值,一般為 0,在防禦時被攻擊會上升; >70(/100 for armors): 破防
arest //實體的 arest 值,表示攻擊者要多少個 frame 後才能再次攻擊
vrest //實體的 vrest 值,表示被攻擊者要多少個 frame 後才能再被攻擊
blink //閃爍計數器,在state 14時返回一個數字,15至1代表閃爍,0代表無閃爍
shake //擊中搖晃計數器,被攻擊者為負數,攻擊者為正數
ctimer //抓住人時這個計數器會從 300 數到 0 然後放開
mp //上升到500; 如果低於0,只有按下攻擊才會再次開始上升(復位為0)
hp //血量
dark_hp //深紅色血量
max_hp //最大血量,喝奶瓶能補到的上限
facing //0 表示面對右邊,1 表示面對左邊
x_velocity //明顯是速度
y_velocity //..
z_velocity //..
x //明顯是場上的位置
z //..
y //..
D //1 表示此按鍵目前按下,否則為0
J //..
A //..
left //..
up //..
right //..
down //..
DlA //其值為目前滿足的按鍵數,無按鍵時為0,剛按過D為1,
DuA //滿足兩顆鍵為2,完全滿足為3
DrA //
DdA //(一旦輸入被接受用於動作,則返回0,或者通過按壓不同的鍵而被排除)
DlJ //
DuJ //l,u,r,d代表左上下右下
DrJ //..
DdJ //..
DJA //..
角色和目標的位置對於你通常的動作是最重要的,這決定了目標是否在某些行動的範圍內。
有一些變量不屬於self.或target. 並將讓你知道正在發生什麼樣的戰鬥:
stage_bound //
stage_clear //
current_phase //
current_phase_count//
current_stage //
bg_width //地圖寬度,即地圖最右方的X值,最左邊的X為0
bg_zwidth1 //地圖Z方向頂端
bg_zwidth2 //地圖Z方向底端
mode //0: VS, 1: Stage, 2: 1on1, 3: 2on2, 4: Battle, 5: Demo, 6: Playback, 7: Quit
difficulty //-1: CRAZY!, 0: difficult, 1: normal, 2: easy
你甚至可以像這樣創建自己的變量:
int xdistance = self.x-target.x;
2017年02月26日 17点02分 5
level 12
mrsmallbee 楼主
檢查範圍的最簡單方法是減去角色和目標的位置以獲得距離,然後將其與動作的命中目標範圍進行比較:
if (((self.x-target.x) => 0) && ((self.x-target.x) =< 80))
但是這種方式只有當目標在我們角色右邊80px內時才會執行移動。 要使它同樣在左邊以及只有當角色面對他的目標時生效,我們將包括self.facing到距離計算,如下:
(self.x-target.x)*(2*(self.facing?1:0)-1)
附加計算將self.facing從0和1變為-1和1。現在,當目標在z軸上太遠時,角色也不應執行動作。 這更簡單一點,因為無論目標是高於還是低於我們的角色都無關緊要,Silva已經實現了一個絕對函數將任何值轉換為正值:
if (abs(self.z-target.z) =< 8)
在這個條件下,只有當目標在z軸上的17px內時,才會執行動作。y軸通常不像其他兩個有趣,但如果你有一個近戰動作,不能擊中下降中的角色,你可能想要檢查目標是否在地面上:
if (target.y == 0)
現在到遠程動作的部份,整個事情變得越來越複雜,因為z範圍隨著投射物的飛行距離增加而上升和下降。 你可以簡單地做一個x和z距離的劃分,以得到一個你可以比較的角度:
if (abs(100*(self.z-target.z)/(self.x-target.x)) =< 15)
現在條件已設置,您可以通過放置一個或幾個可用的命令來執行動作。
2017年02月26日 17点02分 6
level 12
mrsmallbee 楼主
這些都是你可以給角色的命令:
D(x,y); //x=1,y=0: 單按一次該按鍵
J(x,y); //x=1,y=1: 單按一次該按鍵/按著該按鍵(行走時有用)
A(x,y); //x=0,y=0: 放開該按鍵(如果使用void id()函數,則為必需)
left(x,y); //..
up(x,y); //..
right(x,y); //..
down(x,y); //..
DlA();
DuA();
DrA();
DdA();
DlJ();
DuJ();
DrJ();
DdJ();
DJA();
以上這是你需要用來創建簡單的AI腳本的知識,如果你希望創建更複雜的AI請繼續閱讀。
如果您的腳本有問題請閱讀錯誤和調試的部分。
2017年02月26日 17点02分 7
level 12
mrsmallbee 楼主
以下是一些有用的預定義函數:
abs(i); //返回i的絕對值(負數將變為正數)
rand(i); //隨機返回一個從0到i的數字
loadTarget(i); //這允許你改變你的目標,而i是一個從0到399的數字
//該函數將返回對像類型或-1(如果對像不存在)
//而且對象i = 0至7都是玩家的角色
但你也可以創建自己的函數:
int sum(int x, int y){
int z = x + y;
return z;
}
第一行函數定義將會返回的變量類型以及它將使用的變量類型。 這裡有兩個可以怎樣調用的例子:
int variable = sum(self.x, self.y);
if (sum(target.z, target.x) < 0){}
你可以看到函數可以在計算和條件中使用,用變量做複雜的計算,並讓你像變量一樣使用返回的值。 在第一個例子中,函數用於將角色x和y坐標的和寫入變量,第二個用於將目標z和x坐標的和作為條件。 所以如果你需要經常使用不同的變量來做相同計算的話,只需為它創建一個函數。
如果你需要一個不返回任何東西的函數,你可以叫它做"void functionname()",就像void id()函數。
2017年02月26日 17点02分 8
level 12
mrsmallbee 楼主
如果你不知道你正在處理什麼,並需要看到一些基於你的條件的值,你可以使用函數print(),如果你不喜歡控制台運完整運行可以用clr()。以下是一個示例:
print("text"); //在控制台中打印文本
print(variable); //在控制台中打印變量的值
print("\n"); //在控制台中添加了一個新行
print(variable+"text\n");//使用新行打印值和文本
clr() //清除控制台
2017年02月26日 17点02分 9
level 12
mrsmallbee 楼主
如果你的腳本中有語法錯誤,控制台會發出錯誤消息。 以下是一些解讀和處理的例子:
ai\0.as(8, 10): ERROR : Expected ';'
這個錯誤只是意味著在文件“0.as”中你忘了放一個“;”在第8行位置10。只需到那裡添加它,問題解決。
ai\0.as(11, 2): ERROR : Unexpected end of file
它意味著你忘了關閉某處的括號。 你可以在結尾添加一個,但這可能不是正確的位置,所以最好完整地檢查你的腳本,也許還有更多的地方出錯。
ai\0.as(6, 38): ERROR : No conversion from 'bool' to math type available.
這意味著你在數學計算中嘗試使用布爾變量(如self.facing,它只能是true或false)。 要將變量轉換為相應的數學值,只需在其末尾添加“?1:0”。(例如:self.facing?1:0; 1為真,0為假)
2017年02月26日 17点02分 10
level 12
mrsmallbee 楼主
現在你和你的AI都越來越進步了,想了解更多關於其他沒有被選為基礎AI目標的遊戲對像。 loadTarget(i)會為你做這個。 它加載對象編號的目標變量i並返回它的類型或-1(如果它不存在時)。 遊戲中有400個對象槽(0到399),前8個是為玩家保留的。 所以如果你想選擇其中一個,而不知道它的數字,你將需要一個for循環,檢查出所有400個的對象槽:
for (int i = 0; i < 400; ++i){
if (loadTarget(i) == 0 && target.team != self.team){
print("opponent "+i+" has "+target.hp+"hp\n");
}
}
這個例子將打印所有對手的hp。但是它将只有随后选择的对象編號399。 我們將需要添加一些變量和另一個條件來選擇它們中的某一個。 我以hp最少的對手作為目標:
int k = 0;
int hp = loadTarget(0);
for (int i = 0; i < 400; ++i){
if (loadTarget(i) == 0 && target.team != self.team && target.hp < hp){
hp = target.hp;
k = i;
}
}
loadTarget(k);
你當然也可以嘗試得到最接近你的對手(或結合兩個條件),在範圍內尋找武器或檢查敵對投射物。 但是有一個問題:如果你只使用ego()函數,基礎AI將總是通過它自己的條件重新選擇目標。 您應該最好僅基於自選目標使用特殊動作。 最有用的範疇可能是與任何團隊相關的動作,例如治療或合♂體。例如,John可以檢查他所有的隊友,無論他們是否足夠接近他和需要治療。 而Jan可以簡單地檢查所有的隊友來執行她的天使的祝福。
2017年02月26日 17点02分 11
level 12
mrsmallbee 楼主
拖了好像兩星期[瘫坐]終於翻譯完了[Yeah]
2017年02月26日 17点02分 12
level 13
马克
2017年02月27日 08点02分 13
楼主有联系方式吗?qq或者其他的?我想做一套完整的十斗士对战比赛用ai
2017年03月02日 08点03分
@撸过的海天酱油 我只是翻譯,沒實際做過[汗]
2017年03月02日 11点03分
我遲些開貼發些別人做的ai腳本
2017年03月02日 11点03分
@mrsmallbee 好吧…
2017年03月02日 14点03分
level 8
dalao,瑟瑟发抖。[勉强]可以,很赞噢
2017年02月27日 08点02分 14
level 11
LFE?
2017年03月02日 18点03分 15
1 2 尾页