diff --git a/Assets/Scripts/Game/AIPlayer.cs b/Assets/Scripts/Game/AIPlayer.cs index 96ce0fa..0f3435b 100644 --- a/Assets/Scripts/Game/AIPlayer.cs +++ b/Assets/Scripts/Game/AIPlayer.cs @@ -5,14 +5,7 @@ using UnityEngine; namespace Game { public class AIPlayer : Player { - - /* - * Possible optimizations: - * - Try to hit ball with edge - */ - - public Difficulty Difficulty { get; set; } private float FutureSeconds => (float) Difficulty * 0.5f; @@ -41,14 +34,17 @@ namespace Game { Vector2 m2 = e2 - o2; /* - * o1x + r * m1x = o2x + s * m2x - * o1y + r * m1y = o2y + s * m2y - * - * Solve for r and s: - * Formulas below achieved by reordering - * Order is irrelevant, but if m1x == 0 then first approach results in division by zero -> - * Invert order then, and if division by zero is still a problem, both lines are parallel anyway - */ + * + * o1 + r * m1 = 02 + s * m2 + * + * o1x + r * m1x = o2x + s * m2x + * o1y + r * m1y = o2y + s * m2y + * + * Solve for r and s: + * Formulas below achieved by reordering + * Order is irrelevant, but if m1x == 0 then first approach results in division by zero -> + * Invert order then, and if division by zero is still a problem, both lines are parallel anyway + */ float r, s; if (m1.x != 0) { @@ -72,6 +68,8 @@ namespace Game { private float IdlePosition => Difficulty >= Difficulty.Medium ? 0 : X(); + // TODO solution for balls outside of border + // TODO Also must include fact that players have a height, maybe check the incoming angle private bool IsPositionReachableInTime(float futurePosition, float seconds) { float requiredDistance = Mathf.Abs(futurePosition - X()) - Width / 2; if (requiredDistance < 0) @@ -160,19 +158,33 @@ namespace Game { return IdlePosition; } + private float currentSmoothV; private void ApproachPosition(float pos) { - // Move smoothly, velocity capped by Speed + float result = Mathf.SmoothDamp(X(), pos, ref currentSmoothV, .5f); + transform.position = new Vector2(result, Y()); + ClampInsideBorders(); } + private bool isApproaching; + private float lastDirection; private void FixedUpdate() { float target = GetTargetPosition(); - const float h = 0.5f; + float h = Width / 2; goingLeft = target < X() - h; goingRight = target > X() + h; - if (goingLeft || goingRight) + if (goingLeft || goingRight) { + isApproaching = false; + lastDirection = goingLeft ? -1 : 1; TryLinearMove(Time.fixedDeltaTime); - else + } + else { + if (!isApproaching) { + isApproaching = true; + currentSmoothV = Speed * lastDirection; + } ApproachPosition(target); + } + } } } \ No newline at end of file diff --git a/Assets/Scripts/Game/Player.cs b/Assets/Scripts/Game/Player.cs index fd9b1f5..0538915 100644 --- a/Assets/Scripts/Game/Player.cs +++ b/Assets/Scripts/Game/Player.cs @@ -18,7 +18,7 @@ namespace Game { protected float Speed => 10; // Unit distance from zero - private float Border => 10; + private float Border => 7; private SpeedModification speedModification; private BorderModification borderModification; @@ -36,16 +36,20 @@ namespace Game { return transform.position.y; } - protected void TryLinearMove(float h) { - Vector2 trans = new Vector2((goingLeft ? -1 : 0) + (goingRight ? 1 : 0), 0); - trans *= Speed * h; - transform.Translate(trans); + protected void ClampInsideBorders() { if (LeftSide < -Border) transform.Translate(Vector2.right * (-Border - LeftSide)); if (RightSide > Border) transform.Translate(Vector2.left * (RightSide - Border)); } + protected void TryLinearMove(float h) { + Vector2 trans = new Vector2((goingLeft ? -1 : 0) + (goingRight ? 1 : 0), 0); + trans *= Speed * h; + transform.Translate(trans); + ClampInsideBorders(); + } + private void Start() { float y = Side switch { ESide.Bottom => BorderSize.Singleton.y1,