简单的坦克

2023-10-31

作业题目

坦克对战游戏AI设计

作业要求

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

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

实现过程

首先从asset store中下载坦克资源,然后将里面的地图拖入场景中,直接使用他提供的地图。
在这里插入图片描述
地图上存在很多障碍物,可以达到测试的效果。

坦克的设计

游戏中存在两种坦克:AI坦克与玩家控制的坦克。首先设计坦克基类以实现基本的坦克功能。
主要有血量的设置与获取,然后是子弹的发射。

public float getblood()
{
    return blood;
}
public void setblood(float b)
{
    blood = b;
}

public void shoot(TankType type)
{
    GameObject bullet = Singleton<factory>.Instance.getBullets(type);
    bullet.transform.position = new Vector3(transform.position.x, 1.5f, transform.position.z) + transform.forward * 1.5f;
    bullet.transform.forward = transform.forward; //方向
    bullet.GetComponent<Rigidbody>().AddForce(bullet.transform.forward * 20, ForceMode.Impulse);
}

对于AI坦克来说其继承了坦克基类,然后可以根据玩家的坐标实现自动追踪玩家;还可以每隔一段时间发射炮弹。

void Update()
{
    playerpo = GameDirector.getInstance().currentSceneController.getPlayer().transform.position;
    gameover = GameDirector.getInstance().currentSceneController.getGameOver();
    if (!gameover)
    {
        if (getblood() <= 0 && recycle_event != null)
        {
            recycle_event(this.gameObject);
        }
        else
        {
            // 自动向player移动
            NavMeshAgent agent = gameObject.GetComponent<NavMeshAgent>();
            agent.SetDestination(playerpo);
        }
    }
    else
    {
        //游戏结束,停止寻路
        NavMeshAgent agent = gameObject.GetComponent<NavMeshAgent>();
        agent.velocity = Vector3.zero;
        agent.ResetPath();
    }
}

IEnumerator shoot()
{
    while (!gameover)
    {
        for (float i = 1; i > 0; i -= Time.deltaTime)
        {
            yield return 0;
        }
        if (Vector3.Distance(playerpo, gameObject.transform.position) < 14)
        {
            shoot(TankType.ENEMY);
        }
    }
}

对于玩家控制的坦克主要实现移动与发射炮弹功能,发射子弹已在父类tank实现,所以只需要实现移动即可。

void Update () {
    if (getblood() <= 0)
    {
        gameObject.SetActive(false);
        destroy_event();
    }
}

public void moveup()
{
    gameObject.GetComponent<Rigidbody>().velocity = gameObject.transform.forward * 10;
}

public void movedown()
{
    gameObject.GetComponent<Rigidbody>().velocity = -gameObject.transform.forward * 10;
}

public void turn(float jiao)
{
    //根据主轴旋转
    gameObject.transform.localEulerAngles = new Vector3(gameObject.transform.localEulerAngles.x, gameObject.transform.localEulerAngles.y + jiao * 2, 0);
}
游戏的控制

使用一个场景类来对游戏进行控制,包括游戏的开始与结束以及获取玩家对坦克的控制。

//返回游戏状态
public bool getGameOver()
{
    return gameOver;
}

//设置游戏结束
public void setGameOver()
{
    gameOver = true;
}

//玩家控制坦克移动
public void moveForward()
{
    p.GetComponent<player>().moveup();
}
public void moveBackWard()
{
    p.GetComponent<player>().movedown();
}

//通过水平轴上的增量,改变玩家坦克的欧拉角,从而实现坦克转向
public void turn(float offsetX)
{
    p.GetComponent<player>().turn(offsetX);
}

public void shoot()
{
    p.GetComponent<player>().shoot(TankType.PLAYER);
}

AI坦克与子弹采用工厂模式生产,子弹在坦克之间是通用的。

public GameObject getEnemys()
{
    GameObject newTank = null;
    if (freeTanks.Count <= 0)
    {
        newTank = GameObject.Instantiate<GameObject>(enemy) as GameObject;
        usingTanks.Add(newTank);
        newTank.transform.position = new Vector3(Random.Range(-100, 100), 0, Random.Range(-100, 100));
    }
    else
    {
        newTank = freeTanks[0];
        freeTanks.RemoveAt(0);
        usingTanks.Add(newTank);
    }
    newTank.SetActive(true);
    return newTank;
}

