产怪

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_33950757/article/details/102557438

```csharp
 // 自定义每波敌人的参数
2 [System.Serializable]                   // 序列化
3 public class Wave
4 {
5     public GameObject enemyPrefab;      // 敌人模型
6     public int count;                   // 敌人数量
7     public float rate;                  // 敌人生成间隔
8 }
 1 public class EnemySpawner : MonoBehaviour {
 2     public Wave[] waves;                            // 定义每波敌人参数
 3     public Transform start;                         // 敌人出生点
 4     public int waveRate = 3;                        // 每波敌人生成间隔
 5     public static int countEnemyAlive = 0;          // 生存敌人个数
 6 
 7     // Use this for initialization
 8     void Start () {
 9         StartCoroutine(SpawnEnemy());               // 启动线程
10     }
11 
12     IEnumerator SpawnEnemy()
13     {
14         foreach(Wave wave in waves)                 // 遍历每一波敌人
15         {
16             for (int i = 0; i < wave.count; ++i)    // 生成每个敌人
17             {
18                 // 生成敌人
19                 GameObject.Instantiate(wave.enemyPrefab, start.position, Quaternion.identity);
20                 countEnemyAlive++;                  // 生存敌人个数+1
21                 if (i != wave.count - 1)            // 敌人生成间隔
22                     yield return new WaitForSeconds(wave.rate);
23             }
24             while (countEnemyAlive > 0)             // 上一波敌人全部死亡后,才能生成下一波敌人
25             {
26                 yield return 0;
27             }
28             yield return new WaitForSeconds(waveRate);      // 等待生成下一波敌人
29         }
30     }
31 }








```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IBuilder<T> {

    //获取到游戏物体身上的脚本对象,从而去赋值
    T GetProductClass(GameObject gameObject);

    //使用工厂去获取具体的游戏对象
    GameObject GetProduct();

    //获取数据信息
    void GetData(T productClassGo);

    //获取特有资源与信息
    void GetOtherResource(T productClassGo);
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterBuilder : IBuilder<Monster>
{
    public int m_monsterID;
    private GameObject monsterGo;

    public void GetData(Monster productClassGo)
    {
        productClassGo.monsterID = m_monsterID;
        productClassGo.HP = m_monsterID * 100;
        productClassGo.currentHP = productClassGo.HP;
        productClassGo.initMoveSpeed = m_monsterID;
        productClassGo.moveSpeed = m_monsterID;
        productClassGo.prize = m_monsterID * 50;
    }

    public void GetOtherResource(Monster productClassGo)
    {
        productClassGo.GetMonsterProperty();
    }

    public GameObject GetProduct()
    {
        GameObject itemGo = GameController.Instance.GetGameObjectResource("MonsterPrefab");
        Monster monster = GetProductClass(itemGo);
        GetData(monster);
        GetOtherResource(monster);
        return itemGo;
    }

    public Monster GetProductClass(GameObject gameObject)
    {
        return gameObject.GetComponent<Monster>();
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 游戏控制管理,负责控制游戏的整个逻辑
/// </summary>
public class GameController : MonoBehaviour {

    private static GameController _instance;
    public static GameController Instance
    {
        get
        {
            return _instance;
        }
    }

    //引用
    public Level level;
    private GameManager mGameManager;
    public int[] mMonsterIDList;//当前波次的产怪列表
    public Stage currentStage;
    public MapMaker mapMaker;
    public Transform targetTrans;//集火目标
    public GameObject targetSignal;//集火信号
    public GridPoint selectGrid;//上一个选择的格子

    //游戏资源
    public RuntimeAnimatorController[] controllers;//怪物的动画播放控制器

    //游戏UI的面板
    public NormalModelPanel normalModelpanel;

    //用于计数的成员变量
    public int killMonsterNum;//当前波次杀怪数
    public int clearItemNum;//道具销毁数量
    public int killMonsterTotalNum;//杀怪总数
    public int mMonsterIDIndex;//用于统计当前怪物列表产生怪物的索引

    //属性值
    public int carrotHp = 10;
    public int coin;
    public int gameSpeed;//当前游戏进行速度
    public bool isPause;
    public bool creatingMonster;//是否继续产怪
    public bool gameOver;//游戏是否结束

    //建造者
    public MonsterBuilder monsterBuilder;
    public TowerBuilder towerBuilder;

    //建塔有关的成员变量
    public Dictionary<int, int> towerPriceDict;//建塔价格表  
    public GameObject towerListGo;//建塔按钮列表
    public GameObject handleTowerCanvasGo;//处理塔升级与买卖的画布



    private void Awake()
    {
#if Game
        _instance = this;
        mGameManager = GameManager.Instance;
        //测试代码
        //currentStage = new Stage(10,5,new int[] { 1,2,3,4,5},false,0,1,1,true,false);
        currentStage = mGameManager.currentStage;
        normalModelpanel = mGameManager.uiManager.mUIFacade.currentScenePanelDict[StringManager.NormalModelPanel] as NormalModelPanel;
        normalModelpanel.EnterPanel();
        mapMaker = GetComponent<MapMaker>();
        mapMaker.InitMapMaker(); 
        mapMaker.LoadMap(currentStage.mBigLevelID,currentStage.mLevelID);
        //成员变量赋值
        gameSpeed = 1;
        coin = 1000;

        monsterBuilder = new MonsterBuilder();
        towerBuilder = new TowerBuilder();
        //建塔列表的处理
        for (int i = 0; i < currentStage.mTowerIDList.Length; i++)
        {
            GameObject itemGo = mGameManager.GetGameObjectResource(FactoryType.UIFactory,"Btn_TowerBuild");
            itemGo.transform.GetComponent<ButtonTower>().towerID = currentStage.mTowerIDList[i];
            itemGo.transform.SetParent(towerListGo.transform);
            itemGo.transform.localPosition = Vector3.zero;
            itemGo.transform.localScale = Vector3.one;
        }
        //建塔价格表
        towerPriceDict = new Dictionary<int, int>
        {
            { 1,100},
            { 2,120},
            { 3,140},
            { 4,160},
            { 5,160}
        };

        controllers = new RuntimeAnimatorController[12];
        for (int i = 0; i < controllers.Length; i++)
        {
            controllers[i] = GetRuntimeAnimatorController("Monster/"+mapMaker.bigLevelID.ToString()+"/"+(i+1).ToString());
        }
        level = new Level(mapMaker.roundInfoList.Count, mapMaker.roundInfoList);
        normalModelpanel.topPage.UpdateCoinText();
        normalModelpanel.topPage.UpdateRoundText();
        //level.HandleRound();
        isPause = true;
#endif
    }

    private void Update()
    {
#if Game
        if (!isPause)
        {
            //产怪逻辑
            if (killMonsterNum>=mMonsterIDList.Length)
            {
                //添加当前回合数的索引
                if (level.currentRound==level.totalRound)
                {
                    return;
                }
                AddRoundNum();
            }
            else
            {
                if (!creatingMonster)
                {
                    CreateMonster();
                }
            }
        }
        else
        {
            //暂停
            StopCreateMonster();
            creatingMonster = false;
        }
#endif
    }

    /// <summary>
    /// 与集火目标有关的方法
    /// </summary>
    public void ShowSignal()
    {
        PlayEffectMusic("NormalMordel/Tower/ShootSelect");
        targetSignal.transform.position = targetTrans.position + new Vector3(0,mapMaker.gridHeight/2,0);
        targetSignal.transform.SetParent(targetTrans);
        targetSignal.SetActive(true);
    }

    public void HideSignal()
    {
        targetSignal.gameObject.SetActive(false);
        targetTrans = null;
    }

    /// <summary>
    /// 与玩家信息有关的方法
    /// </summary>
    
    //改变玩家金币
    public void ChangeCoin(int coinNum)
    {
        coin += coinNum;
        //更新游戏UI显示
        normalModelpanel.UpdatePanel();
    }

    //萝卜血量减少
    public void DecreaseHP()
    {
        PlayEffectMusic("NormalMordel/Carrot/Crash");
        carrotHp--;
        //更新萝卜UI显示
        mapMaker.carrot.UpdateCarrotUI();
    }

    //判断当前道具是否全部清除
    public bool IfAllClear()
    {
        for (int x = 0; x < MapMaker.xColumn; x++)
        {
            for (int y = 0; y < MapMaker.yRow; y++)
            {
                if (mapMaker.gridPoints[x,y].gridState.hasItem)
                {
                    return false;
                }
            }
        }
        return true;
    }

    //获取萝卜状态
    public int GetCarrotState()
    {
        int carrotState = 0;
        if (carrotHp>=4)
        {
            carrotState = 1;
        }
        else if (carrotHp>=2)
        {
            carrotState = 2;
        }
        else
        {
            carrotState = 3;
        }
        return carrotState;
    }

    /// <summary>
    /// 产生怪物的有关方法
    /// </summary>
    //产怪方法
    public void CreateMonster()
    {
        creatingMonster = true;
        InvokeRepeating("InstantiateMonster",(float)1/gameSpeed, (float)1 / gameSpeed);
    }

    //具体产怪方法
    private void InstantiateMonster()
    {
        PlayEffectMusic("NormalMordel/Monster/Create");
        if (mMonsterIDIndex >= mMonsterIDList.Length)
        {
            StopCreateMonster();
            return;
        }
        //产生特效
        GameObject effectGo = GetGameObjectResource("CreateEffect");
        effectGo.transform.SetParent(transform);
        effectGo.transform.position = mapMaker.monsterPathPos[0];
        //产生怪物
        if (mMonsterIDIndex<mMonsterIDList.Length)
        {
            monsterBuilder.m_monsterID = level.roundList[level.currentRound].roundInfo.mMonsterIDList[mMonsterIDIndex];
        }

        GameObject monsterGo = monsterBuilder.GetProduct();
        monsterGo.transform.SetParent(transform);
        monsterGo.transform.position = mapMaker.monsterPathPos[0];
        mMonsterIDIndex++;
    }
    //停止产生
    public void StopCreateMonster()
    {
        CancelInvoke();
    }
    //增加当前回合数,并且交给下一个回合来处理产怪
    public void AddRoundNum()
    {
        mMonsterIDIndex = 0;
        killMonsterNum = 0;
        level.AddRoundNum();
        level.HandleRound();
        //更新有关回合显示的UI
        normalModelpanel.UpdatePanel();
    }

    /// <summary>
    /// 与游戏处理逻辑有关的方法
    /// </summary>

#if Game

    //打开奖品页面
    public void ShowPrizePage()
    {
        normalModelpanel.ShowPrizePage();
    }

    //开始游戏
    public void StartGame()
    {
        isPause = false;
        level.HandleRound();
    }

    //格子处理方法
    public void HandleGrid(GridPoint grid)//当前选择的格子
    {
        if (grid.gridState.canBuild)
        {
            if (selectGrid==null)//没有上一个格子
            {
                selectGrid = grid;
                selectGrid.ShowGrid();
                PlayEffectMusic("NormalMordel/Grid/GridSelect");
            }
            else if (grid==selectGrid)//选中同一个格子
            {
                grid.HideGrid();
                selectGrid = null;
                PlayEffectMusic("NormalMordel/Grid/GridDeselect");
            }
            else if (grid!=selectGrid)//选中不同格子
            {
                selectGrid.HideGrid();
                selectGrid = grid;
                selectGrid.ShowGrid();
                PlayEffectMusic("NormalMordel/Grid/GridSelect");
            }
        }
        else
        {
            grid.HideGrid();
            grid.ShowCantBuild();
            PlayEffectMusic("NormalMordel/Grid/SelectFault");
            if (selectGrid!=null)
            {
                selectGrid.HideGrid();
            }
        }
    }
#endif
    /// <summary>
    /// 资源获取的有关方法
    /// </summary>
    /// <param name="resourcePath"></param>
    /// <returns></returns>
    public Sprite GetSprite(string resourcePath)
    {
        return mGameManager.GetSprite(resourcePath);
    }
    public AudioClip GetAudioClip(string resourcePath)
    {
        return mGameManager.GetAudioClip(resourcePath);
    }
    public RuntimeAnimatorController GetRuntimeAnimatorController(string resourcePath)
    {
        return mGameManager.GetRunTimeAnimatorController(resourcePath);
    }
    public GameObject GetGameObjectResource(string resourcePath)
    {
        return mGameManager.GetGameObjectResource(FactoryType.GameFactory,resourcePath);
    }
    public void PushGameObjectToFactory(string resourcePath,GameObject itemGo)
    {
        mGameManager.PushGameObjectToFactory(FactoryType.GameFactory,resourcePath,itemGo);
    }

    //播放特效音
    public void PlayEffectMusic(string audioClipPath)
    {
        mGameManager.audioSourceManager.PlayEffectMusic(GetAudioClip(audioClipPath));
    }
}


/// <summary>
/// 怪物
/// </summary>
public class Monster : MonoBehaviour
{

    //属性值
    public int monsterID;
    public int HP;//总血量
    public int currentHP;//当前血量
    public float moveSpeed;//当前速度
    public float initMoveSpeed;//初始速度
    public int prize;//奖励金钱
    //引用
    private Animator animator;
    private Slider slider;
    //private GameController.Instance GameController.Instance;
    private List<Vector3> monsterPointList;

    //用于计数的属性或开关
    private int roadPointIndex = 1;
    private bool reachCarrot;//到达终点
    private bool hasDecreasSpeed;//是否减速

    private float decreaseSpeedTimeVal;//减速计时器
    private float decreaseTime;//减速持续的具体时间

    //资源
    public AudioClip dieAudioClip;
    public RuntimeAnimatorController runtimeAnimatorController;
    private GameObject TshitGo;

    private void Awake()
    {
        animator = GetComponent<Animator>();
        slider = transform.Find("MonsterCanvas").Find("HPSlider").GetComponent<Slider>();
        slider.gameObject.SetActive(false);
        //GameController.Instance = GameController.Instance.Instance;
        monsterPointList = GameController.Instance.mapMaker.monsterPathPos;
        TshitGo = transform.Find("TShit").gameObject;
    }

    private void OnEnable()
    {
        monsterPointList = GameController.Instance.mapMaker.monsterPathPos;
        //怪物的转向
        if (roadPointIndex + 1 < monsterPointList.Count)
        {
            float xOffset = monsterPointList[0].x - monsterPointList[1].x;
            if (xOffset < 0)//右走
            {
                transform.eulerAngles = new Vector3(0, 0, 0);
            }
            else if (xOffset > 0)
            {
                transform.eulerAngles = new Vector3(0, 180, 0);
            }
        }
    }

    private void Update()
    {
        if (GameController.Instance.isPause||GameController.Instance.gameOver)
        {
            return;
        }
        if (!reachCarrot)
        {
            transform.position = Vector3.Lerp(transform.position, monsterPointList[roadPointIndex],
                1 / Vector3.Distance(transform.position, monsterPointList[roadPointIndex]) * Time.deltaTime * moveSpeed * GameController.Instance.gameSpeed);
            if (Vector3.Distance(transform.position, monsterPointList[roadPointIndex]) <= 0.01f)
            {
                //怪物的转向
                if (roadPointIndex + 1 < monsterPointList.Count)
                {
                    float xOffset = monsterPointList[roadPointIndex].x - monsterPointList[roadPointIndex + 1].x;
                    if (xOffset < 0)//右走
                    {
                        transform.eulerAngles = new Vector3(0, 0, 0);
                    }
                    else if (xOffset > 0)
                    {
                        transform.eulerAngles = new Vector3(0, 180, 0);
                    }
                }
                slider.gameObject.transform.eulerAngles = Vector3.zero;
                roadPointIndex++;
                if (roadPointIndex >= GameController.Instance.mapMaker.monsterPathPos.Count)
                {
                    reachCarrot = true;
                }
            }
        }
        else//到达终点
        {
            DestoryMonster();
            //萝卜减血
            GameController.Instance.DecreaseHP();
        }

        if (hasDecreasSpeed)
        {
            decreaseSpeedTimeVal += Time.deltaTime;
        }
        if (decreaseSpeedTimeVal >= decreaseTime)
        {
            CancelDecreaseDebuff();
            decreaseSpeedTimeVal = 0;
        }
    }

    //销毁怪物
    private void DestoryMonster()
    {
        if (GameController.Instance.targetTrans==transform)
        {
            GameController.Instance.HideSignal();
        }

        if (!reachCarrot)//被玩家杀死的
        {
            //生成金币以及数目
            GameObject coinGo = GameController.Instance.GetGameObjectResource("CoinCanvas");
            coinGo.transform.Find("Emp_Coin").GetComponent<CoinMove>().prize = prize;
            coinGo.transform.SetParent(GameController.Instance.transform);
            coinGo.transform.position = transform.position;
            //增加玩家的金币数量
            GameController.Instance.ChangeCoin(prize);
            //关于奖品的掉落
            int randomNum = Random.Range(0,100);
            if (randomNum<10)
            {
                GameObject prizeGo = GameController.Instance.GetGameObjectResource("Prize");
                prizeGo.transform.position = transform.position-new Vector3(0,0,6);
                GameController.Instance.PlayEffectMusic("NormalMordel/GiftCreate");
            }
        }
        //产生销毁特效
        GameObject effectGo = GameController.Instance.GetGameObjectResource("DestoryEffect");
        effectGo.transform.SetParent(GameController.Instance.transform);
        effectGo.transform.position = transform.position;
        GameController.Instance.killMonsterNum++;
        GameController.Instance.killMonsterTotalNum++;
        InitMonsterGo();
        GameController.Instance.PushGameObjectToFactory("MonsterPrefab", gameObject);

    }

    //初始化怪物的方法
    private void InitMonsterGo()
    {
        monsterID = 0;
        HP = 0;
        currentHP = 0;
        moveSpeed = 0;
        roadPointIndex = 1;
        dieAudioClip = null;
        reachCarrot = false;
        slider.value = 1;
        slider.gameObject.SetActive(false);
        prize = 0;
        transform.eulerAngles = new Vector3(0, 0, 0);
        decreaseSpeedTimeVal = 0;
        decreaseTime = 0;
        CancelDecreaseDebuff();
    }

    //承受伤害的方法
    private void TakeDamage(int attackValue)
    {
        slider.gameObject.SetActive(true);
        currentHP -= attackValue;
        if (currentHP < 0)
        {
            //播放死亡音效
            GameController.Instance.PlayEffectMusic("NormalMordel/Monster/"+GameController.Instance.currentStage.mBigLevelID.ToString()+"/"+monsterID.ToString());
            DestoryMonster();
            return;
        }
        slider.value = (float)currentHP / HP;
    }

    //减速buff的方法
    private void DecreaseSpeed(BullectProperty bullectProperty)
    {
        if (!hasDecreasSpeed)
        {
            moveSpeed = moveSpeed - bullectProperty.debuffValue;
            TshitGo.SetActive(true);
        }
        decreaseSpeedTimeVal = 0;
        hasDecreasSpeed = true;
        decreaseTime = bullectProperty.debuffTime;
    }

    //用来取消减速buff的方法
    private void CancelDecreaseDebuff()
    {
        hasDecreasSpeed = false;
        moveSpeed = initMoveSpeed;
        TshitGo.SetActive(false);
    }

    //获取特异性属性的方法
    public void GetMonsterProperty()
    {
        runtimeAnimatorController = GameController.Instance.controllers[monsterID - 1];
        animator.runtimeAnimatorController = runtimeAnimatorController;
    }

#if Game

    private void OnMouseDown()
    {
        if (GameController.Instance.targetTrans == null)
        {
            GameController.Instance.targetTrans = transform;
            GameController.Instance.ShowSignal();
        }
        //转换新目标
        else if (GameController.Instance.targetTrans != transform)
        {
            GameController.Instance.HideSignal();
            GameController.Instance.targetTrans = transform;
            GameController.Instance.ShowSignal();
        }
        //两次点击的是同一个目标
        else if (GameController.Instance.targetTrans == transform)
        {
            GameController.Instance.HideSignal();
        }
    }
#endif
}

猜你喜欢

转载自blog.csdn.net/weixin_33950757/article/details/102557438