Extreme Drift賽車游戲C#源碼詳解(1)

来源:https://www.cnblogs.com/xuyiqing/archive/2018/11/26/10022749.html
-Advertisement-
Play Games

C#我只是一個萌新,由於搞過Java,還是可以看懂C#的 偶然間得到賽車游戲Extreme Drift的源碼 接下來我會花一段時間來解讀,這是一個我學習的過程,記錄在博客 等到我完全解讀之後,我也許會考慮再加入聯機功能等 當然,這個游戲用的是Unity引擎 首先,我先展示一下這個游戲的效果: 選車: ...


C#我只是一個萌新,由於搞過Java,還是可以看懂C#的

偶然間得到賽車游戲Extreme Drift的源碼

接下來我會花一段時間來解讀,這是一個我學習的過程,記錄在博客

等到我完全解讀之後,我也許會考慮再加入聯機功能等

 

當然,這個游戲用的是Unity引擎

首先,我先展示一下這個游戲的效果:

 

選車:

 

然後選圖,進入比賽:

 

 

WASD,SHIFT氮氣,空格漂移

不得不說,車輛的手感非常不錯!

作為育碧的老玩家,講真的,這個小游戲的手感比育碧的賽車手感好多了

甚至就我感覺,車輛除了一些參數感覺需要調整,整體來看,手感和GTA5的感覺有點像

 

不多說了,我打包出來一個Windows可運行的程式,雙擊就可以體驗賽車游戲:

 

鏈接:https://pan.baidu.com/s/1kF61eguRJf1Gd7aGn4w5jg
提取碼:ks1l

 

源碼的地址:花錢買的,免費分享了!

 

鏈接:https://pan.baidu.com/s/1yiayLBXOBcSoJstHJQw33A
提取碼:eyyq

 

下麵正式開始查看源碼:

導入之後目錄結構:並且會自動導入Unity自帶資源ImageEffects

 

打開Scenes的MainMenu場景,啟動游戲:

然而第一次啟動在載入地圖的時候會報錯,因為這一步:

    IEnumerator LoadLevelAsync()
    {

        yield return new WaitForSeconds(0.4f);
        sceneLoadingOperation = Application.LoadLevelAsync(currentLevelNumber + 1);
        sceneLoadingOperation.allowSceneActivation = false;

        while (!sceneLoadingOperation.isDone || sceneLoadingOperation.progress < 0.9f)
        {
            menuLoadTime += Time.deltaTime;

            yield return 0;
        }
    }

 

這裡非同步載入索引為currentLevelNumber+1的場景,然而,實際上不存在這個索引,所以,我們需要在Build Setting設置好這些場景:

 

然後在啟動,就可以順利游戲了!

 

有六個場景,那麼就先從主菜單MainMenu場景來看:

負責UGUI的事件系統:

 

Standalone Input Module:專為滑鼠/鍵盤/控制器輸入而設計:

這裡沒有做什麼多餘操作,只是添加了這個組件,一個參數也沒有改

 

Touch Input Module:為觸摸屏設備而設計,暫時與我無關

 

接下來看UGUI部分:

 

一個Canvas,裡面有八個對象

 

Top Panel是頂部的一個橫條,右邊有金幣設置選項

觀察金幣,發現這隻是一個簡單的圖片,而金幣之內,包含GameScore對象,這個應該是處理金幣的核心

猜錯了,觀察GameScore對象發現,這也是一個簡單的Text,那麼金幣相關功能應該是find這個對象來處理的

然後看設置,是一個Button,綁定了MainMenu裡面的一個函數,而且播放點擊聲音,另外有一個Shadow組件:作用是給按鈕添加陰影輪廓

查看這個函數:

    public void SettingActive(bool activePanel)
    {
        menuPanels.Settings.gameObject.SetActive(activePanel);
    }

OK,只是使另一個UI對象active,可以理解為:點擊設置按鈕後跳轉到另一個頁面

 