public GameObject getBullets(TankType type)
{
    GameObject newBullet;
    if (freeBullets.Count <= 0)
    {
        newBullet = GameObject.Instantiate<GameObject>(bullet) as GameObject;
        usingBullets.Add(newBullet);
        newBullet.transform.position = new Vector3(Random.Range(-100, 100), 0, Random.Range(-100, 100));
    }
    else
    {
        newBullet = freeBullets[0];
        freeBullets.RemoveAt(0);
        usingBullets.Add(newBullet);
    }
    newBullet.GetComponent<bullet>().setTankType(type);
    newBullet.SetActive(true);
    return newBullet;
}

然后再使用一个类获取用户的输入,实现用户对坦克的控制。

void Update()
{
    if (!action.getGameOver())
    {
        if (Input.GetKey(KeyCode.W))
        {
            action.moveForward();
        }

        if (Input.GetKey(KeyCode.S))
        {
            action.moveBackWard();
        }


        if (Input.GetKeyDown(KeyCode.Space))
        {
            action.shoot();
        }
        //获取水平轴上的增量,目的在于控制玩家坦克的转向
        float offsetX = Input.GetAxis("Horizontal");
        action.turn(offsetX);
    }
}

然后设置AI坦克的navigation以实现自动绕开障碍物寻找目标。
在这里插入图片描述

游戏运行

在这里插入图片描述

项目地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简单的坦克 的相关文章

  • 树实现客户端红点系统

    树实现客户端红点系统 红点系统总览 demo 设计 代码设 引用 https zhuanlan zhihu com p 85978429 红点系统总览 如上图所示 规划红点系统的时候 我们将整个系统分为独立的三个部分 结构层 驱动层和表现层
  • unity3D期末作业捕鱼游戏,适合初学者学习使用,包含源程序所有文件

    虚拟现实期末作业捕鱼游戏 免积分下载 点我下载资源 有按钮 背景音乐 可以发射炮弹捕鱼 可以选择难度 可以调节音乐声音大小 有游戏加载进度条 详细情况请看如下动态图 点我下载资源
  • URP——后期处理特效

    通用渲染管道 URP 包括一个后处理效果的集成实现 如果使用URP 则不需要为后期处理效果安装额外的包 URP与Post Processing Stack v2包不兼容 URP使用体积框架进行后期处理效果 下面的图片显示了一个URP场景有没
  • Unity 实现选框选中物体

    最近在看RTS游戏视频注意到了选框功能 就尝试做了一下 功能实现 脚本挂载到Camera上 要不然OnPostRender 函数无法调用 rectMat新建一个材质球 设置成默认的Sprites就可以了 using System Colle
  • Unity3d中使用OnGUI()函数判断“键盘按下抬起”功能的新方法。

    private bool flagJudgeDownAllow true 开始值为true void OnGUI key Event current FunctionKeyCodeV1 key private void FunctionKe
  • Unity的Text Mesh Pro文字显示重叠处理

    在使用Text Mesh Pro的时候 出现文字重叠 如图 在编辑器内显示是正确的 最后发现是换行造成的 原本的文字是从pdf中复制过来 就会重叠 在记事本中删除换行用回车再次换行就能正确显示
  • Unity笔记-打飞碟游戏

    目的 创建一个打飞碟游戏 简陋 游戏要求 游戏要分多个 round 飞碟数量每个 round 都是 n 个 但色彩 大小 发射位置 速度 角度 每次发射数量可以变化 游戏过程中 仅能创建 n 个飞碟 且不容许初始化阶段生成任何飞碟 飞碟线路
  • Unity+Pico 手柄按键控制

    一 定义手柄按键API 1 InputDevices GetDeviceAtXRNode 通过XRNode获取对应的设备 2 XRNode是一个枚举类型 包含LeftEye RightEye CenterEye Head LeftHand
  • 闲云:unity中不能识别monobehevior关键字的问题

    有时候一些小问题很恼人 如unity中新建脚本后不能识别monobehevior关键字 在vs2017右侧的解决方案中点击刷新图标 或者把不能识别的脚本添加到vs2017右侧的解决方案中的Assets中即可 还不行就点击 排除 然后再 添加
  • Unity使用Newtonsoft报错的解决方案

    文章目录 Unity 使用 Newtonsoft 报错的解决方案 问题描述 解决方法 方法一 使用 Unity 的 Package Manager 自动导入 方法二 访问 GitHub 下载 unitypackage 文件手动导入 Unit
  • unity3d 理解刚体(Rigidbody)和碰撞体(Collider)以及触发器(Is Trigger),边学边更新

    unity3d 理解刚体 Rigidbody 和碰撞体 Collider 以及触发器 Is Trigger 边学边更新 分类 Unity3D 2014 04 01 16 50 2755人阅读 评论 2 收藏 举报 刚体 Rigidbody
  • Unity_如何使相机视角一直跟随角色移动

    实例代码如下 using System Collections using System Collections Generic using UnityEngine 相机视角跟踪 public class FollowTarget Mono
  • unity3d 输入法相关API

    Input inputString 获取输入的文字 正在打的中文是接受不到的 只有在文字写到文本框才能获取 Input imeCompositionMode 是否是激活输入框状态 on 是 Input compositionString 空
  • unity中的一些快捷键(齐)

    重命名的快捷键是F2 ALT 鼠标左键点击Hierarchy对象可以展开和收起对象的所有子物体 SHIFT 空格 可以对当前窗口进行放大缩小
  • Unity使用spine动画

    Unity使用spine动画 在 Unity 中 常常使用 Spine 来制作一些动画 引擎本身并不能直接播放 Spine 动画 需要额外导入一个 RunTime 插件库才能支持 官网插件导入 当然 也可以到 Spine 官网关于 Unit
  • Input.GetAxis _ Unity3d

    Input GetAxis 获取轴 static function GetAxis axisName string float Description描述 Returns the value of the virtual axis iden
  • 对Unity3D 静态批处理和动态批处理的理解

    Draw Call就是CPU调用图像编程接口 像OpenGL或者 DirectX 简单来说 Draw Call就是由CPU发起的一个命令 添加到一个命令缓冲区 当GPU完成了上一次的渲染任务之后 会从命令缓冲区的命令队列中再取出一个并执行
  • Unity3D:按键生成物件,Instantia…

    在按下按键之后 可以在画面中生成之前定义好了的物体 这里使用了Instantiate函数来生成 1 先在游戏中定一个空物件GameObject 创建空物件快捷键 ctrl shift n 2 在视图中放置 3 编写脚本 脚本 SpaceCh
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • unity dots jobSystem 记录

    Looking for a way to get started writing safe multithreaded code Learn the principles behind our Job System and how it w

