134 lines
3.9 KiB
ActionScript
134 lines
3.9 KiB
ActionScript
// Mover script object class
|
|
// - handles entity (enemy, platform...) translation along a path (set of Vector2 points)
|
|
// - supports looping paths and animation flip
|
|
// - default speed is 0.8 if 'Speed' property is not set in the tmx file objects
|
|
|
|
class Mover : ScriptObject
|
|
{
|
|
float speed = 0.8f;
|
|
Array<Vector2> path;
|
|
int currentPathID = 1;
|
|
float emitTime = 0.0f;
|
|
float fightTimer = 0.0f;
|
|
float flip = 0.0f;
|
|
uint bufferSize = 0;
|
|
|
|
void Load(Deserializer& deserializer)
|
|
{
|
|
bufferSize = deserializer.ReadUInt(); // Get buffer size
|
|
SetPathAttr(deserializer.ReadVectorBuffer(bufferSize));
|
|
}
|
|
|
|
void Save(Serializer& serializer)
|
|
{
|
|
serializer.WriteVectorBuffer(GetPathAttr(serializer));
|
|
}
|
|
|
|
void SetPathAttr(VectorBuffer buffer)
|
|
{
|
|
if (buffer.size == 0)
|
|
return;
|
|
|
|
while (!buffer.eof)
|
|
path.Push(buffer.ReadVector2());
|
|
}
|
|
|
|
VectorBuffer GetPathAttr(Serializer& serializer)
|
|
{
|
|
VectorBuffer buffer = VectorBuffer();
|
|
|
|
for (uint i=0; i < path.length; ++i)
|
|
buffer.WriteVector2(path[i]);
|
|
|
|
bufferSize = buffer.size;
|
|
serializer.WriteUInt(bufferSize);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
void Update(float timeStep)
|
|
{
|
|
if (path.length < 2)
|
|
return;
|
|
|
|
// Handle Orc states (idle/wounded/fighting)
|
|
if (node.name == "Orc")
|
|
{
|
|
AnimatedSprite2D@ animatedSprite = node.GetComponent("AnimatedSprite2D");
|
|
String anim = "run";
|
|
|
|
// Handle wounded state
|
|
if (emitTime > 0.0f)
|
|
{
|
|
emitTime += timeStep;
|
|
anim = "dead";
|
|
|
|
// Handle dead
|
|
if (emitTime >= 3.0f)
|
|
{
|
|
node.Remove();
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Handle fighting state
|
|
if (fightTimer > 0.0f)
|
|
{
|
|
anim = "attack";
|
|
flip = character2DNode.position.x - node.position.x;
|
|
fightTimer += timeStep;
|
|
if (fightTimer >= 3.0f)
|
|
fightTimer = 0.0f; // Reset
|
|
}
|
|
// Flip Orc animation according to speed, or player position when fighting
|
|
animatedSprite.flipX = flip >= 0.0f;
|
|
}
|
|
// Animate
|
|
if (animatedSprite.animation != anim)
|
|
animatedSprite.SetAnimation(anim);
|
|
}
|
|
|
|
// Don't move if fighting or wounded
|
|
if (fightTimer > 0.0f || emitTime > 0.0f)
|
|
return;
|
|
|
|
// Set direction and move to target
|
|
Vector2 dir = path[currentPathID] - node.position2D;
|
|
Vector2 dirNormal = dir.Normalized();
|
|
node.Translate(Vector3(dirNormal.x, dirNormal.y, 0.0f) * Abs(speed) * timeStep);
|
|
flip = dir.x;
|
|
|
|
// Check for new target to reach
|
|
if (Abs(dir.length) < 0.1f)
|
|
{
|
|
if (speed > 0.0f)
|
|
{
|
|
if (currentPathID + 1 < path.length)
|
|
currentPathID = currentPathID + 1;
|
|
else
|
|
{
|
|
// If loop, go to first waypoint, which equates to last one (and never reverse)
|
|
if (path[currentPathID] == path[0])
|
|
{
|
|
currentPathID = 1;
|
|
return;
|
|
}
|
|
// Reverse path if not looping
|
|
currentPathID = currentPathID - 1;
|
|
speed = -speed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currentPathID - 1 >= 0)
|
|
currentPathID = currentPathID - 1;
|
|
else
|
|
{
|
|
currentPathID = 1;
|
|
speed = -speed;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |