跳至正文

从零开始的简单坐骑

大家好,我叫Korate,也有人叫我阿K,最近在写的人物里有坐骑,但发现好像教程里没有相关的资料,于是自己摸了源码后,来教大火简单写个坐骑。

开场白


众所周知,一个坐骑的实现往往需要三个代码,(好吧并不是众所周知)。分别为:

  1. 坐骑的召唤物,用来按r召唤或者直接使用召唤
  2. 坐骑本身
  3. 坐骑的buff,buff持续时坐骑就会一直存在,按r或者手动取消掉都会取消坐骑

首先最重要的自然是坐骑本身了,这里面有非常多乱七八糟的属性,第一次看可能会让你眼花。首先来看看example里写的坐骑是什么样的

虽然他写了一长串,但实际上有用的东西并不算多,因为下面一大列全都是有关运动时的帧图控制的,不过因为我的坐骑只有一帧所以我决定不ji asdjflasdjflkj

好吧简单说一下,首先mountData.yOffset是影响玩家的位置和坐骑的位置的偏差的,当你发现你的玩家贴图和坐骑贴图没有对准的时候,调试它来获得更好的效果。y是调试上下偏差,xOffset自然就是左右了。还有一个类似的属性 mountData.playerYOffsets,这个值决定了玩家贴图的位置在哪里,如果你的坐骑在运动的时候并不是平稳地,而是类似马或者什么奇怪的东西的话,每一帧玩家所在的位置并不一样,可以尝试通过调整这个值来调整更为准确的玩家贴图的Y轴位置。(注意这是一个数组,array[0]代表着第一帧图的玩家位置,以此类推修改其他帧的玩家位置)

控制跑步帧图的代码

后面一连串Frame相关的也都是调整帧图的,分别决定了在什么运动状态下使用什么帧图,具体作用看英文应该就能知道,比如跑步时,从第0帧开始,每个运动帧间隔12帧,一共有四帧,后面的也都是类似的意思。

坐骑常用的属性详解


好了接下来是用来控制坐骑行为的关键属性了,mountData.spawnDust是召唤坐骑时的粒子特效,没什么追求的可以随便写个数字。mountData.buff 是坐骑的buff,这个一会要写,用来获得一个“你正在骑着坐骑”的状态。

mountData.heightBoost = 20; 这个用来控制坐骑给玩家带来的额外高度,因此有些坐骑无法骑着进门。如果把这个设为0就是正常的玩家身高了

mountData.fallDamage = 0.5f; 骑着坐骑的时候的掉落伤害,0.5则为之前的一半

mountData.runSpeed = 11f;  坐骑的跑步时的最高速度,一般很快就会达到这个值,关于速度的部分还有一个点是,代码里的速度和游戏里的速度大概是1:5的关系。也就是说10速度,在游戏里大致会显示50(其实是51)

mountData.dashSpeed = 18f ; 如果写了这个值,则坐骑还会在达到跑步最大速度后开始冲刺,此为冲刺最大速度,注意要在地上跑才算正在冲刺且加速,在天上飞是不会加速度的 

mountData.flightTimeMax = 0;  如果你的坐骑可以飞行,则设置你的飞行时间,否则为0,飞行时间会随着飞行而一直减少(好像是废话)

mountData.fatigueMax = 0;   可以飞行的坐骑还会有疲劳值,疲劳值越高,则坐骑受到重力影响就越大,此值设置坐骑疲劳值的最大值。这个值会随着飞行时间逐渐增加,直到最大值,就算还有飞行时间,疲劳的坐骑也几乎飞不动,因为受重力影响太大了,具体表现为感觉像脚底裹了两斤水泥。

mountData.jumpHeight = 5;  坐骑的跳跃高度,越大则跳的越高

mountData.acceleration = 0.19f; 坐骑的加速度,越大则越容易达到最大速度,正常来说都是小数,大于1的加速度非常快

mountData.jumpSpeed = 4f; 跳跃速度

mountData.blockExtraJumps = false;这个值对于飞行或悬浮坐骑来说比较关键,禁用额外跳跃。设置true则为禁用。意思是这个坐骑无法额外跳跃,而悬浮坐骑则一次都不能跳,因为你只是在单纯的飞(比如ufo),具体看你想实现什么效果

mountData.totalFrames = 4; 坐骑的总帧数

mountData.constantJump = true; 连跳,如果为true的话按住空格就可以每次落地时自动跳跃

接下来是一个比较复杂的值

mountData.usesHover = true;此值为true是则表明该坐骑为一个悬浮坐骑。悬浮坐骑拥有的属性就很多了,首先他真的是悬浮的(蛤蛤)其次他的疲劳值不会随飞行时间增加,但是它仍然受到飞行时间的影响。飞行时间到了之后表现和其他坐骑不一样,他只会单纯的往你最后速度的方向飘,比如你在上升,他就会一直上升,当然你可以按“下”方向键来下降,也可以左右移动,但是不能再上升了,相当于飞行时间到了后,此坐骑的上升加速度始终为0.

最后是获取你坐骑的贴图,请你的贴图遵循以下命名格式

坐骑名_Front.png 或者 坐骑名_ Back.png

