坦克对战游戏 AI 设计

从商店下载游戏:“Kawaii” Tank 或 其他坦克模型,构建 AI 对战坦克。具体要求

  • 使用“感知-思考-行为”模型,建模 AI 坦克
  • 场景中要放置一些障碍阻挡对手视线
  • 坦克需要放置一个矩阵包围盒触发器,以保证 AI 坦克能使用射线探测对手方位
  • AI 坦克必须在有目标条件下使用导航,并能绕过障碍。(失去目标时策略自己思考)
  • 实现人机对战

GameObjectFactory

单实例工厂管理各种游戏对象:玩家、坦克、子弹等。

public class GameObjectFactory : MonoBehaviour {// 玩家public GameObject player;// npcpublic GameObject tank;// 子弹public GameObject bullet;// 爆炸粒子系统public ParticleSystem ps;private Dictionary<int, GameObject> usingTanks;private Dictionary<int, GameObject> freeTanks;private Dictionary<int, GameObject> usingBullets;private Dictionary<int, GameObject> freeBullets;private List<ParticleSystem> psContainer;private void Awake(){usingTanks = new Dictionary<int, GameObject>();freeTanks = new Dictionary<int, GameObject>();usingBullets = new Dictionary<int, GameObject>();freeBullets = new Dictionary<int, GameObject>();psContainer = new List<ParticleSystem>();}// Use this for initializationvoid Start () {//回收坦克的委托事件AITank.recycleEvent += recycleTank;}public GameObject getPlayer(){return player;}public GameObject getTank(){if(freeTanks.Count == 0){GameObject newTank = Instantiate<GameObject>(tank);usingTanks.Add(newTank.GetInstanceID(), newTank);//在一个随机范围内设置坦克位置newTank.transform.position = new Vector3(Random.Range(-100, 100), 0, Random.Range(-100, 100));return newTank;}foreach (KeyValuePair<int, GameObject> pair in freeTanks){pair.Value.SetActive(true);freeTanks.Remove(pair.Key);usingTanks.Add(pair.Key, pair.Value);pair.Value.transform.position = new Vector3(Random.Range(-100, 100), 0, Random.Range(-100, 100));return pair.Value;}return null;}public GameObject getBullet(tankType type){if (freeBullets.Count == 0){GameObject newBullet = Instantiate(bullet);newBullet.GetComponent<Bullet>().setTankType(type);usingBullets.Add(newBullet.GetInstanceID(), newBullet);return newBullet;}foreach (KeyValuePair<int, GameObject> pair in freeBullets){pair.Value.SetActive(true);pair.Value.GetComponent<Bullet>().setTankType(type);freeBullets.Remove(pair.Key);usingBullets.Add(pair.Key, pair.Value);return pair.Value;}return null;}public ParticleSystem getPs(){for(int i = 0; i < psContainer.Count; i++){if (!psContainer[i].isPlaying) return psContainer[i];}ParticleSystem newPs = Instantiate<ParticleSystem>(ps);psContainer.Add(newPs);return newPs;}public void recycleTank(GameObject tank){usingTanks.Remove(tank.GetInstanceID());freeTanks.Add(tank.GetInstanceID(), tank);tank.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);tank.SetActive(false);}public void recycleBullet(GameObject bullet){usingBullets.Remove(bullet.GetInstanceID());freeBullets.Add(bullet.GetInstanceID(), bullet);bullet.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);bullet.SetActive(false);}
}

AITank

AI坦克未发现玩家时就在巡逻状态,发现附近玩家时,则进入追捕状态。追捕玩家时,如果玩家进入AI坦克射击范围则AI坦克就会开火。

