Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- public class Piece : MonoBehaviour
- {
- public enum PieceType
- {
- Red = 1,
- DarkGreen = 2,
- LightBlue = 3,
- Purple = 4,
- Yellow = 5,
- Comet = 6,
- Star = 7,
- Moon = 8,
- Sun = 9,
- All = 10,
- }
- public int X { get { return _x; } }
- public int Y { get { return _y; } }
- public int Z { get { return _z; } }
- public PieceType Type { get { return _type; } }
- public GameObject selectPrefab;
- public delegate void onNotityPieceStop(Piece piece, List<Piece> matches);
- public event onNotityPieceStop OnPieceStopped;
- [SerializeField] float _timeToMoveInSeconds = 0.3f; // in seconds.
- [SerializeField] float _selectTimeInSeconds = 2.0f; // in seconds.
- [SerializeField] PieceType _type;
- int _x;
- int _y;
- int _z;
- static Piece _clickedPiece = null;
- static Piece _targetPiece = null;
- static bool _isInDrag = false;
- static bool _isSelected = false;
- bool _isMoving = false;
- Board _board;
- Vector3 _previousPosition;
- bool _isReturning = false;
- void Awake()
- {
- _board = FindObjectOfType<Board>();
- }
- void Start()
- {
- OnPieceStopped += ClearOrSwitchBackHandeler;
- }
- protected virtual void ClearOrSwitchBackHandeler(Piece piece, List<Piece> matches)
- {
- var partnerPiece = _board.AllPieces[(int)_previousPosition.x, (int)_previousPosition.y];
- var partnerMatches = GetMatchesAt(partnerPiece);
- if (matches == null && partnerMatches == null) // Either this piece, and partner piece do not have matches, return to original spots.
- {
- if (!_isReturning)
- {
- _isReturning = true;
- MoveTo(_previousPosition, _timeToMoveInSeconds);
- return;
- }
- else
- {
- _isReturning = false;
- return;
- }
- }
- else if (matches == null && partnerMatches != null) // This piece doesn't have matches but partner does. Stand still, don't do anything.
- {
- return;
- }
- else if (matches != null)
- {
- foreach (var pieceToDestroy in matches)
- {
- _board.AllPieces[pieceToDestroy.X, pieceToDestroy.Y] = null;
- Destroy(pieceToDestroy.gameObject);
- }
- }
- }
- /// <summary>
- /// Set the Tile coördinates with x, y, z coordinates.
- /// </summary>
- /// <param name="x"></param>
- /// <param name="y"></param>
- /// <param name="z"></param>
- public void Set(int x, int y, int z = 0)
- {
- _x = x;
- _y = y;
- _z = z;
- }
- //TODO move to other class.
- // START OF Input based on touch input to move pieces.
- void OnMouseDown()
- {
- _isInDrag = true;
- if (_clickedPiece == null && _targetPiece == null)
- {
- _clickedPiece = this;
- }
- if (_clickedPiece != this && !_isSelected)
- {
- _clickedPiece = this;
- }
- else if(_clickedPiece != this && _isSelected)
- {
- CancelSelect();
- _targetPiece = this;
- SwitchPieces(_clickedPiece, _targetPiece);
- _clickedPiece = null;
- _targetPiece = null;
- }
- }
- void OnMouseEnter()
- {
- if (_isInDrag)
- {
- if (_clickedPiece != null && _clickedPiece != this)
- {
- _targetPiece = this;
- }
- }
- }
- void OnMouseUp()
- {
- _isInDrag = false;
- if (_clickedPiece != null && _targetPiece != null)
- {
- SwitchPieces(_clickedPiece, _targetPiece);
- _clickedPiece = null;
- _targetPiece = null;
- }
- if (_clickedPiece == this)
- {
- SelectPieceAt(transform.position);
- }
- }
- // END OF Input based on touch input to move pieces.
- void SelectPieceAt(Vector3 position)
- {
- if (!_isSelected)
- {
- _isSelected = true;
- StartCoroutine(SelectPieceRoutine(position));
- }
- }
- // Some other code regarding selecting a piece ( UI stuff )
- public void SwitchPieces(Piece clickedPiece, Piece targetPiece)
- {
- clickedPiece.MoveTo(targetPiece.transform.position, _timeToMoveInSeconds);
- targetPiece.MoveTo(clickedPiece.transform.position, _timeToMoveInSeconds);
- }
- public void MoveTo(Vector3 destination, float timeToMove)
- {
- StartCoroutine(MovePieceToRoutine(transform.position, destination, timeToMove));
- }
- IEnumerator MovePieceToRoutine(Vector3 startPosition, Vector3 destination, float timeToMove)
- {
- if (!_isMoving)
- {
- _previousPosition = startPosition;
- _isMoving = true;
- var reachedDestination = false;
- var elapsedTime = 0f;
- while (!reachedDestination)
- {
- var t = Mathf.Clamp(elapsedTime / timeToMove, 0f, 1f);
- t = t * t * t * (t * (t * 6 - 15) + 10); // Smootherstep interpolation formula.
- transform.position = Vector3.Lerp(startPosition, destination, t);
- elapsedTime += Time.deltaTime;
- if (Vector3.Distance(transform.position, destination) < 0.01f)
- {
- transform.position = destination;
- Set((int)destination.x, (int)destination.y);
- _board.AllPieces[X, Y] = this;
- reachedDestination = true;
- break;
- }
- yield return null;
- }
- _isMoving = false;
- OnPieceStopped(this, GetMatchesAt(this));
- yield break;
- }
- else
- {
- Debug.Log("MovePieceToRoutine: Piece is already moving.");
- }
- }
- //TODO Implement an event that checks for deadlocks.
- public List<Piece> GetMatchesAt(Piece startPiece, int minimumMatches = 3)
- {
- if (startPiece == null)
- {
- Debug.LogError("GetMatchesAt: variable startPiece is null. Returning null as match list.");
- return null;
- }
- var allMatches = new List<Piece>();
- var directionalList = new List<Piece>();
- var counter = 0;
- Vector2[] searchDirections = { Vector2.right, Vector2.left, Vector2.up, Vector2.down }; // Set directions of search, don't need other ones then these ones.
- foreach (var direction in searchDirections)
- {
- counter++;
- for (int i = 0; i < minimumMatches; i++)
- {
- Piece nextPiece = null;
- var nextPositionToCheck = new Vector2(startPiece.X + ((int)direction.x * i), startPiece.Y + ((int)direction.y * i)); // Calculate next position of the piece to check.
- if (isWithinBounds(nextPositionToCheck))
- {
- nextPiece = _board.AllPieces[(int)nextPositionToCheck.x, (int)nextPositionToCheck.y];
- }
- if (nextPiece == null || nextPiece._type != _type) // In case of hitting the edge of the board. Or empty spot.
- {
- break;
- }
- else if (!directionalList.Contains(nextPiece))
- {
- directionalList.Add(nextPiece);
- }
- }
- if (counter % 2 == 0) // So we seperate horizontal and vertical matches. Otherwise the count of matches gives nasty sideffects.
- {
- if (directionalList.Count >= minimumMatches)
- {
- allMatches = allMatches.Union(directionalList).ToList();
- directionalList.Clear();
- }
- directionalList.Clear();
- }
- }
- if (allMatches.Count >= minimumMatches)
- {
- return allMatches;
- }
- else
- {
- return null;
- }
- }
- bool isWithinBounds(Vector3 position)
- {
- if (position.x > _board.Width - 1 || position.x < 0 || position.y > _board.Height - 1 || position.y < 0 || position.z != 0)
- {
- return false;
- }
- return true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement