Unity——简单实现“贪吃蛇”

简单实现 2D 贪吃蛇

废话不多说直接上图上代码!

第一步 先搞一个背景 创建一个Canvas 再Canvas 下在创建一个Image 命名为bg

这样

第二步 创建一个蛇头 在Canvas 下创建一个Image 命名为SnakeHead(SnakeHead要在bg后面 这样才可以显示在背景的上方

第三步 实现蛇头的移动
创建一个脚本 命名为SnakeHeadController将脚本挂载到SnakeHead上

代码如下:

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

public class SnakeHeadController : MonoBehaviour
{

    public float Timer;                //游戏速度
    public int step;//蛇头的移动距离
    private int X;//移动的增量值
    private int Y;//移动的增量值
    private Vector3 HeadPos;//蛇头的坐标
    public GameObject bodyPrefab;    //蛇尾的预设
    //蛇身列表
    public List<Transform> bodyList = new List<Transform>();
    public Sprite[] bodySprites = new Sprite[2];//图片

    private void Start()
    {
        InvokeRepeating("OnMove", 0, Timer);
        SetSnakeHeadMoveOffset(step, 0); //设置初始移动的方向
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.W) && Y != -step)
        {
            SetSnakeHeadMoveOffset(0, step);
        }
        if (Input.GetKeyDown(KeyCode.S) && Y != step)
        {
            SetSnakeHeadMoveOffset(0, -step);
        }
        if (Input.GetKeyDown(KeyCode.A) && X != step)
        {
            SetSnakeHeadMoveOffset(-step, 0);
        }
        if (Input.GetKeyDown(KeyCode.D) && X != -step)
        {
            SetSnakeHeadMoveOffset(step, 0);
        }

        if (Input.GetKeyDown(KeyCode.Space))//加速
        {
            CancelInvoke();
            InvokeRepeating("OnMove", 0, Timer - 0.2f);
        }
        if (Input.GetKeyUp(KeyCode.Space))
        {
            CancelInvoke();
            InvokeRepeating("OnMove", 0, Timer);
        }
    }
    //监听移动
    public void OnMove()
    {
        HeadPos = gameObject.transform.localPosition;//获取头的位置
        gameObject.transform.localPosition = new Vector3(HeadPos.x + X, HeadPos.y + Y, HeadPos.z);//移动
        if (bodyList.Count > 0)
        { 
            for (int i = bodyList.Count - 2; i >= 0; i--)                                           //从后往前开始移动蛇身
            {
                bodyList[i + 1].localPosition = bodyList[i].localPosition;                          //每一个蛇身都移动到它前面一个节点的位置
            }
            bodyList[0].localPosition = HeadPos;                                                    //第一个蛇身移动到蛇头移动前的位置
        }
    }
    //设置偏移量
    public void SetSnakeHeadMoveOffset(int x, int y)
    {
        X = x;
        Y = y;
    }
    //生长尾巴
    public void Grow()
    {
        int index = (bodyList.Count % 2 == 0) ? 0 : 1;
        GameObject body = Instantiate(bodyPrefab, new Vector3(2000, 2000, 0), Quaternion.identity);
        body.GetComponent<Image>().sprite = bodySprites[index];
        body.transform.SetParent(GameObject.Find("Canvas").transform, false);
        bodyList.Add(body.transform);
    }
   //碰撞
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Food"))
        {
            Destroy(other.gameObject);//销毁食物
            this.Grow();//生长尾巴
            RangeFood.instance.AddFood();//添加食物
        }
    }

}

第四部 创建食物

首先 创建一个食物的预设体(注意 预设体要放在Resources 文件夹下)
Food是食物的预设 body 是蛇尾的预设
然后再创建一个空对象 用来创建食物 并且创建一个脚本挂载到 这个空对象上 命名为 RangeFood在这里插入图片描述
创建的食物代码如下:

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

public class RangeFood : MonoBehaviour
{
    public static RangeFood _instance;
    //单例
    public static RangeFood instance { get { return _instance; } }

    [Header ("食物的所有图片链表")]
    public List<Sprite> FoodSpriteList;
    [Header("食物预设")]
    public GameObject FoodPrefab;

