diff --git a/DungeonShooting_Godot/prefab/role/Role.tscn b/DungeonShooting_Godot/prefab/role/Role.tscn index df672e5..b9a1558 100644 --- a/DungeonShooting_Godot/prefab/role/Role.tscn +++ b/DungeonShooting_Godot/prefab/role/Role.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=19 format=2] +[gd_scene load_steps=20 format=2] [ext_resource path="res://resource/materlal/Shadow.tres" type="Material" id=1] [ext_resource path="res://addons/dungeonShooting_plugin/ActivityObjectTemplate.cs" type="Script" id=2] [ext_resource path="res://resource/sprite/role/role1.png" type="Texture" id=3] +[ext_resource path="res://src/game/role/MountRotation.cs" type="Script" id=4] [sub_resource type="AtlasTexture" id=17] atlas = ExtResource( 3 ) @@ -91,7 +92,6 @@ position = Vector2( 0, -12 ) frames = SubResource( 6 ) animation = "idle" -frame = 2 playing = true [node name="Collision" type="CollisionShape2D" parent="."] @@ -118,3 +118,4 @@ [node name="MountPoint" type="Position2D" parent="."] position = Vector2( 2, -4 ) +script = ExtResource( 4 ) diff --git a/DungeonShooting_Godot/src/game/camera/GameCamera.cs b/DungeonShooting_Godot/src/game/camera/GameCamera.cs index 4b827de..e07aece 100644 --- a/DungeonShooting_Godot/src/game/camera/GameCamera.cs +++ b/DungeonShooting_Godot/src/game/camera/GameCamera.cs @@ -45,14 +45,12 @@ var player = GameApplication.Instance.Room.Player; var viewportContainer = GameApplication.Instance.ViewportContainer; - //var mousePos = InputManager.GetMousePosition(); var camPos = player.GlobalPosition; //var camPos = player.GlobalPosition.LinearInterpolate(mousePos, 0); //_camPos = camPos + _shakeOffset; _camPos = _camPos.LinearInterpolate(camPos, Mathf.Min(5 * delta, 1)) + _shakeOffset; SubPixelPosition = _camPos.Round() - _camPos; (viewportContainer.Material as ShaderMaterial)?.SetShaderParam("offset", SubPixelPosition); - //GlobalPosition = _camPos.Round(); GlobalPosition = _camPos.Round(); } diff --git a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs index 07bc0c1..b973dbe 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs @@ -165,7 +165,8 @@ /// 发射子弹时调用的函数, 每发射一枚子弹调用一次, /// 如果做霰弹武器效果, 一次开火发射5枚子弹, 则该函数调用5次 /// - protected abstract void OnShoot(); + /// 开火时枪口旋转角度 + protected abstract void OnShoot(float fireRotation); /// /// 当开始换弹时调用 @@ -433,22 +434,29 @@ var angle = new Vector2(GameConfig.ScatteringDistance, CurrScatteringRange).Angle(); //先算武器口方向 - var tempAngle = Mathf.Rad2Deg((float)GD.RandRange(-angle, angle)); - //创建子弹 - for (int i = 0; i < bulletCount; i++) - { - //发射子弹 - OnShoot(); + var tempRotation = (float)GD.RandRange(-angle, angle); + var tempAngle = Mathf.Rad2Deg(tempRotation); + + //开火时枪口角度 + var fireRotation = Mathf.Deg2Rad(Master.MountPoint.RealAngle) + tempRotation; + //创建子弹 + for (int i = 0; i < bulletCount; i++) + { + //发射子弹 + OnShoot(fireRotation); } //当前的散射半径 - CurrScatteringRange = Mathf.Min(CurrScatteringRange + Attribute.ScatteringRangeAddValue, Attribute.FinalScatteringRange); + CurrScatteringRange = Mathf.Min(CurrScatteringRange + Attribute.ScatteringRangeAddValue, + Attribute.FinalScatteringRange); //武器的旋转角度 tempAngle -= Attribute.UpliftAngle; RotationDegrees = tempAngle; fireAngle = tempAngle; //武器身位置 - Position = new Vector2(Mathf.Max(-Attribute.MaxBacklash, Position.x - MathUtils.RandRange(Attribute.MinBacklash, Attribute.MaxBacklash)), Position.y); + Position = new Vector2( + Mathf.Max(-Attribute.MaxBacklash, + Position.x - MathUtils.RandRange(Attribute.MinBacklash, Attribute.MaxBacklash)), Position.y); if (FireEvent != null) { @@ -676,6 +684,14 @@ } /// + /// 获取当前武器真实的旋转角度(弧度制), 由于武器旋转时加入了旋转吸附, 所以需要通过该函数来来知道当前武器的真实旋转角度 + /// + public float GetRealGlobalRotation() + { + return Mathf.Deg2Rad(Master.MountPoint.RealAngle) + Rotation; + } + + /// /// 触发扔掉武器操作 /// /// 触发扔掉该武器的的角色 diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs index 79bcce7..5573b04 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs @@ -109,10 +109,10 @@ GameCamera.Main.ProcessDirectionalShake(Vector2.Right.Rotated(GlobalRotation) * 1.5f); } - protected override void OnShoot() + protected override void OnShoot(float fireRotation) { //创建子弹 - CreateBullet(BulletPack, FirePoint.GlobalPosition, (FirePoint.GlobalPosition - OriginPoint.GlobalPosition).Angle()); + CreateBullet(BulletPack, FirePoint.GlobalPosition, fireRotation); } protected override void OnReload() diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs index e3190ef..e1908c8 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs @@ -74,12 +74,12 @@ GameCamera.Main.ProcessDirectionalShake(Vector2.Right.Rotated(GlobalRotation) * 1.5f); } - protected override void OnShoot() + protected override void OnShoot(float fireRotation) { for (int i = 0; i < 5; i++) { //创建子弹 - CreateBullet(BulletPack, FirePoint.GlobalPosition, (FirePoint.GlobalPosition - OriginPoint.GlobalPosition).Angle() + MathUtils.RandRange(-20 / 180f * Mathf.Pi, 20 / 180f * Mathf.Pi)); + CreateBullet(BulletPack, FirePoint.GlobalPosition, fireRotation + MathUtils.RandRange(-20 / 180f * Mathf.Pi, 20 / 180f * Mathf.Pi)); } } diff --git a/DungeonShooting_Godot/src/game/role/MountRotation.cs b/DungeonShooting_Godot/src/game/role/MountRotation.cs new file mode 100644 index 0000000..73059c9 --- /dev/null +++ b/DungeonShooting_Godot/src/game/role/MountRotation.cs @@ -0,0 +1,67 @@ + +using Godot; + +/// +/// 用于限定 Position2D 节点的旋转角度 +/// +public class MountRotation : Position2D +{ + /// + /// 所在的角色 + /// + public Role Master { get; set; } + + /// + /// 当前节点真实的旋转角度 + /// + public float RealAngle + { + get => _readAngle; + // set + // { + // + // } + } + + private float _readAngle = 0; + + /// + /// 设置看向的目标点 + /// + /// + public void SetLookAt(Vector2 target) + { + var myPos = GlobalPosition; + var angle = Mathf.Rad2Deg((target - myPos).Angle()); + + if (Master.Face == FaceDirection.Left) + { + if (angle < 0 && angle > -80) + { + angle = -80; + } + else if (angle >= 0 && angle < 80) + { + angle = 80; + } + } + else + { + angle = Mathf.Clamp(angle, -100, 100); + } + + _readAngle = angle; + + if (Master.GlobalPosition.x >= target.x) + { + angle = -angle; + } + + GlobalRotationDegrees = AdsorptionAngle(angle); + } + + private float AdsorptionAngle(float angle) + { + return ((int)angle / 5) * 5; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/role/Player.cs b/DungeonShooting_Godot/src/game/role/Player.cs index 3fdd3b7..11a9943 100644 --- a/DungeonShooting_Godot/src/game/role/Player.cs +++ b/DungeonShooting_Godot/src/game/role/Player.cs @@ -78,8 +78,6 @@ base._Process(delta); Vector2 mousePos = InputManager.GetMousePosition(); - //枪口跟随鼠标 - MountPoint.LookAt(mousePos); //脸的朝向 var gPos = GlobalPosition; if (mousePos.x > gPos.x && Face == FaceDirection.Left) @@ -90,6 +88,8 @@ { Face = FaceDirection.Left; } + //枪口跟随鼠标 + MountPoint.SetLookAt(mousePos); if (Input.IsActionJustPressed("exchange")) //切换武器 { diff --git a/DungeonShooting_Godot/src/game/role/Role.cs b/DungeonShooting_Godot/src/game/role/Role.cs index 8320680..0a20cdd 100644 --- a/DungeonShooting_Godot/src/game/role/Role.cs +++ b/DungeonShooting_Godot/src/game/role/Role.cs @@ -34,7 +34,7 @@ /// /// 武器挂载点 /// - public Position2D MountPoint { get; private set; } + public MountRotation MountPoint { get; private set; } /// /// 背后武器的挂载点 /// @@ -133,7 +133,8 @@ { base._Ready(); StartScele = Scale; - MountPoint = GetNode("MountPoint"); + MountPoint = GetNode("MountPoint"); + MountPoint.Master = this; BackMountPoint = GetNode("BackMountPoint"); if (OverrideTexture != null) {