这两种名字的区别在于你的坐骑的贴图是出现在玩家的身前还是身后,举个好理解的例子就是ufo是出现在身前的,所以你看不见玩家的jio,因为被遮住了。 贴图名字的不同将导致下列代码获取的贴图不同,并且注意获取贴图时不能是服务器,因为服务器没有贴图数据会导致你的mod崩掉,下面为示例写法:

if (Main.netMode != NetmodeID.Server) {
	mountData.textureWidth = mountData.backTexture.Width;
	mountData.textureHeight = mountData.backTexture.Height;
	//mountData.textureWidth = mountData.frontTexture.Width;
	//mountData.textureHeight = mountData.frontTexture.Height;
}

在了解完这些后,其实使用usesHover来完成一个悬浮坐骑是不理想的。甚至是僵硬的,因为这是一个设置好的属性,你能修改的基本只有坐骑左右的移动速度。上下最高速度只有41,并且刹车的性能也不太灵敏,所以说这个值相当于一个悬浮坐骑的模板。

那么如何写一个自♂由的坐骑呢?

猴子看了都直呼懂了的简易自由悬浮坐骑


首先是理论部分,要做一个悬浮坐骑,

1要让它悬浮,很自然的便是取消掉重力对坐骑的影响。

2玩家自由控制上下移动的加速度,可以通过检测玩家按键来修改玩家的Y轴速度实现

2.EX你会发现你向上的速度可以是无限大,向下的速度却无论如何只能为50,这是因为泰拉限制了玩家自由落体的最高速度,因此我们需要修改这个值。

3坐骑需要学会自己刹车,你一定不希望即便不控制方向,坐骑依然在持续漂移

那么知道了理论,应该如何实现上述效果呢?在 UpdateEffects里面就可以自由的控制玩家属性。因为是保姆级教程,所以这里贴心的设置好了所有简易悬浮坐骑的需要的变量,一问三不知的小白光设置这些速度也能达到一个较好的效果

public override void UpdateEffects(Player Korate)
{
	float 下落最高速度 = 15f;
	float 向下加速度 = 0.5f;
	float 上升最高速度 = 15f;
	float 向上加速度 = 0.5f;
	Korate.gravity = 0; //玩家没有重力
	Korate.maxFallSpeed = 下落最高速度; //控制下落最大速度
	//当按下“下”方向键时,如果Y轴速度没有达到最大则持续增加Y轴速度
	if (Korate.controlDown && Korate.velocity.Y <= 下落最高速度)
	{
		//这个值一般为零点几,大于一的加速度就已经很夸张了
		Korate.velocity.Y += 向下加速度;
	}
	else if ((Korate.controlUp || Korate.controlJump) && Korate.velocity.Y >= -上升最高速度)
	{
		//当按下“上”方向键或者“跳跃”时,如果Y轴速度没有达到最高速度则持续增加
		Korate.velocity.Y -= 向上加速度; //同理
	}
	else if (Korate.velocity.Y > 1.5)Korate.velocity.Y--; //不控制方向时自动开始停车
	else if (Korate.velocity.Y < -1.5)Korate.velocity.Y++;
	else
	{
		Korate.velocity.Y = 0; //速度低于一定程度时则停止运动
		//player.fullRotation
	}
	Korate.fallStart = (int)(Korate.position.Y / 16f);//让你的坐骑拥有一个合理的坠落判定
}

你还可以在这个函数里面控制更多的东西,比如向左右的速度,以及控制玩家倾斜等等,就像ufo那样,使用 player.fullRotation 来控制整个坐骑包括玩家的角度,剩下的就请大家自由探索了

写完了坐骑,剩下的就非常简单了

召唤坐骑的物品以及buff


坐骑的物品没有任何特别的地方,宛如一个你已经写烂了的任何item,唯一不同的是

item.mountType = ModContent.MountType<你坐骑的类名>();

好的这就完成了,是不是非常简单呢

buff就更简单了,宛如一个你已经写烂了的任何buff,一般来说只需要加上

Main.buffNoTimeDisplay[Type] = true;//不显示buff时间

并且在update里设置坐骑

public override void Update(Player player, ref int buffIndex) {
	player.mount.SetMount(ModContent.MountType<坐骑.扫帚>(), player);
	player.buffTime[buffIndex] = 10;
    //player.mount._fatigue=0;//坐骑的疲劳值始终为0
    //player.mount._flyTime=320;//坐骑的飞行时间
}

如果你不是自己写的坐骑运动逻辑而依靠了原版的方法,也可以在这里重置他们的飞行时间和疲劳来达到无限飞行的效果

结束语


好的,寄,下次见

《从零开始的简单坐骑》有3个想法

    1. 据我所知是改不了大小的,我画师画的图用的都是一格大小的像素。如果你的人物是自己画的,就把人物图层和坐骑对比一下就好了,如果使用的原版人物那就随便找个盔甲的图,身体的第4帧加头的第四帧加腿的第7帧就是使用坐骑的动作了(用这个也可以自己修改自己的坐骑使用的人物动作哦mountData.bodyFrame),原版的坐骑大部分都是用的上述动作组合,你的坐骑图如果是前后都有图的(像三明治一样把玩家夹起来的)那还得多画一张图,读取帧图的时候back和front图都读取就行了,请务必确认前后的坐骑图是能对上的,画布大小和在画布中的位置都要一样。(所以我推荐你开多个图层进行对比,包括对比玩家的位置)

发表回复