    private void Awake()
    {
        _instance = this;
    }
    void Start()
    {
        instance.AddFood();//开始时添加一个食物

    }
    //获取单例
    public static RangeFood getInstance()
    {
        return instance;
    }
    //添加一个食物
    public void AddFood()
    {
        GameObject food = GameObject.Instantiate(FoodPrefab); //克隆一个食物的预制体
        food.GetComponent<Image>().sprite = FoodSpriteList[Random.Range(0, FoodSpriteList.Count - 1)];//随机一个食物的图片
        food.transform.parent = this.transform.parent;
        food.transform.localPosition = new Vector3(Random.Range(Const.WidthminX, Const.WidthmaxX), Random.Range(Const.HeightminY, Const.HeightmaxY), 0);//在这里给食物赋值一个随机的位置
        food.transform.localScale = Vector3.one;//让缩放为1
    }
}

这样就简单的实现了贪吃蛇 我们来看一下效果!在这里插入图片描述

如果对您有小小的帮助的话 就帮我点一个赞 鼓励一下新人吧

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
unity贪吃蛇游戏源码+AI-游戏源码: 1.利用ngui插件对界面进行了仿写 在仿写界面途中发现,贪吃蛇这个游戏在界面适应屏幕分辨率,所以在开发中需要注意界面对屏幕的适应性。通过每个图片的宽高 和uiroot的比值,在start方法中对他进行了缩放。 2.利用 ngui 自带的uidragdropItem实现摇杆 界面完成之后,首先对贪吃蛇的摇杆进行了编程。 在unity中的NGUI上,给sprite创建添加一个uidragdropitem 实现了sprite的拖动。 AI的开始,移动逻辑: 整体只考虑三个前景: 1.首先先判断蛇首的简介范围是否有其他蛇死亡了留下的食物,如果有的话设置当前朝向为星星方向,便设置移动倍率为2,否则判断第三种情况; 3.随机朝某个位置移动。如果每帧AI都在更新的话,蛇的反映速度依然会更快,需要设置一下AI的更新间隔,通过调整这个间隔和蛇首的简介方位来调整AI的反映速度,目的是能够让玩家有机会撞死AI。 AI 移动的方向分析: AI在一个平面上运动,坐标就只有两个<x,y> 把他用0和1表示为: ----- 4个方向 上下左右 (0,0) (0,1) (0,-1) (-1,0) (1,0) 四个角度 象限。 (-1,1) (1,1) (-1,-1) (1,-1) 设计思路就是把AI蛇也当作是用摇杆来控制的。那么AI就方便写多了,只是 在还没开始写之前,要考虑的就是AI蛇多了之后程序会不会卡死了。在使用线程控制的过程中发现了一个问题,cup利用率太高。所以想先尝试一下在update上操作。如果不行的在想其他的办法。 设计: 把每个AI蛇都相当于人在控制他。那么想象一下虚拟摇杆,用一个数组来存这些虚拟摇杆的位移坐标 把每条AI蛇的长度也记录下来,默认长度就20 错误: NullReferenceException: Object reference not set to an instance of an object AI6control.flootAIOneBody6 (Vector3 V) (at Assets/AI6control.cs:57) AI6control.AIsix () (at Assets/AI6control.cs:40) AI6control.Update () (at Assets/AI6control.cs:13) 该错误在百度上说:没有实例化的问题 最后一个下午的代码调试 发现由于自己的粗心 导致了把<符号写成了<=符号 就因为这个问题,让贪吃蛇变成了 卡神,害我看了好几天,现在解决了,贪吃蛇也变流畅了好多. Ai蛇也需要吃食物。长大,在游戏刚启动的时候就让Ai蛇在地图中吃食物,成长,当用户进入游戏的时候AI蛇已经吃到了一定的食物。测试了AI蛇确实发现他能吃食物。死后的处理也处理了。 在AI蛇吃食物的时候 ,地图中食物太多,控件太多。没法知道他是什么时候,查了资料说是要遍历地图中的对象,测试了一下,发现对象太多,程序卡得不要不要的,只能用触发器,避免遍历食物让程序运行不流畅或者变得死机等情况。 这样的话 在游戏中运行10-20条蛇是没有问题的。 地图中有10个点,这10个点是用来AI蛇死后复活的地方。 增加了限定时间模式. 经过很多的测试,也发现了很多的bug 不过都基本改完了,现在暂时没有发现bug
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值