public class AITank : Tank {public delegate void recycle(GameObject tank);public static event recycle recycleEvent;private Vector3 target;private bool gameover;// 巡逻点private static Vector3[] points = { new Vector3(37.6f,0,0), new Vector3(40.9f,0,39), new Vector3(13.4f, 0, 39),new Vector3(13.4f, 0, 21), new Vector3(0,0,0), new Vector3(-20,0,0.3f), new Vector3(-20, 0, 32.9f), new Vector3(-37.5f, 0, 40.3f), new Vector3(-37.5f,0,10.4f), new Vector3(-40.9f, 0, -25.7f), new Vector3(-15.2f, 0, -37.6f),new Vector3(18.8f, 0, -37.6f), new Vector3(39.1f, 0, -18.1f)};private int destPoint = 0;private NavMeshAgent agent;private bool isPatrol = false;private void Awake(){destPoint = UnityEngine.Random.Range(0, 13);}// Use this for initializationvoid Start () {setHp(100f);StartCoroutine(shoot());agent = GetComponent<NavMeshAgent>();}private IEnumerator shoot(){while (!gameover){for(float i = 1; i > 0; i -= Time.deltaTime){yield return 0;}// 当敌军坦克距离玩家坦克不到20时开始射击if(Vector3.Distance(transform.position, target) < 20){GameObjectFactory mf = Singleton<GameObjectFactory>.Instance;GameObject bullet = mf.getBullet(tankType.Enemy);bullet.transform.position = new Vector3(transform.position.x, 1.5f, transform.position.z) + transform.forward * 1.5f;bullet.transform.forward = transform.forward;// 发射子弹Rigidbody rb = bullet.GetComponent<Rigidbody>();rb.AddForce(bullet.transform.forward * 20, ForceMode.Impulse);}}}// Update is called once per framevoid Update () {gameover = GameDirector.getInstance().currentSceneController.isGameOver();if (!gameover){target = GameDirector.getInstance().currentSceneController.getPlayerPos();if (getHp() <= 0 && recycleEvent != null){//如果npc坦克被摧毁,则回收它recycleEvent(this.gameObject);}else{if(Vector3.Distance(transform.position, target) <= 30){isPatrol = false;//否则向玩家坦克移动agent.autoBraking = true;agent.SetDestination(target);}else{patrol();}}}else{NavMeshAgent agent = GetComponent<NavMeshAgent>();agent.velocity = Vector3.zero;agent.ResetPath();}}private void patrol(){if(isPatrol){if(!agent.pathPending && agent.remainingDistance < 0.5f)GotoNextPoint();}else{agent.autoBraking = false;GotoNextPoint();}isPatrol = true;}private void GotoNextPoint(){agent.SetDestination(points[destPoint]);destPoint = (destPoint + 1) % points.Length;}
}

SceneController

初始化主摄像机,实现IUserAction接口。

public class SceneController : MonoBehaviour, IUserAction {public GameObject player;private bool gameOver = false;private int enemyCount = 6;private GameObjectFactory mf;private MainCameraControl cameraControl;private void Awake(){GameDirector director = GameDirector.getInstance();director.currentSceneController = this;mf = Singleton<GameObjectFactory>.Instance;player = mf.getPlayer();cameraControl = GetComponent<MainCameraControl>();cameraControl.setTarget(player.transform);}// Use this for initializationvoid Start () {for(int i = 0; i < enemyCount; i++){GameObject gb = mf.getTank();cameraControl.setTarget(gb.transform);}Player.destroyEvent += setGameOver;// 初始化相机位置cameraControl.SetStartPositionAndSize();}// 更新相机位置void Update () {Camera.main.transform.position = new Vector3(player.transform.position.x, 15, player.transform.position.z);}public Vector3 getPlayerPos(){return player.transform.position;}public bool isGameOver(){return gameOver;}public void setGameOver(){gameOver = true;}public void moveForward(){player.GetComponent<Rigidbody>().velocity = player.transform.forward * 20;}public void moveBackWard(){player.GetComponent<Rigidbody>().velocity = player.transform.forward * -20;}public void turn(float offsetX){float y = player.transform.localEulerAngles.y + offsetX * 5;float x = player.transform.localEulerAngles.x;player.transform.localEulerAngles = new Vector3(x, y, 0);}public void shoot(){GameObject bullet = mf.getBullet(tankType.Player);// 设置子弹位置bullet.transform.position = new Vector3(player.transform.position.x, 1.5f, player.transform.position.z) + player.transform.forward * 1.5f;// 设置子弹方向bullet.transform.forward = player.transform.forward;// 发射子弹Rigidbody rb = bullet.GetComponent<Rigidbody>();rb.AddForce(bullet.transform.forward * 20, ForceMode.Impulse);}
}

