欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2020年3月8日游戏研发日志

程序员文章站 2024-01-01 17:28:52
...

简单塔防游戏的设计与实现(三)

在上一篇文章中,游戏的主控器和基本函数都已实现(传送门:https://blog.csdn.net/qq_40606433/article/details/104702048)
这里开始进行下一步的设计与实现,实现EnemySpawn的控制脚本。

对于基础的功能,假设只有一波敌人的话,可以这样编写EnemySpawnController

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

public class EnemySpawnController : MonoBehaviour
{

    //敌人生成器
    //分析:
    //  生成一个敌人: CreateEnemy,认为出生点就是本身
    //  计数:生成的敌人个数和要生成的敌人总数
    //  保存可用路径:可用路径坐标和总数

    GameController gameController;

    Vector3[] route = new Vector3[5]
    {
        new Vector3(5.15f, 0, 6.35f),
        new Vector3(5.15f, 0, 1f),
        new Vector3(-5.82f, 0, 1f),
        new Vector3(-5.82f, 0, -6.0f),
        new Vector3(9.5f, 0, -6.0f)
    };

    //每个敌人生成的间隔
    public float interval = 0.3f;           
    public float current_interval = 0;
    //敌人的最大数量和当前数量,应该如何处理多波敌人?
    public int enemy_max_count = 10;
    public int enemy_count = 0;

    public bool isCreating = false;
    
    void Update()
    {
        if(isCreating)
        {
            current_interval += Time.deltaTime;
            if(current_interval >= interval)
            {
                CreateEnemy();
                current_interval -= interval;
            }
        }
    }  

    public void Begin()
    {
        enemy_count = 0;
        current_interval = 0;
        isCreating = true;
        this.gameController.SetEnemy(enemy_max_count);
    }

    public void CreateEnemy()
    {
        Object enemy = Resources.Load("Enemy");
        if(enemy == null)
        {
            Debug.Log("未能正确加载预设体");
            return;
        }
        GameObject enemy_go = enemy as GameObject;
        if(enemy_go == null)
        {
            Debug.Log("未能将预设体转换为游戏对象");
        }
        enemy_go = Instantiate(enemy_go, this.transform.position, Quaternion.identity);
        Enemy enemyController = enemy_go.GetComponent<Enemy>();
        enemyController.setGameController(gameController);
        enemyController.StartMove(route);

        //控制生成的敌人的数量,全部生成完毕时停止再生成敌人
        enemy_count++;
        if(enemy_count >= enemy_max_count)
        {
            isCreating = false;
        }
    }
    
    public void setGameController(GameController gameController)
    {
        this.gameController = gameController;
    }
}

里面的Enemy预设体大改长这个样子:
2020年3月8日游戏研发日志
这里开始已经出现难题了:
1.波次的控制应该交给谁?
2.敌人的移动有没有更好的解决方法(现在使用的是标记几个拐弯点,敌人走到后向下一个拐弯点移动,但是之前的GUI开发时使用的网格来给敌人定位导航)

由于Unity刚入门,还不熟悉各种操作,因此敌人移动就先使用这样简单粗暴的方法解决,等后续能力足够了再回来想想有什么解决方法。

下面尝试解决波次的控制

分析:波次的控制涉及GameController中的敌人计数器(当敌人为0时开始下一波)和EnemySpawnController(是否正在一波,下一波的内容是什么,按什么顺序造什么兵等等)。
所以这里决定由EnemySpawnController控制波次。
对GameController的改动:

    public bool allClear()      //封装一下场上是否还有敌人的函数
    {
        return enemy == 0;    
    }
    public void Win()
    {
    	Debug.Log("YOU WIN");
    }
    public void Lose()
    {
		Debug.Log("GAME OVER");
    }

对EnemySpawnController的改动:

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

public class EnemySpawnController : MonoBehaviour
{

    //敌人生成器
    //分析:
    //  生成一个敌人: CreateEnemy,认为出生点就是本身
    //  计数:生成的敌人个数和要生成的敌人总数
    //  保存可用路径:可用路径坐标和总数

    GameController gameController;

    Vector3[] route = new Vector3[5]
    {
        new Vector3(5.15f, 0, 6.35f),
        new Vector3(5.15f, 0, 1f),
        new Vector3(-5.82f, 0, 1f),
        new Vector3(-5.82f, 0, -6.0f),
        new Vector3(9.5f, 0, -6.0f)
    };

    //每个敌人生成的间隔
    public float interval = 0.3f;           
    public float current_interval = 0;
    //敌人的最大数量和当前数量,应该如何处理多波敌人?
    public List<int> enemy_counts = new List<int>()
    { 10, 15, 20 };
    public int current_wave = 0;
    public int current_enemy_max_counts;
    public int enemy_count = 0;

    //一波敌人的准备时间
    public bool isComing = false;
    public float wave_interval = 5;
    public float current_wave_interval = 0;

    public bool isCreating = false;
    
    void Update()
    {
        if (isCreating)
        {
            current_interval += Time.deltaTime;
            if (current_interval >= interval)
            {
                CreateEnemy();
                current_interval -= interval;
            }
        }
        else if(isComing)
        {
            current_wave_interval += Time.deltaTime;
            if(current_wave_interval >= wave_interval)
            {
                isComing = false;
                Next();
                current_wave_interval = 0;
            }
        }
        else
        {
            if(gameController.allClear())
            {
                isComing = true;
            }
        }
    }  

    public void Begin()
    {
        isComing = true;
    }

    public void Next()
    {
        if(current_wave >= enemy_counts.Count)
        {
            this.gameController.Win();
            return;
        }
        enemy_count = 0;
        current_interval = 0;
        isCreating = true;
        this.gameController.SetEnemy(enemy_counts[current_wave]);
    }

    public void CreateEnemy()
    {
        Object enemy = Resources.Load("Enemy");
        if(enemy == null)
        {
            Debug.Log("未能正确加载预设体");
            return;
        }
        GameObject enemy_go = enemy as GameObject;
        if(enemy_go == null)
        {
            Debug.Log("未能将预设体转换为游戏对象");
        }
        enemy_go = Instantiate(enemy_go, this.transform.position, Quaternion.identity);
        Enemy enemyController = enemy_go.GetComponent<Enemy>();
        enemyController.setGameController(gameController);
        enemyController.StartMove(route);

        //控制生成的敌人的数量,全部生成完毕时停止再生成敌人
        enemy_count++;
        if(enemy_count >= enemy_counts[current_wave])
        {
            isCreating = false;
            current_wave++;
        }
    }
    
    public void setGameController(GameController gameController)
    {
        this.gameController = gameController;
    }

}

至此敌人生成器已经完成。效率可能较低,游戏性能优化问题待日后自己又能力了再说(突然出现了Flag

上一篇:

下一篇: