AI can smoothly approach a near required position

main
Benjamin Kraft 1 year ago
parent f1fea51cd6
commit 0df62f18f4
  1. 50
      Assets/Scripts/Game/AIPlayer.cs
  2. 14
      Assets/Scripts/Game/Player.cs

@ -6,13 +6,6 @@ namespace Game {
public class AIPlayer : Player { public class AIPlayer : Player {
/*
* Possible optimizations:
* - Try to hit ball with edge
*/
public Difficulty Difficulty { get; set; } public Difficulty Difficulty { get; set; }
private float FutureSeconds => (float) Difficulty * 0.5f; private float FutureSeconds => (float) Difficulty * 0.5f;
@ -41,14 +34,17 @@ namespace Game {
Vector2 m2 = e2 - o2; Vector2 m2 = e2 - o2;
/* /*
* o1x + r * m1x = o2x + s * m2x *
* o1y + r * m1y = o2y + s * m2y * o1 + r * m1 = 02 + s * m2
* *
* Solve for r and s: * o1x + r * m1x = o2x + s * m2x
* Formulas below achieved by reordering * o1y + r * m1y = o2y + s * m2y
* 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 * 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; float r, s;
if (m1.x != 0) { if (m1.x != 0) {
@ -72,6 +68,8 @@ namespace Game {
private float IdlePosition => Difficulty >= Difficulty.Medium ? 0 : X(); 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) { private bool IsPositionReachableInTime(float futurePosition, float seconds) {
float requiredDistance = Mathf.Abs(futurePosition - X()) - Width / 2; float requiredDistance = Mathf.Abs(futurePosition - X()) - Width / 2;
if (requiredDistance < 0) if (requiredDistance < 0)
@ -160,19 +158,33 @@ namespace Game {
return IdlePosition; return IdlePosition;
} }
private float currentSmoothV;
private void ApproachPosition(float pos) { 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() { private void FixedUpdate() {
float target = GetTargetPosition(); float target = GetTargetPosition();
const float h = 0.5f; float h = Width / 2;
goingLeft = target < X() - h; goingLeft = target < X() - h;
goingRight = target > X() + h; goingRight = target > X() + h;
if (goingLeft || goingRight) if (goingLeft || goingRight) {
isApproaching = false;
lastDirection = goingLeft ? -1 : 1;
TryLinearMove(Time.fixedDeltaTime); TryLinearMove(Time.fixedDeltaTime);
else }
else {
if (!isApproaching) {
isApproaching = true;
currentSmoothV = Speed * lastDirection;
}
ApproachPosition(target); ApproachPosition(target);
}
} }
} }
} }

@ -18,7 +18,7 @@ namespace Game {
protected float Speed => 10; protected float Speed => 10;
// Unit distance from zero // Unit distance from zero
private float Border => 10; private float Border => 7;
private SpeedModification speedModification; private SpeedModification speedModification;
private BorderModification borderModification; private BorderModification borderModification;
@ -36,16 +36,20 @@ namespace Game {
return transform.position.y; return transform.position.y;
} }
protected void TryLinearMove(float h) { protected void ClampInsideBorders() {
Vector2 trans = new Vector2((goingLeft ? -1 : 0) + (goingRight ? 1 : 0), 0);
trans *= Speed * h;
transform.Translate(trans);
if (LeftSide < -Border) if (LeftSide < -Border)
transform.Translate(Vector2.right * (-Border - LeftSide)); transform.Translate(Vector2.right * (-Border - LeftSide));
if (RightSide > Border) if (RightSide > Border)
transform.Translate(Vector2.left * (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() { private void Start() {
float y = Side switch { float y = Side switch {
ESide.Bottom => BorderSize.Singleton.y1, ESide.Bottom => BorderSize.Singleton.y1,

Loading…
Cancel
Save