泰拉瑞亞是一款很不錯的的沙盒類遊戲,在遊戲中玩家可以製作各種各樣的道具來對抗敵人,最近很多玩家想知道如何製作飾品,下麵給大家分享下泰拉瑞亞飾品製作詳細教程,希望對大家有所幫助。
飾品製作方法
【基礎篇:飾品創建】
一個mod道具需要有json文件和png文件嘛~
png就不多說了,圖片,不要找太大的就行了,反例請參見ctx的just a simple boss裏的BOSS召喚物——骷髏下巴,因為直接用了骷髏下巴的圖,太大,撿起來放在物品欄的時候縮得不成樣子
當然還有一點:背景色必須是透明,比如:
下麵是json的寫法:以剛寫的ctxmove作範例:
{
"code": "ctxmove",——名字,要和json的文件名一致
"displayName": "CTX's 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原版回血機製的問題)
當然,還有很多……
【娛樂篇:鬼畜cs】
接上篇,繼續往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裏聲明和操作變量,基本現在已經可以複原所有原版飾品的效果了,玩家們也能首夜裸裝站擼機械三王了


泰拉瑞亞1.4手機版">
下載
下載
下載 
下載
下載
下載
下載
下載
下載
喜歡
高興
鬼臉
嗬嗬
無聊
傷心





