Unity3D仿星露谷物語開發32之地面屬性決定角色動作

1、目標

根據地面屬性(diggable, canDropItem, canPlaceFurniture, isPath, isNPCObstacle)決定角色進行何種操作。比如沒有canDropItem屬性的地面,則不能放置物體。

2、優化保存Item數據

PS:這個是對已有代碼的優化,與本節的主題無關。

打開Assets -> Scripts -> SaveSystem -> SceneSave.cs,

已有的代碼如下:

public class SceneSave
{// string key is an identifier name we choose for this listpublic Dictionary<string, List<SceneItem>> listSceneItemDictionary;
}

已有的數據如下:

sceneSave.listSceneItemDictionary.Add("sceneItemList", sceneItemList);

因為當前只有一個itemList,所以不需要存儲為字典,可以直接存儲為List。

調整后代碼如下:

using System.Collections.Generic;[System.Serializable]public class SceneSave
{// string key is an identifier name we choose for this listpublic List<SceneItem> listSceneItem;
}

然后打開Assets -> Scripts -> Scene -> SceneItemsManager.cs做相應的調整。

調整后的代碼如下:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;[RequireComponent(typeof(GenerateGUID))]
public class SceneItemsManager : SingletonMonobehaviour<SceneItemsManager>, ISaveable
{private Transform parentItem;[SerializeField] private GameObject itemPrefab = null;private string _iSaveableUniqueID;private GameObjectSave _gameObjectSave;public string ISaveableUniqueID { get { return _iSaveableUniqueID; } set { _iSaveableUniqueID = value; } }public GameObjectSave GameObjectSave { get { return _gameObjectSave; } set { _gameObjectSave = value; } }private void AfterSceneLoad(){parentItem = GameObject.FindGameObjectWithTag(Tags.ItemsParentTransform).transform;}protected override void Awake(){base.Awake();ISaveableUniqueID = GetComponent<GenerateGUID>().GUID;GameObjectSave = new GameObjectSave();}private void OnEnable(){ISaveableRegister();EventHandler.AfterSceneLoadEvent += AfterSceneLoad;}private void OnDisable(){ISaveableDeregister();EventHandler.AfterSceneLoadEvent -= AfterSceneLoad;}public void ISaveableDeregister(){SaveLoadManager.Instance.iSaveableObjectList.Remove(this);}public void ISaveableRegister(){// 將當前對象添加到iSaveableObjectList中SaveLoadManager.Instance.iSaveableObjectList.Add(this);}// 恢復場景public void ISaveableRestoreScene(string sceneName){if(GameObjectSave.sceneData.TryGetValue(sceneName, out SceneSave sceneSave)){if(sceneSave.listSceneItem != null){// scene list items found - destroy existing items in sceneDestroySceneItems();// new instantiate the list of scene itemsInstantiateSceneItems(sceneSave.listSceneItem);}}}private void InstantiateSceneItems(List<SceneItem> sceneItemList){GameObject itemGameObject;foreach(SceneItem sceneItem in sceneItemList){itemGameObject = Instantiate(itemPrefab, new Vector3(sceneItem.position.x, sceneItem.position.y, sceneItem.position.z), Quaternion.identity, parentItem);Item item = itemGameObject.GetComponent<Item>();item.ItemCode = sceneItem.itemCode;item.name = sceneItem.itemName;}}// Destroy items currently in the sceneprivate void DestroySceneItems(){// Get all items in the sceneItem[] itemsInScene = GameObject.FindObjectsOfType<Item>();// Loop through all scene items and destroy themfor(int i = itemsInScene.Length - 1; i > -1; i--){Destroy(itemsInScene[i].gameObject);}}// 保存場景public void ISaveableStoreScene(string sceneName){// Remove old scene save for gameObject if existsGameObjectSave.sceneData.Remove(sceneName);// Get all items in the sceneList<SceneItem> sceneItemList = new List<SceneItem>();Item[] itemsInScene = FindObjectsOfType<Item>();// Loop through all scene itemsforeach(Item item in itemsInScene){SceneItem sceneItem = new SceneItem();sceneItem.itemCode = item.ItemCode;sceneItem.position = new Vector3Serializable(item.transform.position.x, item.transform.position.y,item.transform.position.z);sceneItem.itemName = item.name;// Add scene item to listsceneItemList.Add(sceneItem);}// Create list scene items dictionary in scene save and add to itSceneSave sceneSave = new SceneSave();sceneSave.listSceneItem = sceneItemList;// Add scene save to gameobjectGameObjectSave.sceneData.Add(sceneName, sceneSave);}
}

改動點是:

// 恢復場景
? ? public void ISaveableRestoreScene(string sceneName)
? ? {
? ? ? ? if(GameObjectSave.sceneData.TryGetValue(sceneName, out SceneSave sceneSave))
? ? ? ? {
? ? ? ? ? ? if(sceneSave.listSceneItem != null)? // 精簡了這塊的代碼
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // scene list items found - destroy existing items in scene
? ? ? ? ? ? ? ? DestroySceneItems();

? ? ? ? ? ? ? ? // new instantiate the list of scene items
? ? ? ? ? ? ? ? InstantiateSceneItems(sceneSave.listSceneItem);
? ? ? ? ? ? }
? ? ? ? }
? ? }

