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

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

Extreme Drift賽車游戲C#源碼詳解(1) 接著上次的源碼分析: MainMenu場景的UGUI部分: Canvas中的EnoughMoney: 作用:當買車後金幣不足彈出的頁面 內部一個Text和一個Button,讓我有點疑惑的是,Button綁定的點擊事件是BuyVehicle函數: ...


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

 

接著上次的源碼分析:

MainMenu場景的UGUI部分:

Canvas中的EnoughMoney:

作用:當買車後金幣不足彈出的頁面

內部一個Text和一個Button,讓我有點疑惑的是,Button綁定的點擊事件是BuyVehicle函數:

    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);
        }
    }

 

下一個對象LevelChooser:

內含三個對象,Top,Bottom,Levels:

Top:帶有OutlineLogo的簡單的Text

Bottom:內含Back和Start,返回上一個場景,原理是傳入一個索引值,函數如下

    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;
            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.EnoughMoney.SetActive(true);
                menuPanels.SelectLevel.SetActive(false);
                break;
        }
    }

Start對應的函數如下:調用StartGame,然後調用下麵的兩個函數

    public void StartGame()
    {
        //防止出錯
        if (startingGame) return;
        //設置背景
        FadeBackGround.SetBool("FadeOut", true);
        //調用協程載入(由於不能直接調用C#的多線程,這個函數實現多線程)
        StartCoroutine(LoadLevelGame(1.5f));
        startingGame = true;
    }


    IEnumerator LoadLevelGame(float waitTime)
    {
        yield return new WaitForSeconds(waitTime);
        //激活載入頁面
        menuGUI.loading.SetActive(true);
        //載入
        StartCoroutine(LoadLevelAsync());

    }

    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;
        }
    }

 

Levels是一個帶有Scroll Rect的Image,內含Group,下有五張地圖對象

每一個地圖下有star1,star2,star3,簡單的Image表實獲取到的成績,以及一個locked表示是否解鎖,本質是一個簡單的Image

還有一個CurrentLevel對象,簡單的Image背景,裡面有兩個簡單的Text表示曾經獲取的成績

每一張地圖對象只是一個圖片,並不實際含有地圖,並且綁定一個函數,根據傳參進行下一步:

public void currentLevel(int current)
    {

        for (int i = 0; i < levelSetting.Length; i++)
        {
            if (i == current)
            {
                currentLevelNumber = current;
                levelSetting[i].panel.image.color = Color.white;
                levelSetting[i].panel.enabled = true;
                levelSetting[i].lockImage.gameObject.SetActive(false);
                PlayerPrefs.SetInt("CurrentLevelNumber", currentLevelNumber);
            }
            else if (levelSetting[i].locked == false)
            {
                levelSetting[i].panel.image.color = new Color(0.3f, 0.3f, 0.3f);
                levelSetting[i].panel.enabled = true;
                levelSetting[i].lockImage.gameObject.SetActive(false);
            }
            else
            {
                levelSetting[i].panel.image.color = new Color(1.0f, 0.5f, 0.5f);
                levelSetting[i].panel.enabled = false;
                levelSetting[i].lockImage.gameObject.SetActive(true);
            }
            //根據保存過的信息進行顯示
            if (levelSetting[i].bestTime)
            {
                if (PlayerPrefs.GetFloat("BestTime" + (i + 1).ToString()) != 0.0f)
                {
                    if (PlayerPrefs.GetInt("LevelStar" + (i + 1)) == 1)
                    {
                        levelSetting[i].stars.Star1.color = Color.white;
                    }
                    else if (PlayerPrefs.GetInt("LevelStar" + (i + 1)) == 2)
                    {
                        levelSetting[i].stars.Star1.color = Color.white;
                        levelSetting[i].stars.Star2.color = Color.white;
                    }
                    else if (PlayerPrefs.GetInt("LevelStar" + (i + 1)) == 3)
                    {
                        levelSetting[i].stars.Star1.color = Color.white;
                        levelSetting[i].stars.Star2.color = Color.white;
                        levelSetting[i].stars.Star3.color = Color.white;
                    }

                    levelSetting[i].bestTime.text = "BEST : " + GetComponent<FormatSecondsScript>().FormatSeconds(PlayerPrefs.GetFloat("BestTime" + (i + 1))).ToString();
                }
            }
        }
    }

 

下一個選項,Settings:設置界面

一個深色的BackGround

SettingsPanel:下麵有七個對象

close是一個簡單的Button,綁定MainMenu的函數:

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

Quality下有四個Button,用於設置畫質,一個line用來分割,綁定的函數如下:

