diff --git a/Assets/Scenes/test.unity b/Assets/Scenes/test.unity
index 7288358..c3b912a 100644
--- a/Assets/Scenes/test.unity
+++ b/Assets/Scenes/test.unity
@@ -463,7 +463,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 326335321}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
- m_LocalPosition: {x: -0.9, y: -0.8, z: 0}
+ m_LocalPosition: {x: -8.16, y: -0.8, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 321454206}
@@ -629,7 +629,7 @@ MonoBehaviour:
speed: 10
jumpForce: 20
hammerCD: 1
- sickleCD: 10
+ sickleCD: 0
sicklePrefab: {fileID: 8280362330273855463, guid: 2e2fb120ae20d5e4faaad5a2a2fcca30, type: 3}
HP: 10
hitToflyParameter: {x: 10, y: 10}
@@ -1107,7 +1107,7 @@ MonoBehaviour:
m_PersistentCalls:
m_Calls: []
delay: 0
- duration: 3
+ duration: 8
easeType: 1
easeCurve:
serializedVersion: 2
@@ -1143,7 +1143,7 @@ MonoBehaviour:
autoPlay: 1
autoKill: 0
relative: 0
- isLocal: 0
+ isLocal: 1
isClosedPath: 1
pathResolution: 10
pathMode: 3
@@ -1153,28 +1153,58 @@ MonoBehaviour:
upDirection: {x: 0, y: 1, z: 0}
tweenRigidbody: 0
wps:
- - {x: 8.32342, y: -1.0342596, z: 0}
+ - {x: 1.410517, y: -1.0342596, z: 0}
fullWps: []
path:
wpLengths:
- 0
- - 3.503422
- - 3.503422
+ - 4.030519
+ - 4.030519
wps:
- - {x: 4.82, y: -1.03, z: 0}
- - {x: 8.32342, y: -1.0342596, z: 0}
- - {x: 4.82, y: -1.03, z: 0}
+ - {x: -2.62, y: -1.03, z: 0}
+ - {x: 1.410517, y: -1.0342596, z: 0}
+ - {x: -2.62, y: -1.03, z: 0}
type: 0
subdivisionsXSegment: 10
subdivisions: 30
controlPoints: []
- length: 7.006844
+ length: 8.061038
isFinalized: 1
timesTable:
- 0
- 0.5
- 1
- lengthsTable: []
+ lengthsTable:
+ - 0.044636283
+ - 0.17024052
+ - 0.36435583
+ - 0.6145263
+ - 0.9082949
+ - 1.2332048
+ - 1.5767996
+ - 1.9266229
+ - 2.2702177
+ - 2.5951276
+ - 2.8888958
+ - 3.1390667
+ - 3.3331816
+ - 3.4587862
+ - 3.503422
+ - 3.5480578
+ - 3.6736624
+ - 3.8677778
+ - 4.117948
+ - 4.411716
+ - 4.7366266
+ - 5.0802217
+ - 5.430045
+ - 5.77364
+ - 6.09855
+ - 6.3923187
+ - 6.642488
+ - 6.8366036
+ - 6.9622073
+ - 7.0068436
inspectorMode: 0
pathType: 0
handlesType: 0
@@ -1182,9 +1212,9 @@ MonoBehaviour:
handlesDrawMode: 0
perspectiveHandleSize: 0.5
showIndexes: 1
- showWpLength: 0
+ showWpLength: 1
pathColor: {r: 1, g: 1, b: 1, a: 0.5}
- lastSrcPosition: {x: 4.82, y: -1.03, z: 0}
+ lastSrcPosition: {x: -2.62, y: -1.03, z: 0}
lastSrcRotation: {x: 0, y: 0, z: 0, w: 1}
wpsDropdown: 1
dropToFloorOffset: 0
@@ -1200,11 +1230,16 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2127494698a58b642b7d3ec5f92f8974, type: 3}
m_Name:
m_EditorClassIdentifier:
- HP: 0
+ HP: 3
ATK: 1
+ speed: 1
coin: 0
HPLeft: 0
state: 0
+ hitToflyParameter: {x: 3, y: 3}
+ deadRotationRangeMax: 500
+ deadRotationRangeMin: 500
+ inPath: 1
--- !u!4 &1478051114
Transform:
m_ObjectHideFlags: 0
@@ -1213,7 +1248,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1478051109}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
- m_LocalPosition: {x: 4.82, y: -1.03, z: 0}
+ m_LocalPosition: {x: -2.62, y: -1.03, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
diff --git a/Assets/Scripts/Enemy.cs b/Assets/Scripts/Enemy.cs
index f41904f..36953de 100644
--- a/Assets/Scripts/Enemy.cs
+++ b/Assets/Scripts/Enemy.cs
@@ -19,25 +19,24 @@ public class Enemy : MonoBehaviour
///
/// 生命值上限
///
- [BoxGroup("属性")][Header("生命值上限")]
+ [FoldoutGroup("属性")][Header("生命值上限")]
public float HP;
///
/// 攻击力
///
- [BoxGroup("属性")][Header("攻击力")]
+ [FoldoutGroup("属性")][Header("攻击力")]
public float ATK;
///
/// 速度
///
- [BoxGroup("属性")]
- public float speed{get{return speed;} set{speed = value;}}
-
+ [FoldoutGroup("属性")][Header("移动速度")]
+ public float speed;
///
/// 打死后掉多少金币
///
- [BoxGroup("属性")][Header("掉落金币数")]
+ [FoldoutGroup("属性")][Header("掉落金币数")]
public int coin;
///
@@ -55,13 +54,13 @@ public class Enemy : MonoBehaviour
///
/// 当前生命值
///
- [ReadOnly][SerializeField][ProgressBar(0,10,0.15f,0.47f,0.74f)][BoxGroup("状态")]
+ [ReadOnly][SerializeField][ProgressBar(0,10,0.15f,0.47f,0.74f)][FoldoutGroup("状态")]
protected float HPLeft;
///
/// 当前状态
///
- [EnumPaging][SerializeField][ReadOnly][Header("当前状态")][BoxGroup("状态")]
+ [EnumPaging][SerializeField][ReadOnly][Header("当前状态")][FoldoutGroup("状态")]
protected State state;
// ______ _
@@ -74,7 +73,7 @@ public class Enemy : MonoBehaviour
///
/// 当怪物死的时候Call这个函数
///
- protected void OnDead(){}
+ protected virtual void OnDead(){}
///
/// 当怪物触碰到玩家的时候Call这个
@@ -86,12 +85,28 @@ public class Enemy : MonoBehaviour
///
/// 攻击方式,枚举类型,具体看MyPlayer
/// 受击方向,-1左,1右
- protected void OnBeHit(MyPlayer.AtkMethod hitMethod,int hitDir){}
+ protected virtual void OnBeHit(MyPlayer.AtkMethod hitMethod,int hitDir){}
///
/// 当怪物发现玩家的时候Call这个
///
protected void OnFindThePlayer(){}
+ ///
+ /// 当怪物着地的时候触发一次
+ ///
+ protected virtual void OnRetouchedTheGround(){}
+
+ // _ _ _
+ // | \ | | | |
+ // | \| | ___ _ __ _ __ ___ __ _| |
+ // | . ` |/ _ \| '__| '_ ` _ \ / _` | |
+ // | |\ | (_) | | | | | | | | (_| | |
+ // |_| \_|\___/|_| |_| |_| |_|\__,_|_|
+
+ ///
+ /// 看看死了没
+ ///
+ protected bool CheckDead(){return !(HPLeft > 0);}
// _____ _ _ _ _
@@ -104,6 +119,19 @@ public class Enemy : MonoBehaviour
{
if(other.gameObject.TryGetComponent(out MyPlayer player))
{OnTouchThePlayer(player);}//如果创到的是玩家,则Call事件
+ //如果被镰刀创到,Call一下OnBeHit事件,传入攻击方式和攻击来袭方向
+ else if(other.gameObject.TryGetComponent(out Sickle sickle))
+ {OnBeHit(MyPlayer.AtkMethod.镰刀,
+ (transform.position.x -
+ sickle.transform.position.x > 0) ? -1 : 1);
+ Destroy(sickle.gameObject);}
+ //如果被锤子锤到,和上面一样
+ else if(other.gameObject.TryGetComponent(out Hammer hammer))
+ {OnBeHit(MyPlayer.AtkMethod.锤子,
+ (transform.position.x -
+ hammer.transform.position.x > 0) ? -1 : 1);}
+ else if(other.gameObject.tag == "地面")
+ {OnRetouchedTheGround();}
}
protected void OnTriggerEnter2D(Collider2D other)
{
diff --git a/Assets/Scripts/Hammer.cs b/Assets/Scripts/Hammer.cs
new file mode 100644
index 0000000..13823f7
--- /dev/null
+++ b/Assets/Scripts/Hammer.cs
@@ -0,0 +1,8 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class Hammer : MonoBehaviour
+{
+
+}
diff --git a/Assets/Scripts/Hammer.cs.meta b/Assets/Scripts/Hammer.cs.meta
new file mode 100644
index 0000000..8bb11ec
--- /dev/null
+++ b/Assets/Scripts/Hammer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e8542bc5f7711d44d8c471ae7ca4eb87
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/MyPlayer.cs b/Assets/Scripts/MyPlayer.cs
index ccb3aca..f696c6a 100644
--- a/Assets/Scripts/MyPlayer.cs
+++ b/Assets/Scripts/MyPlayer.cs
@@ -30,11 +30,11 @@ public class MyPlayer : MonoBehaviour
public float speed = 10f;
[Header("玩家跳跃力度的大小")][FoldoutGroup("Info")]
public float jumpForce = 10f;
- [BoxGroup("CD")][Header("挥动锤子的CD时长")]
+ [FoldoutGroup("CD")][Header("挥动锤子的CD时长")]
public float hammerCD = 1f;
- [BoxGroup("CD")][Header("发射镰刀的CD时长")]
+ [FoldoutGroup("CD")][Header("发射镰刀的CD时长")]
public float sickleCD = 10f;
- [Header("镰刀游戏物体")][BoxGroup("预制体")]
+ [Header("镰刀游戏物体")][FoldoutGroup("预制体")]
public GameObject sicklePrefab;
public enum AtkMethod{镰刀,锤子,反弹炸弹};
///
@@ -47,6 +47,11 @@ public class MyPlayer : MonoBehaviour
///
[Header("被攻击后击飞的力度调整值")][FoldoutGroup("其他",false,0)]
public Vector2 hitToflyParameter;
+ ///
+ /// 攻击方式的倍率列表
+ ///
+ [DictionaryDrawerSettings()][Header("攻击方式的倍率列表")][ShowInInspector][FoldoutGroup("其他",false,0)]
+ public static Dictionary atkMethodMagnification;
// _____ _ _
// | __ \ (_) | |
@@ -63,9 +68,9 @@ public class MyPlayer : MonoBehaviour
private DOTweenAnimation wavingAnimation;//锤子挥动动画组件
private SpriteRenderer hammerSprite;//锤子的图片组件
private BoxCollider2D hammerCollider;//锤子的碰撞体
- [BoxGroup("CD")][Header("挥动锤子的CD还剩多长时间")][SerializeField][ReadOnly]
+ [FoldoutGroup("CD")][Header("挥动锤子的CD还剩多长时间")][SerializeField][ReadOnly]
private float hammerCDLeft = 0f;
- [BoxGroup("CD")][Header("发射镰刀的CD还剩多长时间")][SerializeField][ReadOnly]
+ [FoldoutGroup("CD")][Header("发射镰刀的CD还剩多长时间")][SerializeField][ReadOnly]
private float sickleCDLeft = 0f;
private int faceDir = 1;//面部朝向
private Transform sickleFirePoint;//镰刀发射点的transform
@@ -73,7 +78,7 @@ public class MyPlayer : MonoBehaviour
private Transform sickleClearerR;//右边的镰刀清除触发器
[FoldoutGroup("其他",false,1)][Header("玩家现在是否处于控制状态下(物理)")][SerializeField][ReadOnly]
private bool inControl = true;
- [SerializeField][ReadOnly][ProgressBar(0,10,0.15f,0.47f,0.74f)]
+ [SerializeField][ReadOnly][ProgressBar(0,10,0.15f,0.47f,0.74f)][FoldoutGroup("Info")]
private float HPLeft;
// _____ _ _ ____ _
@@ -117,6 +122,10 @@ public class MyPlayer : MonoBehaviour
sickleClearerR = transform.Find("镰刀飞出消除触发器右");
sickleClearerR.gameObject.AddComponent();
HPLeft = HP;
+ atkMethodMagnification = new Dictionary();
+ atkMethodMagnification.Add(AtkMethod.镰刀,1);
+ atkMethodMagnification.Add(AtkMethod.锤子,1);
+ atkMethodMagnification.Add(AtkMethod.反弹炸弹,2);
}
//移动函数,处理水平方向移动
diff --git a/Assets/Scripts/NormalEnemy.cs b/Assets/Scripts/NormalEnemy.cs
index f23c11a..6391d7e 100644
--- a/Assets/Scripts/NormalEnemy.cs
+++ b/Assets/Scripts/NormalEnemy.cs
@@ -1,14 +1,158 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
+using DG.Tweening;
+using Sirenix.OdinInspector;
+///
+/// 普通怪物类,三关都有的那个
+///
public class NormalEnemy : Enemy
{
- protected override void OnTouchThePlayer(MyPlayer player)
- {
+ // _____ _ _ _
+ // | __ \ | | | (_)
+ // | |__) | _| |__ | |_ ___
+ // | ___/ | | | '_ \| | |/ __|
+ // | | | |_| | |_) | | | (__
+ // |_| \__,_|_.__/|_|_|\___|
+
+ [Header("被攻击后击飞的力度调整值")][FoldoutGroup("其他",false,0)]
+ public Vector2 hitToflyParameter;
+ [FoldoutGroup("其他",false,0)][Header("怪物死后旋转速度的随机区间")]
+ public float deadRotationRangeMax;
+ [FoldoutGroup("其他",false,0)]
+ public float deadRotationRangeMin;
+
+ // _____ _ _
+ // | __ \ (_) | |
+ // | |__) | __ ___ ____ _| |_ ___
+ // | ___/ '__| \ \ / / _` | __/ _ \
+ // | | | | | |\ V / (_| | || __/
+ // |_| |_| |_| \_/ \__,_|\__\___|
+
+ protected Rigidbody2D m_rigidbody;
+ ///
+ /// 死的时候的受击朝向
+ ///
+ protected int deadDir;
+ ///
+ /// 记录一下游戏开始时怪物的位置,方便被击飞后怪物重新回到巡逻起点
+ ///
+ protected Vector3 sourcePosition;
+ protected DOTweenPath doTweenPath;
+ [SerializeField][ReadOnly][FoldoutGroup("状态")]
+ protected bool inPath = true;
+ ///
+ /// 现在正在执行的动画,在受击中断的时候用
+ ///
+ private Tween tweenNow;
+
+ // _____ _ _ ____ _
+ // / ____| | | | _ \ | |
+ // | | __ _| | | |_) | __ _ ___| | __
+ // | | / _` | | | _ < / _` |/ __| |/ /
+ // | |___| (_| | | | |_) | (_| | (__| <
+ // \_____\__,_|_|_|____/ \__,_|\___|_|\_\
+ void Start(){Init();}
+
+ // _ _ _
+ // | \ | | | |
+ // | \| | ___ _ __ _ __ ___ __ _| |
+ // | . ` |/ _ \| '__| '_ ` _ \ / _` | |
+ // | |\ | (_) | | | | | | | | (_| | |
+ // |_| \_|\___/|_| |_| |_| |_|\__,_|_|
+ protected void Init(){
+ //生命值初始化为满
+ HPLeft = HP;
+ //Get插件
+ doTweenPath = GetComponent();
+ m_rigidbody = GetComponent();
+ sourcePosition = transform.position;
+ //初始话目前播放的Tween动画为巡逻
+ tweenNow = doTweenPath.tween;
+ }
+
+ ///
+ /// 协程用,删除自己这个游戏物体
+ ///
+ protected void Dead(){Destroy(gameObject);}
+
+ ///
+ /// 被击飞的击飞效果处理
+ ///
+ /// 被击方向
+ public void BeHitToFly(int dir){
+ m_rigidbody.velocity += new Vector2( //给予自身一个
+ -1 * dir * hitToflyParameter.x,//X方向为力度系数乘以受击方向
+ hitToflyParameter.y//Y方向为力度系数
+ //的绝对的速度
+ );
+ }
+
+ // ______ _
+ // | ____| | |
+ // | |____ _____ _ __ | |_
+ // | __\ \ / / _ \ '_ \| __|
+ // | |___\ V / __/ | | | |_
+ // |______\_/ \___|_| |_|\__|
+ protected override void OnTouchThePlayer(MyPlayer player){
+ //告诉玩家,你被攻击了
player.OnBeHit(ATK,
((transform.position.x -
player.transform.position.x)
- > 0) ? 1 : -1);
+ > 0) ? 1 : -1);//通过自身位置和玩家位置的比较来返回玩家本次的受击方向
+ }
+
+ protected override void OnBeHit(MyPlayer.AtkMethod hitMethod, int hitDir){
+ //结束当前动画
+ tweenNow.Pause();
+ //让自己被击飞
+ BeHitToFly(hitDir);
+ //修改标志表示自己当前不在Path中
+ inPath = false;
+ //结算生命值
+ HPLeft -= MyPlayer.atkMethodMagnification[hitMethod];
+ //看下死了没
+ //死了就记录下死亡时候的面部朝向,用来做死亡翻滚效果,然后再Call一下死亡事件
+ if(CheckDead()) {deadDir = hitDir;OnDead();}
+ }
+
+ protected override void OnRetouchedTheGround(){
+ if(!inPath){//如果此时怪物没在巡逻且着地了,说明时被击飞然后着地了
+ //新建一个动画,让怪物回到初始记录位置
+ Tween tween = transform.DOMove(sourcePosition,
+ Mathf.Abs(sourcePosition.x - transform.position.x) / speed,
+ false);
+ //设置该动画插值方式为线性
+ tween.SetEase(Ease.Linear);
+ //更改记录的此时正在执行的动画
+ tweenNow = tween;
+ //写一个委托,插入这个新动画的结束事件
+ TweenCallback myCallBack = () =>
+ //结束说明回到了初始点,此时让怪物重新开始巡逻,同时更改记录中的正在执行的动画为巡逻
+ {doTweenPath.DORestart(); tweenNow = doTweenPath.tween;};
+ //插入写的委托
+ tween.OnComplete(myCallBack);
+ //标记自身重新回到巡逻动画
+ inPath = true;
+ //矫正一下faceDir的问题
+ transform.rotation = Quaternion.
+ Euler
+ (transform.rotation.x,
+ ((sourcePosition.x - transform.position.x > 0) ? 0:-180),
+ transform.rotation.z);
+ }
+ }
+
+ protected override void OnDead()
+ {
+ //标记当前状态为死亡
+ state = State.dead;
+ //加一个扭矩,营造死亡的效果
+ m_rigidbody.AddTorque(Random.Range(deadRotationRangeMin,deadRotationRangeMax) * deadDir);
+ //关掉自己的碰撞体
+ GetComponent().enabled = false;
+ //两秒后自己毁灭
+ Invoke("Dead",2f);
}
}