3、優化SceneSave.cs

增加保存地面屬性信息。

using System.Collections.Generic;[System.Serializable]public class SceneSave
{// string key is an identifier name we choose for this listpublic List<SceneItem> listSceneItem;public Dictionary<string, GridPropertyDetails> gridPropertyDetailsDictionary; // key是坐標信息,value是地面屬性信息
}

public Dictionary<string, GridPropertyDetails> gridPropertyDetailsDictionary;中,string會保存網格的坐標信息。

4、創建GridPropertyDetails.cs

在Assets -> Scripts -> Map下新增GridPropertyDetails.cs腳本。


[System.Serializable]
public class GridPropertyDetails
{public int gridX;public int gridY;public bool isDiggable = false;public bool canDropItem = false;public bool canPlaceFurniture = false;public bool isPath = false;public bool isNPCObstacle = false;public int daysSinceDug = -1;public int daysSinceWatered = -1;public int seedItemCode = -1;public int growthDays = -1;public int daysSinceLastHarvest = -1;public GridPropertyDetails() { }
}

其中上半部分的屬性是已知的,下半部分的信息是在運行中賦值的。

5、創建GridPropertiesManager.cs腳本

在Assets -> Scripts -> Map下新增GridPropertiesManager.cs腳本。

該類會讀取Assets -> Scriptable Object Assets -> Maps下的3個so_xxx資源文件,然后寫到SceneSave的gridPropertyDetailsDictionary中去。

