This commit is contained in:
2024-06-12 21:03:42 +02:00
parent 4685d9942b
commit aef3b3ab97
1548 changed files with 5615 additions and 72 deletions

View File

@@ -0,0 +1,264 @@
using System;
using System.IO;
using UnityEngine;
using Newtonsoft.Json;
using static GameHandler;
using static LevelSpawner;
using static PlayerScript;
using static PlayersHandler;
namespace Assets.Scripts
{
public class DataBearer : SingletonMB<DataBearer>
{
#region PROPERTIES
public bool DataSaved { get; private set; }
public Attempt CurrentAttempt { get; private set; }
public SessionData Session
{
get
{
if (_session == null)
{
_session = GetSettings();
}
return _session;
}
private set
{
_session = value;
}
} private SessionData _session = null;
public GameState GameState { get; set; } = new();
public Players Players { get { return Session.Players; } }
public Rules Rules { get { return Session.Rules; } }
#endregion
#region VARIABLES
private GameHandler _gameHandler;
private ScoreHandler _scoreHandler;
private PlayersHandler _playerHandler;
private LevelSpawner _levelSpawner;
#endregion
#region EVENTS
public void RegisterAttempt_OnAttemptEnded(object sender, AttemptEventArgs eventArgs)
{
Session.Attempts.Add(CurrentAttempt);
CurrentAttempt = null;
} //
public void RegisterPlayer_OnPlayerInstanciated(object sender, PlayerEventArgs args)
{
var player = args.player;
var newPlayer = new RegisteredPlayer()
{
Name = player.Name,
Id = player.Id,
Human = player.IsHuman
};
if(!Session.RegisteredPlayers.Exists(rp => rp.Name == newPlayer.Name))
{
Session.RegisteredPlayers.Add(newPlayer);
}
player.OnBonusTouched += RecordBonus_OnBonusTouched;
player.OnObstacleTouched += RecordObstacle_OnObstacleTouched;
} //
public void CreateAttemptRecord_OnAttemptStarted(object sender, AttemptEventArgs args)
{
CurrentAttempt = args.attempt;
foreach(var player in Session.RegisteredPlayers)
{
PlayerAttempt playerAttempt = new PlayerAttempt()
{
PlayerName = player.Name
};
CurrentAttempt.PlayersAttempts.Add(player.Name, playerAttempt);
}
} //
public void RecordAttemptObstacle_OnPrefabSpawned(object sender, PrefabSpawnedEventArgs args)
{
LevelPrefab obstacle = new() {
PrefabName = args.pattern.name, //todo : prefab name has "(clone)" at the end
PrefabNumber = CurrentAttempt.Level.Count + 1,
TickTimeWhenTouched = _gameHandler.TickAttemptDuration
};
CurrentAttempt.Level.Add(obstacle);
} //
public void RecordObstacle_OnObstacleTouched(object sender, PrefabTouchedEventArgs args)
{
var prefab = args.objectTouched;
TouchedGameObject touchedGameObject = new()
{
FullObjectName = prefab.name, //todo : prefab name is laser... It should be full pattern name
ObjectTypeName = SortingLayer.IDToName(prefab.layer), // todo : <unknown layer>
GameSpeed = _gameHandler.MapSpeed,
PrefabName = prefab.name,
TickTimeWhenTouched = _gameHandler.TickAttemptDuration
};
CurrentAttempt.PlayersAttempts[args.playerName].ObstaclesTouched.Add(touchedGameObject);
RecordPlayerScore(args.playerId, args.playerName);
} //
public void RecordBonus_OnBonusTouched(object sender, PrefabTouchedEventArgs args)
{
var prefab = args.objectTouched;
TouchedGameObject touchedGameObject = new()
{
FullObjectName = prefab.name,
ObjectTypeName = SortingLayer.IDToName(prefab.layer),
GameSpeed = _gameHandler.MapSpeed,
PrefabName = prefab.name,
TickTimeWhenTouched = _gameHandler.TickAttemptDuration
};
CurrentAttempt.PlayersAttempts[args.playerName].BonusTouched.Add(touchedGameObject);
RecordPlayerScore(args.playerId, args.playerName);
} //
#endregion
#region ENDPOINTS
public void ResetSession()
{
_session = null;
}
public void SaveData()
{
string directoryPath = Path.Combine(Application.persistentDataPath, "SessionsData");
if (!Directory.Exists(directoryPath))// Crée le répertoire s'il n'existe pas déjà
{
Directory.CreateDirectory(directoryPath);
}
var existingFiles = Directory.GetFiles(directoryPath, "*.json");
int sessionNumber = existingFiles.Length + 1;
Session.SessionNumber = sessionNumber;
string jsonData = JsonConvert.SerializeObject(Session);
string fileName = $"Session_{sessionNumber}.json";
string filePath = Path.Combine(directoryPath, fileName);
File.WriteAllText(filePath, jsonData);
DataSaved = true;
Debug.Log($"Session saved to {filePath}");
}
public void RecordSessionTime(float time)
{
Session.SessionTime = time;
}
public void RecordSessionDate(DateTime date)
{
Session.Date = date;
}
/// <summary>
/// Record all players scores
/// </summary>
public void RecordPlayersScore()
{
Session.RegisteredPlayers.ForEach(p =>
{
RecordPlayerScore(p.Id, p.Name);
});
}
/// <summary>
/// Find and record a player score
/// </summary>
public void RecordPlayerScore(int playerId, string playerName)
{
int score = (int) _scoreHandler.GetPlayerScore(playerId);
var tickTime = _gameHandler.TickAttemptDuration;
GenericVector<int, int> ScoreByTime = new() { X = tickTime, Y = score };
CurrentAttempt.PlayersAttempts[playerName].PlayerScoresOverTicksTime.Add(ScoreByTime);
}
/// <summary>
/// Record a player final score
/// </summary>
public void RecordPlayerFinalScore(int score, string playerName)
{
CurrentAttempt.PlayersAttempts[playerName].FinalScore = score;
}
/// <summary>
/// Record the distance parcoured by the player
/// </summary>
public void RecordPlayerDistance(string playerName)
{
CurrentAttempt.PlayersAttempts[playerName].Distance = (int)_gameHandler.TotalDistance;
}
public void RecordPlayerAttemptDuration(string playerName)
{
CurrentAttempt.PlayersAttempts[playerName].AttemptDurationSeconds = _gameHandler.TimeAttemptDuration;
CurrentAttempt.PlayersAttempts[playerName].AttemptDurationTicks = _gameHandler.TickAttemptDuration;
}
#endregion
#region METHODS
private SessionData GetSettings()
{
SessionData session = new();
session.Players.Human = bool.Parse(PlayerPrefs.GetString(Settings.HumanPlayerSelected));
session.Players.OmnicientBot = bool.Parse(PlayerPrefs.GetString(Settings.OmnicientBotSelected));
session.Players.ObserverBot = bool.Parse(PlayerPrefs.GetString(Settings.ObserverBotSelected));
session.Players.IteratorBot = bool.Parse(PlayerPrefs.GetString(Settings.IteratorBotSelected));
session.Rules.ChangeSeedEachTry = bool.Parse(PlayerPrefs.GetString(Settings.ChangeSeedSetting));
session.Rules.UsesDefaultSeed = bool.Parse(PlayerPrefs.GetString(Settings.UseDefaultSeedSetting));
session.Rules.Lasers = bool.Parse(PlayerPrefs.GetString(Settings.LaserSettingToggle));
session.Rules.Missiles = bool.Parse(PlayerPrefs.GetString(Settings.MissileSettingToggle));
session.Rules.BonusCoins = bool.Parse(PlayerPrefs.GetString(Settings.CoinSettingToggle));
session.Rules.MalusCoins = bool.Parse(PlayerPrefs.GetString(Settings.BadCoinSettingToggle));
session.Rules.ScoreOnDistance = bool.Parse(PlayerPrefs.GetString(Settings.SurviveScoreSettingToggle));
session.Rules.RushMode = bool.Parse(PlayerPrefs.GetString(Settings.RushModeSettingToggle));
session.Rules.MaxDistance = PlayerPrefs.GetFloat(Settings.MaxDistanceSettingValue);
session.Rules.MaxAttempts = PlayerPrefs.GetInt(Settings.MaxTrySettingValue);
session.Rules.MaxSessionTime = PlayerPrefs.GetInt(Settings.MaxTimeSettingValue);
session.Rules.MaxSpeed = PlayerPrefs.GetFloat(Settings.MaxSpeedSettingValue);
session.Rules.StartSpeed = PlayerPrefs.GetFloat(Settings.StartSpeedSettingValue);
session.Rules.DifficultyMultiplier = PlayerPrefs.GetFloat(Settings.DifficultyMultiplierSettingValue);
return session;
}
#endregion
#region LIFECYCLE
protected override void Awake()
{
DataSaved = false;
Session = GetSettings();
base.Awake();
_gameHandler = GameHandler.Instance;
_scoreHandler = ScoreHandler.Instance;
_playerHandler = PlayersHandler.Instance;
_levelSpawner = LevelSpawner.Instance;
_gameHandler.OnAttemptEnded += RegisterAttempt_OnAttemptEnded;
_gameHandler.OnAttemptStarted += CreateAttemptRecord_OnAttemptStarted;
_playerHandler.OnPlayerInstanciated += RegisterPlayer_OnPlayerInstanciated;
_levelSpawner.OnPrefabSpawned += RecordAttemptObstacle_OnPrefabSpawned;
}
#endregion
}
}

