《泰拉瑞亚》饰品制作方法( 五 )


②平面向量学霸或者痛恨三角函数 , 请前往条目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;

推荐阅读