1. 程式人生 > >Unity3D初級案例-經典貪吃蛇一

Unity3D初級案例-經典貪吃蛇一

引言:小生今日分享的是經典貪吃蛇案例,特別感謝Siki學院的老師們。小生會根據自己理解,做一些程式碼上的修改!大家也可以有自己的主見!開發版本:unity 2017.1.1f1適合人群:初學Unity者原始檔連結請見文末!開啟學習之旅吧!效果預覽:主要實現功能:WASD鍵或上下左右鍵控制蛇移動方向,吃到冰淇淋加分,並且增長蛇身。遊戲提供兩種蛇的樣式可選,而且有兩種有無邊界模式可選。記錄當前得分和歷史最高分。

01 場景搭建

新建2D工程,新建StartScene場景,Game場景設定為1280*720大小,匯入資源我們使用UGUI製作UI及人物,開始介面效果如下:Canvas要設定為Screen Sapce Camera模式需要注意的是,面板和模式分別只能二選一,Toggle Group的Allow Switch off不能勾選
新建主場景MainScene,效果如下:因為需要開發一個邊界模式,新建四個物件,放入場景四邊,並新增碰撞體,勾選Is Trigger注意四面牆分別命名為Up,Down,Left,Right,新建一個父物件統一管理

02 實現思路

有兩種主要方式可以實現蛇的移動第一種方式,從蛇尾的最後開始一節開始,依次向前一節蛇身的位置移動第二種,蛇頭每向前移動一個位置,就將蛇尾的最後一節移動到蛇頭剛才的位置我們選擇第一種方式,因為我們的蛇有兩種顏色相間的蛇身,如果第二種方式,會讓蛇身的顏色混亂

03 開發蛇頭

新建一個Image,命名為SnackHead,Source Image修改為蛇頭圖片,長寬設定為45*45,新增Rigidbody2D和BoxCollider2D元件,勾選Is Trigger,為其新增一個空的父物體Snack,方便管理蛇頭和以後新增的蛇身
在SnakeHead上掛載指令碼SnakeHead.cs首先實現蛇頭的移動,轉頭,空格鍵加速操作實現主要思想,InvokeRepeating方法持續間隔一定時間呼叫控制蛇頭移動的Move方法,然後Update方法監聽按鍵,判斷蛇頭移動的XY增量並實現蛇頭轉向,利用InvokeRepeating的間隔呼叫時間來控制蛇頭移動的速度需要注意根據實際情況設計蛇頭移動步長Step的大小,最好能讓蛇頭在有限範圍內移動整數步
 public float velocity = 0.35f;
    //每一步蛇頭移動距離
    public int step;
    //x軸蛇頭移動增量
    private int x;
    //y軸蛇頭移動增量
    private int y;

  private void Start()
    {
        //初始化,讓蛇頭可以向上移動
        x = 0;
        y = step;
        //InvokeRepeating等待0秒,然後每隔velocity時間呼叫Move方法
        InvokeRepeating("Move", 0, velocity);
    }

  private void Update()
    {
        //虛擬軸控制移動
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        //Input.GetKeyDown鍵按下瞬間
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //CancelInvoke先取消之前的InvokeRepeating命令
            CancelInvoke();
            //將間隔呼叫“Move”方法的時間減小,則蛇移動變快
            InvokeRepeating("Move", 0, velocity - 0.2f);
        }
        //Input.GetKeyUp鍵擡起瞬間
        if (Input.GetKeyUp(KeyCode.Space))
        {
            CancelInvoke();
            InvokeRepeating("Move", 0, velocity);
        }
        //如果此時y = -step說明蛇正在向下移動,為了防止蛇目前在向下移動,突然向上移動,加y != -step判斷,以下同理
        {
            //設定當頭上下左右移動的時候,蛇頭的方向和移動方向一致,以下同理
            //Quaternion代表四元數,identity表示初始旋轉角度,可理解為new Vector(0,0,0)
            gameObject.transform.localRotation = Quaternion.identity;
            //設定蛇的移動方向,x = 0,y = step說明蛇頭在Y軸向上移動,以下同理
            x = 0;
            y = step;
        }
        if (v < 0 && y != step)
        {
            //Quaternion.Euler將尤拉角轉化為四元數,需要注意尤拉角要與移動方向匹配
            gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 180));
            x = 0;
            y = -step;
        }
        if (h < 0 && x != step)
        {
            gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 90));
            x = -step;
            y = 0;
        }
        if (h > 0 && x != -step)
        {
            gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, -90));
            x = step;
            y = 0;
        }
    }

    void Move()
    {
        //獲取當前蛇頭移動的區域性座標
        headPos = gameObject.transform.localPosition;
        //將蛇頭當前的移動位置加上x軸和y軸的移動增量,實現蛇頭的移動
        gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, 0);
    }



