Created
October 14, 2024 21:41
-
-
Save KVinS/d1581844d56efa193f3141fc28b35e4b to your computer and use it in GitHub Desktop.
Connect dots - Unity3D minigame
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using System.Collections.Generic; | |
using Unity.VisualScripting; | |
public class LineConnector : MonoBehaviour | |
{ | |
[SerializeField] private List<LineRenderer> _linesCash = new List<LineRenderer>(); | |
[SerializeField] private float _minDrawDistance = 0.05f; | |
[SerializeField] private float _radius = 5f; // Радиус игрового поля | |
[SerializeField] private LineLevel _level; | |
private bool isDrawingLine = false; | |
private Vector2 _lastDrawnPoint; | |
private LinePoint _startPoint; | |
private LineRenderer _currentLine; | |
private Dictionary<Color, LineRenderer> _lineRenderers = new Dictionary<Color, LineRenderer>(); | |
private void Start() | |
{ | |
} | |
private void TryStartDrawLine(Vector2 pos) | |
{ | |
foreach (var point in _level.Points) | |
{ | |
if (Vector2.Distance(pos, point.transform.position) < _minDrawDistance) | |
{ | |
if (_lineRenderers.ContainsKey(point.Color)) | |
{ | |
return; | |
} | |
_startPoint = point; | |
isDrawingLine = true; | |
_lastDrawnPoint = pos; | |
_currentLine = _linesCash[0]; | |
_linesCash.Remove(_currentLine); | |
_currentLine.positionCount = 1; | |
_currentLine.SetPosition(0, _startPoint.transform.position); | |
_currentLine.startColor = point.Color; | |
_currentLine.endColor = point.Color; | |
} | |
} | |
} | |
private void TryAddPoint(Vector2 pos) | |
{ | |
if (Vector2.Distance(pos, _lastDrawnPoint) >= _minDrawDistance) | |
{ | |
if (CheckLineIntersection(_lastDrawnPoint, pos)) | |
{ | |
StopDrawLine(); | |
return; | |
} | |
foreach (var point in _level.Points) | |
{ | |
if (Vector2.Distance(pos, point.transform.position) < _minDrawDistance && point.Color != _startPoint.Color) | |
{ | |
StopDrawLine(); | |
return; | |
} | |
} | |
_lastDrawnPoint = pos; | |
_currentLine.positionCount++; | |
_currentLine.SetPosition(_currentLine.positionCount - 1, _lastDrawnPoint); | |
} | |
} | |
private void StopDrawLine() | |
{ | |
if (isDrawingLine) | |
{ | |
_currentLine.positionCount = 0; | |
_linesCash.Add(_currentLine); | |
_lineRenderers.Remove(_startPoint.Color); | |
} | |
_currentLine = null; | |
isDrawingLine = false; | |
_startPoint = null; | |
} | |
private void Update() | |
{ | |
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); | |
if (Input.GetMouseButton(0)) | |
{ | |
if (!IsPointWithinCircle(mousePosition)) | |
{ | |
StopDrawLine(); | |
return; | |
} | |
// Начало рисования линии | |
if (isDrawingLine) | |
{ | |
TryAddPoint(mousePosition); | |
} | |
else | |
{ | |
TryStartDrawLine(mousePosition); | |
} | |
} else if (isDrawingLine) | |
{ | |
CheckLineCompletion(mousePosition); | |
} | |
} | |
private void CheckLineCompletion(Vector2 pos) | |
{ | |
bool checkWin = false; | |
foreach (var point in _level.Points) | |
{ | |
if (point != _startPoint && point.Color == _startPoint.Color && Vector2.Distance(pos, point.transform.position) < _minDrawDistance * 2) | |
{ | |
isDrawingLine = false; | |
_currentLine.SetPosition(_currentLine.positionCount - 1, point.transform.position); | |
_lineRenderers.Add(_startPoint.Color, _currentLine); | |
checkWin = true; | |
} | |
} | |
StopDrawLine(); | |
if (checkWin) | |
{ | |
if (_level.Points.Count / 2 == _lineRenderers.Count) | |
{ | |
Debug.Log("WIN"); | |
} | |
} | |
} | |
private bool IsPointWithinCircle(Vector2 point) | |
{ | |
return Vector3.Distance(point, Vector3.zero) <= _radius; | |
} | |
private bool CheckLineIntersection(Vector3 start, Vector3 end) | |
{ | |
foreach (LineRenderer line in _lineRenderers.Values) | |
{ | |
for (int i = 0; i < line.positionCount - 1; i++) | |
{ | |
Vector3 lineStart = line.GetPosition(i); | |
Vector3 lineEnd = line.GetPosition(i+1); | |
if (LineLineIntersection(start, end, lineStart, lineEnd)) | |
{ | |
return true; | |
} | |
} | |
} | |
for (int i = 0; i < _level.Borders.positionCount - 1; i++) | |
{ | |
Vector3 lineStart = _level.Borders.GetPosition(i); | |
Vector3 lineEnd = _level.Borders.GetPosition(i+1); | |
if (LineLineIntersection(start, end, lineStart, lineEnd)) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
private bool LineLineIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4) | |
{ | |
// Алгоритм проверки пересечения отрезков (прямая - отрезок) | |
float denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y); | |
if (denominator == 0) | |
{ | |
return false; // Линии параллельны или совпадают | |
} | |
float uA = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator; | |
float uB = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator; | |
return (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1); | |
} | |
// Метод для рестарта текущего уровня | |
public void RestartLevel() | |
{ | |
// Удаление всех линий | |
isDrawingLine = false; | |
} | |
// Метод для перехода к следующему уровню | |
public void NextLevel() | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class LineLevel : MonoBehaviour | |
{ | |
[SerializeField] private List<LinePoint> _points; | |
[SerializeField] private LineRenderer _borders; | |
public List<LinePoint> Points | |
{ | |
get { return _points; } | |
} | |
public LineRenderer Borders | |
{ | |
get { return _borders; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class LinePoint : MonoBehaviour | |
{ | |
[SerializeField] private Color _color; | |
public Color Color => _color; | |
[SerializeField] private SpriteRenderer _renderer; | |
private void Awake() | |
{ | |
_renderer.color = _color; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment