202 lines
5.8 KiB
C#
202 lines
5.8 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Marro.PacManUdon
|
|
{
|
|
public class PelletManager : SyncedObject
|
|
{
|
|
public int PelletCount => pellets.Length;
|
|
public int PelletCollectedCount { get; private set; }
|
|
|
|
Pellet[] pellets;
|
|
Animator[] powerPellets;
|
|
|
|
bool powerPelletBlinkEnabled;
|
|
float powerPelletBlinkToggleInterval;
|
|
float powerPelletBlinkProgress;
|
|
bool powerPelletBlinkCurrentlyVisible;
|
|
|
|
byte[] syncedPelletsCollected;
|
|
|
|
int[] collisionMap;
|
|
|
|
const int mazeWidth = 28;
|
|
const int mazeHeight = 31;
|
|
|
|
public void Initialize()
|
|
{
|
|
gameObject.SetActive(true);
|
|
pellets = GetComponentsInChildren<Pellet>(includeInactive: true);
|
|
|
|
powerPellets = GetComponentsInChildren<Animator>(true);
|
|
powerPelletBlinkToggleInterval = PacManConstants.GetPowerPelletBlinkToggleInterval();
|
|
SetPowerPelletsBlink(false);
|
|
|
|
RestoreAllPellets();
|
|
|
|
SubscribeToEvent(NetworkEventType.SyncPellets);
|
|
}
|
|
|
|
#region Power pellet blink
|
|
public override void SyncedUpdate()
|
|
{
|
|
if (!powerPelletBlinkEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
powerPelletBlinkProgress += networkManager.SyncedDeltaTime;
|
|
if (powerPelletBlinkProgress >= powerPelletBlinkToggleInterval)
|
|
{
|
|
// Debug.Log($"{gameObject} PowerPelletBlink toggle");
|
|
powerPelletBlinkProgress -= powerPelletBlinkToggleInterval;
|
|
powerPelletBlinkCurrentlyVisible = !powerPelletBlinkCurrentlyVisible;
|
|
SetPowerPelletsVisible(powerPelletBlinkCurrentlyVisible);
|
|
}
|
|
}
|
|
|
|
void SetPowerPelletsVisible(bool visible)
|
|
{
|
|
// Debug.Log($"{gameObject} SetPowerPelletVisible {visible}, powerPellets.Length: {powerPellets.Length}");
|
|
foreach (Animator powerPellet in powerPellets)
|
|
{
|
|
powerPellet.SetBool("Visible", visible);
|
|
}
|
|
}
|
|
|
|
public void SetPowerPelletsBlink(bool enabled)
|
|
{
|
|
// Debug.Log($"{gameObject} SetPowerPelletBlink {enabled}");
|
|
powerPelletBlinkEnabled = enabled;
|
|
|
|
powerPelletBlinkCurrentlyVisible = true;
|
|
powerPelletBlinkProgress = 0;
|
|
SetPowerPelletsVisible(true);
|
|
}
|
|
|
|
public void FreezePowerPelletsBlink(bool frozen)
|
|
{
|
|
powerPelletBlinkEnabled = !frozen;
|
|
}
|
|
#endregion
|
|
|
|
#region Collision
|
|
public bool IsWallUpcoming(Vector2 position, Vector2 directionVector)
|
|
{
|
|
var result = GetTileAt(position + directionVector) == (int)PacManTileType.Wall;
|
|
return result;
|
|
}
|
|
|
|
public int GetAvailableDirections(Vector2 position)
|
|
{
|
|
var directions = GetTileAt(position);
|
|
|
|
if (directions <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return directions;
|
|
}
|
|
|
|
private int GetTileAt(Vector2 position) => collisionMap[GetTilemapIndex(position)];
|
|
|
|
private int GetTilemapIndex(Vector2 position)
|
|
{
|
|
position = Clamp(position, 0, mazeWidth - 1, 1 - mazeHeight, 0);
|
|
var index = (int)(position.x + 0.5) - (int)(position.y - 0.5) * mazeWidth;
|
|
return index;
|
|
}
|
|
#endregion
|
|
|
|
#region Pellet collecting
|
|
public int PelletCollected(Pellet pellet)
|
|
{
|
|
pellet.gameObject.SetActive(false);
|
|
|
|
var index = pellet.transform.GetSiblingIndex();
|
|
syncedPelletsCollected[index/8] |= (byte)(1 << index%8);
|
|
|
|
PelletCollectedCount++;
|
|
|
|
return PelletCollectedCount;
|
|
}
|
|
|
|
public int RestoreAllPellets()
|
|
{
|
|
foreach (var pellet in pellets)
|
|
{
|
|
pellet.gameObject.SetActive(true);
|
|
}
|
|
|
|
syncedPelletsCollected = new byte[pellets.Length/8 + 1];
|
|
PelletCollectedCount = 0;
|
|
|
|
collisionMap = PacManConstants.GetMazeCollisionInfo();
|
|
|
|
return PelletCount;
|
|
}
|
|
|
|
private void SetPelletsCollectedFromSync()
|
|
{
|
|
for (int i = 0; i < pellets.Length; i++)
|
|
{
|
|
var active = (syncedPelletsCollected[i/8] & (byte)(1 << i%8)) == 0;
|
|
pellets[i].gameObject.SetActive(active);
|
|
}
|
|
}
|
|
|
|
public override void CollectSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
if (eventType != NetworkEventType.SyncPellets)
|
|
{
|
|
return;
|
|
}
|
|
|
|
data.Append((byte)PelletCollectedCount, ref index);
|
|
data.Append(syncedPelletsCollected, ref index);
|
|
}
|
|
|
|
public override bool WriteSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
if (eventType != NetworkEventType.SyncPellets)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
PelletCollectedCount = data.ReadByte(ref index);
|
|
Array.Copy(data, index, syncedPelletsCollected, 0, syncedPelletsCollected.Length);
|
|
index += syncedPelletsCollected.Length;
|
|
SetPelletsCollectedFromSync();
|
|
return true;
|
|
}
|
|
#endregion
|
|
|
|
#region Utils
|
|
private static Vector2 Clamp(Vector2 vector, float xMin, float xMax, float yMin, float yMax)
|
|
{
|
|
if (vector.x < xMin)
|
|
{
|
|
vector.x = xMin;
|
|
}
|
|
|
|
if (vector.x > xMax)
|
|
{
|
|
vector.x = xMax;
|
|
}
|
|
|
|
if (vector.y < yMin)
|
|
{
|
|
vector.y = yMin;
|
|
}
|
|
|
|
if (vector.y > yMax)
|
|
{
|
|
vector.y = yMax;
|
|
}
|
|
|
|
return vector;
|
|
}
|
|
#endregion
|
|
}
|
|
} |