using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEngine;[RequireComponent(typeof(GenerateGUID))]
public class GridPropertiesManager : SingletonMonobehaviour<GridPropertiesManager>, ISaveable
{public Grid grid;private Dictionary<string, GridPropertyDetails> gridPropertyDictionary;[SerializeField] private SO_GridProperties[] so_gridPropertiesArray = null;private string _iSaveableUniqueID;private GameObjectSave _gameObjectSave;public string ISaveableUniqueID { get { return _iSaveableUniqueID; } set { _iSaveableUniqueID = value; } }public GameObjectSave GameObjectSave { get { return _gameObjectSave; } set { _gameObjectSave = value; } }protected override void Awake(){base.Awake();ISaveableUniqueID = GetComponent<GenerateGUID>().GUID;GameObjectSave = new GameObjectSave();}private void OnEnable(){ISaveableRegister();EventHandler.AfterSceneLoadEvent += AfterSceneLoaded;}private void OnDisable() {ISaveableDeregister();EventHandler.AfterSceneLoadEvent -= AfterSceneLoaded;}private void AfterSceneLoaded(){// Get Gridgrid = GameObject.FindObjectOfType<Grid>();}public void ISaveableDeregister(){SaveLoadManager.Instance.iSaveableObjectList.Remove(this);}public void ISaveableRegister(){SaveLoadManager.Instance.iSaveableObjectList.Add(this);}public void ISaveableRestoreScene(string sceneName){// Get sceneSave for scene - it exists since we created it in initialiseif(GameObjectSave.sceneData.TryGetValue(sceneName, out SceneSave sceneSave)){// get grid property details dictionary - it exists since we created it in initialiseif(sceneSave.gridPropertyDetailsDictionary != null){gridPropertyDictionary = sceneSave.gridPropertyDetailsDictionary;}}}public void ISaveableStoreScene(string sceneName){// Remove sceneSave for sceneGameObjectSave.sceneData.Remove(sceneName);// Create sceneSave for sceneSceneSave sceneSave = new SceneSave();// create & add dict grid property details dictionarysceneSave.gridPropertyDetailsDictionary = gridPropertyDictionary;// Add scene save to game object scene dataGameObjectSave.sceneData.Add(sceneName, sceneSave);}private void Start(){InitialiseGridProperties();}/// <summary>/// This initialises the grid property dictionary with the values from the SO_GridProperties assets and stores the values for each scene in/// GameObjectSave sceneData/// </summary>private void InitialiseGridProperties(){// loop through all gridproperties in the arrayforeach(SO_GridProperties so_GridProperties in so_gridPropertiesArray){// Create dictionary of grid property detailsDictionary<string, GridPropertyDetails> gridPropertyDictionary = new Dictionary<string, GridPropertyDetails>();// Populate grid property dictionary - Iterate through all the grid properties in the so gridproperties listforeach(GridProperty gridProperty in so_GridProperties.gridPropertyList){GridPropertyDetails gridPropertyDetails;gridPropertyDetails = GetGridPropertyDetails(gridProperty.gridCoordinate.x, gridProperty.gridCoordinate.y, gridPropertyDictionary);if(gridPropertyDetails == null){gridPropertyDetails = new GridPropertyDetails();}switch (gridProperty.gridBoolProperty){case GridBoolProperty.diggable:gridPropertyDetails.isDiggable = gridProperty.gridBoolValue;break;case GridBoolProperty.canDropItem:gridPropertyDetails.canDropItem = gridProperty.gridBoolValue;break;case GridBoolProperty.canPlaceFurniture:gridPropertyDetails.canPlaceFurniture = gridProperty.gridBoolValue;break;case GridBoolProperty.isPath:gridPropertyDetails.isPath = gridProperty.gridBoolValue;break;case GridBoolProperty.isNPCObstacle:gridPropertyDetails.isNPCObstacle = gridProperty.gridBoolValue;break;default:break; }SetGridPropertyDetails(gridProperty.gridCoordinate.x, gridProperty.gridCoordinate.y, gridPropertyDetails, gridPropertyDictionary);}// Create scene save for this gameobjectSceneSave sceneSave = new SceneSave();// Add grid property dictionary to scene save datasceneSave.gridPropertyDetailsDictionary = gridPropertyDictionary;// If starting scene set the griProertyDictionary member variable to the current iterationif(so_GridProperties.sceneName.ToString() == SceneControllerManager.Instance.startingSceneName.ToString()){this.gridPropertyDictionary = gridPropertyDictionary;}// Add scene save to game object scene dataGameObjectSave.sceneData.Add(so_GridProperties.sceneName.ToString(), sceneSave);}}/// <summary>/// Returns the gridPropertyDetails at the gridlocation fro the supplied dictionary,/// or null if no properties exist at that location/// </summary>/// <param name="gridX"></param>/// <param name="gridY"></param>/// <param name="gridPropertyDictionary"></param>/// <returns></returns>public GridPropertyDetails GetGridPropertyDetails(int gridX, int gridY, Dictionary<string, GridPropertyDetails> gridPropertyDictionary){// Construct key from coordinatestring key = "x" + gridX + "y" + gridY;GridPropertyDetails gridPropertyDetails;// Check if grid property details exist for coordinate and retrieveif (!gridPropertyDictionary.TryGetValue(key, out gridPropertyDetails)){// if not foundreturn null;}else{return gridPropertyDetails;}}public GridPropertyDetails GetGridPropertyDetails(int gridX, int gridY){return GetGridPropertyDetails(gridX, gridY, gridPropertyDictionary);}/// <summary>/// Set the grid property details to gridPropertyDetails fro the tile at (gridX, gridY) for current scene/// </summary>/// <param name="gridX"></param>/// <param name="gridY"></param>/// <param name="gridPropertyDetails"></param>public void SetGridPropertyDetails(int gridX, int gridY, GridPropertyDetails gridPropertyDetails){SetGridPropertyDetails(gridX, gridY, gridPropertyDetails, gridPropertyDictionary);}/// <summary>/// Set the grid property details to gridPropertyDetails for the title at (gridX, gridY) for the gridPropertyDictionary./// </summary>/// <param name="gridX"></param>/// <param name="gridY"></param>/// <param name="gridPropertyDetails"></param>/// <param name="gridPropertyDictionary"></param>public void SetGridPropertyDetails(int gridX, int gridY, GridPropertyDetails gridPropertyDetails, Dictionary<string, GridPropertyDetails> gridPropertyDictionary){// Construct key from coordinatestring key = "x" + gridX + "y" + gridY;gridPropertyDetails.gridX = gridX;gridPropertyDetails.gridY = gridY;// Set value gridPropertyDictionary[key] = gridPropertyDetails;}}

6、優化Settings.cs

Assets -> Scripts -> Misc -> Settings.cs文件。

增加如下代碼:

 // Tilemappublic const float gridCellSize = 1f; // grid cell size in unity units

7、優化UIInventorySlot.cs

Assets -> Scripts -> UI -> UIInventory -> UIInventorySlot.cs

經過前面幾步的準備,現在我們在Drop Item時可以做一層判斷。

調整DropSelectedItemAtMousePosition函數如下:

  private void DropSelectedItemAtMousePosition(){if(itemDetails != null && isSelected){Vector3 worldPosition = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -mainCamera.transform.position.z));// If can drop item hereVector3Int gridPosition = GridPropertiesManager.Instance.grid.WorldToCell(worldPosition);GridPropertyDetails gridPropertyDetails = GridPropertiesManager.Instance.GetGridPropertyDetails(gridPosition.x, gridPosition.y);if(gridPropertyDetails != null && gridPropertyDetails.canDropItem){// Create item from prefab at mouse positionGameObject itemGameObject = Instantiate(itemPrefab, new Vector3(worldPosition.x, worldPosition.y - Settings.gridCellSize/2f, worldPosition.z), Quaternion.identity, parentItem);Item item = itemGameObject.GetComponent<Item>();item.ItemCode = itemDetails.itemCode;// Remove item from player's inventoryInventoryManager.Instance.RemoveItem(InventoryLocation.player, item.ItemCode);// If no more of item then clear selectedif (InventoryManager.Instance.FindItemInInventory(InventoryLocation.player, item.ItemCode) == -1){ClearSelectedItem();}}}}

因為Item的中心在pivot(底部),如果不調整item的中心位置,每次放置Item到地面時都會導致Item的y軸上的落地點比鼠標位置高一點。

所以我們通過new Vector3(worldPosition.x, worldPosition.y - Settings.gridCellSize/2f, worldPosition.z),適當調整y的位置。

UIInventorySlot.cs完整代碼如下:

using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;public class UIInventorySlot : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{private Camera mainCamera;private Transform parentItem; // 場景中的物體父類private GameObject draggedItem; // 被拖動的物體private Canvas parentCanvas;public Image inventorySlotHighlight;public Image inventorySlotImage;public TextMeshProUGUI textMeshProUGUI;[SerializeField] private UIInventoryBar inventoryBar = null;[SerializeField] private GameObject itemPrefab = null;[SerializeField] private int slotNumber = 0; // 插槽的序列號[SerializeField] private GameObject inventoryTextBoxPrefab = null;[HideInInspector] public ItemDetails itemDetails;[HideInInspector] public int itemQuantity;[HideInInspector] public bool isSelected = false;private void Awake(){parentCanvas = GetComponentInParent<Canvas>();}private void OnDisable(){EventHandler.AfterSceneLoadEvent -= SceneLoaded;}private void OnEnable(){EventHandler.AfterSceneLoadEvent += SceneLoaded;}public void SceneLoaded(){parentItem = GameObject.FindGameObjectWithTag(Tags.ItemsParentTransform).transform;}private void Start(){mainCamera = Camera.main;//parentItem = GameObject.FindGameObjectWithTag(Tags.ItemsParentTransform).transform;}public void OnBeginDrag(PointerEventData eventData){if(itemDetails != null) {// Disable keyboard inputPlayer.Instance.DisablePlayerInputAndResetMovement();// Instatiate gameobject as dragged itemdraggedItem = Instantiate(inventoryBar.inventoryBarDraggedItem, inventoryBar.transform);// Get image for dragged itemImage draggedItemImage = draggedItem.GetComponentInChildren<Image>();draggedItemImage.sprite = inventorySlotImage.sprite;SetSelectedItem();}}public void OnDrag(PointerEventData eventData){// move game object as dragged itemif(!draggedItem != null){draggedItem.transform.position = Input.mousePosition;}}public void OnEndDrag(PointerEventData eventData){// Destroy game object as dragged itemif (draggedItem != null) {Destroy(draggedItem);// if drag ends over inventory bar, get item drag is over and swap thenif (eventData.pointerCurrentRaycast.gameObject != null && eventData.pointerCurrentRaycast.gameObject.GetComponent<UIInventorySlot>() != null) {// get the slot number where the drag endedint toSlotNumber = eventData.pointerCurrentRaycast.gameObject.GetComponent<UIInventorySlot>().slotNumber;// Swap inventory items in inventory listInventoryManager.Instance.SwapInventoryItems(InventoryLocation.player, slotNumber, toSlotNumber);// Destroy inventory text boxDestroyInventoryTextBox();// Clear selected itemClearSelectedItem();}else{// else attemp to drop the item if it can be droppedif (itemDetails.canBeDropped){DropSelectedItemAtMousePosition();}}// Enable player inputPlayer.Instance.EnablePlayerInput();}}/// <summary>/// Drops the item(if selected) at the current mouse position. called by the DropItem event/// </summary>private void DropSelectedItemAtMousePosition(){if(itemDetails != null && isSelected){Vector3 worldPosition = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -mainCamera.transform.position.z));// If can drop item hereVector3Int gridPosition = GridPropertiesManager.Instance.grid.WorldToCell(worldPosition);GridPropertyDetails gridPropertyDetails = GridPropertiesManager.Instance.GetGridPropertyDetails(gridPosition.x, gridPosition.y);if(gridPropertyDetails != null && gridPropertyDetails.canDropItem){// Create item from prefab at mouse positionGameObject itemGameObject = Instantiate(itemPrefab, new Vector3(worldPosition.x, worldPosition.y - Settings.gridCellSize/2f, worldPosition.z), Quaternion.identity, parentItem);Item item = itemGameObject.GetComponent<Item>();item.ItemCode = itemDetails.itemCode;// Remove item from player's inventoryInventoryManager.Instance.RemoveItem(InventoryLocation.player, item.ItemCode);// If no more of item then clear selectedif (InventoryManager.Instance.FindItemInInventory(InventoryLocation.player, item.ItemCode) == -1){ClearSelectedItem();}}}}public void OnPointerEnter(PointerEventData eventData){// Populate text box with item detailsif(itemQuantity != 0){// Instantiate inventory text boxinventoryBar.inventoryTextBoxGameobject = Instantiate(inventoryTextBoxPrefab, transform.position, Quaternion.identity);inventoryBar.inventoryTextBoxGameobject.transform.SetParent(parentCanvas.transform, false);UIInventoryTextBox inventoryTextBox = inventoryBar.inventoryTextBoxGameobject.GetComponent<UIInventoryTextBox>();// Set item type descriptionstring itemTypeDescription = InventoryManager.Instance.GetItemTypeDescription(itemDetails.itemType);// Populate text boxinventoryTextBox.SetTextboxText(itemDetails.itemDescription, itemTypeDescription, "", itemDetails.itemLongDescription, "", "");// Set text box position according to inventory bar positionif (inventoryBar.IsInventoryBarPositionBottom){inventoryBar.inventoryTextBoxGameobject.GetComponent<RectTransform>().pivot = new Vector2(0.5f, 0f);inventoryBar.inventoryTextBoxGameobject.transform.position = new Vector3(transform.position.x, transform.position.y + 50f, transform.position.z);}else{inventoryBar.inventoryTextBoxGameobject.GetComponent<RectTransform>().pivot = new Vector2(0.5f, 1f);inventoryBar.inventoryTextBoxGameobject.transform.position = new Vector3(transform.position.x, transform.position.y - 50f, transform.position.z);}}}public void OnPointerExit(PointerEventData eventData){DestroyInventoryTextBox();}private void DestroyInventoryTextBox(){if (inventoryBar.inventoryTextBoxGameobject != null) {Destroy(inventoryBar.inventoryTextBoxGameobject);}}public void OnPointerClick(PointerEventData eventData){// if left clickif (eventData.button == PointerEventData.InputButton.Left){// if inventory slot currently selected then deselectif (isSelected == true){ClearSelectedItem();}else  // 未被選中且有東西則顯示選中的效果{if(itemQuantity > 0){SetSelectedItem();}}}}/// <summary>/// Set this inventory slot item to be selected/// </summary>private void SetSelectedItem(){// Clear currently highlighted itemsinventoryBar.ClearHighlightOnInventorySlots();// Highlight item on inventory barisSelected = true;// Set highlighted inventory slotsinventoryBar.SetHighlightedInventorySlots();// Set item selected in inventoryInventoryManager.Instance.SetSelectedInventoryItem(InventoryLocation.player, itemDetails.itemCode);if (itemDetails.canBeCarried == true){// Show player carrying itemPlayer.Instance.ShowCarriedItem(itemDetails.itemCode);}else {Player.Instance.ClearCarriedItem();}}private void ClearSelectedItem(){// Clear currently highlighted iteminventoryBar.ClearHighlightOnInventorySlots();isSelected = false;// set no item selected in inventoryInventoryManager.Instance.ClearSelectedInventoryItem(InventoryLocation.player);// Clear player carrying itemPlayer.Instance.ClearCarriedItem();}
}

8、創建GridPropertiesManager對象

在Hierarchy -> PersistentScene下創建空物體命名為:GridPropertiesManager。

添加組件GridPropertiesManager如下(同時會自動創建Generate GUID組件):

然后,鎖定面板,將3個so_xxx 文件拖到So_grid Properties Array中:

保存后執行程序:將采集的corn拖到地板位置,無法放置。

9、繪制CanDropItem區域

點擊Scene1_Farm的GridProperties對象,在Inspector勾選組件啟用。

點擊BoolCanDropItem對象,點擊Tile Palette面板,使用tile在scene界面中放置瓦片。

然后進入Inspector面板,反勾選Tilemap Render組件。

接著點擊GridProperties對象,反勾選GridProperties組件。此時點擊Assets -> Scriptable Object Assets的So_Grid_Properties_Scene1_Farm文件,可以看到Grid Property List有2000+個元素。

接下來,針對Scene2和Scene3進行同樣的操作。

Scene2:

Scene3:

10、效果演示

如上所示,草地位置是有CanDropItem屬性的,所以可以放置南瓜;而屋頂位置沒有CanDropItem屬性,所以無法放置南瓜。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74073.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74073.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74073.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

031-valgrind

valgrind 以下是從原理到代碼實現、參數優化及結果分析的Valgrind技術調研報告&#xff0c;結合C示例和可視化工具使用說明&#xff1a; 一、Valgrind核心原理與架構 1.1 系統架構 #mermaid-svg-xIgV3fg90dGhEEq4 {font-family:"trebuchet ms",verdana,arial,sans-…

C/C++藍橋杯算法真題打卡(Day12)

一、P8752 [藍橋杯 2021 省 B2] 特殊年份 - 洛谷 算法代碼&#xff1a; #include<bits/stdc.h> using namespace std; int cnt;int main() {int i1;while(i<5){int num;cin>>num;string string_numto_string(num);if(string_num[0]string_num[2]&&str…

MySQL 復制與主從架構(Master-Slave)

MySQL 復制與主從架構&#xff08;Master-Slave&#xff09; MySQL 復制與主從架構是數據庫高可用和負載均衡的重要手段。通過復制數據到多個從服務器&#xff0c;既可以實現數據冗余備份&#xff0c;又能分擔查詢壓力&#xff0c;提升系統整體性能與容錯能力。本文將詳細介紹…

《大模型部署》——ollama下載及大模型本地部署(詳細快速部署)

ollama Ollama 是一款開源跨平臺的大語言模型&#xff08;LLM&#xff09;運行工具&#xff0c;旨在簡化本地部署和管理 AI 模型的流程。 下載ollama 進入官網下載https://ollama.com/ 選擇需要的系統下載 下載完成后直接進行安裝 下載大模型 選擇想要部署的模型&#…

Java關于包和final

什么是包&#xff1f; 包就是文件夾。用來管理等各種不同功能的java類&#xff0c;方便后期代碼維護 包名的規則&#xff1a;公司域名反寫包的作用&#xff0c;需要全部英文小寫&#xff0c;見名知意。例如&#xff1a;com.pdsu.domain package com.pdsu.demain;public class…

數據層的基本操作

1.數據層的更名: Arcmap內容列表中,數據框所包含的每個圖層及每個圖層所包含的一系列地理要素,都有相應的描述字符與之對應.默認情況下,添加進地圖的圖層是以其數據源的名字命名的,而地理要素的描述就是要素類型字段取值.由于這些命名影響到用戶對數據的理解和地圖輸出時的圖例…

Vue舞臺劇

Vue 的舞臺劇比喻 &#x1f3ad;&#xff08;完整表格版&#xff09; Vue 結構及路由管理 Vue 結構比喻&#xff08;舞臺劇&#xff09;&#x1f3ad;作用index.html空白場地 &#x1f3df;?Vue 負責填充內容&#xff0c;提供 #app 容器&#xff0c;等待演出開始。main.js導…

【Windows】win10系統安裝.NET Framework 3.5(包括.NET 2.0和3.0)失敗 錯誤代碼:0×80240438

一、.NET3.5(包括.NET 2.0和3.0)安裝方式 1.1 聯網安裝(需要聯網,能訪問微軟,簡單,很可能會失敗) 1.2 離線安裝-救急用(需要操作系統iso鏡像文件,復雜,成功幾率大) 二、聯網安裝 通過【控制面板】→【程序】→【程序和功能】→【啟用或關閉Windows功能】 下載過程…

Android學習總結之RecyclerView補充篇

在 Android 開發中&#xff0c;列表數據更新的性能一直是關鍵痛點。傳統的 notifyDataSetChanged() 會觸發全量刷新&#xff0c;導致不必要的界面重繪。而 DiffUtil 作為 Android 提供的高效差異計算工具&#xff0c;能精準識別數據變化&#xff0c;實現局部更新&#xff0c;成…

Miniforge3高效管理 Python環境:2025年最新實踐指南

Miniforge3 高效管理 Python 環境:2025 年最新實踐指南 在現代開發中,靈活高效地管理 Python 環境至關重要。Miniforge3 作為一款輕量級 Conda 管理工具,不僅默認采用更新更快的 conda-forge 軟件源,還對 ARM 架構(例如 Apple M1/M2/M3)有著出色的適配性。相比于傳統的 …

山東大學軟件學院項目創新實訓開發日志(4)之中醫知識問答數據存儲、功能結構、用戶界面初步設計

目錄 數據庫設計&#xff1a; 功能設計&#xff1a; 用戶界面: 數據庫設計&#xff1a; --對話表 (1個對話包含多條消息) CREATE TABLE conversations ( conv_id VARCHAR(36) PRIMARY KEY, -- 對話ID user_id VARCHAR(36) NOT NULL, -- 所屬用戶 title VARCHAR(100), -- 對話…

交換機、路由器、VLAN、單臂路由、三層交換、STP

華為模擬安裝 1.依次安裝wincap 2.wireshark 3.virtual box 4.ensp 一、設置 1.virtual box設置 2.計算機防火墻允許以上程序 3.eNSP設置 路由器&#xff1a;AR2240 交換機&#xff1a;S5700、CE12800 防火墻USG6000V 交換機 一、交換機工作原理 1、回顧 二層交換機…

【藍橋杯】每日練習 Day15

目錄 前言 奶牛選美 分析 代碼 大臣的旅費 分析 代碼 飛機降落 分析 代碼 母親的牛奶 分析 代碼 掃雷 分析 代碼 前言 雖為誕辰&#xff0c;但也不忘完成每日的訓練。 今天給大家帶來五道dfs的題目&#xff0c;包括組合數&#xff0c;連通塊&#xff0c;數的…

ipconfig、ping、ipconfig/all 4個常用 **Windows終端(CMD)命令** 的詳細解釋

ipconfig、ping、ipconfig/all 4個常用 Windows終端&#xff08;CMD&#xff09;命令 的詳細解釋、用途分析和使用示例 1. ipconfig 作用 快速查看本地網絡連接的 IP地址、子網掩碼、默認網關 等基礎信息。 示例輸出 Windows IP 配置無線局域網適配器 WLAN:IPv4 地址 . . .…

@emotion/css + react+動態主題切換

1.下載插件 npm install --save emotion/css 2.創建ThemeContext.tsx // src/ThemeContext.tsx import React, { createContext, useContext, useState } from "react";// 定義主題類型 export type Theme "light" | "dark";// 定義主題上下…

【信奧一本通提高篇】基礎算法之貪心算法

原文 https://bbs.fmcraft.top/blog/index.php/archives/22/ 貪心算法 概述 近年來的信息學競賽試題&#xff0c;經常出現求一個問題的可行解或最優解的題目。這類問題就是我們通常所說的最優化問題。貪心算法是求解這類問題的一種常用算法。在眾多的算法中&#xff0c;貪心…

CentOS-7.0系統基礎操作

配置ip地址 編輯網卡文件&#xff1a; vi etc/sysconfig/network-scripts/ifcfg-ens33 在網卡文件里參照如下設置&#xff1a; BOOTPROTO"static" IPADDR192.168.61.233 GATEWAY192.168.61.2 NETMASK255.255.255.0 ONBOOT"yes" 防火墻管理 開啟防火墻&am…

【大模型應用】信息抽取的調研

老規矩&#xff0c;先占坑&#xff0c;后續更新。 關鍵詞&#xff1a; Pydantic functioncal 參考文獻&#xff1a;小白學大模型&#xff1a;自定義信息抽取Agent-CSDN博客

MySQL內存使用率高問題排查與解決方案:

目錄標題 **一、問題現象****二、核心排查步驟****1. 參數檢查****2. 內存使用分析****3. 存儲過程/函數/視圖檢查****4. 操作系統級檢查** **三、解決方案****1. 調整MySQL配置****2. 關閉透明大頁&#xff08;THP&#xff09;****3. 優化查詢與存儲過程****4. 硬件與環境優化…

華為GaussDB數據庫的手動備份與還原操作介紹

數據庫的備份以A機上的操作為例。 1、使用linux的root用戶登錄到GaussDB服務器。 2、用以下命令切換到 GaussDB 管理員用戶&#xff0c;其中&#xff0c;omm 為當前數據庫的linux賬號。 su - omm 3、執行gs_dump命令進行數據庫備份&#xff1a; 這里使用gs_dump命令進行備…