直接調用系統畫質API,然後持久化保存數據

    public void QualitySetting(int quality)
    {
        QualitySettings.SetQualityLevel(quality - 1, true);
        PlayerPrefs.SetInt("QualitySettings", quality);
    }

 

Sound音量設置下是兩個Toggle:選項框綁定函數:設置後保存

    public void DisableAudioButton(Toggle toggle)
    {
        if (toggle.isOn)
        {
            AudioListener.volume = 1;
            PlayerPrefs.SetInt("AudioActive", 0);
        }
        else
        {
            AudioListener.volume = 0;
            PlayerPrefs.SetInt("AudioActive", 1);
        }
    }


    public void DisableMusicButton(Toggle toggle)
    {
        if (toggle.isOn)
        {
            menuMusic.GetComponent<AudioSource>().mute = false;
            PlayerPrefs.SetInt("MusicActive", 0);
        }
        else
        {
            menuMusic.GetComponent<AudioSource>().mute = true;
            PlayerPrefs.SetInt("MusicActive", 1);
        }
    }

 

Control下四個對象,用於設置操作相關

兩個選項框用於設置操作模式

    public void ControlModeButtons(Toggle value)
    {
        if (value.isOn)
            PlayerPrefs.SetString("ControlMode", "Buttons");
    }
    public void ControlModeAccel(Toggle value)
    {
        if (value.isOn)
            PlayerPrefs.SetString("ControlMode", "Accel");
    }

下麵是音量設置:都是一些簡單的函數

    public void DisableAudioButton(Toggle toggle)
    {
        if (toggle.isOn)
        {
            AudioListener.volume = 1;
            PlayerPrefs.SetInt("AudioActive", 0);
        }
        else
        {
            AudioListener.volume = 0;
            PlayerPrefs.SetInt("AudioActive", 1);
        }
    }


    public void DisableMusicButton(Toggle toggle)
    {
        if (toggle.isOn)
        {
            menuMusic.GetComponent<AudioSource>().mute = false;
            PlayerPrefs.SetInt("MusicActive", 0);
        }
        else
        {
            menuMusic.GetComponent<AudioSource>().mute = true;
            PlayerPrefs.SetInt("MusicActive", 1);
        }
    }

保存敏感繫數函數:

    public void EditSensitivity()
    {
        PlayerPrefs.SetFloat("Sensitivity", menuGUI.sensitivity.value);
    }

 

最後一個Erase All Data是激活下麵的Reset Panel,進行數據清除

Reset Panel是一個紅色背景和選擇YES或者NO

    public void EraseSave()
    {
        //清除所有數據後重新載入
        PlayerPrefs.DeleteAll();
        currentVehicleNumber = 0;
        Application.LoadLevel(0);

        foreach (Material mat in allRestMaterials)
            mat.SetColor("_Color", new Color(0.7f, 0.7f, 0.7f));
    }

 

Fade Background是一個隱藏對象,如果激活後,會顯示車輪樣的載入圖片,帶有一個綁定了動畫的Animator

 

到這裡,UGUI的Canvas就分析完了

 

下一個,先看簡單的Vehicle Root對象

裡面裝有12輛車和一個Shadow陰影

這12輛車就是汽車的3D模型,沒什麼好說的,Shadow是汽車的陰影

Shadow實現是利用Projector投影,用到一些陰影資源,這裡就不深究了

下一個Garage對象,也很簡單,就是一個車庫3D模型

 

最後來看Main Camera:

Main Camera下有兩個Audio Source,分別是背景音樂和點擊音效

Main Camera首先綁定的是MainMenu:

這兩篇文章都是圍繞MainMenu講的,現在從頭來看:

先看一些全局變數:這裡大部分的意思我都看懂了,不過有一部分我無法理解

    //金幣
    private int gameScore { get; set; }
    //視角移動速度
    public float cameraRotateSpeed = 5;
    //載入背景
    public Animator FadeBackGround;
    //背景音樂
    public AudioSource menuMusic;
    //簡單的GO
    public Transform vehicleRoot;
    //所有材質
    public Material[] allRestMaterials;
    //主界面:含有五個場景對象
    public MenuPanels menuPanels;
    //界面GUI,含有多個對象
    public MenuGUI menuGUI;
    //車輛數組,保存了汽車的各種信息
    public VehicleSetting[] vehicleSetting;
    //關卡數組,保存了關卡的信息
    public LevelSetting[] levelSetting;
    //預設以第一個界面開啟
    private Panels activePanel = Panels.MainMenu;
    //含義暫定
    private bool vertical, horizontal;
    private Vector2 startPos;
    private Vector2 touchDeltaPosition;

    //滑鼠按下位置記錄
    private float x, y = 0;

    //當前車輛以及各種信息
    private VehicleSetting currentVehicle;

    private int currentVehicleNumber = 0;
    private int currentLevelNumber = 0;

    private Color mainColor;
    private bool randomColorActive = false;
    private bool startingGame = false;

    private float menuLoadTime = 0.0f;
    private AsyncOperation sceneLoadingOperation = null;

 