View File

@@ -0,0 +1,164 @@
using Assets.Scripts;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using static GameHandler;
public class GameController : SingletonMB<GameController>
{
#region PROPERTIES
public bool IsExiting { get; private set; }
public SessionData Session { get; private set; } = new SessionData();
#endregion
#region VARIABLES
private GameHandler _gameHandler;
private ScoreHandler _scoreHandler;
private LevelSpawner _LevelSpawner;
private PlayersHandler _playerHandler;
private DataBearer _dataBearer;
private int maxSessionTime;
private float currentSessionTime;
private int maxAttempts;
private int currentAttempts;
#endregion
#region EVENTS
public event EventHandler<SessionEventArgs> OnSessionEnded;
public class SessionEventArgs : EventArgs
{
public SessionData session;
public SessionEventArgs(SessionData session)
{
this.session = session;
}
}
private void ProcessNextAttempt_OnAttemptEnded(object sender, AttemptEventArgs args)
{
if(!IsExiting)
{
PrepareNextRound();
}
}
#endregion
#region METHODS
/// <summary>
/// Initialize a new round if there are more available attempts
/// </summary>
public void PrepareNextRound()
{
currentAttempts+=1;
if(maxAttempts == 0 || _dataBearer.Session.Attempts.Count < maxAttempts)
{
_gameHandler.InitAttempt();
}
else
{
ExitToMenu("Nombre maximum d'essais atteint");
}
}
public void ExitToMenu(string message)
{
IsExiting = true;
Debug.Log("Session END");
//StartCoroutine(ExitToMenuCoroutine(message));
_gameHandler.ResumeGame();
//yield return null;
if (!_gameHandler.AttemptEnding) _gameHandler.HaltAttempt(message);
Clean();
SceneManager.LoadScene("MainMenu");
_dataBearer.ResetSession();
}
//private IEnumerator ExitToMenuCoroutine(string message)
//{
// _gameHandler.ResumeGame();
// //yield return null;
// if(!_gameHandler.AttemptEnding) _gameHandler.HaltAttempt(message);
// _dataBearer.ResetSession();
// Clean();
// SceneManager.LoadScene("MainMenu");
//}
#endregion
#region LIFECYCLE
// Start is called before the first frame update
private void Start()
{
Debug.Log($"Start session for {Session.Rules.MaxAttempts} rounds");
_dataBearer.RecordSessionDate(DateTime.Now);
currentSessionTime = 0f;
PrepareNextRound();
}
// Awake is called before Start
protected override void Awake()
{
base.Awake();
_gameHandler = GameHandler.Instance;
_scoreHandler = ScoreHandler.Instance;
_playerHandler = PlayersHandler.Instance;
_dataBearer = DataBearer.Instance;
_gameHandler.OnAttemptEnded += ProcessNextAttempt_OnAttemptEnded;
maxAttempts = _dataBearer.Rules.MaxAttempts;
maxSessionTime = _dataBearer.Rules.MaxSessionTime;
currentAttempts = 0;
}
// Update is called once per frame
void Update()
{
currentSessionTime += Time.deltaTime;
_dataBearer.RecordSessionTime(currentSessionTime);
if (maxSessionTime > 0 && currentSessionTime >= maxSessionTime)
{
currentSessionTime = maxSessionTime;
_dataBearer.RecordSessionTime(currentSessionTime);
ExitToMenu("Temps <20>coul<75>");
}
}
//Unsubscribe events, save databearer;
private void OnDestroy()
{
Clean();
}
private void OnApplicationQuit()
{
Clean();
}
public void Clean()
{
_gameHandler.OnAttemptEnded -= ProcessNextAttempt_OnAttemptEnded;
if (!_dataBearer.DataSaved)
{
//datasaving logic
_dataBearer.RecordSessionTime(currentSessionTime);
_dataBearer.SaveData();
}
}
#endregion
}

