72 lines
3.2 KiB
C#
72 lines
3.2 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using MagnetismHeroes.Core;
|
|
using UnityEngine;
|
|
|
|
namespace MagnetismHeroes.UnityRuntime.Presentation
|
|
{
|
|
public sealed class BoardPresenter : MonoBehaviour
|
|
{
|
|
[SerializeField] private BallView _ballPrefab;
|
|
[SerializeField] private GroupBadge _badgePrefab;
|
|
[SerializeField] private Camera _camera;
|
|
private readonly Dictionary<string, BallView> _balls = new Dictionary<string, BallView>();
|
|
private readonly List<GroupBadge> _badges = new List<GroupBadge>();
|
|
private BoardRules _board;
|
|
public Camera Camera => _camera;
|
|
public IReadOnlyDictionary<string, BallView> Balls => _balls;
|
|
|
|
public void Render(BoardRules board)
|
|
{
|
|
_board = board;
|
|
foreach (var view in _balls.Values) { view.gameObject.SetActive(false); Destroy(view.gameObject); }
|
|
foreach (var badge in _badges) { badge.gameObject.SetActive(false); Destroy(badge.gameObject); }
|
|
_balls.Clear(); _badges.Clear();
|
|
if (board == null) return;
|
|
foreach (var group in board.Groups)
|
|
{
|
|
foreach (var ballId in group.ballIds)
|
|
{
|
|
var state = board.Balls.First(ball => ball.id == ballId);
|
|
var ball = Instantiate(_ballPrefab, ToVector(state.position), Quaternion.identity, transform);
|
|
ball.Bind(ballId, group.id, board.CountedBallIds.Contains(ballId)); _balls.Add(ballId, ball);
|
|
}
|
|
_badges.Add(Instantiate(_badgePrefab, transform));
|
|
}
|
|
PositionBadges();
|
|
}
|
|
|
|
public void PreviewGroup(string groupId, Vector3 delta)
|
|
{
|
|
foreach (var state in _board.Balls)
|
|
_balls[state.id].transform.position = ToVector(state.position) + (_balls[state.id].GroupId == groupId ? delta : Vector3.zero);
|
|
PositionBadges();
|
|
}
|
|
|
|
public void CancelPreview()
|
|
{
|
|
if (_board == null) return;
|
|
foreach (var state in _board.Balls) _balls[state.id].transform.position = ToVector(state.position);
|
|
PositionBadges();
|
|
}
|
|
|
|
private void PositionBadges()
|
|
{
|
|
if (_board == null) return;
|
|
var groups = _board.Groups;
|
|
for (int index = 0; index < groups.Length; index++)
|
|
{
|
|
var group = groups[index];
|
|
var center = group.ballIds.Select(id => _balls[id].transform.position).Aggregate(Vector3.zero, (sum, value) => sum + value) / group.ballIds.Length;
|
|
var representative = _balls[group.ballIds[0]].transform.position;
|
|
_badges[index].Bind(group.ballIds.Length, center + Vector3.up * 0.95f,
|
|
representative - _camera.transform.forward * 0.49f);
|
|
_badges[index].FaceCamera(_camera);
|
|
}
|
|
}
|
|
private void LateUpdate() => PositionBadges();
|
|
public static Vector3 ToVector(Position3 position) => new Vector3(position.x, position.y, position.z);
|
|
public static Position3 ToPosition(Vector3 vector) => new Position3(vector.x, vector.y, vector.z);
|
|
}
|
|
}
|