随机推荐

  • 笔试题(十二):走梅花桩

    Redraiment是走梅花桩的高手 Redraiment可以选择任意一个起点 从前到后 但只能从低处往高处的桩子走 他希望走的步数最多 你能替Redraiment研究他最多走的步数吗 数据范围 每组数据长度满足 1 n 200 数据大小满
  • 利用Charles打断点修改返回数据

    1 选择你需要修改数据的接口 2 选中后 proxy gt breakPoint Setting 在出来的弹窗中找到你标记的接口 双击 选择对应的方法 get post 然后将Query里面的删掉 写上 确保一下request和respon
  • python学习之基于Python的人脸识别技术学习

    摘要 面部识别技术的应用越来越广泛 它广泛应用于安全系统 人机交互 社交媒体 医疗保健等领域 本文介绍了基于Python的人脸识别技术 包括人脸检测 人脸特征提取和人脸识别三个部分 我们使用OpenCV和Dlib库来实现这些功能 并使用Py
  • Python实现最小顶点覆盖算法

    Python实现最小顶点覆盖算法 最小顶点覆盖问题是图论中的重要问题 其目标是找到至少数量的顶点 使得每一条边至少有一个端点被这些顶点所覆盖 该问题在实际中有诸多应用 例如网络流分析和计算机视觉等领域 本文将介绍如何使用Python实现最小
  • 10.Docker(一)-----安装、初步使用、镜像、Dockerfile常用指令、通过Dockerfile文件封装nginx镜像并优化

    安装 初步使用 镜像 Dockerfile常用指令 通过Dockerfile文件封装nginx镜像并优化 一 简介 二 安装 1 安装配置 仓库配有的安装包 安装 桥接 2 导入马里奥游戏 浏览器访问172 25 15 1 3 删除 4 导
  • 删除链表中重复的元素

    题目描述 给定一个排序链表 删除所有含有重复数字的节点 只保留原始链表中 没有重复出现 的数字 样例 输入 1 gt 2 gt 3 gt 3 gt 4 gt 4 gt 5 输出 1 gt 2 gt 5 分析 从头结点开始遍历该链表 如果当前
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • 逆向工具(IDA、pyinstxtractor+uncompyle6、jadx等持续更新)

    IDA Pro IDA Pro Interactive Disassembler Professional 交互式反汇编器专业版 CTF RE PWN必备 打开一个可执行文件前 应先用file命令或者DIE等工具 确定是32位还是64位 然
  • 使用armDebian基本的操作方式

    1 查看进程id pgrep ttnode 2 杀死进程 kill 1308 3 查看硬盘的分区 sudo fdisk l 3 卸载文件卷 umount dev sda1 4 格式化 mkfs vfat dev sda1 5 重启 rebo
  • C++:类和对象(中)---默认成员函数---运算符重载---const的含义

    文章目录 默认成员函数 构造函数 析构函数 拷贝构造函数 运算符重载 赋值运算符重载 const的含义 取地址及const取地址操作符重载 默认成员函数 首先要理解什么是默认成员函数 类在什么都不写的时 编译器会生成六个默认成员函数 用户没
  • 阿里微服务架构Spring Cloud Alibaba Nacos实战

    Spring Cloud Alibaba Nacos 1 常用特性 2 注册中心 配置中心对比 3 生态图 4 安装 5 名词解析 6 代码实战 注册中心 配置中心 nacos官方文档 https nacos io zh cn docs q
  • multipart/form-data格式接口调用工具类,实现文件上传

    1 添加依赖
  • Access violation at address 00000000. Read of address 00000000.的解决办法

    Access violation at address 00000000 Read of address 00000000 原理 解决办法 在使用spacesniffer查看C盘空间的时候报错 原理 这个问题是关于Access Violat
  • ZBrush中自动保存在哪里

    在使用 ZBrush 执行任何会话期间 您都可以设置将文件自动保存 并可以修改保存时间间隔 文件保存位置等设置 发生系统错误后要重新启动ZBrush时 可以从临时文件夹或指定的文件夹中恢复备份文件 如果您选择不恢复备份文件 退出应用程序后文
  • Android内存泄漏原因及解决办法

    前言 面试中最常问的就是 你了解Android内存泄漏和Android内存溢出的原因吗 请简述一下 然后大多数的人都能说出原因及其例子和解决办法 但是实际项目中稍微不注意还是会导致内存泄漏 今天就来梳理一下那些是常见的内存泄漏写法和解决方法
  • 1.2小尺度衰落

    书接上文 谈完大尺度衰落 接下来谈谈传输过程中遇到的小尺度衰落 小尺度衰落是指短期内的衰落 具体指移动台移动小距离时 接收信号在短期内的波动 通常可由以下因素决定 多径传播 移动台的速度 周围物体的速度和信号传输带宽 1 2 1 小尺度衰落
  • 基于Flex (词法分析生成器) 构造词法分析器

    备忘录1 阿林的词法分析器答辩内容 前言 我们知道 通过一些词法分析生成器工具可以完成一个编译器的词法分析过程 比如说flex 我们可以通过它完成词法分析过程 但是它完成了这个过程并不会将整个词法分析的结果打印出来 因此我们需要使用正则表达
  • 小程序开发之WebSocket

    本文旨在记录如何实现小程序使用websocket接受 推送消息 websocket 是什么 websocket 服务器端和客户端 小程序如何和websocket建立连接 并实现消息推送 接受 websocket是什么 websocket是一
  • 一套干净的企业数据管理系统,拿来直接用

    项目介绍 此项目为企业数据管理系统的后端部分 前端部分请参考vue admin 项目实现了菜单管理 用户管理 角色管理和权限管理四个基础模块 前端菜单管理结合动态路由可自由添加菜单 结合Shiro权限管理实现了菜单和按钮的权限控制 前端采用
  • 简单的坦克

    作业题目 坦克对战游戏AI设计 作业要求 从商店下载游戏 Kawaii Tank 或 其他坦克模型 构建 AI 对战坦克 具体要求 使用 感知 思考 行为 模型 建模 AI 坦克 场景中要放置一些障碍阻挡对手视线 坦克需要放置一个矩阵包围盒