基于Unity3D的塔防游戏

课题主要内容

设计建议塔防游戏,实现规定敌人移动路线,在塔的基座的基础上升级塔、卖掉塔、更换塔,来射击敌人。
要求:1、基于c#编程语言实现;
2、发射子弹攻击敌人;
记录分数,判定游戏成功与否。

课题研究方案

基于Android平台进行开发,开发工具使用Unity3D 3.7 、 PhotoshopCS6、Visual Studio 2019。
游戏UI设计与制作主要用PhotoshopCS6,包括游戏场景的背景、个性化按钮、游戏信息的显示等贴图。
游戏的模型建立使用Unity3D 开发工具,包括地图制作、环境制作、粒子效果、模型的物理特性等。
游戏中最核心部分脚本代码的编写需要使用Visual Studio 2019编辑工具,代码的语言选用比较简单易操作的C#语言。将脚本指定给游戏模型,再将各种类型参数连接,完成游戏设计方案

功能要求

此为塔防游戏,即地图一端会自动产生敌人到另一端,在中间部位玩家可按照自己的思路放置炮塔来阻击敌人的前进,一旦炮塔的放置位置不对,或者所选择的炮塔攻击力不够的话,便阻止不了敌人的前进,那么敌人很容易就能逃脱,玩家便输了。所以这类策略游戏不仅可以使玩家娱乐,还能使玩家的智力得到很好地提升,为此,要求此游戏要给玩家尽量大的个人发挥空间。

游戏描述

1.敌人从地图的一端进入,经过某个特定的路径后最终达到目的地(通常是地图相反的一端)。
2.玩家沿着路径放置一些防御炮塔,在敌人经过时朝他们开火。敌人一波一波的过来,玩家需要不断放置更多的防御工事,同时升级这些炮塔。
3.要赢得游戏,玩家得挺过1分钟,并且得分大于等于200分。
4.本游戏设计只设置玩家得分和游戏时间,而不设置宝物。并且本游戏中的关卡不会在此体现出来,不同关卡知识地图不同,开始时系统排出的出兵方式不同,其他都一样。故只对一个关卡进行分析。

游戏场景

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

GameController模块

public class GameController : MonoBehaviour
{
    public static bool GameIsOver;
    void Start()
    {
        GameIsOver = false;
    }
    void Update()
    {
        if (GameIsOver)
        {
            return;
        }
        if (Convert.ToInt16(Time.time) == 60)
        {
            if (Bullet.grade >= 200)
            {
                GameReturn();
            }
            else
            {
                GameEnd();
            }
        }
    }
    private void GameEnd()
    {
        GameIsOver = true;
        Global.GetInstance().GetEvent().Invoke(EventEnum.failureMenu, gameObject);
        Time.timeScale = 0;
    }
    private void GameReturn()
    {
        Global.GetInstance().GetEvent().Invoke(EventEnum.successMenu, gameObject);
        Time.timeScale = 0;
    }
}

Enemy模块

public class diren : MonoBehaviour
{
    public GameObject pathObject;
    public GameObject enemyPrefab;
    public GameObject enemy;
private float currentAddEnemyTime = 0.0f;
    public float addEnemyDutacion = 0.0f;
    private ObjectPool enemyPool = new ObjectPool();
    private List<GameObject> enemyList = new List<GameObject>();
    void Start()
    {
        for(int i = 0;i < 10;i++)
        {
            GameObject enemy = this.CreateEnemy();
            enemyPool.PushObject(enemy);
        }
        Global.GetInstance().SetEnemyController(gameObject);
    }
GameObject CreateEnemy()
    {
        GameObject enemy = Instantiate(enemyPrefab);
        enemy.transform.parent = this.transform;
        enemy.transform.GetComponent<dr>().SetObjectPool(enemyPool);
        return enemy;
    }
    public List<GameObject> GetEnemyList()
    {
        return enemyList;
    }
    void AddEnemy()
    {
        GameObject enemy = enemyPool.GetObject();
        if(enemy == null)
        {
            enemy = this.CreateEnemy();
        }
        enemy.SetActive(true);
enemy.transform.parent = transform;
        enemy.transform.position = pathObject.transform.GetChild(0).transform.position;
        enemy.transform.GetComponent<dr>().InitWithData(pathObject, gameObject);   
           this.enemyList.Add(enemy);
    }
    void Update()
    {
        if(this.currentAddEnemyTime >= addEnemyDutacion)
        {
            this.AddEnemy();
            this.currentAddEnemyTime = 0.0f;
        }
        else
        {
            this.currentAddEnemyTime += Time.deltaTime;
        }
    }
    public void EnemyEnd(GameObject enemy)
    {
        enemyList.Remove(enemy);
        Debug.Log("enemy list" + enemyList.Count);
    }
}