04 食物生成

開發食物,新建一個Image,命名為SnackBody,source image設定為任意的食物圖片,長寬設定為35*35,新增Box Collider2D,勾選is trigger, 需要注意碰撞器大小設定稍微小一點,防止蛇頭擦肩而過的時候,發生碰撞,標籤設定為Food,最後設為預製體。設定步長step為30px,計算後得到世界座標中心點到四周的步數,但為了防止出現食物"卡"在邊緣,如下圖,將步數各減一步在Canvas下設定一個子物體FoodRoot,掛載指令碼FoodCreator.cs將FoodCreator設定為單例模式,只需例項化一次,方便呼叫我們規定遊戲開始,就生成一個食物,蛇每吃掉一個食物就隨機生成其他食物,並有一定機率生成特殊獎勵特殊獎勵的預製體和食物製作差不多。
public class FoodCreator : MonoBehaviour
{
    private static FoodCreator instance;
    public static FoodCreator Instance
    {
        get
        {
            return instance;
        }
    }
    public int xMinLimit = 11;
    public int xMaxLimit = 20;
    public int yMinLimit = 11;
    public int yMaxLimit = 11;
    //要和蛇頭移動步長一致
    public int step = 30;
    public GameObject foodPrefabs;
    //設定
    public GameObject rewardPrefabs;
    //儲存食物的Sprites
    public Sprite[] foodSprites;
    private Transform foodHolder;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
    }

    private void Start()
    {
        foodHolder = GameObject.FindGameObjectWithTag("FoodRoot").transform;
        //遊戲開始時,就生成一個食物
        CreateFood(false);
    }

    public void CreateFood(bool isReward)
    {
        //隨機取得一個食物的下標
        int index = Random.Range(0, foodSprites.Length);
        //例項化food預製體
        GameObject food = Instantiate(foodPrefabs);
        //將食物的image source改為選中下標的食物
        food.GetComponent<Image>().sprite = foodSprites[index];
        //將food設定為foodHolder的子物體,false會使得food保持區域性座標不變
        food.transform.SetParent(foodHolder, false);
        //隨機取得食物生成位置
        int x = Random.Range(-xMinLimit, xMaxLimit + 1);
        int y = Random.Range(-yMinLimit, yMaxLimit + 1);
        food.transform.localPosition = new Vector3(x * step, y * step, 0);
        //判斷是否生成獎勵
        if (isReward)
        {
            //同理
            GameObject reward = Instantiate(rewardPrefabs);
            reward.transform.SetParent(foodHolder, false);
            x = Random.Range(-xMinLimit, xMaxLimit);
            y = Random.Range(-yMinLimit, yMaxLimit);
            reward.transform.localPosition = new Vector3(x * step, y * step, 0);
        }
    }
}


05 處理蛇身的生成

蛇身SnakeBody的製作和前面類似,tag設定為Body,設為預製體我們使用List<Transform>來儲存蛇身,需要注意引用名稱空間using System.Collections.Generic;在SnakeHead.cs中新增AddBody()方法,然後新增OnTriggerEnter2D()用於觸發檢測,當碰到食物或者獎勵的時候,呼叫AddBody()方法,實現蛇吃食物增加蛇身的功能
  void AddBody()
    {
        //三元運算子,如果bodyList.Count被2模除則返回0,否則返回1,控制身體奇偶數輪換顏色
        int index = (bodyList.Count % 2 == 0) ? 0 : 1;
        //new Vector3(2000, 2000, 0)先將身體例項化在螢幕外
        GameObject newBody = Instantiate(bodyPrefab, new Vector3(2000, 2000, 0), Quaternion.identity);
        newBody.GetComponent<Image>().sprite = bodySprites[index];
        newBody.transform.SetParent(snackRoot, false);
        //將新生成的蛇身加入到bodyList中
        bodyList.Add(newBody.transform);
    }

 private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Food"))
        {
            Destroy(collision.gameObject);
            AddBody();
            //(Random.Range(0, 100) < 20) ? true : false 三元運算子 隨機值小於20則返回true,否則false
            FoodCreator.Instance.CreateFood((Random.Range(0, 100) < 20) ? true : false);
        }
        else if (collision.gameObject.CompareTag("Reward"))
        {
            Destroy(collision.gameObject);
            AddBody();
        }
}


