Unity3D 2D贪吃蛇
Beat 1.0
只是实现了单个节点的移动,一个寒假没有用Unity 很多细节忘记了。反而在这里也花了很久的时间。
问题: 忘记将Rigibody 2D中的 Gravity Scale 设为0,导致在移动的时候一直往下掉,卡了蛮久想起来这个问题。
Beta 2.0
用队列得方式实现了贪吃蛇的移动,将身体依次入队,来实现贪吃蛇的链接,每次移动,只将最后一节身体出队,移到头节点刚刚离开的位置,然后入队。
因为每次移动都是走一格,控制速度是靠改变FixUpdate调用的频率
dest=transform.posiotion+dir*2
准备在3.0版本中试一下用一个节点跟着一个节点移动的方式实现一下。
素材包里没有墙的素材,还没做碰撞。大概会在3.0版本里补上
遇到的问题
原本吃食物用的碰撞检测是OnCollisionEnter2D 后来发现撞到食物后头结点的位置会稍微改变,导致后续身体节点的位置跟不上,会断开。所以将碰撞检测改成了 OnTriggerEnter2D
Beta 3.0
尝试了另一种运动方式,一个节点跟着一个节点得移动,并改变了移动方式所以看起来是更平滑的移动。
Vector2 p = Vector2.MoveTowards(transform.position, dest, speed);
GetComponent<Rigidbody2D>().MovePosition(p);
改进
增加了一个变量,判断何时改变蛇头的图片,这样就不会蛇头的图片已经换了方向,然而蛇还没转弯。
2.0的移动代码
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Collections;
public class Move : MonoBehaviour {
private Queue <GameObject> BodyQueue = new Queue<GameObject>();
public GameObject body_1;
public GameObject body_2;
public GameObject body_3;
public GameObject BodyPrefab;
public Vector2 dir = Vector2.right;
public Vector2 dest = Vector2.zero;
public static bool New = false;
const float speed=2;
// Use this for initialization
void Start () {
BodyQueue.Enqueue(body_3);
BodyQueue.Enqueue(body_2);
BodyQueue.Enqueue(body_1);
dest = transform.position;
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.UpArrow) && dir != -Vector2.up)
dir = Vector2.up;
if (Input.GetKey(KeyCode.RightArrow) && dir != -Vector2.right)
dir = Vector2.right;
if (Input.GetKey(KeyCode.DownArrow) && dir != Vector2.up)
dir = -Vector2.up;
if (Input.GetKey(KeyCode.LeftArrow) && dir != Vector2.right)
dir = -Vector2.right;
}
void FixedUpdate()
{
if ((Vector2)transform.position == dest)
{
HeadSprite.Changing = true;
if (New)
{
BodyQueue.Enqueue(Instantiate(BodyPrefab, transform.position, Quaternion.identity));
New = false;
}
else
{
GameObject last = BodyQueue.Dequeue();
BodyQueue.Enqueue(last);
last.transform.position = transform.position;
}
dest = (Vector2)transform.position + dir * speed;
}
transform.position = (Vector2)transform.position + dir * speed;
}
}
3.0的蛇头移动代码
using UnityEngine;
using System.Collections;
public class HeadMove : MonoBehaviour
{
public static float speed = 0.1f;
public Vector2 dest;
public Vector2 dir = Vector2.right;
public Vector2 Lastdir = Vector2.right;
// Use this for initialization
void Start()
{
dest = transform.position;
}
// Update is called once per frame
void FixedUpdate()
{
if ((Vector2)transform.position == dest)
{
HeadSprite.Changing = true;
Lastdir = dir;
dest = (Vector2)transform.position + dir * 2;
}
Vector2 p = Vector2.MoveTowards(transform.position, dest, speed);
GetComponent<Rigidbody2D>().MovePosition(p);
if (Input.GetKey(KeyCode.UpArrow) && dir != -Vector2.up)
dir = Vector2.up;
if (Input.GetKey(KeyCode.RightArrow) && dir != -Vector2.right)
dir = Vector2.right;
if (Input.GetKey(KeyCode.DownArrow) && dir != Vector2.up)
dir = -Vector2.up;
if (Input.GetKey(KeyCode.LeftArrow) && dir != Vector2.right)
dir = -Vector2.right;
}
}
身体移动
using UnityEngine;
using System.Collections;
public class BodyMove : MonoBehaviour {
public static bool New;
public static GameObject LastBody;
public GameObject pre;
public Vector2 dir=Vector2 .zero;
public Vector2 Lastdir=Vector2 .zero ;
public Vector2 dest;
public float speed;
public bool First;
public bool Last;
GameObject BodyPrefab;
// Use this for initialization
void Start () {
New = false;
speed = HeadMove.speed;
dest = transform.position;
BodyPrefab = (GameObject )Resources.Load("Prefabs/Body");
if(!Last)
LastBody = GameObject.Find("Body (2)");
}
// Update is called once per frame
void FixedUpdate()
{
if ((Vector2)transform.position == dest)
{
Lastdir = dir;
if (First)
dir = GameObject.Find("Head").GetComponent<HeadMove>().Lastdir;
else
dir = pre.GetComponent<BodyMove>().Lastdir;
if (New&&Last)
CreatBody();
dest = (Vector2)transform.position + dir*2;
}
Vector2 p = Vector2.MoveTowards(transform.position, dest, speed);
GetComponent<Rigidbody2D>().MovePosition(p);
}
void CreatBody()
{
GameObject NewBody;
Vector3 InitialPosition = transform.position - (Vector3)Lastdir * 2;
NewBody = Instantiate(BodyPrefab, InitialPosition, Quaternion.identity);
NewBody.GetComponent<BodyMove>().Last = true;
NewBody.GetComponent<BodyMove>().First = false;
NewBody.GetComponent<BodyMove>().pre = LastBody;
Last = false;
LastBody = NewBody;
New = false;
}
}
链接:http://pan.baidu.com/s/1slz0twL 密码:0qcq