Files
Sokoban/Assets/Scripts/Objects/Player.cs
2023-06-16 19:10:51 +03:00

145 lines
4.0 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using Level;
using DG.Tweening;
namespace Objects
{
public class Player : MonoBehaviour
{
// Static
private static Player instance;
// Events
public delegate void PlayerMovedHandler();
public event PlayerMovedHandler PlayerMoved;
// Public
public Vector2Int layoutPosition;
public InputActionAsset actions;
private bool isMoving = false;
private InputAction moveAction;
private InputAction testAction;
public static Player Instance => instance;
public bool CanMove
{
get
{
return !isMoving && GameManager.Instance.currentState == GameState.Gameplay;
}
}
private void Awake()
{
if (instance != null && instance != this)
{
Destroy(gameObject);
return;
}
instance = this;
moveAction = actions.FindActionMap("Gameplay").FindAction("Move");
moveAction.Enable();
}
private void Start()
{
LevelBuilder.Instance.LevelInitialized += OnLevelInitialized;
LevelBuilder.Instance.LevelDestroyed += OnLevelDestroy;
}
private void Update()
{
if (CanMove && moveAction.WasPressedThisFrame())
{
Vector2 directionFloat = moveAction.ReadValue<Vector2>();
directionFloat = Vector2.ClampMagnitude(directionFloat, 1f);
Vector2Int direction = Vector2Int.RoundToInt(directionFloat);
// Allow movement along single axis only
if (direction.x != 0 && direction.y != 0)
{
direction = new Vector2Int(direction.x, 0);
}
Move(direction);
}
}
public void Teleport(LayoutCell targetCell, bool clearOldCell=true)
{
LayoutCell currentCell = LevelBuilder.Instance.GetCellAtLayout(layoutPosition);
if (clearOldCell)
{
// Free previous cell
currentCell.cellData.cellContent = LayoutCell.LayoutCellData.CellContent.None;
}
// Occupy new cell
targetCell.cellData.cellContent = LayoutCell.LayoutCellData.CellContent.Player;
// Update position
layoutPosition = targetCell.layoutPosition;
transform.position = targetCell.worldPos;
}
public void Move(Vector2Int direction)
{
LayoutCell currentCell = LevelBuilder.Instance.GetCellAtLayout(layoutPosition);
LayoutCell targetCell = LevelBuilder.Instance.GetCellAtLayout(layoutPosition + direction);
if (targetCell == null)
{
return;
}
if (targetCell.IsFree)
{
// Free previous cell
currentCell.cellData.cellContent = LayoutCell.LayoutCellData.CellContent.None;
// Occupy new cell
targetCell.cellData.cellContent = LayoutCell.LayoutCellData.CellContent.Player;
// Update position
layoutPosition = layoutPosition + direction;
// Move object
isMoving = true;
transform.DOMove(targetCell.worldPos, 1f).OnComplete(() => isMoving = false);
}
else if (targetCell.cellData.cellContent == LayoutCell.LayoutCellData.CellContent.Crate)
{
targetCell.crate.Move(direction);
}
PlayerMoved?.Invoke();
}
private void OnLevelInitialized()
{
gameObject.SetActive(true);
Teleport(LevelBuilder.Instance.GetCellAtLayout(new Vector2Int(0, 0)), false);
}
private void OnLevelDestroy()
{
gameObject.SetActive(false);
}
}
}