Just for fun——Unity5制作貪吃蛇小游戲

前言

說出來你可能不信。有一天晚上睡不著覺,就突然想到做游戲開發(fā)這么久,還沒親手實現(xiàn)過經(jīng)典游戲貪吃蛇呢。然后就在床上想實現(xiàn)的方法,越想越手癢,要不是怕把枕邊人吵醒,第二天又要上班,真要立刻爬起來把這小游戲?qū)崿F(xiàn)了。于是想了一會兒,理清思路之后就逼自己入睡了。
第二天下班之后,回到家就開始動手,已經(jīng)搞定了。為了節(jié)約篇幅,本篇文章只簡單說下思路。不想看我廢話,需要直接參考代碼的同學(xué)可以到我的Github。

準備工作

我使用了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ū)分開。
如圖是我們需要的所有資源:

retro_snaker_res.png

其中,所有的材質(zhì)都使用上述的shader并指定不同的顏色。
除此之外,我們需要在Project Settings的Input中增加四個按鈕:
UP,DOWN,LEFT,RIGHT
我們的關(guān)卡也很簡單:
1.創(chuàng)建幾個Sphere物體當(dāng)做貪吃蛇的食物,設(shè)置位置為整數(shù)以便于我們的貪吃蛇在運動時能夠吃個正著(因為Unity默認的Cube物體的邊長是1,Sphere的半徑是0.5)。
2.將SphereCollider的半徑設(shè)小一點,例如0.25以便于我們的貪吃蛇碰到這些食物時看起來像真的吞噬了它們。
3.將SphereCollider設(shè)為觸發(fā)器。
看起來像這樣:

retro_snaker_level

實現(xiàn)

首先定義一個枚舉來代表節(jié)點運動的四個方向:

public enum MoveDir
{
    UP,
    LEFT,
    RIGHT,
    DOWN
}

我們僅需三個類來完成這個游戲的核心部分。
RetroSnaker負責(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ù)來完成運動。ChangeMoveDir函數(shù)接受用戶輸入并記錄轉(zhuǎn)向。

SnakeNode是組成貪吃蛇上每一個節(jié)點上的類。主要控制該節(jié)點運動。
部分代碼如下:

    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é)點的運動方向。所以我用一個list來記錄總共需要發(fā)生幾次轉(zhuǎn)向。用戶每產(chǎn)生一個有效的輸入就增加一個轉(zhuǎn)向。每次繪制后逐一對這些轉(zhuǎn)向遍歷,并將改變了的索引加1,下次繪制時即可改變后一節(jié)點的運動方向。如果索引超出了貪吃蛇的長度,則可以移除該轉(zhuǎn)向。
這里貼出完成一次移動后設(shè)置節(jié)點運動方向,以及移除一個轉(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!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 原文地址 http://www.fx114.net/qa-75-172454.aspx 使用Profiler工具...
    IongX閱讀 6,241評論 1 11
  • 111. [動畫系統(tǒng)]如何將其他類型的動畫轉(zhuǎn)換成關(guān)鍵幀動畫? 動畫->點緩存->關(guān)鍵幀 112. [動畫]Unit...
    胤醚貔貅閱讀 13,518評論 3 88
  • This article is a record of my journey to learn Game Deve...
    蔡子聰閱讀 4,109評論 0 9
  • 老爸是一九五三年出生的,沒過幾年好日子,六零年就到了。老爸就喜歡上學(xué),能有點吃的,家里人多,都吃不上飯,...
    馬有才2008閱讀 168評論 2 1
  • 不眠的夜晚在嘲笑永眠的靈魂, 黑色在嘲笑虛無,虛無沒有回應(yīng), 或者在回應(yīng)所有,你無法分辨。 逝去的,眉眼,借新的面...
    Probot閱讀 228評論 0 0

友情鏈接更多精彩內(nèi)容