EnemyController模块

public class dr : MonoBehaviour
{
    private List<Vector3> pathList = new List<Vector3>();
    private int pathIndex = 0;
    private Vector3 targetPos = Vector3.zero;
    private ObjectPool enemyPool = null;
    private GameObject enemyController = null;
void Start()
    {
        
}
 public void SetObjectPool(ObjectPool pool)
    {
        enemyPool = pool;
}
    void Update()
    {
      if(pathList.Count!=0&&targetPos.Equals(Vector3.zero)&&pathIndex<pathList.Count)
        {
            targetPos = pathList[pathIndex];
        }
        if(!targetPos.Equals(Vector3.zero))
        {
            transform.position = Vector3.MoveTowards(transform.position, targetPos, 0.08f);
        }
        
        float distance = Vector3.Distance(transform.position, targetPos);
        if(distance < 0.1f)
        {
            pathIndex ++;
            targetPos = Vector3.zero;
            if(pathIndex == pathList.Count)
            {
                this.enemyController.transform.GetComponent<diren>().EnemyEnd(gameObject);
                enemyPool.PushObject(gameObject);
            }
        }
    }
    public void InitWithData(GameObject path,GameObject ctl )
    {
        this.enemyController = ctl;
        for (int i = 0; i < path.transform.childCount; i++)
        {
            pathList.Add(path.transform.GetChild(i).transform.position);
        }
}
}

TowerBase模块

public class TowerBase : MonoBehaviour
{
    void Start()
    {}
    void Update()
    {}
    public void OnMouseDown()
    {
        Global.GetInstance().GetEvent().Invoke(EventEnum.BuildMenu, gameObject);
    }
}

Tower模块