View File

@@ -0,0 +1,299 @@
using Assets.Scripts;
using System;
using System.Collections;
using Unity.VisualScripting;
using UnityEditor.Rendering;
using UnityEngine;
using static PlayersHandler;
/// <summary>
/// GameHandler gère le fonctionnement général d'une partie de jeu. Il se charge de faire apparaître les joueurs
/// </summary>
public class GameHandler : SingletonMB<GameHandler>
{
#region PROPERTIES
int Seed
{
get { return _seed; }
set
{
_seed = value;
UnityEngine.Random.InitState(value);
}
} private int _seed;
public float FrameDistance { get; private set; }
public float TotalDistance { get; private set; }
[SerializeField] public float MapSpeed { get; private set; }
public Attempt CurrentAttempt { get; private set; }
public bool MaxDifficultyReached { get; private set; }
public bool IsPaused { get; private set; } = false;
public bool HaveHumanPlayer { get; private set; } = false;
public bool AttemptEnding { get; private set; }
public int TickAttemptDuration { get; private set; }
public float TimeAttemptDuration {get; private set;}
#endregion
#region VARIABLES
private const float DIFFICULTY_DAMP = 0.01f;
[SerializeField] private GameObject finishLine;
private ScoreHandler _scoreHandler;
private LevelSpawner _levelSpawner;
private PlayersHandler _playerHandler;
private DataBearer _dataBearer;
private TileSpawner _tileSpawner;
private Vector3 playerSpawnPosition = new Vector3(-3, 0, 0);
private float maxSpeed;
private float maxDistance;
private bool raiseScoreOnDistance;
private float difficultyMultiplier;
private bool finishLineSpawned;
private short tickCounter;
#endregion
#region EVENTS
public event EventHandler<AttemptEventArgs> OnAttemptStarted;
public event EventHandler<AttemptEventArgs> OnAttemptEnding;
public event EventHandler<AttemptEventArgs> OnAttemptEnded;
public event EventHandler<EventArgs> OnGamePaused;
public event EventHandler<EventArgs> OnGameResumed;
public event EventHandler<EventArgs> OnInstanciatingPlayers;
public class AttemptEventArgs : EventArgs
{
public Attempt attempt;
public AttemptEventArgs(Attempt attempt) { this.attempt = attempt; }
}
public void HaltAttempt_OnAllPlayersFinished(object sender, EventArgs agrs)
{
HaltAttempt("Tous les joueurs sont Out");
}
public void CheckIfHumanPlayer_OnPlayerInstanciated(object sender, PlayerEventArgs args)
{
if (args.player.IsHuman)
{
HaveHumanPlayer = true;
}
}
#endregion
#region METHODS
/// <summary>
/// Return a seed which depend on selected settings and attempt number
/// </summary>
private int SetSeed()
{
int seed;
if (_dataBearer.Session.Rules.ChangeSeedEachTry & CurrentAttempt.AttemptNumber > 1) //Get a random seed each new try
{
seed = UnityEngine.Random.Range(100000000, 1000000000); //generate a random 9 digits seed
}
else //Get either default seed or custom seed
{
seed = _dataBearer.Session.Rules.UsesDefaultSeed
? PlayerPrefs.GetInt(Settings.DefaultSeedSettingValue)
: PlayerPrefs.GetInt(Settings.CustomSeedSettingValue);
}
return seed;
}
private void RaiseScore()
{
float scoreToAdd = FrameDistance;// * Time.deltaTime;
_scoreHandler.AddScoreToAllAlivePlayers(scoreToAdd);
}
private void RaiseDifficulty()
{
if(MapSpeed > maxSpeed)
{
MapSpeed = maxSpeed;
MaxDifficultyReached = true;
}
MapSpeed += MapSpeed * difficultyMultiplier * Time.deltaTime;
}
private void SpawnPlayers()
{
if (_dataBearer.Session.Players.Human)
_playerHandler.InstanciatePlayer<HumanPlayerBehaviour>(playerSpawnPosition);
if (_dataBearer.Session.Players.OmnicientBot)
_playerHandler.InstanciatePlayer<OmnicientBehaviour>(playerSpawnPosition);
if (_dataBearer.Session.Players.ObserverBot)
_playerHandler.InstanciatePlayer<ObserverBehaviour>(playerSpawnPosition);
if (_dataBearer.Session.Players.IteratorBot)
_playerHandler.InstanciatePlayer<IteratorBehaviour>(playerSpawnPosition);
}
#endregion
#region ENDPOINTS
public void PauseGame()
{
if (!IsPaused)
{
StartCoroutine(PauseGameCoroutine());
}
}
private IEnumerator PauseGameCoroutine()
{
yield return null;
Time.timeScale = 0; // Met le jeu en pause
IsPaused = true;
OnGamePaused.Invoke(this, new EventArgs());
}
public void ResumeGame()
{
if (IsPaused)
{
Time.timeScale = _dataBearer.Rules.RushMode ? 15 : 1; // Reprend le jeu
IsPaused = false;
OnGameResumed.Invoke(this, new EventArgs());
}
}
public void InitAttempt()
{
TimeAttemptDuration = 0;
TickAttemptDuration = 0;
Debug.LogWarning("Initate Attempt !");
AttemptEnding = false;
CurrentAttempt = new Attempt();
CurrentAttempt.AttemptNumber = _dataBearer.Session.Attempts.Count + 1;
Seed = SetSeed();
CurrentAttempt.Seed = Seed;
TotalDistance = 0;
MapSpeed = _dataBearer.Rules.StartSpeed;
raiseScoreOnDistance = _dataBearer.Rules.ScoreOnDistance;
maxSpeed = _dataBearer.Rules.MaxSpeed;
difficultyMultiplier = _dataBearer.Rules.DifficultyMultiplier * DIFFICULTY_DAMP;
if(_dataBearer.Rules.RushMode){
Time.timeScale = 15;
foreach (var renderer in FindObjectsOfType<Renderer>())
{
if(renderer.gameObject.GetComponent<ScorePannelScript>()==null)
{renderer.enabled = false;}
}
}
else{
Time.timeScale = 1;
}
MaxDifficultyReached = false;
TotalDistance = 0;
FrameDistance = 0;
finishLineSpawned = false;
tickCounter = 0;
SpawnPlayers();
_scoreHandler.AddScoreToAllAlivePlayers(500);
OnAttemptStarted?.Invoke(this, new AttemptEventArgs(CurrentAttempt));
}
/// <summary>
/// Halt the current attempt
/// </summary>
public void HaltAttempt(string message)
{
Console.WriteLine(message);
AttemptEnding = true;
OnAttemptEnding?.Invoke(this, new AttemptEventArgs(CurrentAttempt));
OnAttemptEnded?.Invoke(this, new AttemptEventArgs(CurrentAttempt));
}
#endregion
#region LIFECYCLE
protected override void Awake()
{
base.Awake();
_scoreHandler = ScoreHandler.Instance;
_levelSpawner = LevelSpawner.Instance;
_playerHandler = PlayersHandler.Instance;
_dataBearer = DataBearer.Instance;
_tileSpawner = TileSpawner.Instance;
_playerHandler.OnAllPlayersFinished += HaltAttempt_OnAllPlayersFinished;
_playerHandler.OnPlayerInstanciated += CheckIfHumanPlayer_OnPlayerInstanciated;
difficultyMultiplier = _dataBearer.Rules.DifficultyMultiplier;
raiseScoreOnDistance = _dataBearer.Rules.ScoreOnDistance;
maxDistance = _dataBearer.Rules.MaxDistance;
}
void Update()
{
FrameDistance = MapSpeed * Time.deltaTime;
TotalDistance += FrameDistance;
TimeAttemptDuration += Time.deltaTime;
TickAttemptDuration += 1;
tickCounter += 1;
if (tickCounter > 1000)
{
//Debug.Log("1000 TICK " + TimeAttemptDuration);
tickCounter = 0;
_dataBearer.RecordPlayersScore();
}
if(maxDistance != 0 && TotalDistance > maxDistance)
{
HaltAttempt("Ligne d'arrivée atteinte");
}
if (raiseScoreOnDistance) RaiseScore();
if (!MaxDifficultyReached) RaiseDifficulty();
if(maxDistance != 0 && !finishLineSpawned && maxDistance-TotalDistance < 20)
{
Instantiate(finishLine, new Vector3(maxDistance - TotalDistance - 3, 0, -1), finishLine.transform.rotation);
finishLineSpawned = true;
}
if (Input.GetKeyDown(KeyCode.Escape))
(IsPaused ? (Action)ResumeGame : PauseGame)();
}
private void OnDestroy()
{
Clean();
}
private void OnDisable()
{
Clean();
}
private void Clean()
{
/*StopAllCoroutines();
_playerHandler.OnAllPlayersFinished -= HaltAttempt_OnAllPlayersFinished;
_playerHandler.OnPlayerInstanciated -= CheckIfHumanPlayer_OnPlayerInstanciated;*/
}
#endregion
}