【3D游戏】坦克对战游戏AI设计相关推荐

  1. 坦克对战游戏 AI 设计

    坦克对战游戏 AI 设计 从商店下载游戏:"Kawaii" Tank 或 其他坦克模型,构建 AI 对战坦克.具体要求 使用"感知-思考-行为"模型,建模 AI ...

  2. 作业十: 坦克对战游戏 AI 设计

    坦克对战游戏 AI 设计 从商店下载游戏:"Kawaii" Tank 或 其他坦克模型,构建 AI 对战坦克.具体要求 使用"感知-思考-行为"模型,建模 AI ...

  3. 端午节-怀念1996之QB45坦克对战游戏

    又是一个端午节,真的老了.坐在计算机边,打开VirtualBox,启动Windows 3.2, 再玩一把坦克对战游戏. 这是1996年端午节前后写的程序.当时备战高考,被题海战术弄得身心俱疲,模拟考试 ...

  4. 【Unity3D】坦克对战游戏 AI 设计

    作业要求 从商店下载游戏:"Kawaii" Tank 或 其他坦克模型,构建 AI 对战坦克.具体要求 使用"感知-思考-行为"模型,建模 AI 坦克 场景中要 ...

  5. 游戏编程技术贴:AI设计的若干规则阐述

    一般来讲,网络游戏的AI历来就是很简单的AI.相比之下,很多单机游戏的AI就要得复杂一些.而笔者并未从事过大型单机游戏的AI设计,所以也就不班门弄斧了.但至于网游的AI,还是略知一二. 目前游戏中的A ...

  6. openFrameworks实现的简单坦克对战游戏-Tank War

    ​ 开发环境:windows.vs2019.of_v0.11.2_vs2017_release. 下载地址:https://download.csdn.net/download/qq_31412239 ...

  7. 区块链软件 NFT游戏开发对战游戏

    案例背景 这是Axie 是一种新型游戏,部分由玩家拥有和运营.通过玩游戏升级并使用它们来决定游戏的未来! 案例详情 冒险对战,与奇美拉战斗并获得对升级 Axie 军队有用的稀有宝物!竞技场之战可以通过 ...

  8. Unity3d--坦克对战游戏 AI 设计

    一.作业要求 从商店下载游戏:"Kawaii" Tank 或 其他坦克模型,构建 AI 对战坦克.具体要求 使用"感知-思考-行为"模型,建模 AI 坦克 场景 ...

  9. 手把手教你用Java实现一个简易联网坦克对战小游戏

    作者:炭烧生蚝 cnblogs.com/tanshaoshenghao/p/10708586.html 介绍 通过本项目能够更直观地理解应用层和运输层网络协议, 以及继承封装多态的运用. 网络部分是本 ...

最新文章

  1. [Nova] Failed to get shared write lock Is another process using the image?
  2. 迈向成功的关键在于执行(摘自李开复博士的《做最好的自己》)
  3. 【华为大咖分享】5.交付在云端-全云DevOps研发实践(后附PPT下载地址)
  4. mysqld_exporter报错Error 1146: Table 'my2.status' doesn't exist
  5. 【笔试/面试】—— 奇葩 C/C++ 语法题(二)
  6. 腾讯二面:引入RabbitMQ后,你如何保证全链路数据100%不丢失 ?
  7. Java web切面编程
  8. html网站使用js实现记住账号密码功能
  9. TX-LCN分布式事务之LCN模式
  10. mysql innerdb 索引,MySQL系列-InnoDB索引优化AHI、Change buffer
  11. macOS、Shimo下载使用及路由配置
  12. 推进全息智慧情报研判,助力构建现代交通安全防控体系
  13. RxJava+Retrofit+Mvp实现购物车(没有结算页面)
  14. php中怎么设计出生日期,php – 将出生日期添加到数据库
  15. dede tag标签作用
  16. php artisan migrate,PHP artisan迁移不创建新表
  17. LNZ32P4-C - Pan-Tilt-Zoom (PTZ) Camera with 1080p HD Video Color Night Vision
  18. 耳机在macOS系统电脑上怎么听不到任何声音怎么办?
  19. C#使用TCP进行聊天通信(详细解析)
  20. python基础代码汇总

热门文章

  1. OSError: /home/yukang/anaconda3/envs/fsgan/lib/python3.9/site-packages/torch/lib/../../nvidia/cublas
  2. 重启IIS某个站点脚本
  3. 扶苏的bitset浅谈
  4. 如何把网页保存成html文档,怎么把网页存成word
  5. Redis 秒杀案例
  6. 汉仪尚巍手书有版权吗_汉仪尚巍手书字体下载 汉仪尚巍手书体W字体免费版下载...
  7. 【shell】Linux Shell远程执行命令
  8. she was A Phantom Of Delight
  9. ground truth解释
  10. c++中CreateEvent函数解析(2)