diff --git a/prefab/Cursor.tscn b/prefab/Cursor.tscn index 3c2fb6e..1202607 100644 --- a/prefab/Cursor.tscn +++ b/prefab/Cursor.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=2] [ext_resource path="res://resource/sprite/effect/Cursor.png" type="Texture" id=1] -[ext_resource path="res://src/Cursor.cs" type="Script" id=2] +[ext_resource path="res://src/effect/Cursor.cs" type="Script" id=2] [node name="Cursor" type="Node2D"] script = ExtResource( 2 ) diff --git a/prefab/Gun.tscn b/prefab/Gun.tscn index c04ae84..449a8b3 100644 --- a/prefab/Gun.tscn +++ b/prefab/Gun.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=4 format=2] [ext_resource path="res://resource/sprite/gun/gun1.png" type="Texture" id=1] -[ext_resource path="res://src/weapon/gun/OrdinaryGun.cs" type="Script" id=2] +[ext_resource path="res://src/gun/OrdinaryGun.cs" type="Script" id=2] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 9.5, 3.5 ) diff --git a/prefab/bullet/Bullet.tscn b/prefab/bullet/Bullet.tscn index eb6d9ff..21eba41 100644 --- a/prefab/bullet/Bullet.tscn +++ b/prefab/bullet/Bullet.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=5 format=2] -[ext_resource path="res://src/weapon/bullet/HighSpeedBullet.cs" type="Script" id=1] +[ext_resource path="res://src/bullet/HighSpeedBullet.cs" type="Script" id=1] [ext_resource path="res://prefab/effect/Hit.tscn" type="PackedScene" id=2] [sub_resource type="Curve" id=1] diff --git a/src/Cursor.cs b/src/Cursor.cs deleted file mode 100644 index 4450f54..0000000 --- a/src/Cursor.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Godot; - -/// -/// 鼠标指针 -/// -public class Cursor : Node2D -{ - - public Gun TargetGun = null; - - private Sprite lt; - private Sprite lb; - private Sprite rt; - private Sprite rb; - - public override void _Ready() - { - lt = GetNode("LT"); - lb = GetNode("LB"); - rt = GetNode("RT"); - rb = GetNode("RB"); - } - - public override void _Process(float delta) - { - if (TargetGun != null) - { - SetScope(TargetGun.CurrScatteringRange); - } - else - { - SetScope(0); - } - SetCursorPos(); - } - - /// - /// 设置光标半径范围 - /// - private void SetScope(float scope) - { - if (TargetGun != null) - { - var len = GlobalPosition.DistanceTo(TargetGun.GlobalPosition); - if (TargetGun.Attribute != null) - { - len = Mathf.Max(0, len - TargetGun.Attribute.FirePosition.x); - } - scope = len / GameConfig.ScatteringDistance * scope; - } - lt.Position = new Vector2(-scope, -scope); - lb.Position = new Vector2(-scope, scope); - rt.Position = new Vector2(scope, -scope); - rb.Position = new Vector2(scope, scope); - } - - private void SetCursorPos() - { - Position = GetGlobalMousePosition(); - } -} \ No newline at end of file diff --git a/src/bullet/Bullet.cs b/src/bullet/Bullet.cs new file mode 100644 index 0000000..a56e98d --- /dev/null +++ b/src/bullet/Bullet.cs @@ -0,0 +1,27 @@ +using Godot; + +/// +/// 子弹 +/// +public abstract class Bullet : Node2D +{ + /// + /// 攻击目标阵营 + /// + public CampEnum TargetCamp { get; private set; } + /// + /// 发射该子弹的武器 + /// + public Gun Gun { get; private set; } + /// + /// 发射该子弹的物体对象 + /// + public Node2D Master { get; private set; } + + public void Init(CampEnum target, Gun gun, Node2D master) + { + TargetCamp = target; + Gun = gun; + Master = master; + } +} \ No newline at end of file diff --git a/src/bullet/HighSpeedBullet.cs b/src/bullet/HighSpeedBullet.cs new file mode 100644 index 0000000..e71eeba --- /dev/null +++ b/src/bullet/HighSpeedBullet.cs @@ -0,0 +1,56 @@ +using Godot; + +/// +/// 高速子弹 +/// +public class HighSpeedBullet : Bullet +{ + [Export] public PackedScene Hit; + //射线检测节点 + private RayCast2D RayCast2D; + //最大飞行距离 + private float Distance; + private Line2D Line; + private float ca = 1; + + public void InitData(float distance, Color color) + { + RayCast2D = GetNode("RayCast2D"); + Line = GetNode("Line"); + Distance = distance; + Modulate = color; + + Vector2 targetPos = new Vector2(distance, 0); + + // + RayCast2D.CastTo = targetPos; + RayCast2D.ForceRaycastUpdate(); + if (RayCast2D.IsColliding()) { //碰到物体 + Vector2 collPosition = RayCast2D.GetCollisionPoint(); + Node2D hit = Hit.Instance(); + hit.RotationDegrees = MathUtils.RandRangeInt(0, 360); + hit.GlobalPosition = collPosition; + GetTree().CurrentScene.AddChild(hit); + //划线的点坐标 + Line.SetPointPosition(1, new Vector2(Line.GlobalPosition.DistanceTo(collPosition), 0)); + } + else + { + //划线的点坐标 + Line.SetPointPosition(1, targetPos); + } + RayCast2D.Enabled = false; + } + + public override void _Process(float delta) + { + ca -= 12 * delta; + if (ca <= 0) { + QueueFree(); + return; + } + Color c = Modulate; + c.a = ca; + Modulate = c; + } +} \ No newline at end of file diff --git a/src/effect/Cursor.cs b/src/effect/Cursor.cs new file mode 100644 index 0000000..4450f54 --- /dev/null +++ b/src/effect/Cursor.cs @@ -0,0 +1,61 @@ +using Godot; + +/// +/// 鼠标指针 +/// +public class Cursor : Node2D +{ + + public Gun TargetGun = null; + + private Sprite lt; + private Sprite lb; + private Sprite rt; + private Sprite rb; + + public override void _Ready() + { + lt = GetNode("LT"); + lb = GetNode("LB"); + rt = GetNode("RT"); + rb = GetNode("RB"); + } + + public override void _Process(float delta) + { + if (TargetGun != null) + { + SetScope(TargetGun.CurrScatteringRange); + } + else + { + SetScope(0); + } + SetCursorPos(); + } + + /// + /// 设置光标半径范围 + /// + private void SetScope(float scope) + { + if (TargetGun != null) + { + var len = GlobalPosition.DistanceTo(TargetGun.GlobalPosition); + if (TargetGun.Attribute != null) + { + len = Mathf.Max(0, len - TargetGun.Attribute.FirePosition.x); + } + scope = len / GameConfig.ScatteringDistance * scope; + } + lt.Position = new Vector2(-scope, -scope); + lb.Position = new Vector2(-scope, scope); + rt.Position = new Vector2(scope, -scope); + rb.Position = new Vector2(scope, scope); + } + + private void SetCursorPos() + { + Position = GetGlobalMousePosition(); + } +} \ No newline at end of file diff --git a/src/gun/Gun.cs b/src/gun/Gun.cs new file mode 100644 index 0000000..f32823c --- /dev/null +++ b/src/gun/Gun.cs @@ -0,0 +1,304 @@ +using Godot; +using System; + +/// +/// 枪的基类 +/// +public abstract class Gun : Node2D +{ + /// + /// 开火回调事件 + /// + public event Action FireEvent; + + /// + /// 属性数据 + /// + public GunAttribute Attribute + { + get + { + if (_attribute == null) + { + throw new Exception("请先调用Init来初始化枪的属性"); + } + return _attribute; + } + private set => _attribute = value; + } + private GunAttribute _attribute; + + /// + /// 枪的图片 + /// + public Sprite GunSprite { get; private set; } + + /// + /// 枪攻击的目标阵营 + /// + public CampEnum TargetCamp { get; set; } + /// + /// 枪管的开火点 + /// + public Position2D FirePoint { get; private set; } + /// + /// 枪管的原点 + /// + public Position2D OriginPoint { get; private set; } + /// + /// 枪的当前散射半径 + /// + public float CurrScatteringRange { get; private set; } = 0; + + //是否按下 + private bool triggerFlag = false; + //扳机计时器 + private float triggerTimer = 0; + //开火前延时时间 + private float delayedTime = 0; + //开火间隙时间 + private float fireInterval = 0; + //开火枪口角度 + private float fireAngle = 0; + //攻击冷却计时 + private float attackTimer = 0; + //攻击状态 + private bool attackFlag = false; + //按下的时间 + private float downTimer = 0; + //松开的时间 + private float upTimer = 0; + //连发次数 + private float continuousCount = 0; + private bool continuousShootFlag = false; + + public override void _EnterTree() + { + GunSprite = GetNode("GunSprite"); + FirePoint = GetNode("FirePoint"); + OriginPoint = GetNode("OriginPoint"); + } + + public override void _Process(float delta) + { + if (triggerFlag) + { + if (upTimer > 0) //第一帧按下扳机 + { + upTimer = 0; + DownTrigger(); + } + downTimer += delta; + } + else + { + if (downTimer > 0) //第一帧松开扳机 + { + downTimer = 0; + UpTriggern(); + } + upTimer += delta; + } + + // 攻击的计时器 + if (attackTimer > 0) + { + attackTimer -= delta; + if (attackTimer < 0) + { + delayedTime += attackTimer; + attackTimer = 0; + } + } + else if (delayedTime > 0) //攻击延时 + { + delayedTime -= delta; + if (attackTimer < 0) + { + delayedTime = 0; + } + } + + //连发判断 + if (continuousCount > 0 && delayedTime <= 0 && attackTimer <= 0) + { + TriggernFire(); + } + + if (!attackFlag && attackTimer <= 0) + { + CurrScatteringRange = Mathf.Max(CurrScatteringRange - Attribute.ScatteringRangeBackSpeed * delta, Attribute.StartScatteringRange); + } + triggerTimer = triggerTimer > 0 ? triggerTimer - delta : 0; + triggerFlag = false; + attackFlag = false; + + //枪身回归 + Position = Position.MoveToward(Vector2.Zero, 35 * delta); + if (fireInterval == 0) + { + RotationDegrees = 0; + } + else + { + RotationDegrees = Mathf.Lerp(0, fireAngle, attackTimer / fireInterval); + } + } + + public void Init(GunAttribute attribute) + { + if (_attribute != null) + { + throw new Exception("当前武器已经初始化过了!"); + } + + Attribute = attribute; + //更新图片 + var texture = ResourceLoader.Load(attribute.Sprite); + GunSprite.Texture = texture; + //开火位置 + FirePoint.Position = new Vector2(attribute.FirePosition.x, -attribute.FirePosition.y); + OriginPoint.Position = new Vector2(0, -attribute.FirePosition.y); + //握把位置 + GunSprite.Position = attribute.HoldPosition; + + Init(); + } + + /// + /// 扳机函数, 调用即视为扣动扳机 + /// + public void Trigger() + { + //是否第一帧按下 + var justDown = downTimer == 0; + //是否能发射 + var flag = false; + if (continuousCount <= 0) //不能处于连发状态下 + { + if (Attribute.ContinuousShoot) //自动射击 + { + if (triggerTimer > 0) + { + if (continuousShootFlag) + { + flag = true; + } + } + else + { + flag = true; + if (delayedTime <= 0 && attackTimer <= 0) + { + continuousShootFlag = true; + } + } + } + else //半自动 + { + if (justDown && triggerTimer <= 0) + { + flag = true; + } + } + } + + if (flag) + { + if (justDown) + { + //开火前延时 + delayedTime = Attribute.DelayedTime; + //扳机按下间隔 + triggerTimer = Attribute.TriggerInterval; + //连发数量 + if (!Attribute.ContinuousShoot) + { + continuousCount = MathUtils.RandRangeInt(Attribute.MinContinuousCount, Attribute.MaxContinuousCount); + } + } + if (delayedTime <= 0 && attackTimer <= 0) + { + TriggernFire(); + } + attackFlag = true; + } + triggerFlag = true; + } + + /// + /// 刚按下扳机 + /// + private void DownTrigger() + { + + } + + /// + /// 刚松开扳机 + /// + private void UpTriggern() + { + continuousShootFlag = false; + if (delayedTime > 0) + { + continuousCount = 0; + } + } + + /// + /// 触发开火 + /// + private void TriggernFire() + { + continuousCount = continuousCount > 0 ? continuousCount - 1 : 0; + fireInterval = 60 / Attribute.StartFiringSpeed; + attackTimer += fireInterval; + + //触发开火函数 + Fire(); + + //开火发射的子弹数量 + var bulletCount = MathUtils.RandRangeInt(Attribute.MaxFireBulletCount, Attribute.MinFireBulletCount); + //枪口角度 + var angle = new Vector2(GameConfig.ScatteringDistance, CurrScatteringRange).Angle(); + + //创建子弹 + for (int i = 0; i < bulletCount; i++) + { + //先算枪口方向 + Rotation = (float)GD.RandRange(-angle, angle); + //发射子弹 + ShootBullet(); + } + + //当前的散射半径 + CurrScatteringRange = Mathf.Min(CurrScatteringRange + Attribute.ScatteringRangeAddValue, Attribute.FinalScatteringRange); + //枪的旋转角度 + RotationDegrees -= Attribute.UpliftAngle; + fireAngle = RotationDegrees; + //枪身位置 + Position = new Vector2(Mathf.Max(-Attribute.MaxBacklash, Position.x - MathUtils.RandRange(Attribute.MinBacklash, Attribute.MaxBacklash)), Position.y); + + if (FireEvent != null) + { + FireEvent(this); + } + } + + /// + /// 初始化时调用 + /// + protected abstract void Init(); + + /// + /// 单次开火时调用的函数 + /// + protected abstract void Fire(); + + /// + /// 发射子弹时调用的函数, 每发射一枚子弹调用一次, + /// 如果做霰弹枪效果, 一次开火发射5枚子弹, 则该函数调用5次 + /// + protected abstract void ShootBullet(); +} \ No newline at end of file diff --git a/src/gun/GunAttribute.cs b/src/gun/GunAttribute.cs new file mode 100644 index 0000000..aaeab64 --- /dev/null +++ b/src/gun/GunAttribute.cs @@ -0,0 +1,117 @@ +using Godot; + +/// +/// 枪上的属性 +/// +public class GunAttribute +{ + /// + /// 枪的图片 + /// + public string Sprite = "res://resource/sprite/gun/gun1.png"; + /// + /// 是否连续发射, 如果为false, 则每次发射都需要扣动扳机 + /// + public bool ContinuousShoot = true; + /// + /// 是否为松发开火, 也就是松开扳机才开火, 若要启用该属性, 必须将 'ContinuousShoot' 设置为 false + /// + public bool LooseShoot = false; + /// + /// 连续发射最小次数, 仅当ContinuousShoot为false时生效 + /// + public int MinContinuousCount = 3; + /// + /// 连续发射最大次数, 仅当ContinuousShoot为false时生效 + /// + public int MaxContinuousCount = 3; + /// + /// 按下一次扳机后需要多长时间才能再次按下 + /// + public float TriggerInterval = 0; + /// + /// 初始射速, 初始每秒分钟能发射多少发子弹 + /// + public float StartFiringSpeed = 300; + /// + /// 最终射速, 最终每秒分钟能发射多少发子弹 + /// + public float FinalFiringSpeed = 300; + /// + /// 按下扳机并开火后射速增加速率 + /// + public float FiringSpeedAddSpeed = 2; + /// + /// 松开扳机后射速消散速率 + /// + public float FiringSpeedBackSpeed = 10; + /// + /// 单次开火发射子弹最小数量 + /// + public int MinFireBulletCount = 1; + /// + /// 单次开火发射子弹最大数量 + /// + public int MaxFireBulletCount = 1; + /// + /// 开火前延时 + /// + public float DelayedTime = 0f; + /// + /// 初始散射半径 + /// + public float StartScatteringRange = 0; + /// + /// 最终散射半径 + /// + public float FinalScatteringRange = 20; + /// + /// 每次发射后散射增加值 + /// + public float ScatteringRangeAddValue = 2; + /// + /// 松开扳机后散射销退速率 + /// + public float ScatteringRangeBackSpeed = 10; + /// + /// 子弹飞行最大距离 + /// + public float MaxDistance = 600; + /// + /// 子弹飞行最小距离 + /// + public float MinDistance = 800; + /// + /// 开火位置 + /// + public Vector2 FirePosition = new Vector2(11, 0); + /// + /// 握把位置 + /// + public Vector2 HoldPosition = new Vector2(4, -3); + /// + /// 重量 + /// + public float Weight = 11; + /// + /// 最大后坐力 (仅用于开火后枪身抖动) + /// + public float MaxBacklash = 4; + /// + /// 最小后坐力 (仅用于开火后枪身抖动) + /// + public float MinBacklash = 2; + /// + /// 开火后枪口上抬角度 + /// + public float UpliftAngle = 30; + /// + /// 开火后枪口角度恢复速度倍数 + /// + public float UpliftAngleRestore = 1; + + public GunAttribute() + { + + } +} \ No newline at end of file diff --git a/src/gun/OrdinaryGun.cs b/src/gun/OrdinaryGun.cs new file mode 100644 index 0000000..047da0c --- /dev/null +++ b/src/gun/OrdinaryGun.cs @@ -0,0 +1,44 @@ +using Godot; + +/// +/// 普通的枪 +/// +public class OrdinaryGun : Gun +{ + //子弹 + private PackedScene bulletPacked; + + + protected override void Init() + { + //子弹 + bulletPacked = ResourceLoader.Load("res://prefab/bullet/Bullet.tscn"); + } + + protected override void Fire() + { + + } + + protected override void ShootBullet() + { + //创建子弹 + var bullet = CreateBullet(bulletPacked); + //位置 + bullet.GlobalPosition = FirePoint.GlobalPosition; + //角度 + bullet.Rotation = (FirePoint.GlobalPosition - OriginPoint.GlobalPosition).Angle(); + GetTree().CurrentScene.AddChild(bullet); + //飞行距离 + var distance = MathUtils.RandRange(Attribute.MinDistance, Attribute.MaxDistance); + //初始化子弹数据 + bullet.InitData(distance, Colors.White); + } + + protected T CreateBullet(PackedScene bulletPack) where T : Bullet + { + T bullet = bulletPack.Instance(); + bullet.Init(TargetCamp, this, null); + return bullet; + } +} \ No newline at end of file diff --git a/src/weapon/bullet/Bullet.cs b/src/weapon/bullet/Bullet.cs deleted file mode 100644 index a56e98d..0000000 --- a/src/weapon/bullet/Bullet.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Godot; - -/// -/// 子弹 -/// -public abstract class Bullet : Node2D -{ - /// - /// 攻击目标阵营 - /// - public CampEnum TargetCamp { get; private set; } - /// - /// 发射该子弹的武器 - /// - public Gun Gun { get; private set; } - /// - /// 发射该子弹的物体对象 - /// - public Node2D Master { get; private set; } - - public void Init(CampEnum target, Gun gun, Node2D master) - { - TargetCamp = target; - Gun = gun; - Master = master; - } -} \ No newline at end of file diff --git a/src/weapon/bullet/HighSpeedBullet.cs b/src/weapon/bullet/HighSpeedBullet.cs deleted file mode 100644 index e71eeba..0000000 --- a/src/weapon/bullet/HighSpeedBullet.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Godot; - -/// -/// 高速子弹 -/// -public class HighSpeedBullet : Bullet -{ - [Export] public PackedScene Hit; - //射线检测节点 - private RayCast2D RayCast2D; - //最大飞行距离 - private float Distance; - private Line2D Line; - private float ca = 1; - - public void InitData(float distance, Color color) - { - RayCast2D = GetNode("RayCast2D"); - Line = GetNode("Line"); - Distance = distance; - Modulate = color; - - Vector2 targetPos = new Vector2(distance, 0); - - // - RayCast2D.CastTo = targetPos; - RayCast2D.ForceRaycastUpdate(); - if (RayCast2D.IsColliding()) { //碰到物体 - Vector2 collPosition = RayCast2D.GetCollisionPoint(); - Node2D hit = Hit.Instance(); - hit.RotationDegrees = MathUtils.RandRangeInt(0, 360); - hit.GlobalPosition = collPosition; - GetTree().CurrentScene.AddChild(hit); - //划线的点坐标 - Line.SetPointPosition(1, new Vector2(Line.GlobalPosition.DistanceTo(collPosition), 0)); - } - else - { - //划线的点坐标 - Line.SetPointPosition(1, targetPos); - } - RayCast2D.Enabled = false; - } - - public override void _Process(float delta) - { - ca -= 12 * delta; - if (ca <= 0) { - QueueFree(); - return; - } - Color c = Modulate; - c.a = ca; - Modulate = c; - } -} \ No newline at end of file diff --git a/src/weapon/gun/Gun.cs b/src/weapon/gun/Gun.cs deleted file mode 100644 index f32823c..0000000 --- a/src/weapon/gun/Gun.cs +++ /dev/null @@ -1,304 +0,0 @@ -using Godot; -using System; - -/// -/// 枪的基类 -/// -public abstract class Gun : Node2D -{ - /// - /// 开火回调事件 - /// - public event Action FireEvent; - - /// - /// 属性数据 - /// - public GunAttribute Attribute - { - get - { - if (_attribute == null) - { - throw new Exception("请先调用Init来初始化枪的属性"); - } - return _attribute; - } - private set => _attribute = value; - } - private GunAttribute _attribute; - - /// - /// 枪的图片 - /// - public Sprite GunSprite { get; private set; } - - /// - /// 枪攻击的目标阵营 - /// - public CampEnum TargetCamp { get; set; } - /// - /// 枪管的开火点 - /// - public Position2D FirePoint { get; private set; } - /// - /// 枪管的原点 - /// - public Position2D OriginPoint { get; private set; } - /// - /// 枪的当前散射半径 - /// - public float CurrScatteringRange { get; private set; } = 0; - - //是否按下 - private bool triggerFlag = false; - //扳机计时器 - private float triggerTimer = 0; - //开火前延时时间 - private float delayedTime = 0; - //开火间隙时间 - private float fireInterval = 0; - //开火枪口角度 - private float fireAngle = 0; - //攻击冷却计时 - private float attackTimer = 0; - //攻击状态 - private bool attackFlag = false; - //按下的时间 - private float downTimer = 0; - //松开的时间 - private float upTimer = 0; - //连发次数 - private float continuousCount = 0; - private bool continuousShootFlag = false; - - public override void _EnterTree() - { - GunSprite = GetNode("GunSprite"); - FirePoint = GetNode("FirePoint"); - OriginPoint = GetNode("OriginPoint"); - } - - public override void _Process(float delta) - { - if (triggerFlag) - { - if (upTimer > 0) //第一帧按下扳机 - { - upTimer = 0; - DownTrigger(); - } - downTimer += delta; - } - else - { - if (downTimer > 0) //第一帧松开扳机 - { - downTimer = 0; - UpTriggern(); - } - upTimer += delta; - } - - // 攻击的计时器 - if (attackTimer > 0) - { - attackTimer -= delta; - if (attackTimer < 0) - { - delayedTime += attackTimer; - attackTimer = 0; - } - } - else if (delayedTime > 0) //攻击延时 - { - delayedTime -= delta; - if (attackTimer < 0) - { - delayedTime = 0; - } - } - - //连发判断 - if (continuousCount > 0 && delayedTime <= 0 && attackTimer <= 0) - { - TriggernFire(); - } - - if (!attackFlag && attackTimer <= 0) - { - CurrScatteringRange = Mathf.Max(CurrScatteringRange - Attribute.ScatteringRangeBackSpeed * delta, Attribute.StartScatteringRange); - } - triggerTimer = triggerTimer > 0 ? triggerTimer - delta : 0; - triggerFlag = false; - attackFlag = false; - - //枪身回归 - Position = Position.MoveToward(Vector2.Zero, 35 * delta); - if (fireInterval == 0) - { - RotationDegrees = 0; - } - else - { - RotationDegrees = Mathf.Lerp(0, fireAngle, attackTimer / fireInterval); - } - } - - public void Init(GunAttribute attribute) - { - if (_attribute != null) - { - throw new Exception("当前武器已经初始化过了!"); - } - - Attribute = attribute; - //更新图片 - var texture = ResourceLoader.Load(attribute.Sprite); - GunSprite.Texture = texture; - //开火位置 - FirePoint.Position = new Vector2(attribute.FirePosition.x, -attribute.FirePosition.y); - OriginPoint.Position = new Vector2(0, -attribute.FirePosition.y); - //握把位置 - GunSprite.Position = attribute.HoldPosition; - - Init(); - } - - /// - /// 扳机函数, 调用即视为扣动扳机 - /// - public void Trigger() - { - //是否第一帧按下 - var justDown = downTimer == 0; - //是否能发射 - var flag = false; - if (continuousCount <= 0) //不能处于连发状态下 - { - if (Attribute.ContinuousShoot) //自动射击 - { - if (triggerTimer > 0) - { - if (continuousShootFlag) - { - flag = true; - } - } - else - { - flag = true; - if (delayedTime <= 0 && attackTimer <= 0) - { - continuousShootFlag = true; - } - } - } - else //半自动 - { - if (justDown && triggerTimer <= 0) - { - flag = true; - } - } - } - - if (flag) - { - if (justDown) - { - //开火前延时 - delayedTime = Attribute.DelayedTime; - //扳机按下间隔 - triggerTimer = Attribute.TriggerInterval; - //连发数量 - if (!Attribute.ContinuousShoot) - { - continuousCount = MathUtils.RandRangeInt(Attribute.MinContinuousCount, Attribute.MaxContinuousCount); - } - } - if (delayedTime <= 0 && attackTimer <= 0) - { - TriggernFire(); - } - attackFlag = true; - } - triggerFlag = true; - } - - /// - /// 刚按下扳机 - /// - private void DownTrigger() - { - - } - - /// - /// 刚松开扳机 - /// - private void UpTriggern() - { - continuousShootFlag = false; - if (delayedTime > 0) - { - continuousCount = 0; - } - } - - /// - /// 触发开火 - /// - private void TriggernFire() - { - continuousCount = continuousCount > 0 ? continuousCount - 1 : 0; - fireInterval = 60 / Attribute.StartFiringSpeed; - attackTimer += fireInterval; - - //触发开火函数 - Fire(); - - //开火发射的子弹数量 - var bulletCount = MathUtils.RandRangeInt(Attribute.MaxFireBulletCount, Attribute.MinFireBulletCount); - //枪口角度 - var angle = new Vector2(GameConfig.ScatteringDistance, CurrScatteringRange).Angle(); - - //创建子弹 - for (int i = 0; i < bulletCount; i++) - { - //先算枪口方向 - Rotation = (float)GD.RandRange(-angle, angle); - //发射子弹 - ShootBullet(); - } - - //当前的散射半径 - CurrScatteringRange = Mathf.Min(CurrScatteringRange + Attribute.ScatteringRangeAddValue, Attribute.FinalScatteringRange); - //枪的旋转角度 - RotationDegrees -= Attribute.UpliftAngle; - fireAngle = RotationDegrees; - //枪身位置 - Position = new Vector2(Mathf.Max(-Attribute.MaxBacklash, Position.x - MathUtils.RandRange(Attribute.MinBacklash, Attribute.MaxBacklash)), Position.y); - - if (FireEvent != null) - { - FireEvent(this); - } - } - - /// - /// 初始化时调用 - /// - protected abstract void Init(); - - /// - /// 单次开火时调用的函数 - /// - protected abstract void Fire(); - - /// - /// 发射子弹时调用的函数, 每发射一枚子弹调用一次, - /// 如果做霰弹枪效果, 一次开火发射5枚子弹, 则该函数调用5次 - /// - protected abstract void ShootBullet(); -} \ No newline at end of file diff --git a/src/weapon/gun/GunAttribute.cs b/src/weapon/gun/GunAttribute.cs deleted file mode 100644 index aaeab64..0000000 --- a/src/weapon/gun/GunAttribute.cs +++ /dev/null @@ -1,117 +0,0 @@ -using Godot; - -/// -/// 枪上的属性 -/// -public class GunAttribute -{ - /// - /// 枪的图片 - /// - public string Sprite = "res://resource/sprite/gun/gun1.png"; - /// - /// 是否连续发射, 如果为false, 则每次发射都需要扣动扳机 - /// - public bool ContinuousShoot = true; - /// - /// 是否为松发开火, 也就是松开扳机才开火, 若要启用该属性, 必须将 'ContinuousShoot' 设置为 false - /// - public bool LooseShoot = false; - /// - /// 连续发射最小次数, 仅当ContinuousShoot为false时生效 - /// - public int MinContinuousCount = 3; - /// - /// 连续发射最大次数, 仅当ContinuousShoot为false时生效 - /// - public int MaxContinuousCount = 3; - /// - /// 按下一次扳机后需要多长时间才能再次按下 - /// - public float TriggerInterval = 0; - /// - /// 初始射速, 初始每秒分钟能发射多少发子弹 - /// - public float StartFiringSpeed = 300; - /// - /// 最终射速, 最终每秒分钟能发射多少发子弹 - /// - public float FinalFiringSpeed = 300; - /// - /// 按下扳机并开火后射速增加速率 - /// - public float FiringSpeedAddSpeed = 2; - /// - /// 松开扳机后射速消散速率 - /// - public float FiringSpeedBackSpeed = 10; - /// - /// 单次开火发射子弹最小数量 - /// - public int MinFireBulletCount = 1; - /// - /// 单次开火发射子弹最大数量 - /// - public int MaxFireBulletCount = 1; - /// - /// 开火前延时 - /// - public float DelayedTime = 0f; - /// - /// 初始散射半径 - /// - public float StartScatteringRange = 0; - /// - /// 最终散射半径 - /// - public float FinalScatteringRange = 20; - /// - /// 每次发射后散射增加值 - /// - public float ScatteringRangeAddValue = 2; - /// - /// 松开扳机后散射销退速率 - /// - public float ScatteringRangeBackSpeed = 10; - /// - /// 子弹飞行最大距离 - /// - public float MaxDistance = 600; - /// - /// 子弹飞行最小距离 - /// - public float MinDistance = 800; - /// - /// 开火位置 - /// - public Vector2 FirePosition = new Vector2(11, 0); - /// - /// 握把位置 - /// - public Vector2 HoldPosition = new Vector2(4, -3); - /// - /// 重量 - /// - public float Weight = 11; - /// - /// 最大后坐力 (仅用于开火后枪身抖动) - /// - public float MaxBacklash = 4; - /// - /// 最小后坐力 (仅用于开火后枪身抖动) - /// - public float MinBacklash = 2; - /// - /// 开火后枪口上抬角度 - /// - public float UpliftAngle = 30; - /// - /// 开火后枪口角度恢复速度倍数 - /// - public float UpliftAngleRestore = 1; - - public GunAttribute() - { - - } -} \ No newline at end of file diff --git a/src/weapon/gun/OrdinaryGun.cs b/src/weapon/gun/OrdinaryGun.cs deleted file mode 100644 index 047da0c..0000000 --- a/src/weapon/gun/OrdinaryGun.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Godot; - -/// -/// 普通的枪 -/// -public class OrdinaryGun : Gun -{ - //子弹 - private PackedScene bulletPacked; - - - protected override void Init() - { - //子弹 - bulletPacked = ResourceLoader.Load("res://prefab/bullet/Bullet.tscn"); - } - - protected override void Fire() - { - - } - - protected override void ShootBullet() - { - //创建子弹 - var bullet = CreateBullet(bulletPacked); - //位置 - bullet.GlobalPosition = FirePoint.GlobalPosition; - //角度 - bullet.Rotation = (FirePoint.GlobalPosition - OriginPoint.GlobalPosition).Angle(); - GetTree().CurrentScene.AddChild(bullet); - //飞行距离 - var distance = MathUtils.RandRange(Attribute.MinDistance, Attribute.MaxDistance); - //初始化子弹数据 - bullet.InitData(distance, Colors.White); - } - - protected T CreateBullet(PackedScene bulletPack) where T : Bullet - { - T bullet = bulletPack.Instance(); - bullet.Init(TargetCamp, this, null); - return bullet; - } -} \ No newline at end of file