I am trying to implement a lives system in Candy Crush Saga where if you run out of lives then in 30 minutes they will regenerate. Here is the code I have so far. So, what I am doing is taking the current time of when the user runs out of lives. Then the next time they open the app I see what the time is and check to see if 30 minutes have elapsed and then refill the lives.
You’ll need to store the actual “real” time the lives ran out somewhere (you could use PlayerPrefs for that)
Then at startup you can check if there is a time stored and calculate how much time has elapsed
Yes, a better aproach would be to create a client-server architecture where this kind of values are stored on the server. That way there is less fraud, but i can imagine that for a simple solution PlayerPrefs works great.
You could also consider storing the time as an encrypted string, so that it is more difficult to cheat
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Text;
using System;
public class LifeFunctionality : MonoBehaviour
{
//For Life Functionality
private bool isPause = true;
public Text lifeText;
DateTime currentDate;
DateTime oldDate;
private long temp;
private float StartTime;
public static int LifeCounter;
private int TimeDifference;
public int timeToAdd;
private int dividesTimeToAddAfterResume;
public GameObject pauseButton;
public GameObject resumeButton;
private float differencePlusRemainingTime;
private float totalDifferenceInSeconds;
void Start()
{
PlayerPrefs.DeleteAll();
//GAME STARTED FIRST TIME SET LIFE COUNTER TO 0
if (!(PlayerPrefs.HasKey ("LifeCounter")))
{
LifeCounter=0;
}
else if ((PlayerPrefs.HasKey ("LifeCounter")))
{
LifeCounter=PlayerPrefs.GetInt("LifeCounter");
}
//GAME PLAYER FIRST TIME AND THERE IS NO SCENE SWITCHING
if (!(PlayerPrefs.HasKey ("RunningGameTimeToAdd")))
{
timeToAdd = 0;
StartTime = Time.timeSinceLevelLoad;
}
//IF SCENE SWITCHING OCCURED , WE ARE STORING THE TIME IN timetoadd INT AND UPDATING LIFE COUNTER
else if ((PlayerPrefs.HasKey ("RunningGameTimeToAdd")))
{
LifeCounter=PlayerPrefs.GetInt("LifeCounter");
StartTime = Time.timeSinceLevelLoad;
timeToAdd=(PlayerPrefs.GetInt("RunningGameTimeToAdd"));
Debug.Log("Remaining Time On Scene Switching-Level-1------->"+ timeToAdd);
}
}
void FixedUpdate()
{
// Debug.Log((int)Time.timeSinceLevelLoad);
TimeDifference = (int)((Time.timeSinceLevelLoad+timeToAdd) - StartTime);
/* Debug.Log("totalDifferenceInSeconds---->"+totalDifferenceInSeconds);
Debug.Log("timeToAdd---->"+timeToAdd);
Debug.Log("ADD---->"+(totalDifferenceInSeconds +timeToAdd));
// Debug.Log("Time.Time---->"+(int)Time.timeSinceLevelLoad);
// Debug.Log("StartTime---->"+StartTime);
Debug.Log("Time Difference---->"+TimeDifference);*/
if (TimeDifference >= 10)
{
timeToAdd = 0;
StartTime = Time.timeSinceLevelLoad;
if(LifeCounter < 5)
{
LifeCounter += 1;
// Debug.Log("LIFE==="+LifeCounter);
}
}
lifeText.text =""+LifeCounter;
}
//THIS IS CALLED WHEN GAME IS RESUMED FROM PAUSE
void CalculateTimeDifference()
{
//Store the current time when it starts
currentDate = System.DateTime.Now;
Debug.Log("Current Date----->"+currentDate);
//Grab the old time from the player prefs as a long
long temp = Convert.ToInt64(PlayerPrefs.GetString("TimeSpent_OnApplicationPause"));
//Convert the old time from binary to a DataTime variable
DateTime oldDate = DateTime.FromBinary(temp);
print("oldDate: " + oldDate);
//Use the Subtract method and store the result as a timespan variable
TimeSpan difference = currentDate.Subtract(oldDate);
print("Difference: " + difference);
string highestPriority = difference.ToString();
//Debug.Log(highestPriority);
String[] priorityCache= highestPriority.Split(":"[0]);
int getHour;
getHour=(int.Parse(priorityCache[0]));
int hoursInSec;
hoursInSec=getHour*3600;
Debug.Log("getHour----------> "+getHour);
Debug.Log("hoursInSec----------> "+hoursInSec);
int getMin;
getMin=(int.Parse(priorityCache[1]));
int minInSec;
minInSec=getMin*60;
Debug.Log("getMin----------> "+getMin);
Debug.Log("minInSec----------> "+getMin);
float getSec;
getSec=((int)float.Parse(priorityCache[2]));
Debug.Log("getSec---------->"+getSec);
totalDifferenceInSeconds=(int)(hoursInSec + minInSec + getSec);
Debug.Log("TOTAL DIFFERENCE IN SECONDS---->"+totalDifferenceInSeconds);
differencePlusRemainingTime=(int)(PlayerPrefs.GetInt("RunningGameTimeToAdd") + totalDifferenceInSeconds);
Debug.Log("TOTAL DIFFERENCE PLUS REMAINING TIME---->"+differencePlusRemainingTime);
timeToAdd = (int)(differencePlusRemainingTime % 10);
Debug.Log("TIME TO ADD AFTER RESUME---------> "+timeToAdd);
if(LifeCounter < 5)
{
LifeCounter += (int)(differencePlusRemainingTime / 10);
Debug.Log("RESUME----> "+LifeCounter);
if(LifeCounter > 5)
{
LifeCounter = 5;
}
}
}
/* void OnApplicationQuit()
{
//Save the current system time as a string in the player prefs class
}*/
public void loadLevel1()
{
PlayerPrefs.SetInt("RunningGameTimeToAdd", TimeDifference);
Debug.Log("RunningGameTimeToAdd------>"+PlayerPrefs.GetInt("RunningGameTimeToAdd"));
PlayerPrefs.SetInt("LifeCounter",LifeCounter);
Debug.Log("Remaining Time On Scene Switching------->"+ PlayerPrefs.GetInt("RunningGameTimeToAdd"));
Application.LoadLevel("Scene1");
}
public void loadLevel2()
{
PlayerPrefs.SetInt("RunningGameTimeToAdd", TimeDifference);
PlayerPrefs.SetInt("LifeCounter",LifeCounter);
Debug.Log("Remaining Time On Scene Switching------->"+ PlayerPrefs.GetInt("RunningGameTimeToAdd"));
Application.LoadLevel("Scene2");
}
public void quitPressed()
{
PlayerPrefs.SetInt("RunningGameTimeToAdd", TimeDifference);
PlayerPrefs.SetInt("LifeCounter",LifeCounter);
Debug.Log("Remaining Time On Scene Switching------->"+ PlayerPrefs.GetInt("RunningGameTimeToAdd"));
Application.LoadLevel("Home");
}
public void level1()
{
PlayerPrefs.SetInt("RunningGameTimeToAdd", TimeDifference);
PlayerPrefs.SetInt("LifeCounter",LifeCounter);
Application.LoadLevel("Scene1");
}
public void level2()
{
PlayerPrefs.SetInt("RunningGameTimeToAdd", TimeDifference);
PlayerPrefs.SetInt("LifeCounter",LifeCounter);
Debug.Log("Remaining Time On Scene Switching------->"+ PlayerPrefs.GetInt("RunningGameTimeToAdd"));
Application.LoadLevel("Scene2");
}
public void pauseGame()
{
PlayerPrefs.SetString("TimeSpent_OnApplicationPause", System.DateTime.Now.ToBinary().ToString());
PlayerPrefs.SetInt("RunningGameTimeToAdd", TimeDifference);
Debug.Log("Remaining Time On Scene Switching------->"+ PlayerPrefs.GetInt("RunningGameTimeToAdd"));
PlayerPrefs.SetInt("LifeCounter",LifeCounter);
resumeButton.SetActive(true);
pauseButton.SetActive(false);
Time.timeScale=0;
}
public void ResumeGame()
{
LifeCounter=PlayerPrefs.GetInt("LifeCounter");
if(PlayerPrefs.HasKey("TimeSpent_OnApplicationPause"))
CalculateTimeDifference();
pauseButton.SetActive(true);
resumeButton.SetActive(false);
Time.timeScale=1;
}
}
In order to calculate the time that was lapsed since you last shut down the game, you should save the last time playerprefs in the function OnApplicationPause and calcuate the timelapsed in the Awake Function.
void Awake () {
if(!PlayerPrefs.HasKey("Lives")){
PlayerPrefs.SetString("LifeUpdateTime", DateTime.Now.ToString());
}
lives = PlayerPrefs.GetInt("Lives", maxLives);
//update life counter only if lives are less than maxLives
if (lives < maxLives)
{
float timerToAdd = (float)(System.DateTime.Now - Convert.ToDateTime(PlayerPrefs.GetString("LifeUpdateTime"))).TotalSeconds;
UpdateLives(timerToAdd);
}
}
void UpdateLives(double timerToAdd ){
if (lives < maxLives)
{
int livesToAdd = Mathf.FloorToInt((float)timerToAdd / lifeReplenishTime);
timerForLife = (float)timerToAdd % lifeReplenishTime;
lives += livesToAdd;
if (lives > maxLives)
{
lives = maxLives;
timerForLife = 0;
}
PlayerPrefs.SetString("LifeUpdateTime", DateTime.Now.AddSeconds(-timerForLife).ToString());
}else{
PlayerPrefs.SetString("LifeUpdateTime", DateTime.Now.ToString());
}
}
void OnApplicationPause(bool isPause)
{
if (isPause)
{
timeOfPause = System.DateTime.Now;
}
else
{
if(timeOfPause == default(DateTime)){
timeOfPause = System.DateTime.Now;
}
float timerToAdd = (float)(System.DateTime.Now - timeOfPause).TotalSeconds;
timerForLife += timerToAdd;
UpdateLives(timerForLife);
}
}