You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.5 KiB
C#

using System.Collections.Generic;
using System.Linq;
namespace Otter {
public class Snake : Component {
public List<Vertebra> Vertebrae = new List<Vertebra>();
public float UpdateThreshold = 0.5f;
List<Vector2> positionLog = new List<Vector2>();
float lastX, lastY;
public int MaxLength { get; private set; }
public Vertebra Head {
get {
return Vertebrae.First();
}
}
public void Add(Vertebra v) {
Vertebrae.Add(v);
}
public void Add(Entity e, int distance) {
var v = new Vertebra();
v.SetEntity(e);
v.Distance = distance;
v.Snake = this;
Add(v);
}
public Snake() {
MaxLength = int.MaxValue;
}
public override void Added() {
base.Added();
positionLog.Insert(0, new Vector2(Entity.X, Entity.Y));
}
public override void Update() {
base.Update();
if (Util.Distance(lastX, lastY, Entity.X, Entity.Y) >= UpdateThreshold) {
positionLog.Insert(0, new Vector2(Entity.X, Entity.Y));
if (positionLog.Count > MaxLength) {
positionLog.RemoveAt(MaxLength);
}
}
var dist = 0;
for (int i = 0; i < Vertebrae.Count; i++) {
var v = Vertebrae[i];
dist += v.Distance;
v.TotalDistance = dist;
v.Update();
}
MaxLength = dist + 2; // Add 2 so the last vertebra can rotate correctly.
// Log the position.
lastX = Entity.X;
lastY = Entity.Y;
}
public Vector2 GetPosition(int distance) {
if (distance >= positionLog.Count) {
return positionLog.Last();
}
if (distance < 0) {
return positionLog.First();
}
return positionLog[distance];
}
public void AddAllVertebraeToScene() {
if (!Entity.IsInScene) return;
foreach (var v in Vertebrae) {
if (v.Entity == null) {
Entity.Scene.Add(v.Entity);
continue;
}
if (!v.Entity.IsInScene) {
Entity.Scene.Add(v.Entity);
}
}
}
}
}