简单的坦克

作业题目

坦克对战游戏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以实现自动绕开障碍物寻找目标。
在这里插入图片描述

游戏运行

在这里插入图片描述

项目地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值