泰拉瑞拉飾品制作方法

《泰拉瑞拉》的飾品制作方法其實還是有一些麻煩的,玩傢們初上手制作可能會遇到一些困難,不過我想這些都不是玩傢們想要制作飾品的阻礙,希望以下的飾品的制作方法,可以讓玩傢們在這款遊戲中可以獲得更多的樂趣。

【基礎篇:飾品創建】

一個mod道具需要有json文件和png文件嘛~

png就不多說瞭,圖片,不要找太大的就行瞭,反例請參見ctx的just a simple boss裡的BOSS召喚物——骷髏下巴,因為直接用瞭骷髏下巴的圖,太大,撿起來放在物品欄的時候縮得不成樣子

當然還有一點:背景色必須是透明,比如:泰拉瑞拉飾品制作方法

下面是json的寫法:以剛寫的ctxmove作范例:

{

“code”: “ctxmove”,——名字,要和json的文件名一致

“displayName”: “CTXs Movement”,——顯示名稱,最好區分大小寫以顯得很正式

“size”: [28,14],——尺寸,兩個數字分別對應png圖像的長和寬

“value”: [0,0,0,0],——價值,四個數字分別對應鉑、金、銀、銅幣的數量(註意這裡是買入價值,賣出時會有折扣,使用打折卡買入也會有折扣)

“rare”: 9,——稀有度,⑨就是最稀有的天藍瞭好像

“toolTip”: “I hate json.”,——第一行道具說明(想加第二行就是toolTip2)

“accessory”:true,——這句是重點,它決定瞭這個道具可以被塞進飾品欄

“recipes”: [——合成表

{

“items”: [“0 Wood”],——用0個木頭

“creates”: 1——合成1個飾品

}

]——這裡的recipe明顯不合格好吧!連tile也沒有——嘛,這不是重點

}

此外,還可以加一些附加的語句,比如”wings”:12,讓玩傢佩戴後獲得蒸汽朋克翅膀,”lifeRegen”:增加回血速度,”defense”:加防禦,好像也就這些瞭。

【進階篇:cs創建】

寫一個和png以及json相同名字的cs文件

首先,在裡面寫:

using System;

using TAPI;

using Microsoft.Xna.Framework.Graphics;

