unity----贪吃蛇详解

忙碌的一周又过去了,代码谁都会写,重要的是思维,同一个功能每个人都有每个人的实现方法,所以要先去想自己怎么去实现这个功能,在摸不到头绪的时候去参考别人的代码,然后回来再想自己的代码怎么实现。

游戏开发的重点就是把一个游戏拆开,怎么去实现它。

贪吃蛇的玩法:按键控制它得移动,吃到食物之后,食物消失,它会在身体的末端增加一个身体,当撞到墙或者自己身体的时候,游戏结束

相对,要实现的功能也就显而易见了

先分析游戏里用到的对象

1.蛇头

2.蛇身子

3.食物

4.地面

5.墙

再分析游戏的功能怎么实现

1键盘控制它得移动--------可以使用InPut.GetKey来实现它的移动

2.吃到食物后,食物消失,也就是食物跟蛇头相接触后,食物消失---------可以采用碰撞检测或触发检测来实现,很明显,我们不需要食物跟蛇头产生“碰撞”效果,所以采用触发检测来实现

3.蛇在吃到食物之后,它得身体会增长1-------可以把身体做成预设体,在蛇头跟食物相接触的时候,实例化一个身子

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">4.</span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">当撞到墙或者自己身体的时候,游戏结束----同样可以采用触发检测的方法来实现</span>

游戏的实现方法大体都分析明白了,但是有一个问题,蛇头移动,身体跟着它动,这要怎么实现,也就是一个跟着一个移动的实现方法

这也算是游戏的核心算法了吧,跟数据结构里的链表是不是很像,头把它的位置传给第一个身子,第一个身子把它得位置传给第二个身子........

源码:

SnackHead 身上的HeadMove脚本

using UnityEngine;
using System.Collections;

public class HeadMove : MonoBehaviour {

	public GameObject snack_Body;
	private GameObject firstBody;
	private GameObject lastBody;
	private GameObject CreatedBody;
	
	//随机生成食物球
	private float cube_foodMax_X =12F;
	private float cube_foodMin_X = -12.8f;
	private float cube_foodMax_Z =14f;
	private float cube_foodMin_Z = -13.8f;
	public GameObject cube_food;
	private float timer = 0f;
	private float time = 0.3f;
	private GameObject cc;
	
	void RandomFood(){
		//随机在哪个位置上生成球
		//求它能出现的最大范围
		//x=-12.8 ,12 z = -13.8, 14
		float cube_food_PositionX = Random.Range (cube_foodMin_X,cube_foodMax_X);
		float cube_food_PositionZ = Random.Range (cube_foodMin_Z,cube_foodMax_Z);
	        cc = Instantiate (cube_food, new Vector3 (cube_food_PositionX,0,cube_food_PositionZ), Quaternion.identity)as GameObject;
	}

	void Start () {
		RandomFood ();
	}
	
	
	/// <summary>
	///  按键移动
	/// W:forward
	/// S:back
	/// A:left
	/// D:right
	/// </summary>

	void Update () {
     
		if (timer > time) {
			 Vector3 old = this.transform.position;
         
			this.transform.position += transform.forward;
			if (firstBody != null) {
          
             //   firstBody.transform.position = old;
				firstBody.GetComponent<CreateBody> ().moveTo (old);
			}
			timer = 0;
		} else {
			timer+=Time.deltaTime;
		}
		//当它得尾巴在前,头在后时,此时,它就不能往前走了(尾巴不能拖着头走)
		if(Input.GetKeyDown(KeyCode.W)&&Vector3.Angle(Vector3.forward,this.transform.forward)<160f){
			//此时可以移动了
			//类似于单链表,头移动,头的坐标传给第一个身体,第一个身体传给第二个身体......
			//写一个移动的方法
			this.transform.forward = Vector3.forward*1;

		}
        if (Input.GetKeyDown(KeyCode.S) && Vector3.Angle(Vector3.back,this.transform.forward) < 160f)
        {
			this.transform.forward = Vector3.back*1;
		}
        if (Input.GetKeyDown(KeyCode.A) && Vector3.Angle(Vector3.left,this.transform.forward) < 160f)
        {
			this.transform.forward = Vector3.left*1;
		}
        if (Input.GetKeyDown(KeyCode.D) && Vector3.Angle(Vector3.right,this.transform.forward) < 160f)
        {
			this.transform.forward = Vector3.right*1;
		}

	}
	void Move(){
     GameObject      CreatedBodys = Instantiate(snack_Body, new Vector3(100f, 100f, 100f), Quaternion.identity) as GameObject;
        if(lastBody!=null){
            lastBody.GetComponent<CreateBody>().next = CreatedBodys;
        }
		if (firstBody== null) {
		   
			firstBody = CreatedBodys;
            print("firstBody==null");
		}
 
	lastBody = CreatedBodys;

	}

	void OnTriggerEnter(Collider other){
		if(other.gameObject.tag.CompareTo("food")==0){

			//创建一个身体
			Destroy(cc);
	
			RandomFood();
            Move();
		}


	}
}


Body身上的CreateBody脚本

using UnityEngine;
using System.Collections;

public class CreateBody : MonoBehaviour {

	public GameObject next;
	void Start () {
	
	}
	

	void Update () {
	
	}

	public void moveTo(Vector3 pos){
		Vector3 old = this.transform.position;
		this.transform.position = pos;//当前坐标变为pos.
		if(next!=null){
			next.GetComponent<CreateBody>().moveTo(old);
		}



	}
}










  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值