自定義的幾個類:

    //游戲的GUI
    [System.Serializable]
    public class MenuGUI
    {
        public Text GameScore;
        public Text VehicleName;
        public Text VehiclePrice;

        public Slider VehicleSpeed;
        public Slider VehicleBraking;
        public Slider VehicleNitro;

        public Slider sensitivity;

        public Toggle audio;
        public Toggle music;
        public Toggle vibrateToggle;
        public Toggle ButtonMode, AccelMode;

        public Image wheelColor, smokeColor;
        public Image loadingBar;

        public GameObject loading;
        public GameObject customizeVehicle;
        public GameObject buyNewVehicle;
    }
    //五個場景的Panel
    [System.Serializable]
    public class MenuPanels
    {
        public GameObject MainMenu;
        public GameObject SelectVehicle;
        public GameObject SelectLevel;
        public GameObject EnoughMoney;
        public GameObject Settings;
    }
    //車輛信息
    [System.Serializable]
    public class VehicleSetting
    {
        public string name = "Vehicle 1";

        public int price = 20000;

        public GameObject vehicle;
        public GameObject wheelSmokes;

        public Material ringMat, smokeMat;
        public Transform rearWheels;

        public VehiclePower vehiclePower;
        //是否購買,隱藏
        [HideInInspector]
        public bool Bought = false;
        //車輛性能參數
        [System.Serializable]
        public class VehiclePower
        {
            public float speed = 80;
            public float braking = 1000;
            public float nitro = 10;
        }
    }
    //可以使用的幾張地圖信息
    [System.Serializable]
    public class LevelSetting
    {
        public bool locked = true;
        public Button panel;
        public Text bestTime;
        public Image lockImage;
        public StarClass stars;
        //該地圖獲得了幾顆星
        [System.Serializable]
        public class StarClass
        {
            public Image Star1, Star2, Star3;
        }
    }

 

這個腳本其他所有的函數都有說過了,除了Awake和Update函數:

先來看看Awake函數:

    //初始化
    void Awake()
    {

        AudioListener.pause = false;
        Time.timeScale = 1.0f;

        //震動選項,這裡沒用
        menuGUI.vibrateToggle.isOn = (PlayerPrefs.GetInt("VibrationActive") == 0) ? true : false;

        //預設金幣999999
        gameScore = 999999;

        //載入第一個場景
        CurrentPanel(0);

        //設置畫質
        if (PlayerPrefs.GetInt("QualitySettings") == 0)
        {
            PlayerPrefs.SetInt("QualitySettings", 4);
            QualitySettings.SetQualityLevel(3, true);
        }
        else
        {
            QualitySettings.SetQualityLevel(PlayerPrefs.GetInt("QualitySettings") - 1, true);
        }
        //設置車輛敏感度
        if (PlayerPrefs.GetFloat("Sensitivity") == 0.0f)
        {
            menuGUI.sensitivity.value = 1.0f;
            PlayerPrefs.SetFloat("Sensitivity", 1.0f);
        }
        else
        {
            menuGUI.sensitivity.value = PlayerPrefs.GetFloat("Sensitivity");
        }

        //設置操作模式
        switch (PlayerPrefs.GetString("ControlMode"))
        {
            case "":
                menuGUI.ButtonMode.isOn = true;
                break;
            case "Buttons":
                menuGUI.ButtonMode.isOn = true;
                break;
            case "Accel":
                menuGUI.AccelMode.isOn = true;
                break;
        }

        //當前車輛
        currentLevelNumber = PlayerPrefs.GetInt("CurrentLevelNumber");
        //地圖解鎖情況處理
        for (int lvls = 0; lvls < levelSetting.Length; lvls++)
        {
            if (lvls <= PlayerPrefs.GetInt("CurrentLevelUnlocked"))
                levelSetting[lvls].locked = false;

        }

        //設置地圖
        currentLevel(currentLevelNumber);

        //讀取預設控制信息設置
        switch (PlayerPrefs.GetString("ControlMode"))
        {
            case "":
                PlayerPrefs.SetString("ControlMode", "Buttons");
                menuGUI.ButtonMode.isOn = true;
                break;
            case "Buttons":
                menuGUI.ButtonMode.isOn = true;
                break;
            case "Accel":
                menuGUI.AccelMode.isOn = true;
                break;
        }

        //預設只買了第一輛車
        PlayerPrefs.SetInt("BoughtVehicle0", 1);


        //背景音樂和音量設置
        menuGUI.audio.isOn = (PlayerPrefs.GetInt("AudioActive") == 0) ? true : false;
        AudioListener.volume = (PlayerPrefs.GetInt("AudioActive") == 0) ? 1.0f : 0.0f;

        menuGUI.music.isOn = (PlayerPrefs.GetInt("MusicActive") == 0) ? true : false;
        menuMusic.mute = (PlayerPrefs.GetInt("MusicActive") == 0) ? false : true;

        currentVehicleNumber = PlayerPrefs.GetInt("CurrentVehicle");
        currentVehicle = vehicleSetting[currentVehicleNumber];


        int i = 0;

        //遍歷所有車輛,進行輪胎顏色煙霧設置
        foreach (VehicleSetting VSetting in vehicleSetting)
        {

            if (PlayerPrefsX.GetColor("VehicleWheelsColor" + i) == Color.clear)
            {
                vehicleSetting[i].ringMat.SetColor("_DiffuseColor", Color.white);
            }
            else
            {
                vehicleSetting[i].ringMat.SetColor("_DiffuseColor", PlayerPrefsX.GetColor("VehicleWheelsColor" + i));
            }



            if (PlayerPrefsX.GetColor("VehicleSmokeColor" + i) == Color.clear)
            {
                vehicleSetting[i].smokeMat.SetColor("_TintColor", new Color(0.8f, 0.8f, 0.8f, 0.2f));
            }
            else
            {
                vehicleSetting[i].smokeMat.SetColor("_TintColor", PlayerPrefsX.GetColor("VehicleSmokeColor" + i));
            }


            //Bought=true說明車沒有買
            if (PlayerPrefs.GetInt("BoughtVehicle" + i.ToString()) == 1)
            {
                VSetting.Bought = true;

                if (PlayerPrefs.GetInt("GameScore") == 0)
                {
                    PlayerPrefs.SetInt("GameScore", gameScore);
                }
                else
                {
                    gameScore = PlayerPrefs.GetInt("GameScore");
                }
            }

            //顯示當前車輛
            if (VSetting == vehicleSetting[currentVehicleNumber])
            {
                VSetting.vehicle.SetActive(true);
                currentVehicle = VSetting;
            }
            else
            {
                VSetting.vehicle.SetActive(false);
            }

            i++;
        }
    }

 

 

再看看Update方法:

    void Update()
    {

        //如果載入了下一個Scene
        if (sceneLoadingOperation != null)
        {
            //根據時間顯示載入輪胎動畫(圓形逐漸圓滿)
            /*public static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta);
            作用是將當前值current移向目標target。(對Vector3是沿兩點間直線)
            maxDistanceDelta就是每次移動的最大長度。
            返回值是當current值加上maxDistanceDelta的值,如果這個值超過了target,返回的就是target的值*/
            menuGUI.loadingBar.fillAmount = Mathf.MoveTowards(menuGUI.loadingBar.fillAmount, sceneLoadingOperation.progress + 0.2f, Time.deltaTime * 0.5f);
            //載入完成
            if (menuGUI.loadingBar.fillAmount > sceneLoadingOperation.progress)
                sceneLoadingOperation.allowSceneActivation = true;
        }


        if (menuGUI.smokeColor.gameObject.activeSelf || randomColorActive)
        {
            //車輛的後輪旋轉
            vehicleSetting[currentVehicleNumber].rearWheels.Rotate(1000 * Time.deltaTime, 0, 0);
            //開啟車輛輪胎煙霧
            vehicleSetting[currentVehicleNumber].wheelSmokes.SetActive(true);
        }
        else
        {
            vehicleSetting[currentVehicleNumber].wheelSmokes.SetActive(false);
        }


        //車輛參數的顯示
        menuGUI.VehicleSpeed.value = vehicleSetting[currentVehicleNumber].vehiclePower.speed / 100.0f;
        menuGUI.VehicleBraking.value = vehicleSetting[currentVehicleNumber].vehiclePower.braking / 100.0f;
        menuGUI.VehicleNitro.value = vehicleSetting[currentVehicleNumber].vehiclePower.nitro / 100.0f;
        menuGUI.GameScore.text = gameScore.ToString();

        //如果車已購買
        if (vehicleSetting[currentVehicleNumber].Bought)
        {
            //一些簡單的設置
            menuGUI.customizeVehicle.SetActive(true);
            menuGUI.buyNewVehicle.SetActive(false);

            menuGUI.VehicleName.text = vehicleSetting[currentVehicleNumber].name;
            menuGUI.VehiclePrice.text = "BOUGHT";
            PlayerPrefs.SetInt("CurrentVehicle", currentVehicleNumber);
        }
        else
        {
            //車沒買的話一些簡單的設置
            menuGUI.customizeVehicle.SetActive(false);
            menuGUI.buyNewVehicle.SetActive(true);

            menuGUI.VehicleName.text = vehicleSetting[currentVehicleNumber].name;
            menuGUI.VehiclePrice.text = "COST: " + vehicleSetting[currentVehicleNumber].price.ToString();
        }

        //我改了下源碼,因為暫時用不到安卓系統
        if (Input.GetMouseButton(0) && activePanel != Panels.SelectLevel)
        {
            //這些數學函數我看不懂,但明白意思,就是滑鼠點擊屏幕出現是視覺效果和旋轉效果
            x = Mathf.Lerp(x, Mathf.Clamp(Input.GetAxis("Mouse X"), -2, 2) * cameraRotateSpeed, Time.deltaTime * 5.0f);
            Camera.main.fieldOfView = Mathf.Clamp(Camera.main.fieldOfView, 50, 60);
            Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, 50, Time.deltaTime);
        }
        else {
            x = Mathf.Lerp(x, cameraRotateSpeed * 0.01f, Time.deltaTime * 5.0f);
            Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, 60, Time.deltaTime);
        }
        //慢慢旋轉視角
        transform.RotateAround(vehicleRoot.position, Vector3.up, x);


    }

 


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