MainMenu相當於是全屏幕,包含了左上的logo和底部的一個Panel:

標題Tilt:一個簡單的圖片,在它下麵的Image有點意思,是一個較亮的矩形,反覆從右到左位移,配合Logo實現發光的效果

實現機制:Image利用Aminator組件將自身和Tilt這個Logo綁定,實現迴圈動畫

然後就是底部的Panel,裡面有四個對象,退出,資源,油管,選車進行下一步

退出:綁定了Shadow、點擊音效的一個按鈕,以及一個MainMenu的函數:就是簡單的退出

    public void ClickExitButton()
    {
        Application.Quit();
    }

資源和油管都是鏈接,本質一個按鈕帶Shadow和Audio,綁定OpenURL腳本的函數:傳入URL,打開,簡單

    public void OpenTab (string URL) {
        Application.OpenURL(URL);
    }

選車:一個簡單的按鈕,帶Shadow,綁定MainMenu的一個函數:我在下麵的註釋中將會詳細解釋

    public void CurrentPanel(int current)
    {
        //這裡為什麼要傳一個INT呢?因為開頭有定義
        //public enum Panels { MainMenu = 0, SelectVehicle = 1, SelectLevel = 2, Settings = 3 }
        //activePanel預設為0,這裡傳入的是1,就是選車
        activePanel = (Panels)current;

        //PlayerPrefs是數據持久化,從存檔取出數據驗證
        if (currentVehicleNumber != PlayerPrefs.GetInt("CurrentVehicle"))
        {
            currentVehicleNumber = PlayerPrefs.GetInt("CurrentVehicle");
            //迴圈所有的車輛
            foreach (VehicleSetting VSetting in vehicleSetting)
            {
                //當前車激活狀態,否則不激活
                if (VSetting == vehicleSetting[currentVehicleNumber])
                {
                    VSetting.vehicle.SetActive(true);
                    currentVehicle = VSetting;
                }
                else
                {
                    VSetting.vehicle.SetActive(false);
                }
            }
        }
        //根據傳入值做一些操作
        switch (activePanel)
        {

            case Panels.MainMenu:
                menuPanels.MainMenu.SetActive(true);
                menuPanels.SelectVehicle.SetActive(false);
                menuPanels.SelectLevel.SetActive(false);
                if (menuGUI.wheelColor) menuGUI.wheelColor.gameObject.SetActive(true);

                break;
            //這裡傳入的是1,進入選車
            case Panels.SelectVehicle:
                menuPanels.MainMenu.gameObject.SetActive(false);
                menuPanels.SelectVehicle.SetActive(true);
                menuPanels.SelectLevel.SetActive(false);
                break;
            case Panels.SelectLevel:
                menuPanels.MainMenu.SetActive(false);
                menuPanels.SelectVehicle.SetActive(false);
                menuPanels.SelectLevel.SetActive(true);
                break;
            case Panels.Settings:
                menuPanels.MainMenu.SetActive(false);
                menuPanels.SelectVehicle.SetActive(false);
                menuPanels.SelectLevel.SetActive(false);
                break;
        }
    }

 

 

VehicleGarage:車庫情景,下麵有五個對象

Top:頂部。左邊一個logo:帶有Outline的一個Text。中下是汽車的名字,也是一個Outline的Text

然後是三個車輛性能信息,速度,剎車,氮氣,都是簡單的Text+Slider

NextVehicle:綁定點擊聲音和MainMenu的一個函數:

    public void NextVehicle()
    {
        if (menuGUI.wheelColor) { menuGUI.wheelColor.gameObject.SetActive(false); }

        currentVehicleNumber++;
        //取模運算,防止越界
        currentVehicleNumber = (int)Mathf.Repeat(currentVehicleNumber, vehicleSetting.Length);

        foreach (VehicleSetting VSetting in vehicleSetting)
        {

            if (VSetting == vehicleSetting[currentVehicleNumber])
            {
                VSetting.vehicle.SetActive(true);
                //迴圈到下一輛車賦值給當前
                currentVehicle = VSetting;
            }
            else
            {
                VSetting.vehicle.SetActive(false);

            }
        }
    }

