泰拉瑞亚-坐骑Mod开发
前言
- 入门级教程请参考上一篇文章
- Git仓库:https://github.com/Cyborg2077/PolWorldMounts
- Steam创意工坊:https://steamcommunity.com/sharedfiles/filedetails/?id=3292980622
- 本文进度会略微落后于创意工坊版本
如何自定义坐骑
- 原版Terraria里的坐骑,首先都要有一个召唤物。
- 其次就是有一个buff图标
最后就是坐骑本体
所以首先我们要先来制作这个召唤物。那么第一步我们先来创建一个Mod项目吧。
制作召唤物
- 召唤物的本质实际上就是一个Item,所以我们创建一个类,继承ModItem即可。
- 在这个类中,我们来定义召唤物的一些属性,以及合成材料
1 | using PolWorldMounts.Content.Mounts; |
- 物品制作完毕后,我们还需要制作贴图,这里我就以帕鲁球为例制作贴图了。画风最好是符合泰拉瑞亚的像素风,这样看起来比较舒服。
- 那我们直接启动幻兽帕鲁,进游戏截一张帕鲁球的图
- 拿到图肯定不能直接用,我们首先要扣掉背景,随后转为像素风,调整尺寸为32*32。扣背景我这里直接用的百度AI图片助手,扣好了之后下载到本地,我们来进一步处理像素风
- 像素风的处理,我这里直接用的Python的PIL库来进行处理
1
2
3
4
5
6
7
8
9
10
11
12
13from PIL import Image
def pixelate(image_path, block_size):
img = Image.open(image_path)
w, h = img.size
img_small = img.resize((w // block_size, h // block_size), resample=Image.NEAREST)
result = img_small.resize(img.size, Image.NEAREST)
return result
pixelated_image = pixelate('帕鲁球.png', 7)
pixelated_image.save('pixelated.png') - 处理后的效果还是不错的,那么云海鹿召唤物的功能,我们就开发完毕了
制作坐骑
- 坐骑的创建,我们同样需要继承ModMount,随后就是定义坐骑的基本属性,云海鹿的特性有二段跳,所以我们这里不阻止使用额外跳跃,只要你装备了云朵瓶或者气球束之类的会产生额外跳跃的饰品,当你在骑行云海鹿的时候,都可以正常触发。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58public class FenglopeMount : ModMount
{
public override void SetStaticDefaults()
{
// 定义坐骑的基本属性
MountData.jumpHeight = 20; // 坐骑能跳多高
MountData.acceleration = 0.19f; // 加速率,即坐骑加速的速度
MountData.jumpSpeed = 20f; // 当按下跳跃键时,坐骑和玩家向上跳跃的速度
MountData.blockExtraJumps = false; // 是否阻止使用额外跳跃(如瓶子中的云)
MountData.constantJump = true; // 是否允许按住跳跃键进行连续跳跃
MountData.heightBoost = 20; // 坐骑与地面之间的高度
MountData.fallDamage = 0f; // 从高处跌落时受到的伤害倍率
MountData.runSpeed = 11f; // 坐骑的奔跑速度
MountData.dashSpeed = 8f; // 冲刺速度
MountData.flightTimeMax = 0; // 最大飞行时间,0表示不能飞行
// 设置疲劳最大值为0,意味着骑乘时不会产生疲劳
MountData.fatigueMax = 0;
// 关联坐骑的Buff,即骑乘时玩家获得的状态效果
MountData.buff = ModContent.BuffType<Buffs.FenglopeMountBuff>();
// 动画帧数和玩家偏移量设置
MountData.totalFrames = 5; // 总共的动画帧数,取决于你自己的贴图
MountData.playerYOffsets = Enumerable.Repeat(20, MountData.totalFrames).ToArray(); // 玩家相对于坐骑的Y轴偏移量数组,用于微调玩家在坐骑贴图的位置
MountData.xOffset = 20; // 玩家相对于坐骑的X轴偏移量,用于微调玩家在坐骑贴图上的位置
MountData.yOffset = -12; // 玩家相对于坐骑的Y轴偏移量,用于微调玩家在坐骑贴图上的位置
MountData.playerHeadOffset = 22; // 玩家头部相对于坐骑的偏移量,用于微调玩家在坐骑贴图上的位置
MountData.bodyFrame = 3; // 玩家身体在坐骑上的帧号
// 不同状态下的动画设置
// 站立
MountData.standingFrameCount = 0;
MountData.standingFrameDelay = 12;
MountData.standingFrameStart = 0;
// 奔跑
MountData.runningFrameCount = 4;
MountData.runningFrameDelay = 120;
MountData.runningFrameStart = 1;
// 飞行
MountData.flyingFrameCount = 0;
MountData.flyingFrameDelay = 0;
MountData.flyingFrameStart = 2;
// 空中
MountData.inAirFrameCount = 1;
MountData.inAirFrameDelay = 12;
MountData.inAirFrameStart = 2;
// 闲置
MountData.idleFrameCount = 4;
MountData.idleFrameDelay = 12;
MountData.idleFrameStart = 0;
MountData.idleFrameLoop = true;
// 游泳
MountData.swimFrameCount = MountData.inAirFrameCount;
MountData.swimFrameDelay = MountData.inAirFrameDelay;
MountData.swimFrameStart = MountData.inAirFrameStart;
}
} - 直接叫上一个好兄弟当工具人,去游戏里简单录一段云海鹿的跑步动画,然后自己截图扣下来
- 整个Mod开发耗时最久的就是抠图,哈哈哈哈,一张一张扣完之后,下载保存到本地,然后我简单写了个合成脚本,把多张图垂直排列合并,并缩放,代码目录下按你的顺序存放1.png~5.png即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46from PIL import Image
def pixelate(image_path, block_size):
img = Image.open(image_path)
w, h = img.size
img_small = img.resize((w // block_size, h // block_size), resample=Image.NEAREST)
result = img_small.resize(img.size, Image.NEAREST)
return result
def scale_image(image, scale_factor):
# 获取当前图片的尺寸
width, height = image.size
# 计算新的尺寸
new_width = width // scale_factor
new_height = height // scale_factor
# 返回缩放后的图片
return image.resize((new_width, new_height), Image.ANTIALIAS)
# 保存处理后的图片对象和尺寸
processed_images = []
total_width = 0
total_height = 0
scale_factor = 4 # 缩放比例
# 处理图片并计算总高度和宽度
for i in range(5):
pixelated_image = pixelate(f'{i + 1}.png', 10)
scaled_image = scale_image(pixelated_image, scale_factor)
processed_images.append(scaled_image)
total_width = max(total_width, scaled_image.width)
total_height += scaled_image.height
# 创建一张新图片,背景颜色为透明
new_image = Image.new('RGBA', (total_width, total_height), color=(0, 0, 0, 0))
# 将每张处理后的图片粘贴到新图片上
y_offset = 0
for img in processed_images:
new_image.paste(img, (0, y_offset), img)
y_offset += img.height
# 保存新图片
new_image.save('combined_pixelated.png', 'PNG') - 最终的效果
制作坐骑BUFF
- 玩家使用坐骑,其实是对自身施加一个buff,所以我们还要编写一个云海鹿的坐骑BUFF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17using PolWorldMounts.Content.Mounts; // 引入模组中 Mounts 目录下的命名空间
using Terraria; // 引入游戏主引擎的命名空间
using Terraria.ModLoader; // 引入模组加载器的命名空间
namespace PolWorldMounts.Content.Buffs { // 定义模组 Buffs 目录下的命名空间
public class FenglopeMountBuff : ModBuff { // 定义一个继承自 ModBuff 的公共类 FenglopeMountBuff
public override void SetStaticDefaults() { // 重写父类的方法 SetStaticDefaults
Main.buffNoTimeDisplay[Type] = true; // 设置此Buff不会显示持续时间
Main.buffNoSave[Type] = true; // 设置此Buff不会被保存,即在死亡或退出世界后消失
}
public override void Update(Player player, ref int buffIndex) { // 重写父类的方法 Update,当Buff应用到玩家身上时被调用
player.mount.SetMount(ModContent.MountType<FenglopeMount>(), player); // 设置玩家的坐骑为 FenglopeMount
player.buffTime[buffIndex] = 10; // 设置Buff的持续时间为10帧,实际作用是持续刷新,因为会不断被重新应用
}
}
} - 简单制作一个Buff图标,同样是使用百度抠图,随后将图片下载到本地,随后像素化,并且指定图片尺寸为32x32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15from PIL import Image
def pixelate(image_path, output_size):
img = Image.open(image_path)
img_small = img.resize(output_size, resample=Image.NEAREST)
block_size_w = img.width // output_size[0]
block_size_h = img.height // output_size[1]
img_pixelated = img_small.resize((img.width // block_size_w, img.height // block_size_h), resample=Image.NEAREST)
result = img_pixelated.resize(output_size, Image.NEAREST)
return result
pixelated_image = pixelate('云海鹿.png', (32, 32))
pixelated_image.save('pixelated_image_云海鹿.png')
泰拉瑞亚 启动!
- 重新生成并加载Mod,我们的云海鹿就已经可以使用了,只需要一块泥土进行制作,不需要任何合成台
未完待续
- 博主是老鸽子了,代码敲完了没空更教程,后续还加了冲刺、不再需要云瓶进行二段跳、增加了草莽猪坐骑,冲刺会撞断沿途的树木,增加了空涡龙坐骑,并且有对应的飞行粒子特效(粉色、尽量还原原版)
- 后续的计划会增加帕鲁专属的工作台,以及优化合成配方,增加更多的坐骑,增加更多的玩法,敬请期待!
评论