public class Tower : MonoBehaviour
{
    public GameObject body;public float attackDistance;
    public float attackDuraction;public GameObject bulletPos;
    public GameObject bulletPrefab; private float currentAttackTime;
    private ObjectPool bulletPool = new ObjectPool();
    private Color currentColor;private int towerLevel = 0;
    private List<Color> levelColor = new List<Color>();
    private GameObject targetEnemy = null;
    GameObject enemyController = Global.GetInstance().GetEnemyController();
    void Start()
    {
        levelColor.Add(Color.blue);
        levelColor.Add(Color.red);
        levelColor.Add(Color.black);
        currentColor = body.transform.GetComponent<MeshRenderer>().material.color;
        for(int i = 0;i < 5;i ++)
        {
            GameObject obj = this.CreateBullet();
            bulletPool.PushObject(obj);
        }
    }
    GameObject CreateBullet()
    {
        GameObject bullet = Instantiate(bulletPrefab);
        bullet.transform.position = this.bulletPos.transform.position;
        bullet.transform.GetComponent<Bullet>().SetObjectPool(bulletPool);
        bullet.transform.parent = transform.parent;
        return bullet;
    }
    void AddBullet(GameObject target)
    {
        GameObject bullet = bulletPool.GetObject();
        if(bullet == null)
        {
            bullet = this.CreateBullet();
        }
        bullet.SetActive(true);
        bullet.transform.position = bulletPos.transform.position;
        bullet.transform.GetComponent<Bullet>().SetTarget(target);
    }
    void Update()
    {
        if (targetEnemy == null)
{  List<GameObject>enemyList=enemyController.transform.GetComponent<diren>().GetEnemyList();
            for(int i = 0;i < enemyList.Count;i ++)
            {
GameObject enemy = enemyList[i];
                Vector3 enemyPos = enemy.transform.position;
                Vector3 towerPos = transform.position;
                float dis = Vector3.Distance(enemyPos,towerPos);
                if(dis < attackDistance)
                {
                    this.targetEnemy = enemy;
                }
            }
        }
        else
        {
            if(this.currentAttackTime > this.attackDistance)
            {
                this.AddBullet(this.targetEnemy);
                this.currentAttackTime = 0.0f;
            }
            else
            {
                this.currentAttackTime += Time.deltaTime;
            }
            Vector3 towerV = new Vector3(0, 0, 1);
            Vector3 enemyV = this.targetEnemy.transform.position - transform.position;
            float angle = Vector3.SignedAngle(towerV, enemyV,Vector3.up);
            transform.rotation = Quaternion.AngleAxis(angle,Vector3.up);
Vector3 enemyPos = this.targetEnemy.transform.position;
            Vector3 towerPos = this.transform.position;
            float dis = Vector3.Distance(enemyPos, towerPos);
            if(dis > this.attackDistance)
            {
                this.targetEnemy = null;
            }
        }
    }
    public void OnMouseDown()
{        
Global.GetInstance().GetEvent().Invoke(EventEnum.ShowUpdateMenu, gameObject);
    }
    public void UpdateLevel()
    {
        if(towerLevel == 3)
        {
            return;
        }
            towerLevel++;
            this.body.transform.GetComponent<MeshRenderer>().material.color= levelColor[towerLevel - 1];
            currentColor = levelColor[towerLevel - 1];
    }
}

TowerController模块

public class TowerController : MonoBehaviour
{
    public List<GameObject> towerPrefabList;
    void Start()
    {
        Global.GetInstance().GetEvent().AddListener(ProcessEvent);
    }
    void ProcessEvent(EventEnum eventType, GameObject obj)
    {
        switch(eventType)
        {
            case EventEnum.BuildTower1:
                this.BuildTower(towerPrefabList[0],obj);
                break;
            case EventEnum.BuildTower2:
                this.BuildTower(towerPrefabList[1],obj);
 break;
            default:
                break;
        }
    }
    void BuildTower(GameObject obj,GameObject tb)
    {
        GameObject tower = Instantiate(obj);
        tower.transform.parent = transform;
        tower.transform.position = tb.transform.position;
    }
    void Update()
    {}
}

Bullet模块

public class Bullet : MonoBehaviour
{
public static int grade = 100;public int timer = 1; private static Bullet instance;
private ObjectPool bulletPool = null; private GameObject targetEnemy = null;
   public static Bullet getInstance
    {
        get
        {
            if (instance == null)
            {
                instance = new Bullet();
            }
            return instance;
        }
    }
    void Start()
    { }
    [System.Obsolete]
    void Update()
    {
        timer -= Convert.ToInt16(Time.deltaTime);
        if(timer <= 0)
        {
            timer = 1;
        }
        if(this.targetEnemy != null && this.targetEnemy.active == true)
        {
            Vector3 enemyPos = this.targetEnemy.transform.position;
            Vector3 bulletPos = transform.position;
            float dis = Vector3.Distance(enemyPos, bulletPos);
            transform.position = Vector3.MoveTowards(bulletPos,enemyPos,0.1f);
            if(dis < 0.5)
            {
                bulletPool.PushObject(gameObject);
                this.targetEnemy = null;
                grade = grade + 10;
            }
        }
    }
    public void SetObjectPool(ObjectPool pool)
    {
        bulletPool = pool;
    }
    public void SetTarget(GameObject target)
    {
        this.targetEnemy = target;
    }
}

UIController 模块

