diff --git a/DungeonShooting_Godot/prefab/role/Player.tscn b/DungeonShooting_Godot/prefab/role/Player.tscn index 25ff66f..bf3afb0 100644 --- a/DungeonShooting_Godot/prefab/role/Player.tscn +++ b/DungeonShooting_Godot/prefab/role/Player.tscn @@ -16,4 +16,4 @@ material = SubResource( 1 ) [node name="AnimatedSprite" parent="." index="2"] -frame = 3 +frame = 1 diff --git a/DungeonShooting_Godot/prefab/ui/Cursor.tscn b/DungeonShooting_Godot/prefab/ui/Cursor.tscn index c2d7b54..b3d50b8 100644 --- a/DungeonShooting_Godot/prefab/ui/Cursor.tscn +++ b/DungeonShooting_Godot/prefab/ui/Cursor.tscn @@ -1,7 +1,8 @@ [gd_scene load_steps=3 format=2] [ext_resource path="res://resource/sprite/ui/Cursor.png" type="Texture" id=1] -[ext_resource path="res://src/game/effect/Cursor.cs" type="Script" id=2] +[ext_resource path="res://src/game/ui/Cursor.cs" type="Script" id=2] + [node name="Cursor" type="Node2D"] diff --git a/DungeonShooting_Godot/src/framework/ActivityObject.cs b/DungeonShooting_Godot/src/framework/ActivityObject.cs index 5f5754b..19cd46b 100644 --- a/DungeonShooting_Godot/src/framework/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/ActivityObject.cs @@ -31,6 +31,7 @@ public bool IsDestroyed { get; private set; } private List> _components = new List>(); + private bool initShadow; public ActivityObject(string scenePath) { @@ -56,19 +57,37 @@ switch (body.Name) { case "AnimatedSprite": - AnimatedSprite = body as AnimatedSprite; + AnimatedSprite = (AnimatedSprite)body; break; case "ShadowSprite": - ShadowSprite = body as Sprite; + ShadowSprite = (Sprite)body; + ShadowSprite.Visible = false; + ShadowSprite.ZIndex = -5; break; case "Collision": - Collision = body as CollisionShape2D; + Collision = (CollisionShape2D)body; break; } } } /// + /// 显示阴影 + /// + /// 用于绘制的纹理 + public void ShowShadowSprite(Texture texture) + { + if (!initShadow) + { + initShadow = true; + ShadowSprite.Material = ResourceManager.ShadowMaterial; + } + + ShadowSprite.Texture = texture; + ShadowSprite.Visible = true; + } + + /// /// 返回是否能与其他ActivityObject互动 /// /// 触发者 @@ -85,6 +104,7 @@ if (!ContainsComponent(component)) { _components.Add(new KeyValuePair(component.GetType(), component)); + component._SetActivityObject(this); component.OnMount(); } } @@ -94,6 +114,7 @@ if (ContainsComponent(component)) { component.OnUnMount(); + component._SetActivityObject(null); } } @@ -127,7 +148,11 @@ var temp = arr[i].Value; if (temp != null && temp.ActivityObject == this && temp.Enable) { - temp._TriggerProcess(delta); + if (!temp.IsStart) + { + temp.Start(); + } + temp.Update(delta); } } } @@ -141,7 +166,11 @@ var temp = arr[i].Value; if (temp != null && temp.ActivityObject == this && temp.Enable) { - temp._TriggerPhysicsProcess(delta); + if (!temp.IsStart) + { + temp.Start(); + } + temp.PhysicsUpdate(delta); } } } diff --git a/DungeonShooting_Godot/src/framework/Component.cs b/DungeonShooting_Godot/src/framework/Component.cs index b1920c0..3e1d828 100644 --- a/DungeonShooting_Godot/src/framework/Component.cs +++ b/DungeonShooting_Godot/src/framework/Component.cs @@ -2,59 +2,94 @@ using Godot; /// -/// 组件基类 +/// 组件基类, 用于挂载到游戏物体上, 相比于原生 Node 更加轻量化, 可以大量添加组件 /// public abstract class Component : IProcess, IDestroy { + /// + /// 当前组件所挂载的游戏对象 + /// public ActivityObject ActivityObject { get; private set; } + /// + /// 当前组件所挂载的物体的坐标 + /// public Vector2 Position { get => ActivityObject.Position; set => ActivityObject.Position = value; } + /// + /// 当前组件所挂载物体的全局坐标 + /// public Vector2 GlobalPosition { get => ActivityObject.GlobalPosition; set => ActivityObject.GlobalPosition = value; } + /// + /// 当前组件是否显示 + /// public bool Visible { get => ActivityObject.Visible; set => ActivityObject.Visible = value; } + /// + /// 挂载物体的动画节点 + /// public AnimatedSprite AnimatedSprite => ActivityObject.AnimatedSprite; + /// + /// 挂载物体的阴影节点 + /// public Sprite ShadowSprite => ActivityObject.ShadowSprite; + /// + /// 挂载物体的碰撞器节点 + /// public CollisionShape2D Collision => ActivityObject.Collision; + /// + /// 是否启用当前组件 + /// public bool Enable { get; set; } = true; + /// + /// 是否被销毁 + /// public bool IsDestroyed { get; private set; } - private bool _isReady = false; + //是否调用过 start 函数 + internal bool IsStart = false; - public Component() + /// + /// 第一次调用 Update 或 PhysicsUpdate 之前调用 + /// + public virtual void Start() { } /// - /// 第一次调用 Process 或 PhysicsProcess 之前调用 + /// 如果启用了组件, 则每帧会调用一次 Update /// - public virtual void Ready() + /// + public virtual void Update(float delta) { } - public virtual void Process(float delta) + /// + /// 如果启用了组件, 则每物理帧会调用一次 PhysicsUpdate + /// + /// + public virtual void PhysicsUpdate(float delta) { } - public virtual void PhysicsProcess(float delta) - { - } - + /// + /// 当组件被销毁时调用 + /// public virtual void OnDestroy() { } @@ -76,7 +111,7 @@ /// /// 当组件销毁 /// - public new void Destroy() + public void Destroy() { if (IsDestroyed) { @@ -91,29 +126,7 @@ OnDestroy(); } - - internal void _TriggerProcess(float delta) - { - if (!_isReady) - { - _isReady = true; - Ready(); - } - - Process(delta); - } - - internal void _TriggerPhysicsProcess(float delta) - { - if (!_isReady) - { - _isReady = true; - Ready(); - } - - PhysicsProcess(delta); - } - + internal void _SetActivityObject(ActivityObject activityObject) { ActivityObject = activityObject; diff --git a/DungeonShooting_Godot/src/framework/IProcess.cs b/DungeonShooting_Godot/src/framework/IProcess.cs index 3e5777f..bc64da8 100644 --- a/DungeonShooting_Godot/src/framework/IProcess.cs +++ b/DungeonShooting_Godot/src/framework/IProcess.cs @@ -7,10 +7,10 @@ /// /// 普通帧每帧调用 /// - void Process(float delta); + void Update(float delta); /// /// 物理帧每帧调用 /// - void PhysicsProcess(float delta); + void PhysicsUpdate(float delta); } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/common/NodeExtend.cs b/DungeonShooting_Godot/src/game/common/NodeExtend.cs index 3a1ac71..3e72dda 100644 --- a/DungeonShooting_Godot/src/game/common/NodeExtend.cs +++ b/DungeonShooting_Godot/src/game/common/NodeExtend.cs @@ -47,9 +47,11 @@ /// 将一个节点扔到地上, 并设置显示的阴影, 函数返回根据该节点创建的 ThrowNode 节点 /// /// 显示的阴影sprite - public static ThrowNode PutDown(this Node2D node, Sprite shadowTarget) + public static ThrowNode PutDown(this ActivityObject node, Sprite shadowTarget) { - return StartThrow(node, Vector2.Zero, node.Position, 0, 0, 0, 0, 0, shadowTarget); + //return StartThrow(node, Vector2.Zero, node.Position, 0, 0, 0, 0, 0, shadowTarget); + RoomManager.Current.ObjectRoot.AddChild(node); + return null; } /// @@ -70,7 +72,7 @@ /// 触发扔掉武器操作 /// /// 触发扔掉该武器的的角色 - public static ThrowWeapon StartThrowWeapon(this Weapon weapon, Role master) + public static ThrowComponent StartThrowWeapon(this Weapon weapon, Role master) { if (master.Face == FaceDirection.Left) { @@ -82,9 +84,10 @@ var direction = master.GlobalRotationDegrees + MathUtils.RandRangeInt(-20, 20); var xf = 30; var yf = MathUtils.RandRangeInt(60, 120); - var rotate = MathUtils.RandRangeInt(-180, 180); + var rotate = MathUtils.RandRangeInt(-360, -360); weapon.Position = Vector2.Zero; - return weapon.StartThrow(new Vector2(20, 20), startPos, startHeight, direction, xf, yf, rotate, weapon.WeaponSprite); + return weapon.StartThrow(new Vector2(20, 20), startPos, startHeight, direction, xf, yf, rotate, weapon.WeaponSprite); + //return weapon.StartThrow(new Vector2(20, 20), startPos, startHeight, direction, xf, yf, rotate, weapon.WeaponSprite); } @@ -105,7 +108,7 @@ return null; } - public static T StartThrow(this ActivityObject node, Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, float ySpeed, float rotate) where T : ThrowComponent + public static T StartThrow(this ActivityObject node, Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, float ySpeed, float rotate, Sprite shadowSprite) where T : ThrowComponent { T throwNode = node.GetComponent(); if (throwNode == null) @@ -117,7 +120,7 @@ { throwNode.StopThrow(); } - throwNode.StartThrow(size, start, startHeight, direction, xSpeed, ySpeed, rotate); + throwNode.StartThrow(size, start, startHeight, direction, xSpeed, ySpeed, rotate, shadowSprite); return throwNode; } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/effect/Cursor.cs b/DungeonShooting_Godot/src/game/effect/Cursor.cs deleted file mode 100644 index a2d6dd4..0000000 --- a/DungeonShooting_Godot/src/game/effect/Cursor.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Godot; - -/// -/// 鼠标指针 -/// -public class Cursor : Node2D -{ - - 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) - { - var targetGun = RoomManager.Current?.Player?.Holster.ActiveWeapon; - if (targetGun != null) - { - SetScope(targetGun.CurrScatteringRange, targetGun); - } - else - { - SetScope(0, targetGun); - } - SetCursorPos(); - } - - /// - /// 设置光标半径范围 - /// - private void SetScope(float scope, Weapon targetGun) - { - 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/DungeonShooting_Godot/src/game/effect/ThrowNode.cs b/DungeonShooting_Godot/src/game/effect/ThrowNode.cs deleted file mode 100644 index a5ebe35..0000000 --- a/DungeonShooting_Godot/src/game/effect/ThrowNode.cs +++ /dev/null @@ -1,265 +0,0 @@ -using Godot; - -/// -/// 模拟抛出的物体, 使用时将对象挂载到该节点上即可 -/// -public class ThrowNode : KinematicBody2D -{ - /// - /// 是否已经结束 - /// - public bool IsOver { get; protected set; } = true; - /// - /// 物体大小 - /// - public Vector2 Size { get; protected set; } - /// - /// 起始坐标 - /// - public Vector2 StartPosition { get; protected set; } - /// - /// 移动方向, 0 - 360 - /// - public float Direction { get; protected set; } - /// - /// x速度, 也就是水平速度 - /// - public float XSpeed { get; protected set; } - /// - /// y轴速度, 也就是竖直速度 - /// - public float YSpeed { get; protected set; } - /// - /// 初始x轴组队 - /// - public float StartXSpeed { get; protected set; } - /// - /// 初始y轴速度 - /// - public float StartYSpeed { get; protected set; } - /// - /// 旋转速度 - /// - public float RotateSpeed { get; protected set; } - /// - /// 挂载的对象 - /// - public Node2D Mount { get; protected set; } - /// - /// 碰撞组件 - /// - public CollisionShape2D CollisionShape { get; protected set; } - /// - /// 绘制阴影的精灵 - /// - public Sprite ShadowSprite { get; protected set; } - - protected Sprite ShadowTarget { get; set; } - - private bool inversionX = false; - - public ThrowNode() - { - Name = "ThrowNode"; - } - - public override void _Ready() - { - //只与墙壁碰撞 - CollisionMask = 1; - CollisionLayer = 0; - //创建碰撞器 - if (Size != Vector2.Zero) - { - CollisionShape = new CollisionShape2D(); - CollisionShape.Name = "Collision"; - var shape = new RectangleShape2D(); - shape.Extents = Size * 0.5f; - CollisionShape.Shape = shape; - AddChild(CollisionShape); - } - } - - /// - /// 初始化该抛物线对象的基础数据 - /// - /// 抛射的物体所占大小, 用于碰撞检测 - /// 起始点 - /// 起始高度 - /// 角度, 0 - 360 - /// 横轴速度 - /// 纵轴速度 - /// 旋转速度 - /// 需要挂载的节点 - /// 抛射的节点显示的纹理, 用于渲染阴影用 - public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, float ySpeed, float rotate, Node2D mount) - { - if (CollisionShape != null) - { - CollisionShape.Disabled = false; - } - - IsOver = false; - Size = size; - GlobalPosition = StartPosition = start; - Direction = direction; - XSpeed = xSpeed; - YSpeed = ySpeed; - StartXSpeed = xSpeed; - StartYSpeed = ySpeed; - RotateSpeed = rotate; - - if (mount != null) - { - Mount = mount; - var mountParent = mount.GetParent(); - if (mountParent == null) - { - AddChild(mount); - } - else if (mountParent != this) - { - mountParent.RemoveChild(mount); - AddChild(mount); - } - mount.Position = new Vector2(0, -startHeight); - } - var parent = GetParent(); - if (parent == null) - { - RoomManager.Current.SortRoot.AddChild(this); - } - else if (parent == RoomManager.Current.SortRoot) - { - parent.RemoveChild(this); - RoomManager.Current.SortRoot.AddChild(this); - } - } - - /// - /// 初始化该抛物线对象的基础数据, 并且渲染阴影 - /// - /// 抛射的物体所占大小, 用于碰撞检测 - /// 起始点 - /// 起始高度 - /// 角度, 0 - 360 - /// 横轴速度 - /// 纵轴速度 - /// 旋转速度 - /// 需要挂载的节点 - /// 抛射的节点显示的纹理, 用于渲染阴影用 - public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, - float ySpeed, float rotate, Node2D mount, Sprite shadowTarget) - { - StartThrow(size, start, startHeight, direction, xSpeed, ySpeed, rotate, mount); - ShadowTarget = shadowTarget; - if (shadowTarget != null) - { - if (ShadowSprite == null) - { - //阴影 - ShadowSprite = new Sprite(); - ShadowSprite.Name = "Shadow"; - ShadowSprite.ZIndex = -5; - ShadowSprite.Material = ResourceManager.ShadowMaterial; - AddChild(ShadowSprite); - } - - inversionX = mount.Scale.y < 0 ? true : false; - if (inversionX) - { - ShadowSprite.Scale = shadowTarget.Scale * new Vector2(1, -1); - } - else - { - ShadowSprite.Scale = shadowTarget.Scale; - } - - ShadowSprite.Texture = shadowTarget.Texture; - } - else if (ShadowSprite != null) - { - ShadowSprite.Texture = null; - } - } - - /// - /// 停止投抛运动 - /// - public Node2D StopThrow() - { - var mount = Mount; - var parent = GetParent(); - if (parent != null && mount != null) - { - var gp = mount.GlobalPosition; - var gr = mount.GlobalRotation; - IsOver = true; - Mount = null; - RemoveChild(mount); - parent.AddChild(mount); - mount.GlobalPosition = gp; - mount.GlobalRotation = gr; - } - QueueFree(); - return mount; - } - - /// - /// 达到最高点时调用 - /// - protected virtual void OnMaxHeight(float height) - { - - } - - /// - /// 结束的调用 - /// - protected virtual void OnOver() - { - GetParent().RemoveChild(this); - RoomManager.Current.ObjectRoot.AddChild(this); - if (CollisionShape != null) - { - CollisionShape.Disabled = true; - } - } - - public override void _Process(float delta) - { - if (!IsOver) - { - if (Mount == null) - { - QueueFree(); - return; - } - MoveAndSlide(new Vector2(XSpeed, 0).Rotated(Direction * Mathf.Pi / 180)); - Mount.Position = new Vector2(0, Mount.Position.y - YSpeed * delta); - var rotate = Mount.GlobalRotationDegrees + RotateSpeed * delta; - Mount.GlobalRotationDegrees = rotate; - if (ShadowSprite != null) - { - ShadowSprite.GlobalRotationDegrees = rotate; - // ShadowSprite.GlobalRotationDegrees = rotate + (inversionX ? 180 : 0); - ShadowSprite.GlobalPosition = ShadowTarget.GlobalPosition + new Vector2(0, 1 - Mount.Position.y); - } - var ysp = YSpeed; - YSpeed -= GameConfig.G * delta; - //达到最高点 - if (ysp * YSpeed < 0) - { - OnMaxHeight(-Mount.Position.y); - } - //落地判断 - if (Mount.Position.y >= 0) - { - Mount.Position = new Vector2(0, 0); - IsOver = true; - OnOver(); - } - } - } - -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/ThrowComponent.cs b/DungeonShooting_Godot/src/game/item/ThrowComponent.cs deleted file mode 100644 index 4618d7f..0000000 --- a/DungeonShooting_Godot/src/game/item/ThrowComponent.cs +++ /dev/null @@ -1,21 +0,0 @@ - -using Godot; - -public class ThrowComponent : Component -{ - public override void Ready() - { - - } - - public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, - float ySpeed, float rotate) - { - - } - - public virtual void StopThrow() - { - - } -} diff --git a/DungeonShooting_Godot/src/game/item/ThrowNode.cs b/DungeonShooting_Godot/src/game/item/ThrowNode.cs new file mode 100644 index 0000000..a5ebe35 --- /dev/null +++ b/DungeonShooting_Godot/src/game/item/ThrowNode.cs @@ -0,0 +1,265 @@ +using Godot; + +/// +/// 模拟抛出的物体, 使用时将对象挂载到该节点上即可 +/// +public class ThrowNode : KinematicBody2D +{ + /// + /// 是否已经结束 + /// + public bool IsOver { get; protected set; } = true; + /// + /// 物体大小 + /// + public Vector2 Size { get; protected set; } + /// + /// 起始坐标 + /// + public Vector2 StartPosition { get; protected set; } + /// + /// 移动方向, 0 - 360 + /// + public float Direction { get; protected set; } + /// + /// x速度, 也就是水平速度 + /// + public float XSpeed { get; protected set; } + /// + /// y轴速度, 也就是竖直速度 + /// + public float YSpeed { get; protected set; } + /// + /// 初始x轴组队 + /// + public float StartXSpeed { get; protected set; } + /// + /// 初始y轴速度 + /// + public float StartYSpeed { get; protected set; } + /// + /// 旋转速度 + /// + public float RotateSpeed { get; protected set; } + /// + /// 挂载的对象 + /// + public Node2D Mount { get; protected set; } + /// + /// 碰撞组件 + /// + public CollisionShape2D CollisionShape { get; protected set; } + /// + /// 绘制阴影的精灵 + /// + public Sprite ShadowSprite { get; protected set; } + + protected Sprite ShadowTarget { get; set; } + + private bool inversionX = false; + + public ThrowNode() + { + Name = "ThrowNode"; + } + + public override void _Ready() + { + //只与墙壁碰撞 + CollisionMask = 1; + CollisionLayer = 0; + //创建碰撞器 + if (Size != Vector2.Zero) + { + CollisionShape = new CollisionShape2D(); + CollisionShape.Name = "Collision"; + var shape = new RectangleShape2D(); + shape.Extents = Size * 0.5f; + CollisionShape.Shape = shape; + AddChild(CollisionShape); + } + } + + /// + /// 初始化该抛物线对象的基础数据 + /// + /// 抛射的物体所占大小, 用于碰撞检测 + /// 起始点 + /// 起始高度 + /// 角度, 0 - 360 + /// 横轴速度 + /// 纵轴速度 + /// 旋转速度 + /// 需要挂载的节点 + /// 抛射的节点显示的纹理, 用于渲染阴影用 + public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, float ySpeed, float rotate, Node2D mount) + { + if (CollisionShape != null) + { + CollisionShape.Disabled = false; + } + + IsOver = false; + Size = size; + GlobalPosition = StartPosition = start; + Direction = direction; + XSpeed = xSpeed; + YSpeed = ySpeed; + StartXSpeed = xSpeed; + StartYSpeed = ySpeed; + RotateSpeed = rotate; + + if (mount != null) + { + Mount = mount; + var mountParent = mount.GetParent(); + if (mountParent == null) + { + AddChild(mount); + } + else if (mountParent != this) + { + mountParent.RemoveChild(mount); + AddChild(mount); + } + mount.Position = new Vector2(0, -startHeight); + } + var parent = GetParent(); + if (parent == null) + { + RoomManager.Current.SortRoot.AddChild(this); + } + else if (parent == RoomManager.Current.SortRoot) + { + parent.RemoveChild(this); + RoomManager.Current.SortRoot.AddChild(this); + } + } + + /// + /// 初始化该抛物线对象的基础数据, 并且渲染阴影 + /// + /// 抛射的物体所占大小, 用于碰撞检测 + /// 起始点 + /// 起始高度 + /// 角度, 0 - 360 + /// 横轴速度 + /// 纵轴速度 + /// 旋转速度 + /// 需要挂载的节点 + /// 抛射的节点显示的纹理, 用于渲染阴影用 + public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, + float ySpeed, float rotate, Node2D mount, Sprite shadowTarget) + { + StartThrow(size, start, startHeight, direction, xSpeed, ySpeed, rotate, mount); + ShadowTarget = shadowTarget; + if (shadowTarget != null) + { + if (ShadowSprite == null) + { + //阴影 + ShadowSprite = new Sprite(); + ShadowSprite.Name = "Shadow"; + ShadowSprite.ZIndex = -5; + ShadowSprite.Material = ResourceManager.ShadowMaterial; + AddChild(ShadowSprite); + } + + inversionX = mount.Scale.y < 0 ? true : false; + if (inversionX) + { + ShadowSprite.Scale = shadowTarget.Scale * new Vector2(1, -1); + } + else + { + ShadowSprite.Scale = shadowTarget.Scale; + } + + ShadowSprite.Texture = shadowTarget.Texture; + } + else if (ShadowSprite != null) + { + ShadowSprite.Texture = null; + } + } + + /// + /// 停止投抛运动 + /// + public Node2D StopThrow() + { + var mount = Mount; + var parent = GetParent(); + if (parent != null && mount != null) + { + var gp = mount.GlobalPosition; + var gr = mount.GlobalRotation; + IsOver = true; + Mount = null; + RemoveChild(mount); + parent.AddChild(mount); + mount.GlobalPosition = gp; + mount.GlobalRotation = gr; + } + QueueFree(); + return mount; + } + + /// + /// 达到最高点时调用 + /// + protected virtual void OnMaxHeight(float height) + { + + } + + /// + /// 结束的调用 + /// + protected virtual void OnOver() + { + GetParent().RemoveChild(this); + RoomManager.Current.ObjectRoot.AddChild(this); + if (CollisionShape != null) + { + CollisionShape.Disabled = true; + } + } + + public override void _Process(float delta) + { + if (!IsOver) + { + if (Mount == null) + { + QueueFree(); + return; + } + MoveAndSlide(new Vector2(XSpeed, 0).Rotated(Direction * Mathf.Pi / 180)); + Mount.Position = new Vector2(0, Mount.Position.y - YSpeed * delta); + var rotate = Mount.GlobalRotationDegrees + RotateSpeed * delta; + Mount.GlobalRotationDegrees = rotate; + if (ShadowSprite != null) + { + ShadowSprite.GlobalRotationDegrees = rotate; + // ShadowSprite.GlobalRotationDegrees = rotate + (inversionX ? 180 : 0); + ShadowSprite.GlobalPosition = ShadowTarget.GlobalPosition + new Vector2(0, 1 - Mount.Position.y); + } + var ysp = YSpeed; + YSpeed -= GameConfig.G * delta; + //达到最高点 + if (ysp * YSpeed < 0) + { + OnMaxHeight(-Mount.Position.y); + } + //落地判断 + if (Mount.Position.y >= 0) + { + Mount.Position = new Vector2(0, 0); + IsOver = true; + OnOver(); + } + } + } + +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/throwObject/ThrowComponent.cs b/DungeonShooting_Godot/src/game/item/throwObject/ThrowComponent.cs new file mode 100644 index 0000000..55194c9 --- /dev/null +++ b/DungeonShooting_Godot/src/game/item/throwObject/ThrowComponent.cs @@ -0,0 +1,190 @@ + +using Godot; + +public class ThrowComponent : Component +{ + + /// + /// 是否已经结束 + /// + public bool IsOver { get; protected set; } = true; + + /// + /// 物体大小 + /// + public Vector2 Size { get; protected set; } = Vector2.One; + + /// + /// 起始坐标 + /// + public Vector2 StartPosition { get; protected set; } + + /// + /// 移动方向, 0 - 360 + /// + public float Direction { get; protected set; } + + /// + /// x速度, 也就是水平速度 + /// + public float XSpeed { get; protected set; } + + /// + /// y轴速度, 也就是竖直速度 + /// + public float YSpeed { get; protected set; } + + /// + /// 初始x轴组队 + /// + public float StartXSpeed { get; protected set; } + + /// + /// 初始y轴速度 + /// + public float StartYSpeed { get; protected set; } + + /// + /// 旋转速度 + /// + public float RotateSpeed { get; protected set; } + + //绑定的kinematicBody2D节点 + private KinematicBody2D _kinematicBody2D; + + //碰撞器形状 + private CollisionShape2D _collisionShape2D; + + private RectangleShape2D _rectangleShape2D; + + public ThrowComponent() + { + _kinematicBody2D = new KinematicBody2D(); + _kinematicBody2D.Name = nameof(ThrowComponent); + //只与墙壁碰撞 + _kinematicBody2D.CollisionMask = 1; + _kinematicBody2D.CollisionLayer = 0; + //创建碰撞器 + _collisionShape2D = new CollisionShape2D(); + _collisionShape2D.Name = "Collision"; + _rectangleShape2D = new RectangleShape2D(); + _collisionShape2D.Shape = _rectangleShape2D; + _kinematicBody2D.AddChild(_collisionShape2D); + + _kinematicBody2D.ZIndex = 2; + } + + public override void Update(float delta) + { + if (!IsOver) + { + _kinematicBody2D.MoveAndSlide(new Vector2(XSpeed, 0).Rotated(Direction * Mathf.Pi / 180)); + Position = new Vector2(0, Position.y - YSpeed * delta); + var rotate = ActivityObject.GlobalRotationDegrees + RotateSpeed * delta; + ActivityObject.GlobalRotationDegrees = rotate; + + ShadowSprite.GlobalRotationDegrees = rotate; + // ShadowSprite.GlobalRotationDegrees = rotate + (inversionX ? 180 : 0); + ShadowSprite.GlobalPosition = AnimatedSprite.GlobalPosition + new Vector2(0, 1 - Position.y); + var ysp = YSpeed; + YSpeed -= GameConfig.G * delta; + //达到最高点 + if (ysp * YSpeed < 0) + { + OnMaxHeight(-Position.y); + } + + //落地判断 + if (Position.y >= 0) + { + Position = new Vector2(0, 0); + IsOver = true; + OnOver(); + } + } + } + + public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, + float ySpeed, float rotate, Sprite shadowSprite) + { + _collisionShape2D.Disabled = false; + + IsOver = false; + Size = size; + _kinematicBody2D.GlobalPosition = StartPosition = start; + Direction = direction; + XSpeed = xSpeed; + YSpeed = ySpeed; + StartXSpeed = xSpeed; + StartYSpeed = ySpeed; + RotateSpeed = rotate; + + _rectangleShape2D.Extents = Size * 0.5f; + + var mountParent = ActivityObject.GetParent(); + if (mountParent == null) + { + _kinematicBody2D.AddChild(ActivityObject); + } + else if (mountParent != ActivityObject) + { + mountParent.RemoveChild(ActivityObject); + _kinematicBody2D.AddChild(ActivityObject); + } + + Position = new Vector2(0, -startHeight); + + var parent = _kinematicBody2D.GetParent(); + if (parent == null) + { + RoomManager.Current.SortRoot.AddChild(_kinematicBody2D); + } + else if (parent == RoomManager.Current.ObjectRoot) + { + parent.RemoveChild(ActivityObject); + RoomManager.Current.SortRoot.AddChild(_kinematicBody2D); + } + //显示阴影 + ActivityObject.ShowShadowSprite(shadowSprite.Texture); + ShadowSprite.Scale = shadowSprite.Scale; + } + + /// + /// 停止投抛运动 + /// + public void StopThrow() + { + if (!IsOver) + { + var gp = ActivityObject.GlobalPosition; + var gr = ActivityObject.GlobalRotation; + IsOver = true; + _kinematicBody2D.RemoveChild(ActivityObject); + var parent = _kinematicBody2D.GetParent(); + parent.AddChild(ActivityObject); + ActivityObject.GlobalPosition = gp; + ActivityObject.GlobalRotation = gr; + } + + _collisionShape2D.Disabled = true; + } + + /// + /// 达到最高点时调用 + /// + protected virtual void OnMaxHeight(float height) + { + + } + + /// + /// 结束的调用 + /// + protected virtual void OnOver() + { + _kinematicBody2D.GetParent().RemoveChild(_kinematicBody2D); + RoomManager.Current.ObjectRoot.AddChild(_kinematicBody2D); + _collisionShape2D.Disabled = true; + } + +} diff --git a/DungeonShooting_Godot/src/game/ui/Cursor.cs b/DungeonShooting_Godot/src/game/ui/Cursor.cs new file mode 100644 index 0000000..a2d6dd4 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/Cursor.cs @@ -0,0 +1,60 @@ +using Godot; + +/// +/// 鼠标指针 +/// +public class Cursor : Node2D +{ + + 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) + { + var targetGun = RoomManager.Current?.Player?.Holster.ActiveWeapon; + if (targetGun != null) + { + SetScope(targetGun.CurrScatteringRange, targetGun); + } + else + { + SetScope(0, targetGun); + } + SetCursorPos(); + } + + /// + /// 设置光标半径范围 + /// + private void SetScope(float scope, Weapon targetGun) + { + 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/DungeonShooting_Godot/src/test/TestNavigation.cs b/DungeonShooting_Godot/src/test/TestNavigation.cs index f393083..4c55343 100644 --- a/DungeonShooting_Godot/src/test/TestNavigation.cs +++ b/DungeonShooting_Godot/src/test/TestNavigation.cs @@ -1,5 +1,6 @@ using Godot; +//测试导航 public class TestNavigation : Node2D {