06 實現蛇移動

實現方法如圖所示在SnakeHead類中新增Move方法,使用 List<Transform>記錄蛇尾的位置資訊public List<Transform> bodyList = new List<Transform>();
 void Move()
    {
        //獲取當前蛇頭移動的區域性座標
        headPos = gameObject.transform.localPosition;
        //將蛇頭當前的移動位置加上x軸和y軸的移動增量,實現蛇頭的移動
        gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, 0);
        
        //剛開始bodyList為空,防止報空指標
        if (bodyList.Count > 0)
        {
            for (int i = bodyList.Count - 2; i >= 0; i--)
            {
                //將前一節蛇尾的位置賦予後一節
                bodyList[i + 1].localPosition = bodyList[i].localPosition;
            }
            //將原來蛇頭的位置賦予給下標為0的蛇尾,也就是蛇頭後一節的蛇尾
            bodyList[0].localPosition = headPos;
        }

        //方法二:將蛇尾最後一節移至蛇頭的位置
        //if (bodyList.Count > 0)
        //{
        //bodyList.Last()獲取list最後的元素
        //    bodyList.Last().localPosition = headPos;
        //Insert將元素插入到指定位置
        //    bodyList.Insert(0, bodyList.Last());
        //RemoveAt移除指定下標的元素
        //    bodyList.RemoveAt(bodyList.Count - 1);
        //}
    }



相關推薦

Unity3D初級案例-經典貪吃

引言:小生今日分享的是經典貪吃蛇案例,特別感謝Siki學院的老師們。小生會根據自己理解,做一些程式碼上的修改!大家也可以有自己的主見!開發版本:unity 2017.1.1f1適合人群:初學Unity者原始檔連結請見文末!開啟學習之旅吧!效果預覽:主要實現功能:WASD鍵或上

Unity3D初級案例-經典貪吃

引言:承接上一篇貪吃蛇案例!喜歡我的就關注我啊,不然沒有繼續寫的動力啦!!! 開發版本:unity 2017.1.1f1 適合人群:初學Unity者 原始檔連結請見文末! 開啟學習之旅吧! 07 邊界傳送 完善蛇頭的觸發檢測,使用switch判斷蛇頭碰撞的牆面

web前端案例貪吃小遊戲

貪吃蛇小遊戲原始碼<!doctype html><html lang="en"

C#winform 經典小遊戲貪吃V1.0(

關於V1.0   為什麼我給這個版本定義為V1.0嘞,因為在這個版本中僅僅實現了蛇的自動行進,按鍵對蛇的行進方向的操作和吃掉食物蛇身的增長等操作。 但是任何事情都必須一步一步來,當我們完成這個乞丐版的貪吃蛇,就為我們版本的更新打下了基礎。 思路 首先我們

從零開始學 Web 之 JavaScript 高階()原型,貪吃案例

一、複習 例項物件和建構函式之間的關係: 1、例項物件是通過建構函式來建立的,建立的過程叫例項化。 2、如何判斷一個物件是不是某種資料型別? 通過構造器的方法。例項物件.constructor === 建構函式名字 (推薦使用)例項物件 instanceof 建構函式名字 二、原型 1、原型的引入 由

自學Unity3D貪吃 添加攝像機跟隨

自學 offset 一個 sta 浮點 處理 做的 限制 unity 3d 在Unity的世界中, 物體的位置都是由向量構成的。 今天所需要做的就是讓攝像機保持跟蛇頭的相對距離。 首先 設蛇頭的位置在A 點 , 攝像機的位置在B 點 則 我們可以知道 他們的offs

超多經典 canvas 實例,動態離子背景、移動炫彩小球、貪吃、坦克大戰、是男人就下100層、心形文字等等等

ntb contex lin 如果 maxwidth sel 容器 操作 reat 超多經典 canvas 實例 普及:<canvas> 元素用於在網頁上繪制圖形。這是一個圖形容器,您可以控制其每一像素,必須使用腳本來繪制圖形。 註意:IE 8 以及更早的版本不