View File

@@ -0,0 +1,215 @@
using Assets.Scripts;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;
using static PlayersHandler;
public class PlayersHandler : SingletonMB<PlayersHandler>
{
// Start is called before the first frame update
[SerializeField] private GameObject playerPrefab;
#region PROPERTIES
public Dictionary<int, PlayerScript> Players { get; private set; } = new();
#endregion
#region VARIABLES
private ScoreHandler _scoreHandler;
private GameHandler _gameHandler;
#endregion
#region EVENTS
/// <summary>
/// Fires when a player is instanciated in the game
/// </summary>
public event EventHandler<PlayerEventArgs> OnPlayerInstanciated;
/// <summary>
/// Fires when a player have finished their attempt
/// </summary>
public event EventHandler<PlayerEventArgs> OnPlayerFinished;
/// <summary>
/// Fires when all players have finished their attempt
/// </summary>
public event EventHandler<EventArgs> OnAllPlayersFinished;
public class PlayerEventArgs : EventArgs
{
public PlayerScript player;
public PlayerEventArgs(PlayerScript player)
{
this.player = player;
}
}
#endregion
#region ENDPOINTS
/// <summary>
/// Remove a player from the game and fire a PlayerFinished event. Fire AllPlayerFinished event if needed
/// </summary>
/// <param name="playerId"></param>
public void RemovePlayer(int playerId)
{
if (Players.TryGetValue(playerId, out PlayerScript player))
{
Players.Remove(playerId);
if(!_gameHandler.AttemptEnding)
OnPlayerFinished.Invoke(this, new PlayerEventArgs(player));
player.Dispose();
}
if(Players.Count == 0 && !_gameHandler.AttemptEnding)
{
OnAllPlayersFinished.Invoke(this, new EventArgs());
}
}
public bool InstanciatePlayer<T>(Vector3 position) where T : MonoBehaviour
{
var player = SpawnPlayer(new Vector3(position.x, position.y, -1));
PlayerScript script = player.GetComponent<PlayerScript>();
player.AddComponent<T>();
Players.Add(script.Id, script);
DecoratePlayer(player);
CreateScorePanel(script);
Debug.Log($"# Player \"{script.Name}\" instanciated !");
OnPlayerInstanciated?.Invoke(this, new PlayerEventArgs(script));
return true;
}
#endregion
#region METHODS
private GameObject SpawnPlayer(Vector3 position)
{
var player = Instantiate(playerPrefab, position, Quaternion.identity);
var script = player.GetComponent<PlayerScript>();
script.SetId(Players.Count);
return player;
}
private void CreateScorePanel(PlayerScript script)
{
_scoreHandler.AddScorePanel(script.Name, script.Id, script.Color);
}
//private GameObject InstantiatePlayer(string playerName, Vector3 position)
//{
// incrementialId++;
// var player = Instantiate(playerPrefab, position, Quaternion.identity);
// var script = player.GetComponent<PlayerScript>();
// script.SetName(playerName);
// script.SetId(incrementialId);
// _scoreHandler.AddScorePanel(script.Name, script.Id, script.Color);
// Players.Add(script);
// return player;
//}
private void DecoratePlayer(GameObject player)
{
Transform child = player.transform.Find("sprite");
PlayerScript script = player.GetComponent<PlayerScript>();
var components = child.GetComponentsInChildren<SpriteRenderer>();
var jetpackFront = child.transform.Find("JetpackFront").GetComponent<SpriteRenderer>();
var jetpackBack = child.transform.Find("JetpackBack").GetComponent<SpriteRenderer>();
float alpha = _gameHandler.HaveHumanPlayer && !script.IsHuman ? 0.4f : 1.0f;
var scriptColor = script.Color!=null ? script.Color : new Color(255, 255, 255);
scriptColor.a = alpha;
foreach ( var component in components )
{
component.color = new Color(255, 255, 255, alpha);
}
jetpackFront.color = scriptColor;
jetpackBack.color = scriptColor;
}
#endregion
#region LIFECYCLE
protected override void Awake()
{
base.Awake();
_scoreHandler = ScoreHandler.Instance;
_gameHandler = GameHandler.Instance;
}
#endregion
}
//public void InstanciateOmnicient(Vector3 position)
//{
// var bot = SpawnPlayer(position);
// PlayerScript script = bot.GetComponent<PlayerScript>();
// Players.Add(script.Id, script);
// DecoratePlayer(bot);
// CreateScorePanel(script);
// OnPlayerInstanciated?.Invoke(this, new PlayerEventArgs(script));
//}
//public void InstanciateObserver(Vector3 position)
//{
// var bot = SpawnPlayer(position);
// PlayerScript script = bot.GetComponent<PlayerScript>();
// Players.Add(script.Id, script);
// DecoratePlayer(bot);
// CreateScorePanel(script);
// OnPlayerInstanciated?.Invoke(this, new PlayerEventArgs(script));
//}
//public void InstanciateIterator(Vector3 position)
//{
// var bot = SpawnPlayer(position);
// PlayerScript script = bot.GetComponent<PlayerScript>();
// Players.Add(script.Id, script);
// DecoratePlayer(bot);
// CreateScorePanel(script);
// OnPlayerInstanciated?.Invoke(this, new PlayerEventArgs(script));
//}
//public void InstanciateHumanPlayer(Vector3 position)
//{
// Debug.Log("Instanciate Human");
// var humanPlayer = SpawnPlayer(new Vector3(position.x, position.y, -1));
// PlayerScript script = humanPlayer.GetComponent<PlayerScript>();
// script.IsHuman = true;
// humanPlayer.AddComponent<HumanPlayer>();
// DecoratePlayer(humanPlayer);
// CreateScorePanel(script);
// Players.Add(script.Id, script);
// OnPlayerInstanciated?.Invoke(this, new PlayerEventArgs(script));
//}