namespace TAPI.【MOD名稱】{

public class 【道具名稱】:ModItem{

public 【道具名稱】(ModBase modbase,Item i):base(modbase,i){}

public override void Effects(Player p){

//等會就是在這裡插入飾品信息滴~

}

}

那些【mod名稱】和【道具名稱】需要換成什麼,就看實際情況和個人喜好瞭……順便:【道具名稱】也要和文件名一樣

然後嘞……這個Effects究竟能幹什麼?答案:幾乎所有!一個玩傢能幹的事!

看見後面括號裡那個Player p瞭麼?這代表接下來Effects裡發生的一切事情,都將施予那個代號為p的玩傢——也就是帶上這個飾品的玩傢~(當然那個p改成player,ctx,lzw神馬的都行,隻是切記要和後面保持一致)

至於Effects究竟能幹啥嘛……先來幾個基本的吧:

首先是對玩傢身上的數據進行操作

寫p.statLifeMax=500;就是玩傢佩戴時生命最大值將瞬間飆到500

p.statManaMax=200;同理,玩傢最大魔法值飆到200

p.statManaMax2=+200;這個就像一般的法師飾品一樣暫時增加瞭玩傢的最大魔法,卸掉飾品就會還原(而前兩個不會)

p.wings = 12;給玩傢戴上蒸汽朋克翅膀

p.statDefense+=233;玩傢防禦增加233

p.lifeRegen+=233;玩傢回血速度增加233(再註:這裡的回血速度最大也隻能增加到每秒一點,是TR原版回血機制的問題)

繼續往Effects裡加條條——

p.statDefense+=2333333333;神馬的就不用我說瞭吧~改數字而已,大傢自便,不要讓自己失去遊戲樂趣就可以瞭

首先是更加神奇的回血:

p.statLife++;

這條代碼能讓玩傢每幀都回復一點血,相當於每秒60點,而且這個回血和玩傢自動回血以及幽靈套、吸血飛刀、HP藥水之類的完全無關,相當於是每秒免費送的60血~

同理,寫p.statMana++;就是每幀回復1藍,每秒額外60藍

另外,如果想看到效果的話可以再加一句p.HealEffect(1);或者p.ManaEffect(1);,分別是回血和回藍1的效果,當然括號裡的數字隨意填,填幾就跳幾的綠/藍數字(最好和寫的回血/回藍數字相同,不然會有困擾)

——什麼?還是太弱瞭?你手殘所以每秒60血根本不夠?

p.longInvince = true;

p.lavaImmune = true;

p.fireWalk = true;

p.noFallDmg = true;

四句分別是延長無敵時間(神聖十字效果),免疫巖漿(黑曜石藥水效果),免疫熱磚塊(黑曜石頭顱效果)以及免疫掉落傷害(馬掌效果)

——什麼?你還想站擼霜月?

記得我說過Effects可以對玩傢數據任意操控吧~

我們可以簡單地做一個內置鎖血鎖藍的效果:

p.statLife=p.statLifeMax;和p.statMana=p.p.statManaMax2;

原理:每幀都讀一下玩傢當前最大血/藍是多少,再賦給剩餘的血/藍

夠鬼畜瞭吧~現在隻要沒有喵殺你的攻擊,對你來說都是浮雲瞭

——什麼?你還要白天去同時站擼骷髏王、地牢守護者和機械骷髏王?

【喪病篇:鬼畜cs進階】

這一篇教程就是一些更華麗的效果瞭……

首先是上期遺留的問題:如何站擼白天吳克?答案就是……誒有人敲門?我的快遞到瞭,去收一下……

……剛才送快遞的LZW小哥告訴我,不能把這個說出來,不然會(ta)極(hui)大(zai)地(jin)影(wan)響(lai)遊(gang)戲(le)平(wo)衡,所以就隻能給一點提示瞭:給玩傢強行上無敵~

子提示①:無敵和免疫的意思很接近

子提示②:TR的變量基本是用英文命名的

子提示③:無敵也需要時間限定

那麼,就這樣吧,作為一個思考題,接下來是——

1.時裝

想穿烏龜套又懶得收集龜甲?萬能的Effects滿足你!

p.head=99;

p.body=65;

p.legs=54;

想穿幽靈套又不想下地牢?萬能的Effects滿足你!

p.head=101;

p.body=66;

p.legs=55;

其它時裝同理,不過實際使用時優先級是時裝欄高於下面的飾品高於上面的飾品高於裝備欄,請務必註意

2.套裝效果

想反傷又嫌烏龜套好難看而且不想穿時裝?還是萬能的Effects滿足你!

p.thorns = true;

p.turtleThorns = true;

想吸血而且覺得幽靈套太醜?依然是是萬能的Effects滿足你!

p.ghostHeal=true;

什麼?嫌幽靈套吸血太慢瞭?那就再來一句:

p.lifeSteal=233f;——瞬間還原至舊版幽靈套的吸血頻率我會說?

3.視覺特效

還是那句話,Effects是萬能的。

想在身上點上火?

for (int i=0;i<9;i++){

int m = Dust.NewDust(p.position, p.width, p.height, 6);

Main.dust[m].noGravity = true;

Main.dust[m].position += p.velocity * Main.rand.Next(-50, 51) * 0.01f;

}

上面這段效果大概就是在身上放上火焰的粒子特效,並且會依據玩傢的速度而延伸成一條火鏈;至於每一句都是起的什麼作用——字面意思,不懂英文的請自行google翻譯,不懂英文又秀優越秀愛國的請右上角

想讓自己身上冒星星?

Gore.NewGore(p.position+new Vector2(Main.rand.Next(p.width),Main.rand.Next(p.height)), p.velocity,Main.rand.Next(16,18));

上面這句就是在玩傢身上隨機的地方冒16號或者17號gore,也就是星星

【DEBUG-查錯階段】

首先是同時掛上蒸汽朋克翅膀、火焰粒子以及星星gore的照片一張

泰拉瑞拉飾品制作方法

這裡需要註意一點:cs開頭的using應該是using Microsoft.Xna.Framework;

也就是說,模板應該是如下:

using System;

using TAPI;

using Microsoft.Xna.Framework;

namespace TAPI.【MOD名稱】{

public class 【道具名稱】:ModItem{

public 【道具名稱】(ModBase modbase,Item i):base(modbase,i){}

public override void Effects(Player p){

//等會就是在這裡插入飾品信息滴~

}

}

這篇主要講述的是運用TR原版的一些方法組來答到寓守於攻、不戰而退敵的效果

首先……先介紹一些需要用到的代碼

1.Rectangle(組詞法:rect是“四”,angle是“角”,四個墻角即為矩形~)

要想快速而方便地判定范圍,首先要在TR裡表示一個矩形(Rectangle)。

TR裡聲明一個矩形的方法是使用new方法組,也就是new Rectangle(坐標X,坐標Y,寬,高)

舉例:new Rectangle(100,200,300,400)表示的是如下圖的矩形:

泰拉瑞拉飾品制作方法

左上頂點坐標(100,200),長300寬400,右下頂點坐標(100+300,200+400),表示的是一個范圍(嗯沒錯那個就是66ccff)

註:矩形的坐標和長寬必須是整數,在使用到玩傢或npc坐標的地方請在前面加個(int),表示取整

2.Rectangle.Intersects(Rectangle r1,Rectangle r2)

intersects方法組,隸屬於xna特有的數學系(重申一遍前面cs格式的.Graphics一定要刪掉!),用來判定兩個矩形是否相交,輸出邏輯值(真或假)

p.s.判定是否在范圍內時好像比直接計算距離略快一點,缺點就是判定是方的不好看

……嘛,戰鬥時誰還管好不好看呢?

3.foreach(類型 代號 in 組)

就像這個語句的名字一樣,它可以把某個組裡的所有東西都拉出來給一個代號,比如foreach(NPC n in Main.npc)就是檢索遊戲中所有NPC並給每個NPC起個名字:n;接下來這個n將要受到什麼代碼的操(rou)作(lin),就完全是個人喜好的問題瞭

4.NPC.AddBuff(int BUFF類型,int BUFF持續時間)

是時候讓那些可惡的怪物們嘗嘗FFF團的怒火瞭!有瞭這個方法組,給NPC隨意加debuff將不是夢想!

·BUFF類型就是想要加的BUFF的編號,比如燃燒是24,詛咒燃燒是39,霜火燃燒是44,等等

·BUFF持續時間是按幀算的,60幀=1秒(0處理落率),如果這裡寫60就是一秒,寫3600是一分鐘,寫23333333就是約4.50102874天,依據自己需求來決定時間吧

5.if(條件)

直譯:如果滿足條件就執行後面的內容,條件應為邏輯值

5.2.else

“否則”是“如果”的好姬友,用於在if的條件不成立時執行後面的語句

5.2.1.多層判定

那啥……else後面也能跟if,所以如果多重判定就可以寫成:

if(條件1){代碼段1}

else if(條件2){代碼段2}

else if(條件3){代碼段3}

else……

……

……else{都不滿足時的代碼段}

5.2.邏輯值的運算

如果需要同時判定多個條件成立,幾個條件就套上幾個if?如果需要多個條件任一成立,幾個條件就寫幾個else,然後在裡面寫相同語句?乃們out瞭!其實許多條件也是可以合並成一個條件的

需要用到的就是邏輯運算符:且(&&)、或(||)和非(!)

且就是數字7上面那個符號打兩遍,或就是右shift上面那個按鍵+shift打出來的(絕對值括號),非就是感嘆號(全都是半角)

且和或用於連接兩個邏輯值,放於兩個邏輯值之間;非放在一個邏輯值的前面,用於否定這個邏輯值(真假顛倒)

5.2.1.幾個邏輯運算的法則

1.!!a就是a

2.!(a&&b)就是(!a)||(!b)

3.!(a||b)就是(!a)&&(!b)

例題1:輸出一個邏輯值M,在a和b同時不成立的前提下要求滿足以下三點中任意兩點便成立:①b和c任一成立②d和e同時成立③f成立

解1:M=(!a)&&(!b)&&(((b||c)&&d&&e)||(f&&d&&e)||((b||c)&&f))

評價:簡單粗♂暴,適用於對多重括號很熟練的兄貴們

解2:int m=0;

if(b||c)m++;

if(d&&e)m++;

if(f)m++;

M=(!(a||b))&&(m>=2)

評價:略運用瞭化簡的技巧,適用於懶♂的兄貴們

6.反擊時刻!

現在讓我們把這四條組成一個給附近300像素以內NPC上霜火debuff的效果吧~

6.1.思路(伸手黨可以跳過這一段直接復制後方的成品,感興趣的還是看一下吧~)

先遍歷所有NPC記作n:foreach(NPC n in Main.npc)

操♂作開始,首先是確定范圍:

NPC所在的矩形是new Rectangle((int)n.position.X,(int)n.position.Y,n.width,n.height)

玩傢上下左右300像素的矩形是new Rectangle((int)p.position.X-300,(int)p.position.Y-300,p.width+600,p.height+600)

接下來是判定相交同時確保n還活著,而且是敵對NPC:

if(n.active&&!n.friendly&&new Rectangle((int)n.position.X,(int)n.position.Y,n.width,n.height).Intersects(new Rectangle((int)p.position.X-300,(int)p.position.Y-300,p.width+600,p.height+600)))

最後嘛……嘗嘗來自北國的FFF團精神吧!

n.AddBuff(44,300);

6.2.成品代碼:

foreach(NPC n in Main.npc){

if(n.active&&!n.friendly&&new Rectangle((int)n.position.X,(int)n.position.Y,n.width,n.height).Intersects(new Rectangle((int)p.position.X-300,(int)p.position.Y-300,p.width+600,p.height+600))){

n.AddBuff(44,300);

}

}

6.3.效果圖:

泰拉瑞拉飾品制作方法

BURN BABY,BURN!

嗯……本期教程就此結束,下期將是:【獵奇篇:讀取操作】,如何用飾品給予玩傢可控的額外火力,盡請期待~

附思考題:

如何做出十動然拒徽章的效果?(排除危險NPC和proj到安全距離以外)(neta自擁著轉)

提示:

①proj對應的組是Main.projectile,proj的類型是Projectile

②proj和NPC一樣有位置和寬高數據,位置可以被任意操作

③敵對NPC特征是friendly邏輯值為假,敵對proj特征是hostile邏輯值為真

【獵奇篇:讀取操作】

前言:

其實這一篇嚴格地說並不是為增強火力而存在的;換句話說,它不隻是為增強火力存在的。

隻要讀取瞭電腦前玩傢的操作,加上自定的一些代碼,玩傢就可以做到擴展整個人物的功能,就像K鍵召喚所有BOSS,F鍵瞬移,等等……

下面是正題:

1.讀取玩傢行動

讀取玩傢行動,其實隻需熟記表示玩傢狀態的幾個邏輯值,就能對玩傢相應的行動做到加強或改變;平時需要用的基本就是這幾條瞭:

controlLeft;控制向左

controlRight;控制向右

controlUp;控制向上

controlDown;控制向下

controlJump;控制跳

controlHook;控制鉤子

例:如何做一個讓玩傢移動速度加快的飾品?

大體思路就是讀取玩傢按下的方向鍵,並相應地適當改變玩傢速度,如下:

if (p.controlLeft)

{

if (p.velocity.X > 0) p.velocity.X *= 0.95f;

else if (p.velocity.X > -30) p.velocity.X -= p.velocity.Y == 0 ? 0.5f : 1f;

}

if (p.controlRight)

{

if (p.velocity.X < 0) p.velocity.X *= 0.95f;

else if (p.velocity.X < 30) p.velocity.X += p.velocity.Y == 0 ? 0.5f : 1f;

}

if (p.controlUp)

{

p.controlJump = true;

if (p.velocity.Y > 0) p.velocity.Y *= 0.95f;

else if (p.velocity.Y > -30) p.velocity.Y -= 1f;

}

以上的作用是:玩傢控制向左時就增加向左速度,玩傢控制向右就增加向右速度;將控制向上和控制跳躍綁定,控制向上就增加向上的速度

2.讀取鼠標狀態

遊戲中自帶顯示鼠標狀態的邏輯值,Main.mouseLeft和Main.mouseRight分別表示鼠標左鍵和右鍵是否按下;相應的還有Main.mouseLeftRelease和Main.mouseRightRelease表示左右鍵是否未按下,可以理解為兩者相反

思考題:如何制作按下鼠標右鍵就回血的飾品?運用前面的教程,題目較為簡單,這裡就不寫示例瞭

3.讀取鍵盤狀態

Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.【按鍵代號】)

這個語句用來讀取鍵盤狀態,如果當前按下瞭指定【按鍵代號】的鍵就等於真;反之,假。一般來說,提取字母鍵的狀態隻需把按鍵代號寫成相應大寫字母;F1-F12也是直接寫大寫F加數字就可以瞭

【獵奇+篇:輔助火力】

提示:這一篇將會有大量的英語和數學成分,不過LZ相信你們會比上學期英語倒10的LZ看得更明白的~

當然最開始還是喜聞樂見地分條講解代碼:

1.Projectile.NewProjectile(坐標X,坐標Y,速度X,速度Y,種類,傷害,擊退,所屬玩傢,ai0,ai1)

字面意思,用來在世界裡生成一個proj,中心對準給定的坐標,速度為給定速度,種類、傷害、擊退等等都是可以指定的,所屬玩傢一般寫Main.myPlayer或者p.whoAmI(當自己被編號為p時)至於那個ai0和ai1,目前還不需要它們,在寫的時候可以純粹省略這兩項,或者填0

這句話可以說是附加火力的核心,沒有它一切都是免談,想象一下,對準怪物按下鼠標,想讓火球飛過去就飛火球,想飛激光就飛激光……

橋豆麻袋!電腦怎麼知道你想讓那個proj飛到哪裡去?下面是一些有關確定速度方向的講解:

①三角函數天才,或者平面向量萬年掛科,請前往條目2

②平面向量學霸或者痛恨三角函數,請前往條目3

1.1.先確定自己和鼠標的位置吧~

Vector2 pc=p.position+new Vector2(p.width,p.height)/2;

Vector2 mc=Main.screenPosition+new Vector2(Main.mouseX,Main.mouseY);

2.Math.Atan2(對邊,斜邊)

兩個向量作差,得到瞭什麼?向量?錯!是直角三角形!

float r=(float)Math.Atan2(mc.Y-pc.Y,mc.X-pc.X);

(這個函數是反正切,又不是反正切,因為它的對邊和斜邊隨便哪個取0都是可以輸出結果的;而且它的值域是2π,也就是一圈!)

接下來,Vector2 v=new Vector2((float)Math.Cos(r),(float)Math.Sin(r));

這就是單位長度,方向從玩傢中心指向鼠標的速度向量

3.Vector2.Distance(向量1,向量2)

這個語句是用來求兩個向量距離的,同樣的效果也可以用求向量長度的語句((向量1-向量2).Length())來實現

Q:沒事求向量長度幹啥?

A:向量除以長度等於單位向量

也就是:Vector2 v=(mc-pc)/Vector2.Distance(mc,pc);

一發♂入魂的單位向量~

下面就可以組裝起來瞭:

Vector2 pc=p.position+new Vector2(p.width,p.height)/2;

Vector2 mc=Main.screenPosition+new Vector2(Main.mouseX,Main.mouseY);

Vector2 v=(mc-pc)/Vector2.Distance(mc,pc);

Projectile.NewProjectile(pc.X,pc.Y,v.X*6,v.Y*6,255,50,0,p.whoAmI);

示例中為使用單位向量法,速度大小為6,傷害為50,無擊退的磁球激光

直接寫進去?不不不那樣會鬼畜的,激光還好,如果寫的是雷♂管之類的和諧物品的話,想象一下每秒60個雷♂管不受控制地射出去的景象……

【獵奇+篇:控制法】

前方大量聲明,註意

要控制火力嘛……不然會鬼畜不是嗎?所以這裡就能利用上前面說的讀取鍵盤狀態瞭

這裡可以分為幾類觸發機制,以下用F鍵作為例子

0.特別說明

務必加上p.whoAmI==Main.myPlayer的判定,如果你不想自己按鍵時全圖玩傢都開始放彈幕,想象一下全圖按鍵會發生什麼

1.單發

原理是記錄上一幀的F鍵狀態,如果兩個狀態不同,代表按下(彈起)瞭F,鍵,就可以放彈幕瞭

具體:

using System;

using TAPI;

using Microsoft.Xna.Framework;

namespace TAPI.【MOD名稱】{

public class 【道具名稱】:ModItem{

public 【道具名稱】(ModBase modbase,Item i):base(modbase,i){}

bool oldF=false;

public override void Effects(Player p){

if(p.whoAmI==Main.myPlayer&&!oldF&&Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.F)){

//這裡面就是寫前面發射子彈代碼的地方

}

oldF=Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.F;

}

}

這種觸發方式的頻率是取決於按鍵速度的,也就是按得越快射♂得越快,理論射速峰值為30發每秒

2.連發

原理是添加一個計時變量,至於具體怎麼計時就看個人喜好瞭,這裡提供一種解決方案:

using System;

using TAPI;

using Microsoft.Xna.Framework;

namespace TAPI.【MOD名稱】{

public class 【道具名稱】:ModItem{

public 【道具名稱】(ModBase modbase,Item i):base(modbase,i){}

int timer=0;

public override void Effects(Player p){

if(timer>0)timer–;

else{

if(p.whoAmI==Main.myPlayer&&Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.F)){

timer=10;

//這裡面就是寫前面發射子彈代碼的地方

}

}

}

}

按住F就可以連射瞭~示例為每秒觸發6次的寫法

3.自動

這裡就略復雜瞭點,需要具有想象力以及數學功底,當然還有對於彈幕的熱愛=w=

簡單地來一個施放旋轉鐮刀的腳本吧~

using System;

using TAPI;

using Microsoft.Xna.Framework;

namespace TAPI.ctx{

public class ctxbullet : ModItem{

int timer = 0;

float r = 0;

float rv = 0;

float ra = 0.001f;

bool barrage = false;

public ctxbullet(ModBase modbase, Item i) : base(modbase, i) { }

public override void Effects(Player p){

rv += ra;

if (rv > 3) rv -= (float)Math.PI * 2f;

r += rv;

if (r > 3) r -= (float)Math.PI * 2f;

timer++;

if (timer > 3) timer -= 3;

if (barrage){

if (p.statMana < 3 || p.whoAmI != Main.myPlayer){

barrage = false;

goto outOfMana;

}

else p.statMana -= 3;

if (timer % 3 == 0){

Vector2 pc = p.position + new Vector2(p.width, p.height) / 2;

Vector2 v = new Vector2((float)Math.Cos(r), (float)Math.Sin(r));

Projectile.NewProjectile(pc.X, pc.Y, v.X * 20f, v.Y * 20f, 274, 100, 0, p.whoAmI);

Projectile.NewProjectile(pc.X, pc.Y, -v.X * 20f, -v.Y * 20f, 274, 100, 0, p.whoAmI);

}

}

outOfMana:

if (Main.keyState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.F)) barrage = !barrage;

}

}

}

因為需要美觀,就多定義瞭幾個角度增速,角度加速度,角度急動度,角度痙攣度神馬的……

效果圖:

泰拉瑞拉飾品制作方法

(所以說彈幕可以培養數學和想象力=w=)

當然,自動類彈幕的形式是非常多的,從上文簡單的噴環環,到折返射、西行寺無餘涅盤、夢想天生、原子崩壞、金剛槍破,等等……隻要看懂彈幕的組成,tAPI就能寫出來!

嘛……作為飾品部分的教程基本已經結束瞭,從道具json的創建一直到在cs裡聲明和操作變量,基本現在已經可以復原所有原版飾品的效果瞭,玩傢們也能首夜裸裝站擼機械三王瞭

Leave a Reply

Your email address will not be published. Required fields are marked *