临时兴起,写一个贪吃蛇教程吧。
本来觉得会很好写,结果写了整整一下午,还是自己代码写的太少,操作起来不灵活,思路会短路。
废话不多说。先上图:
逻辑很简单,但自己本来在明确思路的情况下却在写代码时走了弯路,核心部分是蛇吃了绿色的食物后,变长。
我的方法是存储蛇的最后一节身体位置,每次添加新的长度到末尾。
这里要注意的是采取,从尾至头的方式移动蛇前进,而不是通常我们理解的从头至尾。目的就是方便操作同时到达蛇形蜿蜒的效果。
下面是主题代码:
using UnityEngine;
using System.Collections;
public class GameManager : MonoBehaviour {
private const int height = 14;
private const int width = 14;
private Vector2 origin = new Vector2(-1.84f,-1.25f);
private const float moveUnit = 0.28f;
private bool[,] Meshs = new bool[height,width];
private GameObject[] snakeArray = new GameObject[100];
private GameObject head;
private GameObject food = null;
private Vector2[] snakePositions = new Vector2[100];
public GameObject[] snakeHead = new GameObject[4];
public GameObject snakeBody;
public GameObject food_prefab;
public Animator gameover;
private int direction;
private int head_direction;
private int snakeIndex=0;
public static bool IsGameOn;
// Use this for initialization
void Start () {
InitGame ();
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.LeftArrow)){
direction = 0;
SnakeMove();
}
if(Input.GetKeyDown(KeyCode.RightArrow)){
direction = 1;
SnakeMove();
}
if(Input.GetKeyDown(KeyCode.UpArrow)){
direction = 2;
SnakeMove();
}
if(Input.GetKeyDown(KeyCode.DownArrow)){
direction = 3;
SnakeMove();
}
}
private void InitGame(){
IsGameOn = true;
for (int k=0; k<100; k++)
snakeArray [k] = null;
for (int k=0; k<100; k++)
snakePositions [k] = Vector2.zero;
int i = Random.Range (0,4);//0,1,2,3 represents Left,Right,Up and Down
head_direction = i;
direction=head_direction;
Vector2 originalPosition = new Vector2 (origin.x+moveUnit*7,origin.y+moveUnit*7);
snakePositions [0] = new Vector2 (7, 7);//head's axis value
head = (GameObject)Instantiate (snakeHead[i],originalPosition,Quaternion.identity);
snakeArray [0] = head;
SnakeMove ();
GenerateFood ();
}
private void SnakeBodyMove(){
snakePositions[99] = snakePositions[snakeIndex];
for (int i=snakeIndex; i>0; i--) {
if(snakePositions[i]!=Vector2.zero){
snakePositions[i] = snakePositions[i-1];
if(snakeArray[i]!=null){
snakeArray[i].transform.position = new Vector2(origin.x + moveUnit *snakePositions[i-1].x,origin.y + moveUnit *snakePositions[i-1].y);
}
}
}
}
private void SnakeMove(){
CancelInvoke ("SnakeMove");
if (!IsGameOn)
return;
SnakeBodyMove();
switch(direction){
case 0:
//Debug.Log("0position"+snakePositions[99]);
checkSnakeHead();
head.transform.Translate(-moveUnit,0,0);
snakePositions[0].x--;
Invoke("SnakeMove",0.5f);
break;
case 1:
checkSnakeHead();
head.transform.Translate(moveUnit,0,0);
//snakePositions[99].x++;
snakePositions[0].x++;
Invoke("SnakeMove",0.5f);
break;
case 2:
checkSnakeHead();
head.transform.Translate(0,moveUnit,0);
//snakePositions[99].y++;
snakePositions[0].y++;
Invoke("SnakeMove",0.5f);
break;
case 3:
checkSnakeHead();
head.transform.Translate(0,-moveUnit,0);
//snakePositions[99].y--;
snakePositions[0].y--;
Invoke("SnakeMove",0.5f);
break;
default:
break;
}
if(snakePositions[0].x<0||snakePositions[0].x>13||snakePositions[0].y<0||snakePositions[0].y>13){
IsGameOn=false;
gameover.enabled = true;
}
}
private void checkSnakeHead(){
if(direction!=head_direction){
head_direction = direction;
GameObject tmp = head;
head = (GameObject)Instantiate (snakeHead[head_direction],head.transform.position,Quaternion.identity);
snakeArray[0] = head;
Destroy(tmp.gameObject);
}
}
public void GenerateFood(){
int i = Random.Range (0,14);
int j = Random.Range (0,14);
GameObject tmp = food;
food = (GameObject)Instantiate (food_prefab,new Vector2(origin.x+moveUnit*j,origin.y+moveUnit*i),Quaternion.identity);
if(tmp!= null)
Destroy (tmp.gameObject);
}
public void SnakeGrow(){
snakeIndex++;
Vector2 endPosition = new Vector2 (origin.x + moveUnit * snakePositions[99].x, origin.y + moveUnit * snakePositions[99].y);
snakeArray[snakeIndex] =(GameObject)Instantiate (snakeBody,endPosition,Quaternion.identity);
snakePositions [snakeIndex] = snakePositions [99];
}
}