前言
我是一個剛挑戰用Unity做手機遊戲的菜鳥,以下程式碼主要為方便自我回顧,因為當初參考的網站對我來說非常難理解,導致自己花了很多時間研究,所以我用自己的方式來講解跟優化,希望可以幫助大家更容易讀懂內容。
*此程式碼是用json儲存時間以及體力資料
*判斷第一次登陸滿體力,因為我的做法略微不同,所以這裡沒有寫到,後續的程式紀錄分享會在提到並補上連結
using System;//時間
using UnityEngine.UI;//UI介面設計
public class playdata
{
public int ap;//體力
public string time;//預計AP回滿時間
}
public class AP_restore : MonoBehaviour
{
DateTime nowtime;//現在時間
int powerTimeInt;//時間倒數(秒數)
public Text timetext;//時間倒數
void Start()
{
APtime();//函數名稱
}
void APtime()//計算目前該有的體力
{
nowtime = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
DateTime.Now.Day, ateTime.Now.Hour, DateTime.Now.Minute,
DateTime.Now.Second);//現在時間(年,月,日,時.分,秒)
TimeSpan timeSpan = nowtime - Convert.ToDateTime(play.time);
//時間差 (現在時間-預計恢復體力時間)
double totalSeconds = timeSpan.TotalSeconds;//隔多少秒鐘
bool isStop = false;//做while循環停止的標記
int Seconds = 0;//計算回復AP的秒數
if (totalSeconds >= 0)//超過預計恢復時間,所以體力恢復最大值
{
play.ap = 300;//體力最大值
play.time = nowtime.ToString("yyyy-MM-dd HH:mm:ss");//將時間轉換為文字儲存
AP_add(0);//0代表只更改UI
}
else//未超過預計恢復時間,所以計算要恢復多少體力
{
while (!isStop)//計算經過了多少時間
{
if (Seconds + totalSeconds >= 0)//計算結束(差多少秒+時間差)
{
isStop = true;
}
else
{
Seconds += 1;
}
if (Seconds == 18000)//等於恢復體力上限時間(秒數),代表玩家有調時間
{
isStop = true;
}
}
if (Seconds == 18000)//數字為恢復體力上限時間(秒數),等於玩家有調過時間
{
powerTimeInt = 60 - 1;//時間倒數計時
play.ap = 0;//因調過時間,所以採取歸0計算
AP_add(1);//1代表更改UI外還要開啟計時器
}
else//玩家沒有調過時間
{
powerTimeInt = Seconds % 60;
//因60秒恢復一次體力,取餘數代表還差幾秒可恢復
if (powerTimeInt > 0)//體力上限值-(時間差(秒數)/60)為當時體力
play.ap = 300 - Seconds / 60 - 1;//因有餘數,故而多扣1點
else if (powerTimeInt == 0)
play.ap = 300 - Seconds / 60;
AP_add(1);//1代表更改UI外還要開啟計時器
}
}
}
void AP_add(int Judge)//更改UI介面,並決定是否開啟計時器
{
apAxis.transform.localScale =
new Vector3(oldapbar * (play.ap / 300f), apAxis.transform.localScale.y,
apAxis.transform.localScale.z);//ap條跟隨ap做變化
aptext.text = play.ap + "/300";
saveString = JsonUtility.ToJson(play);//轉成string(json格式)
file = new StreamWriter(System.IO.Path.Combine
(Application.persistentDataPath, "play.json"));//手機路徑
file.Write(saveString);//寫入資料
file.Close();//結束
if (Seconds != 0)//開啟計時器
{
InvokeRepeating("RefreshTimeBySceond", 1f, 1f);
//1秒後執行此函數,並每1秒執行一次
}
}
public void RefreshTimeBySceond()//計時器
{
if (powerTimeInt <= 0)
{
play.ap += 1;//計時完成,體力+1
apAxis.transform.localScale = new Vector3(oldapbar * (play.ap / 300f),
apAxis.transform.localScale.y, apAxis.transform.localScale.z); //ap條跟隨ap做變化
aptext.text = play.ap + "/300";
saveString = JsonUtility.ToJson(play);//轉成string(json格式)
file = new treamWriter(System.IO.Path.Combine
(Application.persistentDataPath, "play.json"));//手機路徑
file.Write(saveString);
file.Close();
if (play.ap >= 300)//體力滿,暫停計時
{
CancelInvoke();//關閉重複執行
}
else//體力未滿,繼續計時
{
powerTimeInt = 60 - 1;//秒數更新,繼續到數
timetext.text = "00:" + powerTimeInt;//時間UI更改
}
}
else
{
powerTimeInt -= 1;
if (powerTimeInt < 10)
timetext.text = "00:0" + powerTimeInt;
else
timetext.text = "00:" + powerTimeInt;
}
}
}
void DealSaveData()//恢復體力的時間計算和儲存
{
int leftmin = 300 - play.ap;//計算恢復滿體力需要多少時間(分鐘)
if (leftmin <= 0)//代表滿體力,存下當前時間
{
play.time = new DateTime(DateTime.Now.Year, DateTime.Now.Month,
DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute,
DateTime.Now.Second).ToString("yyyy-MM-dd HH:mm:ss");//年月日時分秒
}
else//代表體力未滿,需計算什麼時候恢復滿體力,
{
play.time = Convert.ToDateTime(play.time).
AddMinutes(leftmin).ToString("yyyy-MM-dd HH:mm:ss");
//原本預計恢復滿體力的時間再往後加時間
}
}