public class UIController : MonoBehaviour
{
    public GameObject buileMenu;public GameObject updateMenu;
    public GameObject successMenu;public GameObject failureMenu;
    public GameObject targetObject;public GameObject textback;
    void Start()
    {
        Global.GetInstance().GetEvent().AddListener(ProcessEvent);
    }
    void ProcessEvent(EventEnum eventType, GameObject obj)
    {
        this.targetObject = obj;
        switch(eventType)
        {
            case EventEnum.BuildMenu:
                this.ShowBuileMenu(obj);
                break;
            case EventEnum.ShowUpdateMenu:
                this.ShowUpdateMenu(obj);
                break;
            case EventEnum.successMenu:
                this.ShowsuccessMenu(obj);
                break;
            case EventEnum.failureMenu:
                this.ShowfailureMenu(obj);
                break;
            default:
                break;
        }
 }
    void ShowUpdateMenu(GameObject obj)
    {
        this.buileMenu.SetActive(false);this.updateMenu.SetActive(true);
        this.updateMenu.transform.position= Camera.main.WorldToScreenPoint(obj.transform.position);
    }
    void ShowBuileMenu(GameObject obj)
    {
        this.updateMenu.SetActive(false); this.buileMenu.SetActive(true);
        this.buileMenu.transform.position= Camera.main.WorldToScreenPoint(obj.transform.position);
    }

    void ShowsuccessMenu(GameObject obj)
    {
        this.successMenu.SetActive(true);
    }
    void ShowfailureMenu(GameObject obj)
    {
        this.failureMenu.SetActive(true);
    }
    public void OnButtonClick(string data)
    {
        Debug.Log("button click ="+data);
        switch(data)
        {
            case "build-tower-1":
                if (Bullet.grade >= 100)
                {
                    Global.GetInstance().GetEvent().Invoke(EventEnum.BuildTower1, this.targetObject);
                    this.buileMenu.SetActive(false);
                    Bullet.grade = Bullet.grade - 100;
                }
                else
                {
                    this.buileMenu.SetActive(false);
                }
                break;
            case "build-tower-2":
                if (Bullet.grade >= 100)
                {
                    Global.GetInstance().GetEvent().Invoke(EventEnum.BuildTower2, this.targetObject);
                    this.buileMenu.SetActive(false);
                    Bullet.grade = Bullet.grade - 100;
                }
                else
                {
                     this.buileMenu.SetActive(false);
                }
                break;
            case "update":
                if (Bullet.grade >= 100)
                {
                   this.targetObject.transform.GetComponent<Tower>().UpdateLevel();
                    this.updateMenu.SetActive(false);
                    Bullet.grade = Bullet.grade - 100;
                }
                else
                {
                    this.buileMenu.SetActive(false);
                }
                break;
            case "sell":
                Destroy(this.targetObject);
                this.updateMenu.SetActive(false);
                Bullet.grade = Bullet.grade + 50;
                break;
            default:
                break;
        }
}
}

CM 模块

public class CM : MonoBehaviour
{
    public AudioClip music;public AudioSource back;
    public float moveSpeed = 200f;private int t = 0;
    void Start()
    {
        back = this.GetComponent<AudioSource>();
        back.loop = true; //设置循环播放  
        back.volume = 0.5f;//设置音量最大,区间在0-1之间
        back.clip = music;
        back.Play(); //播放背景音乐
     }
void Update()
    {
        float x = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
        float z = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
        transform.Translate(x, 0, z);
 }
    public void OnButtonClick(string data)
    {
        switch (data)
        {
            case "musicbutton":
                ++t;
                if(t % 2 == 1)
                {
                    back.Stop();
                }
                else
                    back.Play();
                break; 
             default:
                break;
        }
    }
}

TextShow 模块

public class TextShow : MonoBehaviour
{
public float timer = 1.0f;
 void Start()
    { }
    void Update()
    {
        timer -= Time.deltaTime;
        GameObject.Find("Canvas/time").GetComponent<Text>().text = "时间:" + Convert.ToInt16(Time.time);
        GameObject.Find("Canvas/grade").GetComponent<Text>().text = "分数:" + Bullet.grade;
    }
}

最后有需要的朋友可以下载看看:基于Unity3D的塔防游戏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值