PreviousVehicle是類似的:

    public void PreviousVehicle()
    {
        if (menuGUI.wheelColor) { menuGUI.wheelColor.gameObject.SetActive(false); }

        currentVehicleNumber--;
        currentVehicleNumber = (int)Mathf.Repeat(currentVehicleNumber, vehicleSetting.Length);

        foreach (VehicleSetting VSetting in vehicleSetting)
        {
            if (VSetting == vehicleSetting[currentVehicleNumber])
            {
                VSetting.vehicle.SetActive(true);
                currentVehicle = VSetting;
            }
            else
            {
                VSetting.vehicle.SetActive(false);
            }
        }
    }

Bottom下有四個對象:

Back:一個按鈕,返回上一場景,原理和上邊的選車按鈕一直,調用同一個函數

Next:下一步地圖選擇頁面,也和上面的原理一樣,都是調用一個函數CurrentPanel

CustomizeVehicle:自定義車輛,按鈕綁定函數,點擊後隱藏一些場景,開啟自定義場景

BuyNewVehicle:買車,預設是不激活的,點擊後激活下一個對象BuyConfirm

BuyConfirm:一個不激活的Panel,被激活後有兩個選項,Yes的話掉MainMenu的函數,否則返回:

    public void BuyVehicle()
    {
        //金幣足夠或者車輛未買才會執行
        if ((gameScore >= vehicleSetting[currentVehicleNumber].price) && !vehicleSetting[currentVehicleNumber].Bought)
        {
            //數據持久化
            PlayerPrefs.SetInt("BoughtVehicle" + currentVehicleNumber.ToString(), 1);
            //減錢
            gameScore -= vehicleSetting[currentVehicleNumber].price;
            //防止負數
            if (gameScore <= 0) { gameScore = 1; }
            //保存金幣數量
            PlayerPrefs.SetInt("GameScore", gameScore);
            //保存車輛購買狀態
            vehicleSetting[currentVehicleNumber].Bought = true;
        }
        else
        {
            menuPanels.EnoughMoney.SetActive(true);
        }
    }

 

CustomizeVehicle:自定義車輛,下麵有三個對象

Top:簡單的一個頂部Logo,Colors裡面有八個顏色對象,綁定了MainMenu的一個函數:

    public void ActiveCurrentColor(Image activeImage)
    {

        mainColor = activeImage.color;

        //根據傳參持久化數據
        if (menuGUI.wheelColor.gameObject.activeSelf)
        {
            vehicleSetting[currentVehicleNumber].ringMat.SetColor("_Color", mainColor);
            PlayerPrefsX.SetColor("VehicleWheelsColor" + currentVehicleNumber, mainColor);
        }
        else if (menuGUI.smokeColor.gameObject.activeSelf)
        {
            vehicleSetting[currentVehicleNumber].smokeMat.SetColor("_TintColor", new Color(mainColor.r, mainColor.g, mainColor.b, 0.2f));
            PlayerPrefsX.SetColor("VehicleSmokeColor" + currentVehicleNumber, new Color(mainColor.r, mainColor.g, mainColor.b, 0.2f));
        }
    }

Bottom下麵很多的對象,首先是一個返回,機制和函數上邊提到了

