WXMC/.svn/pristine/66/667e5fdfb3fd4028155e0b7f31f9ed07fbaddbae.svn-base
2024-12-04 16:18:46 +08:00

515 lines
17 KiB
Plaintext

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System;
public enum LUCKY_SPIN_REWARDS
{
FIVE_COINS_REWARD,
TEN_COINS_REWARD,
TWENTY_COINS_REWARD,
THIRTY_COINS_REWARD,
SINGLE_BREAKER_REWARD,
ROW_BREAKER_REWARD,
COL_BREAKER_REWARD,
RAINBOW_BREAKER_REWARD,
OVEN_BREAKER_REWARD,
BEGIN_FIVE_MOVE_REWARD,
BEGIN_RAINBOW_REWARD,
BEGIN_BOMB_BREAKER_REWARD
}
public class FortuneWheelManager : MonoBehaviour
{
public GameObject PaidTurnButton; // This button is showed when you can turn the wheel for coins
public GameObject FreeTurnButton; // This button is showed when you can turn the wheel for free
public GameObject Circle; // Rotatable GameObject on scene with reward objects
public Text DeltaCoinsText; // Pop-up text with wasted or rewarded coins amount
public Text CurrentCoinsText; // Pop-up text with wasted or rewarded coins amount
public GameObject NextTurnTimerWrapper;
public Text NextFreeTurnTimerText; // Text element that contains remaining time to next free turn
public Image CoinsDeltaImage;
public int SpinCost = 25;
public int boosterRewardCount = 2;
public List<Sprite> awardImage;
private LUCKY_SPIN_REWARDS Sector1 = LUCKY_SPIN_REWARDS.THIRTY_COINS_REWARD;
private LUCKY_SPIN_REWARDS Sector2 = LUCKY_SPIN_REWARDS.SINGLE_BREAKER_REWARD; // single bomb
private LUCKY_SPIN_REWARDS Sector3 = LUCKY_SPIN_REWARDS.ROW_BREAKER_REWARD; // row bomb
private LUCKY_SPIN_REWARDS Sector4 = LUCKY_SPIN_REWARDS.TEN_COINS_REWARD;
private LUCKY_SPIN_REWARDS Sector5 = LUCKY_SPIN_REWARDS.COL_BREAKER_REWARD; // col bomb
private LUCKY_SPIN_REWARDS Sector6 = LUCKY_SPIN_REWARDS.RAINBOW_BREAKER_REWARD; // rainbow bomb
private LUCKY_SPIN_REWARDS Sector7 = LUCKY_SPIN_REWARDS.TWENTY_COINS_REWARD;
private LUCKY_SPIN_REWARDS Sector8 = LUCKY_SPIN_REWARDS.OVEN_BREAKER_REWARD; // oven
private LUCKY_SPIN_REWARDS Sector9 = LUCKY_SPIN_REWARDS.BEGIN_FIVE_MOVE_REWARD; // begin five move
private LUCKY_SPIN_REWARDS Sector10 = LUCKY_SPIN_REWARDS.FIVE_COINS_REWARD;
private LUCKY_SPIN_REWARDS Sector11 = LUCKY_SPIN_REWARDS.BEGIN_RAINBOW_REWARD; // begin rainbow
private LUCKY_SPIN_REWARDS Sector12 = LUCKY_SPIN_REWARDS.BEGIN_BOMB_BREAKER_REWARD; // begin bomb
private bool _isStarted; // Flag that the wheel is spinning
private float[] _sectorsAngles; // All sectors angles
private float _finalAngle; // The final angle is needed to calculate the reward
private float _startAngle = 0; // The first time start angle equals 0 but the next time it equals the last final angle
private float _currentLerpRotationTime; // Needed for spinning animation
private int _turnCost = 25; // How much coins user waste when turn when wheel
private int _currentCoinsAmount = 0; // Started coins amount. In your project it should be picked up from CoinsManager or from PlayerPrefs and so on
private int _previousCoinsAmount;
// Here you can set time between two free turns
private int _timerMaxHours = 24;
private int _timerMaxMinutes = 0;
private int _timerMaxSeconds = 0;
// Remaining time to next free turn
private int _timerRemainingHours = 0;
private int _timerRemainingMinutes = 0;
private int _timerRemainingSeconds = 0;
private DateTime _nextFreeTurnTime;
// Key name for storing in PlayerPrefs
private const string LAST_FREE_TURN_TIME_NAME = "LastFreeTurnTimeTicks";
// Set TRUE if you want to let players to turn the wheel for coins while free turn is not available yet
private bool _isPaidTurnEnabled = true;
// Set TRUE if you want to let players to turn the wheel for FREE from time to time
private bool _isFreeTurnEnabled = true;
// Flag that player can turn the wheel for free right now
private bool _isFreeTurnAvailable = false;
private void Awake ()
{
// define coin amount
_currentCoinsAmount = GameData.instance.GetPlayerCoin();
// spin cost
_turnCost = SpinCost;
_previousCoinsAmount = _currentCoinsAmount;
// Show our current coins amount
CurrentCoinsText.text = _currentCoinsAmount.ToString ();
if (_isFreeTurnEnabled) {
if (!PlayerPrefs.HasKey(LAST_FREE_TURN_TIME_NAME)) {
//print("Very first free spin: " + DateTime.Now.AddDays(-1).Ticks.ToString());
PlayerPrefs.SetString(LAST_FREE_TURN_TIME_NAME, DateTime.Now.AddDays(-7).Ticks.ToString());
}
// Start our timer to next free turn
SetNextFreeTime();
} else {
NextTurnTimerWrapper.gameObject.SetActive (false);
}
}
private void TurnWheelForFree() { TurnWheel (true); }
private void TurnWheelForCoins() { TurnWheel (false); }
private void TurnWheel (bool isFree)
{
_currentLerpRotationTime = 0f;
// Fill the necessary angles (for example if you want to have 12 sectors you need to fill the angles with 30 degrees step)
_sectorsAngles = new float[] { 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360 };
int fullTurnovers = 5;
// Choose random final sector
float randomFinalAngle = _sectorsAngles [UnityEngine.Random.Range (0, _sectorsAngles.Length)];
// Set up how many turnovers our wheel should make before stop
_finalAngle = -(fullTurnovers * 360 + randomFinalAngle);
// Stop the wheel
_isStarted = true;
_previousCoinsAmount = _currentCoinsAmount;
// Decrease money for the turn if it is not free turn
if (!isFree) {
_currentCoinsAmount -= _turnCost;
// Show wasted coins
DeltaCoinsText.text = String.Format ("-{0}", _turnCost);
DeltaCoinsText.gameObject.SetActive (true);
CoinsDeltaImage.overrideSprite = awardImage[0];
// reduce coin sound
AudioManager.instance.CoinPayAudio();
// update game data
GameData.instance.SavePlayerCoin(GameData.instance.GetPlayerCoin() - _turnCost);
// update text label
if (GameObject.Find("MapScene"))
{
GameObject.Find("MapScene").GetComponent<MapScene>().UpdateCoinAmountLabel();
}
// Animations for coins
StartCoroutine (HideCoinsDelta ());
StartCoroutine (UpdateCoinsAmount ());
} else {
// At this step you can save current time value to your server database as last used free turn
// We can't save long int to PlayerPrefs so store this value as string and convert to long later
PlayerPrefs.SetString (LAST_FREE_TURN_TIME_NAME, DateTime.Now.Ticks.ToString());
// Restart timer to next free turn
SetNextFreeTime ();
}
}
public void TurnWheelButtonClick ()
{
if (_isFreeTurnAvailable) {
TurnWheelForFree ();
} else {
// If we have enabled paid turns
if (_isPaidTurnEnabled) {
// If player have enough coins
if (_currentCoinsAmount >= _turnCost) {
TurnWheelForCoins ();
}
}
}
}
public void SetNextFreeTime() {
// Reset the remaining time values
_timerRemainingHours = _timerMaxHours;
_timerRemainingMinutes = _timerMaxMinutes;
_timerRemainingSeconds = _timerMaxSeconds;
// Get last free turn time value from storage
// We can't save long int to PlayerPrefs so store this value as string and convert to long
_nextFreeTurnTime = new DateTime(Convert.ToInt64(PlayerPrefs.GetString (LAST_FREE_TURN_TIME_NAME, DateTime.Now.Ticks.ToString())))
.AddHours(_timerMaxHours)
.AddMinutes(_timerMaxMinutes)
.AddSeconds(_timerMaxSeconds);
_isFreeTurnAvailable = false;
}
private void GiveAwardByAngle ()
{
// Here you can set up rewards for every sector of wheel (clockwise)
switch ((int)_startAngle) {
// Sector 1
case 0:
RewardCoins (Sector1);
break;
// Sector 2
case -330:
RewardCoins(Sector2);
break;
// Sector 3
case -300:
RewardCoins(Sector3);
break;
// Sector 4
case -270:
RewardCoins(Sector4);
break;
// Sector 5
case -240:
RewardCoins(Sector5);
break;
// Sector 6
case -210:
RewardCoins(Sector6);
break;
// Sector 7
case -180:
RewardCoins(Sector7);
break;
// Sector 8
case -150:
RewardCoins(Sector8);
break;
// Sector 9
case -120:
RewardCoins(Sector9);
break;
// Sector 10
case -90:
RewardCoins(Sector10);
break;
// Sector 11
case -60:
RewardCoins(Sector11);
break;
// Sector 12
case -30:
RewardCoins(Sector12);
break;
default:
break;
}
}
private void ShowTurnButtons ()
{
if (_isFreeTurnAvailable) // If have free turn
{
ShowFreeTurnButton ();
EnableFreeTurnButton ();
} else { // If haven't free turn
if (!_isPaidTurnEnabled) // If our settings allow only free turns
{
ShowFreeTurnButton ();
DisableFreeTurnButton (); // Make button inactive while spinning or timer to next free turn
} else { // If player can turn for coins
ShowPaidTurnButton ();
if (_isStarted || _currentCoinsAmount < _turnCost)
DisablePaidTurnButton (); // Make button non interactable if user has not enough money for the turn of if wheel is turning right now
else
EnablePaidTurnButton (); // Can make paid turn right now
}
}
}
private void Update ()
{
// We need to show TURN FOR FREE button or TURN FOR COINS button
ShowTurnButtons ();
// Show timer only if we enable free turns
if (_isFreeTurnEnabled)
UpdateFreeTurnTimer ();
if (!_isStarted)
return;
// Animation time
float maxLerpRotationTime = 4f;
// increment animation timer once per frame
_currentLerpRotationTime += Time.deltaTime;
// If the end of animation
if (_currentLerpRotationTime > maxLerpRotationTime || Circle.transform.eulerAngles.z == _finalAngle) {
_currentLerpRotationTime = maxLerpRotationTime;
_isStarted = false;
_startAngle = _finalAngle % 360;
GiveAwardByAngle ();
StartCoroutine (HideCoinsDelta ());
} else {
// Calculate current position using linear interpolation
float t = _currentLerpRotationTime / maxLerpRotationTime;
// This formula allows to speed up at start and speed down at the end of rotation.
// Try to change this values to customize the speed
t = t * t * t * (t * (6f * t - 15f) + 10f);
float angle = Mathf.Lerp (_startAngle, _finalAngle, t);
Circle.transform.eulerAngles = new Vector3 (0, 0, angle);
}
}
// Give the reward to player
private void RewardCoins(LUCKY_SPIN_REWARDS award)
{
//print("Reward to player: " + award);
int awardCoins = 0;
switch (award)
{
case LUCKY_SPIN_REWARDS.FIVE_COINS_REWARD:
case LUCKY_SPIN_REWARDS.TEN_COINS_REWARD:
case LUCKY_SPIN_REWARDS.TWENTY_COINS_REWARD:
case LUCKY_SPIN_REWARDS.THIRTY_COINS_REWARD:
//print("Award coins");
if (award == LUCKY_SPIN_REWARDS.FIVE_COINS_REWARD) awardCoins = 5;
else if (award == LUCKY_SPIN_REWARDS.TEN_COINS_REWARD) awardCoins = 10;
else if (award == LUCKY_SPIN_REWARDS.TWENTY_COINS_REWARD) awardCoins = 20;
else if (award == LUCKY_SPIN_REWARDS.THIRTY_COINS_REWARD) awardCoins = 30;
_currentCoinsAmount += awardCoins;
// Show animated delta coins
DeltaCoinsText.text = String.Format("+{0}", awardCoins);
DeltaCoinsText.gameObject.SetActive (true);
StartCoroutine (UpdateCoinsAmount ());
// plus coin
GameData.instance.SavePlayerCoin(_currentCoinsAmount);
// play add coin sound
AudioManager.instance.CoinAddAudio();
// update text label
if (GameObject.Find("MapScene"))
{
GameObject.Find("MapScene").GetComponent<MapScene>().UpdateCoinAmountLabel();
}
break;
case LUCKY_SPIN_REWARDS.SINGLE_BREAKER_REWARD:
case LUCKY_SPIN_REWARDS.ROW_BREAKER_REWARD:
case LUCKY_SPIN_REWARDS.COL_BREAKER_REWARD:
case LUCKY_SPIN_REWARDS.RAINBOW_BREAKER_REWARD:
case LUCKY_SPIN_REWARDS.OVEN_BREAKER_REWARD:
case LUCKY_SPIN_REWARDS.BEGIN_FIVE_MOVE_REWARD:
case LUCKY_SPIN_REWARDS.BEGIN_RAINBOW_REWARD:
case LUCKY_SPIN_REWARDS.BEGIN_BOMB_BREAKER_REWARD:
//print("Award booster");
// Show animated delta coins
DeltaCoinsText.text = String.Format("+{0}", boosterRewardCount);
DeltaCoinsText.gameObject.SetActive(true);
if (award == LUCKY_SPIN_REWARDS.SINGLE_BREAKER_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[1];
GameData.instance.SaveSingleBreaker(GameData.instance.GetSingleBreaker() + boosterRewardCount);
}
else if (award == LUCKY_SPIN_REWARDS.ROW_BREAKER_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[2];
GameData.instance.SaveRowBreaker(GameData.instance.GetRowBreaker() + boosterRewardCount);
}
else if (award == LUCKY_SPIN_REWARDS.COL_BREAKER_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[3];
GameData.instance.SaveColumnBreaker(GameData.instance.GetColumnBreaker() + boosterRewardCount);
}
else if (award == LUCKY_SPIN_REWARDS.RAINBOW_BREAKER_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[4];
GameData.instance.SaveRainbowBreaker(GameData.instance.GetRainbowBreaker() + boosterRewardCount);
}
else if (award == LUCKY_SPIN_REWARDS.OVEN_BREAKER_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[5];
GameData.instance.SaveOvenBreaker(GameData.instance.GetOvenBreaker() + boosterRewardCount);
}
else if (award == LUCKY_SPIN_REWARDS.BEGIN_FIVE_MOVE_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[6];
GameData.instance.SaveBeginFiveMoves(GameData.instance.GetBeginFiveMoves() + boosterRewardCount);
}
else if (award == LUCKY_SPIN_REWARDS.BEGIN_RAINBOW_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[7];
GameData.instance.SaveBeginRainbow(GameData.instance.GetBeginRainbow() + boosterRewardCount);
}
else if (award == LUCKY_SPIN_REWARDS.BEGIN_BOMB_BREAKER_REWARD)
{
CoinsDeltaImage.overrideSprite = awardImage[8];
GameData.instance.SaveBeginBombBreaker(GameData.instance.GetBeginBombBreaker() + boosterRewardCount);
}
// play add coin sound
AudioManager.instance.CoinAddAudio();
break;
default:
print("Default award");
break;
}
}
// Hide coins delta text after animation
private IEnumerator HideCoinsDelta ()
{
yield return new WaitForSeconds (1f);
DeltaCoinsText.gameObject.SetActive (false);
}
// Animation for smooth increasing and decreasing the number of coins
private IEnumerator UpdateCoinsAmount ()
{
const float seconds = 0.5f; // Animation duration
float elapsedTime = 0;
while (elapsedTime < seconds) {
CurrentCoinsText.text = Mathf.Floor(Mathf.Lerp (_previousCoinsAmount, _currentCoinsAmount, (elapsedTime / seconds))).ToString ();
elapsedTime += Time.deltaTime;
yield return new WaitForEndOfFrame ();
}
_previousCoinsAmount = _currentCoinsAmount;
CurrentCoinsText.text = _currentCoinsAmount.ToString ();
}
// Change remaining time to next free turn every 1 second
private void UpdateFreeTurnTimer ()
{
// Don't count the time if we have free turn already
if (_isFreeTurnAvailable)
return;
// Update the remaining time values
_timerRemainingHours = (int)(_nextFreeTurnTime - DateTime.Now).Hours;
_timerRemainingMinutes = (int)(_nextFreeTurnTime - DateTime.Now).Minutes;
_timerRemainingSeconds = (int)(_nextFreeTurnTime - DateTime.Now).Seconds;
// If the timer has ended
if (_timerRemainingHours <= 0 && _timerRemainingMinutes <= 0 && _timerRemainingSeconds <= 0) {
NextFreeTurnTimerText.text = " Ready!";
// Now we have a free turn
_isFreeTurnAvailable = true;
} else {
// Show the remaining time
NextFreeTurnTimerText.text = " " + String.Format ("{0:00}:{1:00}:{2:00}", _timerRemainingHours, _timerRemainingMinutes, _timerRemainingSeconds);
// We don't have a free turn yet
_isFreeTurnAvailable = false;
}
}
private void EnableButton (GameObject button)
{
button.SetActive(true);
}
private void DisableButton(GameObject button)
{
button.SetActive(false);
}
// Function for more readable calls
private void EnableFreeTurnButton () { EnableButton (FreeTurnButton); }
private void DisableFreeTurnButton () { DisableButton (FreeTurnButton); }
private void EnablePaidTurnButton () { EnableButton (PaidTurnButton); }
private void DisablePaidTurnButton () { DisableButton (PaidTurnButton); }
private void ShowFreeTurnButton ()
{
FreeTurnButton.gameObject.SetActive(true);
PaidTurnButton.gameObject.SetActive(false);
}
private void ShowPaidTurnButton ()
{
PaidTurnButton.gameObject.SetActive(true);
FreeTurnButton.gameObject.SetActive(false);
}
public void ButtonClickAudio()
{
AudioManager.instance.ButtonClickAudio();
}
}