diff --git a/DungeonShooting_Godot/src/framework/ActivityObject.cs b/DungeonShooting_Godot/src/framework/ActivityObject.cs
index 98a79b6..30022c1 100644
--- a/DungeonShooting_Godot/src/framework/ActivityObject.cs
+++ b/DungeonShooting_Godot/src/framework/ActivityObject.cs
@@ -147,28 +147,66 @@
///
/// 投抛该物体达到最高点时调用
///
- public virtual void OnMaxHeight(float height)
+ public virtual void OnThrowMaxHeight(float height)
{
}
- public virtual void PickUp()
+ ///
+ /// 投抛状态下第一次接触地面时调用, 之后的回弹落地将不会调用该函数
+ ///
+ public virtual void OnFirstFallToGround()
{
}
- public virtual void PickDown()
+ ///
+ /// 投抛状态下每次接触地面时调用
+ ///
+ public virtual void OnFallToGround()
{
}
+ ///
+ /// 投抛结束时调用
+ ///
+ public virtual void OnThrowOver()
+ {
+
+ }
+
+ public void PickUp()
+ {
+
+ }
+
+ public void PickDown()
+ {
+
+ }
+
+ ///
+ /// 将该节点投抛出去
+ ///
+ /// 碰撞器大小
+ /// 起始坐标 (全局)
+ /// 起始高度
+ /// 投抛角度 (0-360)
+ /// 移动速度
+ /// 下坠速度
+ /// 旋转速度
+ /// 落地时是否回弹
+ /// 落地回弹力度, 1为不消耗能量, 值越小回弹力度越小
+ /// 落地回弹后的速度, 1为不消速度, 值越小回弹速度消耗越大
public void Throw(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed,
- float ySpeed, float rotate)
+ float ySpeed, float rotate, bool bounce = false, float bounceStrength = 0.5f, float bounceSpeed = 0.8f)
{
if (_throwData == null)
{
_throwData = new ObjectThrowData();
}
+
SetThrowCollision();
_throwData.IsOver = false;
@@ -182,31 +220,15 @@
_throwData.RotateSpeed = rotate;
_throwData.LinearVelocity = new Vector2(_throwData.XSpeed, 0).Rotated(_throwData.Direction * Mathf.Pi / 180);
_throwData.Y = startHeight;
+ _throwData.Bounce = bounce;
+ _throwData.BounceStrength = bounceStrength;
+ _throwData.BounceSpeed = bounceSpeed;
_throwData.RectangleShape.Extents = _throwData.Size * 0.5f;
Throw();
}
- private void Throw()
- {
- var parent = GetParent();
- if (parent == null)
- {
- RoomManager.Current.SortRoot.AddChild(this);
- }
- else if (parent == RoomManager.Current.ObjectRoot)
- {
- parent.RemoveChild(this);
- RoomManager.Current.SortRoot.AddChild(this);
- }
- GlobalPosition = _throwData.StartPosition + new Vector2(0, -_throwData.Y);
-
- //显示阴影
- ShowShadowSprite();
- ShadowSprite.Scale = AnimatedSprite.Scale;
- }
-
///
/// 强制停止投抛运动
///
@@ -216,39 +238,6 @@
RestoreCollision();
}
- ///
- /// 结束的调用
- ///
- public void OnOver()
- {
- if (_throwData.FirstOver)
- {
- _throwData.FirstOver = false;
- if (this is Weapon gun)
- {
- gun._FallToGround();
- }
- }
- //如果落地高度不够低, 再抛一次
- if (_throwData.StartYSpeed > 1)
- {
- _throwData.StartPosition = Position;
- _throwData.Y = 0;
- _throwData.XSpeed = _throwData.StartXSpeed = _throwData.StartXSpeed * 0.8f;
- _throwData.YSpeed = _throwData.StartYSpeed = _throwData.StartYSpeed * 0.5f;
- _throwData.RotateSpeed = _throwData.RotateSpeed * 0.5f;
- _throwData.LinearVelocity = new Vector2(_throwData.XSpeed, 0).Rotated(_throwData.Direction * Mathf.Pi / 180);
- _throwData.FirstOver = true;
- _throwData.IsOver = false;
- }
- else //结束
- {
- GetParent().RemoveChild(this);
- RoomManager.Current.ObjectRoot.AddChild(this);
- RestoreCollision();
- }
- }
-
public void AddComponent(Component component)
{
if (!ContainsComponent(component))
@@ -314,14 +303,18 @@
//投抛计算
if (_throwData != null && !_throwData.IsOver)
{
- MoveAndSlide(_throwData.LinearVelocity);
+ _throwData.LinearVelocity = MoveAndSlide(_throwData.LinearVelocity);
Position = new Vector2(Position.x, Position.y - _throwData.YSpeed * delta);
var rotate = GlobalRotationDegrees + _throwData.RotateSpeed * delta;
GlobalRotationDegrees = rotate;
//计算阴影位置
+ var pos = AnimatedSprite.GlobalPosition + new Vector2(0, 2 + _throwData.Y);
ShadowSprite.GlobalRotationDegrees = rotate;
- ShadowSprite.GlobalPosition = AnimatedSprite.GlobalPosition + new Vector2(0, 2 + _throwData.Y);
+ ShadowSprite.GlobalPosition = pos;
+ //碰撞器位置
+ Collision.GlobalPosition = pos;
+
var ysp = _throwData.YSpeed;
_throwData.Y += _throwData.YSpeed * delta;
@@ -330,15 +323,44 @@
//达到最高点
if (ysp * _throwData.YSpeed < 0)
{
- OnMaxHeight(_throwData.Y);
+ ZIndex = 0;
+ OnThrowMaxHeight(_throwData.Y);
}
-
+
//落地判断
if (_throwData.Y <= 0)
{
ShadowSprite.GlobalPosition = AnimatedSprite.GlobalPosition + new Vector2(0, 2);
_throwData.IsOver = true;
- OnOver();
+
+ //第一次接触地面
+ if (_throwData.FirstOver)
+ {
+ _throwData.FirstOver = false;
+ OnFirstFallToGround();
+ }
+
+ //如果落地高度不够低, 再抛一次
+ if (_throwData.StartYSpeed > 1 && _throwData.Bounce)
+ {
+ _throwData.StartPosition = Position;
+ _throwData.Y = 0;
+ _throwData.XSpeed = _throwData.StartXSpeed = _throwData.StartXSpeed * _throwData.BounceSpeed;
+ _throwData.YSpeed = _throwData.StartYSpeed = _throwData.StartYSpeed * _throwData.BounceStrength;
+ _throwData.RotateSpeed = _throwData.RotateSpeed * _throwData.BounceStrength;
+ _throwData.LinearVelocity *= _throwData.BounceSpeed;
+ // _throwData.LinearVelocity =
+ // new Vector2(_throwData.XSpeed, 0).Rotated(_throwData.Direction * Mathf.Pi / 180);
+ _throwData.FirstOver = false;
+ _throwData.IsOver = false;
+
+ OnFallToGround();
+ }
+ else //结束
+ {
+ OnFallToGround();
+ ThrowOver();
+ }
}
}
@@ -408,6 +430,32 @@
return false;
}
+ ///
+ /// 触发投抛动作
+ ///
+ private void Throw()
+ {
+ var parent = GetParent();
+ if (parent == null)
+ {
+ RoomManager.Current.SortRoot.AddChild(this);
+ }
+ else if (parent == RoomManager.Current.ObjectRoot)
+ {
+ parent.RemoveChild(this);
+ RoomManager.Current.SortRoot.AddChild(this);
+ }
+
+ GlobalPosition = _throwData.StartPosition + new Vector2(0, -_throwData.Y);
+
+ //显示阴影
+ ShowShadowSprite();
+ ShadowSprite.Scale = AnimatedSprite.Scale;
+ }
+
+ ///
+ /// 设置投抛状态下的碰撞器
+ ///
private void SetThrowCollision()
{
if (_throwData != null && _throwData.UseOrigin)
@@ -416,8 +464,13 @@
_throwData.OriginPosition = Collision.Position;
_throwData.OriginRotation = Collision.Rotation;
_throwData.OriginScale = Collision.Scale;
- _throwData.OriginCollisionEnable = Collision.Disabled;
_throwData.OriginZIndex = ZIndex;
+ _throwData.OriginCollisionEnable = Collision.Disabled;
+ _throwData.OriginCollisionPosition = Collision.Position;
+ _throwData.OriginCollisionRotation = Collision.Rotation;
+ _throwData.OriginCollisionScale = Collision.Scale;
+ _throwData.OriginCollisionMask = CollisionMask;
+ _throwData.OriginCollisionLayer = CollisionLayer;
if (_throwData.RectangleShape == null)
{
@@ -428,12 +481,20 @@
//Collision.Position = Vector2.Zero;
Collision.Rotation = 0;
Collision.Scale = Vector2.One;
- Collision.Disabled = false;
- _throwData.UseOrigin = false;
ZIndex = 2;
+ Collision.Disabled = false;
+ Collision.Position = Vector2.Zero;
+ Collision.Rotation = 0;
+ Collision.Scale = Vector2.One;
+ CollisionMask = 1;
+ CollisionLayer = 0;
+ _throwData.UseOrigin = false;
}
}
+ ///
+ /// 重置碰撞器
+ ///
private void RestoreCollision()
{
if (_throwData != null && !_throwData.UseOrigin)
@@ -442,10 +503,27 @@
Collision.Position = _throwData.OriginPosition;
Collision.Rotation = _throwData.OriginRotation;
Collision.Scale = _throwData.OriginScale;
- Collision.Disabled = _throwData.OriginCollisionEnable;
ZIndex = _throwData.OriginZIndex;
-
+ Collision.Disabled = _throwData.OriginCollisionEnable;
+ Collision.Position = _throwData.OriginCollisionPosition;
+ Collision.Rotation = _throwData.OriginCollisionRotation;
+ Collision.Scale = _throwData.OriginCollisionScale;
+ CollisionMask = _throwData.OriginCollisionMask;
+ CollisionLayer = _throwData.OriginCollisionLayer;
+
_throwData.UseOrigin = true;
}
}
+
+ ///
+ /// 投抛结束
+ ///
+ private void ThrowOver()
+ {
+ GetParent().RemoveChild(this);
+ RoomManager.Current.ObjectRoot.AddChild(this);
+ RestoreCollision();
+
+ OnThrowOver();
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/ObjectThrowData.cs b/DungeonShooting_Godot/src/framework/ObjectThrowData.cs
index 7590dbd..21d31f3 100644
--- a/DungeonShooting_Godot/src/framework/ObjectThrowData.cs
+++ b/DungeonShooting_Godot/src/framework/ObjectThrowData.cs
@@ -5,7 +5,7 @@
///
/// 是否是第一次结束
///
- public bool FirstOver = false;
+ public bool FirstOver = true;
///
/// 是否已经结束
@@ -57,6 +57,21 @@
///
public RectangleShape2D RectangleShape;
+ ///
+ /// 落地之后是否弹跳
+ ///
+ public bool Bounce;
+
+ ///
+ /// 回弹的强度
+ ///
+ public float BounceStrength = 0.5f;
+
+ ///
+ /// 回弹后的速度
+ ///
+ public float BounceSpeed = 0.8f;
+
public Vector2 CurrPosition;
public float Y;
public Vector2 LinearVelocity;
@@ -67,6 +82,11 @@
public Vector2 OriginPosition;
public float OriginRotation;
public Vector2 OriginScale;
- public bool OriginCollisionEnable;
public int OriginZIndex;
+ public bool OriginCollisionEnable;
+ public Vector2 OriginCollisionPosition;
+ public float OriginCollisionRotation;
+ public Vector2 OriginCollisionScale;
+ public uint OriginCollisionMask;
+ public uint OriginCollisionLayer;
}
\ 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 f3d9d2e..2d84709 100644
--- a/DungeonShooting_Godot/src/game/common/NodeExtend.cs
+++ b/DungeonShooting_Godot/src/game/common/NodeExtend.cs
@@ -68,27 +68,6 @@
}
///
- /// 触发扔掉武器操作
- ///
- /// 触发扔掉该武器的的角色
- public static void StartThrowWeapon(this Weapon weapon, Role master)
- {
- if (master.Face == FaceDirection.Left)
- {
- weapon.Scale *= new Vector2(1, -1);
- weapon.RotationDegrees = 180;
- }
- var startHeight = 6;
- var direction = master.GlobalRotationDegrees + MathUtils.RandRangeInt(-20, 20);
- var xf = 30;
- var yf = MathUtils.RandRangeInt(60, 120);
- var rotate = MathUtils.RandRangeInt(-180, 180);
- //weapon.Position = Vector2.Zero;
- weapon.Throw(new Vector2(20, 20), master.MountPoint.GlobalPosition, startHeight, direction, xf, yf, rotate);
- }
-
-
- ///
/// 尝试将一个node2d节点转换成一个 ActivityObject 类
///
public static ActivityObject AsActivityObject(this Node2D node2d)
diff --git a/DungeonShooting_Godot/src/game/item/weapon/ThrowWeapon.cs b/DungeonShooting_Godot/src/game/item/weapon/ThrowWeapon.cs
index 5286173..49ae0f7 100644
--- a/DungeonShooting_Godot/src/game/item/weapon/ThrowWeapon.cs
+++ b/DungeonShooting_Godot/src/game/item/weapon/ThrowWeapon.cs
@@ -20,7 +20,7 @@
fristOver = false;
if (ActivityObject is Weapon gun)
{
- gun._FallToGround();
+
}
}
//如果落地高度不够低, 再抛一次
diff --git a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs
index 2ded6cf..5d011d4 100644
--- a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs
+++ b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs
@@ -6,7 +6,6 @@
///
public abstract class Weapon : ActivityObject
{
-
///
/// 武器的唯一id
///
@@ -21,12 +20,7 @@
/// 属性数据
///
public WeaponAttribute Attribute { get; private set; }
-
- // ///
- // /// 武器的图片
- // ///
- //public Sprite WeaponSprite { get; private set; }
-
+
///
/// 动画播放器
///
@@ -131,7 +125,6 @@
Id = id;
Attribute = attribute;
- //WeaponSprite = GetNode("WeaponBody/WeaponSprite");
FirePoint = GetNode("WeaponBody/FirePoint");
OriginPoint = GetNode("WeaponBody/OriginPoint");
ShellPoint = GetNode("WeaponBody/ShellPoint");
@@ -622,8 +615,9 @@
{
if (master is Role roleMaster) //与role碰撞
{
+ var holster = roleMaster.Holster;
//查找是否有同类型武器
- var index = roleMaster.Holster.FindWeapon(Id);
+ var index = holster.FindWeapon(Id);
if (index != -1) //如果有这个武器
{
if (CurrAmmo + ResidueAmmo == 0) //没有子弹了
@@ -631,7 +625,7 @@
return;
}
- var weapon = roleMaster.Holster.GetWeapon(index);
+ var weapon = holster.GetWeapon(index);
//子弹上限
var maxCount = Attribute.MaxAmmoCapacity;
//是否捡到子弹
@@ -666,13 +660,13 @@
}
else //没有武器
{
- if (roleMaster.Holster.PickupWeapon(this) == -1)
+ if (holster.PickupWeapon(this) == -1)
{
- var slot = roleMaster.Holster.SlotList[roleMaster.Holster.ActiveIndex];
+ var slot = holster.SlotList[holster.ActiveIndex];
if (slot.Type == Attribute.WeightType)
{
- var weapon = roleMaster.Holster.RemoveWeapon(roleMaster.Holster.ActiveIndex);
- weapon.StartThrowWeapon(roleMaster);
+ var weapon = holster.RemoveWeapon(holster.ActiveIndex);
+ weapon.TriggerThrowWeapon(roleMaster);
roleMaster.PickUpWeapon(this);
}
}
@@ -680,15 +674,26 @@
}
}
- public Vector2 GetItemPosition()
- {
- return GlobalPosition;
- }
-
///
- /// 触发落到地面
+ /// 触发扔掉武器操作
///
- public void _FallToGround()
+ /// 触发扔掉该武器的的角色
+ public void TriggerThrowWeapon(Role master)
+ {
+ if (master.Face == FaceDirection.Left)
+ {
+ Scale *= new Vector2(1, -1);
+ RotationDegrees = 180;
+ }
+ var startHeight = 6;
+ var direction = master.GlobalRotationDegrees + MathUtils.RandRangeInt(-20, 20);
+ var xf = 30;
+ var yf = MathUtils.RandRangeInt(60, 120);
+ var rotate = MathUtils.RandRangeInt(-180, 180);
+ Throw(new Vector2(30, 15), master.MountPoint.GlobalPosition, startHeight, direction, xf, yf, rotate, true);
+ }
+
+ public override void OnThrowOver()
{
//启用碰撞
CollisionShape2D.Disabled = false;
diff --git a/DungeonShooting_Godot/src/game/role/Role.cs b/DungeonShooting_Godot/src/game/role/Role.cs
index a19b0ec..85d5073 100644
--- a/DungeonShooting_Godot/src/game/role/Role.cs
+++ b/DungeonShooting_Godot/src/game/role/Role.cs
@@ -231,7 +231,7 @@
//播放抛出效果
if (weapon != null)
{
- weapon.StartThrowWeapon(this);
+ weapon.TriggerThrowWeapon(this);
}
}