WheelColor、SmokeColor和RandomColor都是綁定MainMenu幾個函數,這幾個函數不難:

    public void ActiveWheelColor(Image activeImage)
    {
        randomColorActive = false;

        activeImage.gameObject.SetActive(true);
        menuGUI.wheelColor = activeImage;
        menuGUI.smokeColor.gameObject.SetActive(false);
    }


    public void ActiveSmokeColor(Image activeImage)
    {
        randomColorActive = false;

        activeImage.gameObject.SetActive(true);
        menuGUI.smokeColor = activeImage;
        menuGUI.wheelColor.gameObject.SetActive(false);
    }
    public void RandomColor()
    {

        randomColorActive = true;

        menuGUI.wheelColor.gameObject.SetActive(false);
        menuGUI.smokeColor.gameObject.SetActive(false);
        //隨機數函數
        vehicleSetting[currentVehicleNumber].ringMat.SetColor("_Color", new Color(Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f)));
        vehicleSetting[currentVehicleNumber].smokeMat.SetColor("_TintColor", new Color(Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), 0.2f));
        //持久化
        PlayerPrefsX.SetColor("VehicleWheelsColor" + currentVehicleNumber, vehicleSetting[currentVehicleNumber].ringMat.GetColor("_Color"));
        PlayerPrefsX.SetColor("VehicleSmokeColor" + currentVehicleNumber, vehicleSetting[currentVehicleNumber].smokeMat.GetColor("_TintColor"));
    }

 

下麵是EnoughMoney,明天再看

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. python的簡介 python的創始⼈人為吉多·範羅蘇姆(Guido van Rossum)。1989年年的聖誕節期間,吉多· 範羅蘇姆為了了在阿姆斯特丹丹打發時間,決⼼心開發⼀個新的腳本解釋程式,作為ABC語言的⼀種繼承。新的TIOBE排⾏行行榜,Python已經占據世界第四名的位置, P ...
  • if語句是條件判斷功能 1. if 條件: if語句塊 執行流程:判斷條件是否為真. 如果真. 執行if語句塊 2. if 條件: if語句塊 else: else語句塊 執行流程:判斷條件是否為真. 如果真. 執行if語句塊 否則執行else語句塊 3. if 條件1: if-1 elif 條件2 ...
  • SSM整合 ssm框架 框架整合 在博客的前面介紹了mybatis,spring,springmvc的使用,那麼這篇博客將介紹將mybatis和spring,springmvc的整合。 <!-- more --> 整合之前,我們需要明白一個點,spring和mybatis之間進行整合不像spring ...
  • 部分基礎知識 1.python常量和變數 2.python基本數據類型 3.python用戶交互 4.python的if迴圈和嵌套 未完........ ...
  • 嗯,這是本人的第一篇隨筆,就從最簡單的單例模式開始,一步一步地記錄自己的成長。 單例模式是最常見的設計模式之一,在項目代碼中幾乎隨處可見。這個設計模式的目的就是為了保證實例只能存在一個。單例模式往下還能再細分為懶漢模式和餓漢模式。下麵逐個來看。 1.餓漢模式 餓漢模式的做法是在類載入的時候就完成實例 ...
  • 我的網站的圖片不想被公開瀏覽、下載、盜鏈怎麼辦?本文主要通過解讀一下ASP.NET Core對於靜態文件的處理方式的相關源碼,來看一下為什麼是wwwroot文件夾,如何修改或新增一個靜態文件夾,為什麼新增的文件夾名字不會被當做controller處理?訪問授權怎麼做? 一、靜態文件夾 所謂靜態文件, ...
  •  寫在前面 上篇文章我們講瞭如在在實際項目開發中使用Git來進行代碼的版本控制,當然介紹的都是比較常用的功能。今天我再帶著大家一起熟悉下一個ORM框架Dapper,實例代碼的演示編寫完成後我會通過Git命令上傳到GitHub上,正好大家可以再次熟悉下Git命令的使用,來鞏固上篇文章的知識。本篇文章 ...
  • 首先使用Nugut安裝NLog, NLog.Extensions.Logging,using NLog.Web,並且加上配置文件 ”nlog.config“,配置文件內容網上都可以百度的到。這是我自己的: 創建表: CREATE TABLE `sys_log` ( `Id` int(11) NOT ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...