working on aiming
This commit is contained in:
@@ -22,7 +22,7 @@ public partial class Attack : RigidBody2D
|
||||
{
|
||||
base._PhysicsProcess(delta);
|
||||
if (_speed != Vector2.Zero){
|
||||
ApplyCentralImpulse(_speed);
|
||||
LinearVelocity = _speed;
|
||||
_speed = Vector2.Zero;
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public partial class Attack : RigidBody2D
|
||||
|
||||
public void Shoot(Vector2 FORCE){
|
||||
_speed = FORCE;
|
||||
// Set("velocity", FORCE);
|
||||
GravityScale = 1;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -47,7 +47,8 @@ public partial class PlayerController : TurnController
|
||||
|
||||
public override void StartTurn()
|
||||
{
|
||||
_towers.Where(t=> t._commander != null).ToList().ForEach(t=>t._commander._actions = t._commander._actionsMax);
|
||||
_towers.ForEach(t => t.StartTurn());
|
||||
// _towers.Where(t=> t._commander != null).ToList().ForEach(t=>t._commander._actions = t._commander._actionsMax);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,13 +6,19 @@ using System.Diagnostics;
|
||||
public partial class Tower : Sprite2D
|
||||
{
|
||||
public bool _hovered, _aiming;
|
||||
public Vector2 _aimOffset;
|
||||
public int _launchForce = 1000, _arcIterations = 50;
|
||||
public float _gravity, _drag;
|
||||
public Vector2 _aimOffset, _arcEnd;
|
||||
public List<Vector2> _arc = new();
|
||||
public Marker2D _offset, _attackSpawn;
|
||||
public Area2D _area;
|
||||
public Commander _commander;
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
_gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity");
|
||||
_drag = (float)ProjectSettings.GetSetting("physics/2d/default_linear_damp");
|
||||
|
||||
_area = GetNode<Area2D>("Area");
|
||||
_offset = GetNode<Marker2D>("Offset");
|
||||
_attackSpawn = GetNode<Marker2D>("AttackSpawn");
|
||||
@@ -24,6 +30,11 @@ public partial class Tower : Sprite2D
|
||||
{
|
||||
if (_aiming)
|
||||
{
|
||||
if (_arcEnd != GetGlobalMousePosition())
|
||||
{
|
||||
CalculateLaunchAngle(_attackSpawn.GlobalPosition, GetGlobalMousePosition(), _launchForce, _gravity, _drag);
|
||||
DrawArc();
|
||||
}
|
||||
if (Input.IsActionJustPressed("rightClick"))
|
||||
{
|
||||
_commander.UnloadAttack();
|
||||
@@ -32,14 +43,15 @@ public partial class Tower : Sprite2D
|
||||
else if (Input.IsActionJustPressed("leftClick"))
|
||||
{
|
||||
|
||||
_aimOffset = GetGlobalMousePosition() - GlobalPosition;
|
||||
_aimOffset = CalculateLaunchAngle(_attackSpawn.GlobalPosition, GetGlobalMousePosition(), _launchForce, _gravity, _drag);
|
||||
|
||||
_commander.ShootCurrentAttack(_aimOffset);
|
||||
_aiming = false;
|
||||
}
|
||||
}
|
||||
if (Input.IsActionJustPressed("leftClick"))
|
||||
else if (_hovered)
|
||||
{
|
||||
if (_hovered)
|
||||
if (Input.IsActionJustPressed("leftClick"))
|
||||
{
|
||||
_aiming = true;
|
||||
_commander.LoadAttack(_attackSpawn.Position);
|
||||
@@ -48,28 +60,102 @@ public partial class Tower : Sprite2D
|
||||
}
|
||||
}
|
||||
|
||||
public List<Vector2> PredictPath()
|
||||
public Vector2 CalculateLaunchAngle(Vector2 startPos, Vector2 targetPos, float launchSpeed, float gravity, float drag, int maxIterations = 20)
|
||||
{
|
||||
Vector2 velocity = _aimOffset;
|
||||
float timeBetweenSteps = 0.05f;
|
||||
Vector2 startPosition = _attackSpawn.Position;
|
||||
float gravity = -(float)ProjectSettings.GetSetting("physics/2d/default_gravity", 980.0f);
|
||||
float drag = (float)ProjectSettings.GetSetting("physics/2d/default_linear_damp", 0.0f);
|
||||
|
||||
List<Vector2> points = [startPosition];
|
||||
for (int i = 0; i < 151; i++)
|
||||
{
|
||||
velocity.Y += gravity * timeBetweenSteps;
|
||||
// GD.Print(velocity);
|
||||
velocity *= (float)Math.Clamp(1.0 - drag * timeBetweenSteps, 0, 1);
|
||||
Vector2 toTarget = targetPos - startPos;
|
||||
float baseAngle = toTarget.Angle(); // Directly pointing at the target
|
||||
|
||||
points.Add(points[^1] + velocity);
|
||||
// Pure vertical angle going straight up (-Y is up in Godot)
|
||||
float straightUpAngle = -Mathf.Pi / 2.0f;
|
||||
|
||||
// We use a normalized 0.0 to 1.0 search range to avoid radian sign confusion
|
||||
float lowT = 0.0f; // 0% = pointing straight at target
|
||||
float highT = 1.0f; // 100% = pointing straight up
|
||||
|
||||
float bestAngle = baseAngle;
|
||||
float delta = 1.0f / 60.0f; // Matches standard physics step
|
||||
|
||||
for (int i = 0; i < maxIterations; i++)
|
||||
{
|
||||
float testT = (lowT + highT) / 2.0f;
|
||||
|
||||
// Interpolate smoothly between the base angle and straight up
|
||||
float testAngle = Mathf.LerpAngle(baseAngle, straightUpAngle, testT);
|
||||
|
||||
float error = EvaluateSimulationError(testAngle, startPos, targetPos, launchSpeed, gravity, drag, delta);
|
||||
|
||||
if (Mathf.Abs(error) < 0.2f)
|
||||
{
|
||||
bestAngle = testAngle;
|
||||
break;
|
||||
}
|
||||
|
||||
// error > 0 means the simulated projectile landed below the target (+Y is down)
|
||||
if (error > 0)
|
||||
{
|
||||
// It fell short or low. We need to loft it higher up (move toward 1.0)
|
||||
lowT = testT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// It flew over the target. We need to lower the arc (move toward 0.0)
|
||||
highT = testT;
|
||||
}
|
||||
|
||||
bestAngle = testAngle;
|
||||
}
|
||||
return points;
|
||||
|
||||
return Vector2.FromAngle(bestAngle) * _launchForce;
|
||||
}
|
||||
|
||||
// public Dictionary<> Ra
|
||||
public void DrawArc()
|
||||
{
|
||||
Path2D path = _commander._attack.GetNode<Path2D>("PredictedPath");
|
||||
path.Curve.ClearPoints();
|
||||
for (int i = 0; i < _arc.Count; i++)
|
||||
{
|
||||
path.Curve.AddPoint(_arc[i]);
|
||||
}
|
||||
GD.Print(path.Curve.PointCount);
|
||||
}
|
||||
|
||||
private float EvaluateSimulationError(float angle, Vector2 start, Vector2 target, float speed, float gravity, float drag, float delta)
|
||||
{
|
||||
Vector2 velocity = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * speed;
|
||||
Vector2 position = start;
|
||||
|
||||
float directionSign = Mathf.Sign(target.X - start.X);
|
||||
float maxFlightTime = 6.0f;
|
||||
int totalSteps = (int)(maxFlightTime / delta);
|
||||
_arc = [start];
|
||||
|
||||
for (int step = 0; step < totalSteps; step++)
|
||||
{
|
||||
velocity.Y += gravity * delta;
|
||||
velocity -= velocity * drag * delta;
|
||||
position += velocity * delta;
|
||||
_arc.Add(position);
|
||||
|
||||
// Check if our projectile crossed the target line on the X axis
|
||||
bool reachedTargetX = (directionSign >= 0) ? (position.X >= target.X) : (position.X <= target.X);
|
||||
|
||||
if (reachedTargetX)
|
||||
{
|
||||
return position.Y - target.Y;
|
||||
}
|
||||
}
|
||||
_arcEnd = _arc[^1];
|
||||
// If it ran out of time or hit a wall before crossing target.X, penalize it heavily
|
||||
return (position.Y > target.Y) ? 99999f : -99999f;
|
||||
}
|
||||
|
||||
public void StartTurn()
|
||||
{
|
||||
if (_commander != null)
|
||||
{
|
||||
_commander._actions = _commander._actionsMax;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMouseEntered(){
|
||||
_hovered = true;
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
[ext_resource type="Script" uid="uid://dm2gyxmgwbmg8" path="res://Attack.cs" id="1_63pi1"]
|
||||
[ext_resource type="Texture2D" uid="uid://nwj4n7if8kqd" path="res://Art/circle25r.png" id="2_hqc8w"]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_63pi1"]
|
||||
bounce = 0.25
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_7yfhp"]
|
||||
radius = 8.0
|
||||
|
||||
@@ -10,6 +13,7 @@ radius = 8.0
|
||||
|
||||
[node name="Attack" type="RigidBody2D" unique_id=1225359241]
|
||||
input_pickable = true
|
||||
physics_material_override = SubResource("PhysicsMaterial_63pi1")
|
||||
contact_monitor = true
|
||||
max_contacts_reported = 100
|
||||
script = ExtResource("1_63pi1")
|
||||
@@ -23,6 +27,7 @@ texture = ExtResource("2_hqc8w")
|
||||
|
||||
[node name="PredictedPath" type="Path2D" parent="." unique_id=1505290715]
|
||||
modulate = Color(1, 0, 1, 1)
|
||||
top_level = true
|
||||
curve = SubResource("Curve2D_63pi1")
|
||||
|
||||
[connection signal="body_entered" from="." to="." method="TakeAction"]
|
||||
|
||||
Reference in New Issue
Block a user