前言

v0.7更新

  1. 为空涡龙增加了三个技能:烈焰风暴(Z键)、光束彗星(X键)、龙彗星(C键)。烈焰风暴会吸附周围的敌对NPC、龙彗星会沿鼠标方向发射、光束彗星的初始方向沿鼠标方向发射,随后自动追踪周围敌怪。
  2. 云海鹿和草莽猪的冲刺改为Z键。

v0.6更新

  1. 增加了空涡龙坐骑,合成配方:10个夜明锭 + 20个丝绸 + 5个蓝玉,需要帕鲁装置制作台
  2. 增加了帕鲁装置制作台,合成材料:30个木头 + 10个丝绸 + 10个蓝玉
  3. 修改了草莽猪和云海鹿的合成配方
  • 草莽猪:10个木头 + 10个石头 + 5个蓝玉 + 10个皮革 + 5个椎骨,单击右键进行冲刺,冲刺会摧毁沿途路上的普通树木(一些特殊树木如樱花树等除外)
  • 云海鹿:20个神圣锭 + 5个飞翔之魂 + 5个光明之魂 + 5个蓝玉,可以进行二段跳,单击右键进行冲刺

如何自定义坐骑

  • 原版Terraria里的坐骑,首先都要有一个召唤物。
  • 其次就是有一个buff图标
  • 最后就是坐骑本体

  • 所以首先我们要先来制作这个召唤物。那么第一步我们先来创建一个Mod项目吧。

制作召唤物

  • 召唤物的本质实际上就是一个Item,所以我们创建一个类,继承ModItem即可。
  • 在这个类中,我们来定义召唤物的一些属性,以及合成材料
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
using PolWorldMounts.Content.Mounts;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace PolWorldMounts.Content.Items.Mounts
{
public class FenglopeMountItem : ModItem
{
public override void SetDefaults() {
Item.width = 20;
Item.height = 30;
Item.useTime = 20;
Item.useAnimation = 20;
Item.useStyle = ItemUseStyleID.Swing;
Item.value = Item.sellPrice(gold: 3);
Item.rare = ItemRarityID.Green;
Item.UseSound = SoundID.Item79;
Item.noMelee = true;
Item.mountType = ModContent.MountType<FenglopeMount>(); // 这个是调用我们自定义的坐骑
}

// 这里简单用一个泥土合成,实际上可以改成10个木材、10个石头、5个蓝宝石来进行合成,这样的合成配方和帕鲁中类似
public override void AddRecipes() {
Recipe recipe = CreateRecipe();
recipe.AddIngredient(ItemID.DirtBlock, 1);
recipe.Register();
}
}
}
  • 物品制作完毕后,我们还需要制作贴图,这里我就以帕鲁球为例制作贴图了。画风最好是符合泰拉瑞亚的像素风,这样看起来比较舒服。
  • 那我们直接启动幻兽帕鲁,进游戏截一张帕鲁球的图
  • 拿到图肯定不能直接用,我们首先要扣掉背景,随后转为像素风,调整尺寸为32*32。扣背景我这里直接用的百度AI图片助手,扣好了之后下载到本地,我们来进一步处理像素风
  • 像素风的处理,我这里直接用的Python的PIL库来进行处理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from 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
    58
    public 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
    46
    from 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
    17
    using 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
    15
    from 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,我们的云海鹿就已经可以使用了,只需要一块泥土进行制作,不需要任何合成台

未完待续

  • 博主是老鸽子了,代码敲完了没空更教程,后续还加了冲刺、不再需要云瓶进行二段跳、增加了草莽猪坐骑,冲刺会撞断沿途的树木,增加了空涡龙坐骑,并且有对应的飞行粒子特效(粉色、尽量还原原版)
  • 后续的计划会增加帕鲁专属的工作台,以及优化合成配方,增加更多的坐骑,增加更多的玩法,敬请期待!