貪吃“大作戰”(

com 我們 清除 令行 初始 長大 log ont 動作   前兩天在博客園看到一個基於Qpython 的貪吃蛇遊戲的代碼,有點好奇貪吃蛇怎麽用Python簡單實現,就開始對這個程序代碼進行分析。下面是我轉載自sunny開始學壞的代碼: 1 import os,ran

面向對象案例——貪吃遊戲

函數聲明 上線 auto ech 對象 render 暴露 ive food 最近項目上線,近一個星期沒更博了,今天來寫一個經典的遊戲案例——貪吃蛇。在這個簡單的案例裏可以體會javaScript 面向對象開發相關模式,學習使用面向對象的方式分析問題。 1.功能實現 1.1

JS高級----------------->貪吃案例

ase nbsp eid 暫時 sele last 函數 height ctype <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

C語言實現經典小遊戲貪吃

純c語言寫的小遊戲,本人才疏學淺,程式碼有很多不足,僅供給初學者參考。 實現功能: ↑ ↓ ← →分別用來控制上下左右四個方向 空格暫停 esc退出遊戲 f1加速, f2 減速 蛇的長度越長,速度越快(速度有上限) 食物顏色隨機

unity3d貪吃

臨時興起,寫一個貪吃蛇教程吧。 本來覺得會很好寫,結果寫了整整一下午,還是自己程式碼寫的太少,操作起來不靈活,思路會短路。 廢話不多說。先上圖: 邏輯很簡單,但自己本來在明確思路的情況下卻在寫程式碼時走了彎路,核心部分是蛇吃了綠色的食物後,變長。 我的方法是儲存蛇的最後一

步用Canvas寫一個貪吃

之前在慕課網看了幾集Canvas的視訊,一直想著寫點東西練練手。感覺貪吃蛇算是比較簡單的了,當年大學的時候還寫過C語言字元版的,沒想到還是遇到了很多問題。 最終效果如下(圖太大的話 時間太長 錄製gif的軟體有時限…) 首先定義遊戲區域。貪吃蛇的螢幕上只有蛇身和蘋果兩種元素,而這兩個都可以用正方形格子

呼叫鏈系列():解讀UAVStack中的貪吃-呼叫鏈

背景         對於分散式線上服務,一個請求需要經過多個系統中多個模組,可能多達上百臺機器的協作才能完成單次請求。這種場景下單靠人力無法掌握整個請求中各個階段的效能開銷,更無法快速的定位系統中效能瓶頸。當發生故障時通常需要檢視大量日誌跨越多個團隊來確認問題。

js面向對象案例 貪吃

val bre 組成 run pre osi 重新 window 獲取   食物對象 1 (function () { 2 //map:所在的父盒子,obj自身的一些屬都具有默認值 3 function Food(map, obj) { 4

貪吃

          還記得小時候玩過的貪吃蛇小遊戲嗎?每當小蛇吃到食物時,身體便會長大一截;但當碰到圍牆或自己的身體時,那麼,遊戲結束!!現在讓我們學習如何一步一步完成這個遊戲吧。 (1)建立舞臺背景           在“背景”標籤中選中“用顏色填充”的工具,選取兩種

c++經典專案控制檯貪吃小遊戲詳細教程

貪吃蛇GreedySnake 本文將講解如何使用c++面向物件方法編寫控制檯版貪吃蛇小遊戲,專案github地址:silence1772/GreedySnake 遊戲下載:GreedySnake 本人屬初學者,水平所限,難免有所錯誤及不妥之處,勞請指出或發

Android快樂貪吃遊戲實戰專案開發教程-02虛擬方向鍵()自定義控制元件概述

一、自定義控制元件簡介 在本專案中,無論是遊戲主區域還是虛擬方向鍵都是通過自定義控制元件來實現的,我們有必要先對自定義控制元件有個簡單的瞭解。而且通過自定義控制元件的學習能更好的理解系統自帶控制元件的內部機制。 什麼是自定義控制元件呢? 我們平時用的控制元件(比如Button、TextVie

JAVA貪吃小遊戲分論(

引言:Java貪吃蛇小遊戲是一款非常經典的小遊戲,在總論中分析了我的貪吃蛇小遊戲的執行過程,以及貪吃蛇的演算法分析等等,對於貪吃蛇的移動原理,隨機點的出現等有了一定的瞭解,那麼,分論三篇將從我寫的程式碼出發,分析貪食蛇小遊戲的具體組成原理和程式碼實現,分論一主要說明貪吃蛇小遊戲的介面設計,貪

借用經典案例,來扒扒會員體系

執行 如果 頻率 還要 社交圈 自然 支付 頻繁 能力 在過去,會員體系風靡市場,大至各個行業,小至街頭小吃美發,都喜歡用會員體系來促進消費、維系用戶關系,不過,隨著市場競爭加劇,會員體系同質化嚴重,效果也自然而然地下降。 創新不足:很多產品都沒有根據自己的實際情況去搭建