-Advertisement-
Play Games
更多相關文章
  • 由於C#在性能方面,和C++還是有不少的差距,所以在項目中有一塊是用C++的OCX控制項實現,然後包括在WPF項目中。由於C++,C#屬於不同的體系架構,造成了許多問題,特使是拖拽TreeViewItem到OCX控制項上面,兩者的渲染方式不同,OCX控制項一直顯示在最前面,所以拖拽的時候,看不見拖拽的Ad ...
  • 找了很多網上關於Ztree的例子和代碼才搞定。 首先,關於Ztree的代碼不介紹了,網上下載之後,引用下列四個文件就能使用了。 1.關於配置選項。主要通過回調函數來實現向後臺發送數據,實現增刪改查。 2.後臺處理的方法。。我項目中是使用C#代碼寫的,mvc框架 我項目中的情況是需要用ztree來實現 ...
  • 見圖說話,修改參數option實現上圖顯示: 1. 共用參數title還有一個屬性subtext,可以用來設置副標題 2. tooltip與toolbox也是共用屬性 3. dataZoom是設置滾動條的,此滾動條是用來確定橫欄從哪裡開始哪裡結尾,如圖滾動條前頭有段空白,所以橫欄從類目3開始,後頭無 ...
  • Asp.net Core 和類庫讀取配置文件信息 看乾貨請移步至 " .net core 讀取配置文件公共類 " 首先開一個腦洞,Asp.net core 被使用這麼長時間了,但是關於配置文件(json)的讀取,微軟官方似乎並沒有給出像.net framework讀取web.config那樣簡單且完 ...
  • 今天寫一個wpf的demo,用到綁定數據,給控制項綁定了數據源,但是數據卻沒有顯示出來,排查代碼發現綁定數據源的的成員用的是欄位不是屬性。 前端代碼: 後臺代碼: 如果把Employe的name,去掉{get;set;},改為一個欄位, public string name;數據就無法綁定了。原因是屬 ...
  • C#的Dictionary類型的值,知道key後,value可以修改嗎?答案是肯定能修改的。我在遍歷的過程中可以修改Value嗎?答案是也是肯定能修改的,但是不能用For each迴圈。否則會報以下的Exception. 之所以會報Exception是For each本身的問題,和Dictionar ...
  • 1.非同步同步的定義 同步方法:多個任務一個一個執行,同一時刻系統中只有一個任務在執行 非同步方法:發起一個調用,並不等著計算結束,而是直接去運行下一行;剛纔的計算,會啟動一個新的線程去執行 2.非同步同步的比較 2.1. 同步方法卡界面,因為UI線程忙於計算;非同步多線程方法不卡界面,主線程閑置,計算任務 ...
  • ASP.NET -- WebForm: HttpResponse 類的方法和屬性 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...