View File

@@ -0,0 +1,201 @@
using System.Collections.Generic;
using UnityEngine;
using Assets.Scripts;
using System;
using static GameController;
using static PlayersHandler;
using static GameHandler;
using System.Linq;
public class ScoreHandler : SingletonMB<ScoreHandler>
{
#region PROPERTIES
private Dictionary<int, PlayerScore> PlayersScores { get; set; }
private Dictionary<int, PlayerScore> OuttedPlayers { get; set; }
#endregion
#region VARIABLES
[SerializeField] private GameObject ScorePanelPrefab;
[SerializeField] private GameObject UiDocument;
private GameController _gameController;
private PlayersHandler _playersHandler;
private GameHandler _gameHandler;
private DataBearer _dataBearer;
#endregion
#region EVENTS
public event EventHandler<ScoreEventArgs> OnScoreReachingZero;
public class ScoreEventArgs : EventArgs
{
public int playerId;
public ScoreEventArgs(int id)
{
playerId = id;
}
}
internal void RemovePlayer_OnPlayerFinished(object sender, PlayerEventArgs args)
{
if (PlayersScores.TryGetValue(args.player.Id, out PlayerScore looser))
{
_dataBearer.RecordPlayerDistance(looser.PlayerName);
_dataBearer.RecordPlayerScore(looser.PlayerId, looser.PlayerName);
_dataBearer.RecordPlayerAttemptDuration(looser.PlayerName);
OuttedPlayers.Add(looser.PlayerId, looser);
PlayersScores.Remove(looser.PlayerId);
}
}
private void RemoveScores_OnAttemptEnded(object sender, AttemptEventArgs args)
{
List<int> keys;
if (PlayersScores.Count > 0)
{
keys = new List<int>(PlayersScores.Keys);
foreach(var key in keys)
{
_dataBearer.RecordPlayerDistance(PlayersScores[key].PlayerName);
_dataBearer.RecordPlayerScore(key, PlayersScores[key].PlayerName);
_dataBearer.RecordPlayerAttemptDuration(PlayersScores[key].PlayerName);
OuttedPlayers.Add(key, PlayersScores[key]);
_playersHandler.RemovePlayer(key);
}
PlayersScores.Clear();
}
keys = new List<int>(OuttedPlayers.Keys);
foreach (var key in keys)
{
_dataBearer.RecordPlayerFinalScore((int)OuttedPlayers[key].Score, OuttedPlayers[key].PlayerName);
OuttedPlayers[key].ScorePanel.Dispose();
}
OuttedPlayers = new();
PlayersScores = new();
}
#endregion
#region ENDPOINTS
public void AddScorePanel(string playerName, int playerId)
{
var newScorePanel = Instantiate(ScorePanelPrefab, UiDocument.transform);
var scoreScript = newScorePanel.GetComponent<ScorePannelScript>();
scoreScript.SetPlayerName(playerName);
PlayerScore newRecord = new PlayerScore(playerName, playerId, scoreScript);
PlayersScores.Add(playerId, newRecord);
}
public void AddScorePanel(string playerName, int playerId, Color playerColor)
{
var newScorePanel = Instantiate(ScorePanelPrefab, UiDocument.transform);
var scoreScript = newScorePanel.GetComponent<ScorePannelScript>();
scoreScript.SetColor(playerColor);
scoreScript.SetPlayerName(playerName);
PlayerScore newRecord = new PlayerScore(playerName, playerId, scoreScript);
PlayersScores.Add(playerId, newRecord);
}
public void SetScore(float score, int playerId)
{
if (PlayersScores.TryGetValue(playerId, out PlayerScore updatedScore))
{
updatedScore.Score = score;
updatedScore.ScorePanel.SetScore(score);
PlayersScores[playerId] = updatedScore;
}
if ( score <= 0) //false &&
{
OnScoreReachingZero.Invoke(this, new ScoreEventArgs(playerId));
}
}
public void AddToScore(float score, int playerId)
{
if (PlayersScores.TryGetValue(playerId, out PlayerScore updatedScore))
{
updatedScore.Score += score;
SetScore(updatedScore.Score, playerId);
}
}
public void AddScoreToAllAlivePlayers(float scoreToAdd)
{
var keys = new List<int>(PlayersScores.Keys);
foreach (var key in keys)
{
AddToScore(scoreToAdd, key);
}
}
public float GetPlayerScore(int playerId)
{
return PlayersScores.TryGetValue(playerId, out PlayerScore pscore)
? pscore.Score
: OuttedPlayers.TryGetValue(playerId, out PlayerScore oscore)
? oscore.Score
: 0;
}
#endregion
#region METHODS
#endregion
#region LIFECYCLE
protected override void Awake()
{
base.Awake();
_gameController = GameController.Instance;
_playersHandler = PlayersHandler.Instance;
_gameHandler = GameHandler.Instance;
_dataBearer = DataBearer.Instance;
_playersHandler.OnPlayerFinished += RemovePlayer_OnPlayerFinished;
_gameHandler.OnAttemptEnding += RemoveScores_OnAttemptEnded;
PlayersScores = new();
OuttedPlayers = new();
}
#endregion
struct PlayerScore
{
internal string PlayerName { get; set; }
internal int PlayerId { get; set; }
internal float Score { get; set; }
internal ScorePannelScript ScorePanel { get; set; }
public PlayerScore(string playerName, int playerId, ScorePannelScript scorePannel)
{
PlayerName = playerName;
PlayerId = playerId;
Score = 0f;
ScorePanel = scorePannel;
}
}
}
#region PROPERTIES
#endregion
#region VARIABLES
#endregion
#region EVENTS
#endregion
#region METHODS
#endregion
#region LIFECYCLE
#endregion