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

@ -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);
}
}
}
}

@ -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,

Loading…
Cancel
Save