前言
說出來你可能不信正塌。有一天晚上睡不著覺,就突然想到做游戲開發(fā)這么久恤溶,還沒親手實現(xiàn)過經(jīng)典游戲貪吃蛇呢乓诽。然后就在床上想實現(xiàn)的方法,越想越手癢咒程,要不是怕把枕邊人吵醒鸠天,第二天又要上班,真要立刻爬起來把這小游戲?qū)崿F(xiàn)了孵坚。于是想了一會兒粮宛,理清思路之后就逼自己入睡了。
第二天下班之后卖宠,回到家就開始動手巍杈,已經(jīng)搞定了。為了節(jié)約篇幅扛伍,本篇文章只簡單說下思路筷畦。不想看我廢話,需要直接參考代碼的同學(xué)可以到我的Github刺洒。
準(zhǔn)備工作
我使用了Unity自帶的創(chuàng)建簡單3D物體的功能來制作蛇頭和蛇身的prefab鳖宾。蛇身直接用Cube,而蛇頭需要添加BoxCollider和Rigidbody組件逆航。為了將不同的物體區(qū)別開鼎文,我還寫了一個純色的shader:
Shader "Custom/PureColor" {
Properties{
_Color ("顏色", Color) = (0.8 ,0,0,0)
}
SubShader {
Pass{
Color[_Color]
}
}
FallBack "Diffuse"
}
我們可以創(chuàng)建一個材質(zhì),將材質(zhì)的shader設(shè)為Custom/PureColor因俐,再將該材質(zhì)賦給特定物體拇惋。可以用這個shader創(chuàng)建多個材質(zhì)與其他物體區(qū)分開抹剩。
如圖是我們需要的所有資源:
其中撑帖,所有的材質(zhì)都使用上述的shader并指定不同的顏色。
除此之外澳眷,我們需要在Project Settings的Input中增加四個按鈕:
UP,DOWN,LEFT,RIGHT
我們的關(guān)卡也很簡單:
1.創(chuàng)建幾個Sphere物體當(dāng)做貪吃蛇的食物胡嘿,設(shè)置位置為整數(shù)以便于我們的貪吃蛇在運(yùn)動時能夠吃個正著(因為Unity默認(rèn)的Cube物體的邊長是1,Sphere的半徑是0.5)钳踊。
2.將SphereCollider的半徑設(shè)小一點衷敌,例如0.25以便于我們的貪吃蛇碰到這些食物時看起來像真的吞噬了它們勿侯。
3.將SphereCollider設(shè)為觸發(fā)器。
看起來像這樣:
實現(xiàn)
首先定義一個枚舉來代表節(jié)點運(yùn)動的四個方向:
public enum MoveDir
{
UP,
LEFT,
RIGHT,
DOWN
}
我們僅需三個類來完成這個游戲的核心部分逢享。
RetroSnaker負(fù)責(zé)游戲的主要控制罐监,包括游戲狀態(tài)更新吴藻,用戶輸入瞒爬,產(chǎn)生新節(jié)點等。
部分代碼如下:
void Awake()
{
_snakeHeadPrefab = Resources.Load(_snakeHeadResPath) as GameObject;
_snakeNodePrefab = Resources.Load(_snakeNodeResPath) as GameObject;
}
// Use this for initialization
void Start()
{
RetroSnakerStart();
}
// Update is called once per frame
void Update()
{
if (_isInPause)
return;
_timer += Time.deltaTime;
if (_timer >= _timeGap)
{
_timer = 0.0f;
MoveSnake();
}
ChangeMoveDir();
}
RetroSnakerStart函數(shù)在游戲開始時生成一條起始蛇沟堡。MoveSnake函數(shù)主要調(diào)用當(dāng)前所有節(jié)點的Move函數(shù)來完成運(yùn)動侧但。ChangeMoveDir函數(shù)接受用戶輸入并記錄轉(zhuǎn)向。
SnakeNode是組成貪吃蛇上每一個節(jié)點上的類航罗。主要控制該節(jié)點運(yùn)動禀横。
部分代碼如下:
public void Move()
{
switch (moveDir)
{
case MoveDir.UP:
MoveUp();
break;
case MoveDir.DOWN:
MoveDown();
break;
case MoveDir.LEFT:
MoveLeft();
break;
case MoveDir.RIGHT:
MoveRight();
break;
}
}
Apple是我們的貪吃蛇要吃的東西,將掛載到我們創(chuàng)建的Sphere物體上粥血。
代碼如下:
using UnityEngine;
using System.Collections;
public class Apple : MonoBehaviour
{
public static int numberOfObjects = 0;
#region mono
// Use this for initialization
void Start()
{
++numberOfObjects;
}
void OnTriggerEnter(Collider collider)
{
gameObject.SetActive(false);
--numberOfObjects;
RetroSnaker snake = GameObject.FindObjectOfType<RetroSnaker>();
if (snake != null && snake.isActiveAndEnabled)
snake.OnEatApple();
}
#endregion mono
}
在Apple類中我們使用一個靜態(tài)成員numberOfObjects記錄Apple的數(shù)量,這樣當(dāng)該成員變?yōu)?時复亏,則我們吃光了Apple,完成關(guān)卡缔御。
主要難點我感覺在于貪吃蛇接受輸入后轉(zhuǎn)向,其余節(jié)點在下次繪制時要跟隨上一節(jié)點的運(yùn)動方向耕突。所以我用一個list來記錄總共需要發(fā)生幾次轉(zhuǎn)向笤成。用戶每產(chǎn)生一個有效的輸入就增加一個轉(zhuǎn)向。每次繪制后逐一對這些轉(zhuǎn)向遍歷眷茁,并將改變了的索引加1炕泳,下次繪制時即可改變后一節(jié)點的運(yùn)動方向上祈。如果索引超出了貪吃蛇的長度培遵,則可以移除該轉(zhuǎn)向。
這里貼出完成一次移動后設(shè)置節(jié)點運(yùn)動方向雇逞,以及移除一個轉(zhuǎn)向的代碼:
List<int> tempIndexs = new List<int>();
for (int i = 0; i < _indexs.Count; i++)
{
int index = _indexs[i];
if (index > 0 && index < _snake.Count)
{
_snake[index].moveDir = _snake[index - 1].moveDir;
_indexs[i]++;
}
if (_indexs[i] < _snake.Count)
tempIndexs.Add(_indexs[i]);
}
_indexs = tempIndexs;
最后荤懂,還是建議你到我的Github查看完整工程塘砸。Have Fun!